FE - Cycle analytics architecture improvements
## Background
Recently we built out group level cycle analytics, this involved moving cycle analytics from a project level, to a group level and [refactoring existing HAML](https://gitlab.com/gitlab-org/gitlab/merge_requests/15039) functionality into Vue components. The initial approach was to simply port existing functionality as we were preparing to add new features.
Since then we have been building additional features:
- [Customizable cycle analytics](https://gitlab.com/gitlab-org/gitlab-ee/issues/12196)
- [Group analytics over time charts](https://gitlab.com/gitlab-org/gitlab/issues/12755)
- [Visualizing tasks by type](https://gitlab.com/gitlab-org/gitlab/issues/32421)
- [Visualizing flow of tasks](https://gitlab.com/gitlab-org/gitlab/issues/32422)
Previously we had a single endpoint for cycle analytics data, but by completion of https://gitlab.com/gitlab-org/gitlab-ee/issues/12196 we will have multiple endpoints to fetch individual sections of data. Additionally we now have multiple "top-level" components that have different data requirements.

| Endpoint | Result |
| --- | --- |
| `GET` /-/analytics/cycle_analytics/summary | returns: Summary data |
| `GET\|POST` /-/analytics/cycle_analytics/stages | returns: Stages, Custom stage events, post creates a custom stage |
| `GET` /-/analytics/cycle_analytics/stages/:stage_id/records | returns: Stage events |
| `GET` /-/analytics/cycle_analytics/stages/:stage_id/median | returns: Stage median value |
| `GET` /-/analytics/cycle_analytics/stages/:stage_id/duration_chart | returns: Duration chart data |
| `GET\|PUT\|DELETE` /-/analytics/cycle_analytics/stages/:stage_id | returns a stage, update / delete stage |
| `GET` /groups/:group_id/-/labels | returns: Group labels |
| `GET` /-/analytics/type_of_work/tasks_by_type | returns: Task by type data |
| `GET` /-/analytics/type_of_work/tasks_by_stage - not implemented yet | I expect this would return the Tasks by stage data |
| Section | Summary data | Stages | Group labels | Stage events | Stage medians | Tasks by type | Tasks by stage | Custom stage events | Duration chart data |
| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
| A | [x] | [ ] | [ ] | [ ] | [ ] | [ ] | [ ] | [ ] | [ ] |
| B | [ ] | [x] | [x] | [x] | [x] | [ ] | [ ] | [x] | [ ] |
| C | [ ] | [x] | [ ] | [ ] | [ ] | [ ] | [ ] | [ ] | [x] |
| D | [ ] | [ ] | [x] | [ ] | [ ] | [x] | [ ] | [ ] | [ ] |
| E | [ ] | [ ] | [x] | [ ] | [ ] | [ ] | [x] | [ ] | [ ] |
## Challenges
After a group is selected a series of request are sent to fetch the data required to render the stage table and charts required.
* Multiple requests to different endpoints needed to fetch all the required data
* Vuex store is getting quite large with some dependent requests
- Stage medians requires Stages request first
- Stage events requires Stages request first
- Tasks by type requires group labels
## Possible improvements
### Split `/-/analytics/cycle_analytics/stages` endpoint
Currently this endpoint returns the stages for cycle analytics as well as the events needed to create a custom analytics stage, changes to the stage list (adding a stage, hiding a default stage, removing a custom stage and eventually updating the order of stages) require a refetch to the endpoint to retrieve the updated list of stages, returning the custom stage events seems a bit wasteful here.
#### Pros
* We only fetch the custom stage events when we need them (when we display the form)
* Clearer purpose for the endpoint
#### Cons
* Another endpoint
* Possibly premature optimization / yak-shaving
### Split the major components into several modules
We should be able to confidently split the `base.vue` component into smaller modules, similar to the approach taken for [productivity analytics](https://gitlab.com/gitlab-org/gitlab/tree/master/ee/app/assets/javascripts/analytics/productivity_analytics/store):
- Summary data (A)
- Stage table (B)
- Charts (C, D, E)
This should provide a clearer distinction between the data and requests needed for a specific module and the data needed across all the modules.
#### Pros
- Seems to be an [accepted Vuex pattern](https://vuex.vuejs.org/guide/modules.html)
- Gives us smaller more maintainable apps to work with moving forward
- Similar approach already taken with [productivity analytics]() so we would be adding consistency to analytics
- We can better work independently on new features / enhancements with less conflicts
- Easier to progressively load parts of the page as requests for data complete
#### Cons
- Some refactoring required
- Probably additional testing needed
### Move requests to a graphql endpoint
We have graphql available but have not explored this yet for analytics features, if part of our vision is to provide graphql as the [main way to interact with our APIs](https://docs.gitlab.com/ee/api/graphql/#vision), now seems like a good time to explore what this might mean for analytics.
#### Pros
- Single endpoint for all our current data
- Easier discoverability of cycle analytics data when building FE features
- Looser coupling between UI and API endpoints
- Good opportunity to understand potential issues we will encounter moving analytics endpoints to graphql
#### Cons
- Needs a bit more investigation
- Extra time needed to get up to speed + possibly more engineering burden
- Adding another layer of complexity
### Continue along
#### Pros
* We can continue to ship features
* No additional work required
* We can continue to iterate on possible ways forward while gathering user feedback
#### Cons
* Potentially harder to bring new FE's up to speed since theres already a lot going on
* More moving parts that are interrelated, more chance of bugs / regressions
* Kicking the can down the road, future features will probably be more time consuming to develop than they need to be
epic