CI catalog - FE architectural blueprint
Architectural discussion: CI catalog
The CI catalog is a collection of CI components. The main goal of the page is to allow components to be discovered with ease.
Depending on this thread answer, we will adjust the strategy for the page.
General structure
We will store all components for the catalog under EE
for now because the feature, although planned to be available to some extent as a free feature, is not the case now. Therefore, we are legally required to put our files in EE folder. I would propose ee/app/assets/javascript/ci/catalog
There, we want a typical structure of the following subfolders:
- components
- graphql
- utils
At the root of private
directory, we want the entry points of the app including the Vue app itself ci_private_catalog_app.vue
and the index.js
file which creates the app entry point.
Public vs Private CI components
We are going to have two pages: one is for the private catalog and one is for the public one. For the MVC, we are going to have only one page, which is the private catalog.
However, we need to structure our code so that we can differentiate what are shared components between the 2 and what will be unique. We should aim to have as much as possible that could be shared and used independently. Therefore, we should aim to create common interfaces for things like a list of components. The list should get data from its parent so that we can pass whatever list we need/want. Therefore, things like searching, filtering or just being on a different page will be handle by a parent component so that the list can be reused in any context.
There is a high likelihood that private catalog will see more features than public ones. Therefore, as we are starting with the private catalog, we should keep in mind that anything that we know for a fact will differ from the public one should have a generalized approach. For example, if we know that a section of a list Item will change in the private or public catalog, then it could be done via a prop or slot.
On the other hand, if we are not 100% sure, then we should not eagerly optimize/generalize to avoid unnecessary complexity. The following section is my suggestion of a compromise of flexibility and structure for the MVC.
Data flow
Chart
Reasoning
The whole structure has been designed keeping in mind the fact that eventually, we are going to want a public catalog. If we decided not to have 2 versions, but rather one page that behave differently for EE and CE, then the proposed structure could be adapted as well. The important part is to ensure is that the entry point of the private catalog lives in in EE
directory given that it is an ultimate feature. This way, we do not include the mounting app code if a user is not a paying user for self-hosted. If/when we have a public directory, then we could either have a different entry point in CE folder for a different page OR we could conditionally load the public catalog with ee_else_ce
to get either the EE version of the public catalog or the free version.
Then, we want to use VueRouter as the catalog app will be a SPA (single page application). To make sharing URLs to component easier, we will have a route for the main list and one for a specific item. We should also have query params for search and filter, to allow users to share search results or favourite their search.
Then we have 1 top level component (for now) which is ci_private_catalog_app.vue
. This should also live in the EE folder and will be responsible for providing data that might differ in the public catalog. This should include things like the title and desc of the page + the graphql query to execute. We can copy the variable structure where we let the shared child component execute the queries, but the parent defined what they are. We already know that a public catalog would have a different graphQL query because they will not be fetched by namespaces, but rather for all of gitlab. We could make a fragment for the CiComponents
field to allow easier reuse (see #393567 (closed))
Then we for all of the children components, they should not be in EE folder because they can be used for the public catalog as well. The shared component will execute queries and handle pagination and the like, the home component will display data and so on all the way to the bottom of the structure.
If/when we need to extend functionality to a public catalog, then all components from the tree starting with the shared graphql component can be reuse with barely any change. So if we keep the private and public catalog separate, we can grow the section by having specific EE components version of the "shared" components that live in the normal repository. If we end up with one page for all (public and private live under gitlab.com/catalog) then we would have only one mounting point, but we would still have to use something like ee_else_ce
to mount either the EE version of the component (which would in itself then use all the EE versions of the sub components) or the CE version.
Another important point is that the top structure of the app itself will then descend into the home
component which will have the router to handle different page. Then, each "route" child component will have its own graphqL queries at the "root" level, so I think when constructing the directory structures, we should make each of the pages name end with page
and put each of them in the same folder, probably components/pages
Overall, this structure should allow us to ship the MVC with a structure that can support either direction without much overhead.