Add a configurable footer to analytics dashboard panels
What does this MR do and why?
The DAP Impact design puts a link at the bottom of each Overview panel that takes the user to another tab of the same dashboard. Analytics dashboard panels had no way to render anything below the body, so this adds a footer to the panel schema and drives the link from the dashboard YAML.
footer:
dashboardViewLink:
text: View adoption
view: 1The destination is a view rather than a URL, which keeps arbitrary user-authored destinations out of the config, so there is no scheme to validate and no off-instance link to reason about.
Some notes on the shape:
textfollows the existingViewdefinition, which already uses it for the label of a view-switching control.titlewould collide withpanel.titleand with the HTMLtitleattribute.viewis a positional index because that is the contract the?view=query param already uses, chosen there because view titles are neither guaranteed unique nor URL-safe. Footers move to a slug alongside the query param.- Nesting under
dashboardViewLinkleaves room for other footer content, such as an external link or a progress bar, without a breaking schema change.
GlDashboardPanel exposes no slot for content below the panel body, so ExtendedDashboardPanel builds one by splitting its body slot into a column: the body content takes the remaining space and keeps the scroll container, and the footer sits below it. Appending the footer as a plain child of the body would not work, because that div is gl-grow gl-overflow-y-auto and a visualization rendering at height: 100% already fills it, so the footer would scroll out of view. The wrapper is temporary and can go once GlDashboardPanel has a footer slot of its own.
Two consequences worth calling out for review:
- The dashboard moves to the compact grid. A footer takes part of a panel's fixed height, and the default grid sizes a cell at 137px, so a stat panel could only be one row, which clipped the footer, or two, which was far taller than the design. The compact grid's cells are 10px, so the stat panels sit at 150px and the bar chart keeps roughly the 550px it had.
- Selecting the compact grid needed fixing first. The distinction isn't custom vs. system dashboards, it's which route serves the dashboard.
dashboard_loader.vue(the/exploreroute) reads the raw stored config, where the schema spells the valuecompact. The other route, served throughanalytics_dashboard.vue, readsgridHeightoff a GraphQL enum field, which serialises to the enum nameCOMPACT. The comparison indashboard_loader.vuewas checking for the enum name, so on this route the compact grid silently fell back to the default cell. Nothing had hit this before because the three dashboards that use the compact grid all render through the other route.
Only the /explore route is wired up. The custom-dashboard route does not request dashboard-level views, so a view index has nothing to point at there.
No changelog entry: the /explore route sits behind the default-off explore_analytics_dashboards feature flag.
Documentation is deliberately deferred until the config shape settles, since the footer content types and the view reference are both expected to change.
References
- Closes https://gitlab.com/gitlab-org/gitlab/-/issues/627609
- Discussion this came out of: https://gitlab.com/gitlab-org/gitlab/-/issues/622352#note_3773356786
- Upstream footer slot, which retires the wrapper: gitlab-org/gitlab-services/design.gitlab.com#3629 (closed)
- View slug, which the
viewindex migrates to: #607444
Screenshots or screen recordings
| Before | After |
|---|---|
![]() |
![]() |
How to set up and validate locally
-
Enable the feature flag in the Rails console:
Feature.enable(:explore_analytics_dashboards) -
Visit
/explore/analytics_dashboardsand open DAP Impact. -
Select a namespace, so the panels render.
-
Each Overview panel shows a link at the bottom: the two adoption stats link to Adoption, completed sessions to Work, and both credit panels to Spend.
-
Click one. The target tab activates and the URL becomes
?view=<index>without a page reload. Browser Back returns to Overview and the tab strip follows. Middle-clicking opens the target view in a new tab. -
Check the tall Where credits went panel: the footer stays pinned and the panel body does not scroll.
-
Panels without a
footerare unchanged.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

