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: 1

The 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:

  • text follows the existing View definition, which already uses it for the label of a view-switching control. title would collide with panel.title and with the HTML title attribute.
  • view is 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 dashboardViewLink leaves 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:

  1. 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.
  2. 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 /explore route) reads the raw stored config, where the schema spells the value compact. The other route, served through analytics_dashboard.vue, reads gridHeight off a GraphQL enum field, which serialises to the enum name COMPACT. The comparison in dashboard_loader.vue was 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

Screenshots or screen recordings

Before After
Screenshot 2026-09-03 at 4.31.18 PM.png Screenshot 2026-09-03 at 3.30.19 PM.png

How to set up and validate locally

  1. Enable the feature flag in the Rails console:

    Feature.enable(:explore_analytics_dashboards)
  2. Visit /explore/analytics_dashboards and open DAP Impact.

  3. Select a namespace, so the panels render.

  4. 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.

  5. 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.

  6. Check the tall Where credits went panel: the footer stays pinned and the panel body does not scroll.

  7. Panels without a footer are 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.

Edited by Rudy Crespo

Merge request reports

Loading
Loading