Adds the Sovereign Dashboard surface at
/sovereign/provision/$deploymentId/dashboard rendering a Recharts
<Treemap> where box AREA tracks the selected resource limit and box
COLOR is a continuous gradient (blue -> green -> red) over a
selectable utilisation/health/age metric. Toolbar lets the operator
pick Size, Color, and up to 4 nested Layer dimensions
(sovereign/cluster/family/namespace/application). Capacity size
metrics auto-lock the colour scale to utilisation. Drill-down walks
the in-memory tree (no refetch); breadcrumb chips pop back. Hover
yields a viewport-clamped tooltip with a deep link to AppDetail.
Architecture notes baked into the code:
- Module-level callback refs (_onCellHover/_onCellClick/_activeColorFn
/_itemsByName) are required because Recharts clones the cell content
component without preserving React closures or hooks.
- Parent-bounds Map clips child labels under the 24px nested header
strip so a tall narrow child can't render under its parent's title.
- Cell renderers gate label visibility on width >= 50px / height >= 24px
to avoid noisy text on tiny cells.
- isAnimationActive=false for perf on 500+ cells.
Backend (catalyst-api):
- New GET /api/v1/dashboard/treemap?group_by=A,B&color_by=C&size_by=D
returning the nested TreemapItem[] shape the UI consumes.
- v1 emits a static placeholder shape derived from the canonical
Catalyst-Zero family list (20 cells across 6 families). The HTTP
schema is the target schema; only the data SOURCE is a placeholder.
Replacing it with metrics-server integration is a follow-up.
Tests:
- 30 colour-gradient + drill-walk unit tests in
src/lib/treemap.types.test.ts (0%->blue, 50%->green, 100%->red,
interpolation, walk, query string).
- 9 controller toolbar tests (add/remove layer caps, capacity-metric
auto-lock, dimension exclusion).
- 6 Dashboard render tests (toolbar, empty state, total count,
breadcrumb root chip).
- 6 Go handler tests (default/nested response shape, dimension/colour/
size validation, percentage-in-range invariant).
Sidebar gets a Dashboard nav entry. Sidebar.test updated to reflect.
Vite dev proxy gains a /sovereign/api passthrough (rewrites to /api)
so dev mirrors the production traefik prefix-strip.
Co-authored-by: hatiyildiz <hatice.yildiz@openova.io>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>