Context
The list page now consumes most of the @dashboard(...) annotation: layout:"kanban" drives a list↔board toggle (#commit 0973ef2) and sort_default seeds the initial sort (2aa7584). The one part still unconsumed is widgets.
The demo schema declares, e.g. on Deal:
@dashboard(widgets: ["count", "sum:value", "avg:value"], layout: "kanban", group_by: "stage", sort_default: "-expected_close")
widgets is a list of aggregate specs — count, sum:<field>, avg:<field> (and likely min/max) — that imply a row of KPI tiles above the list/board summarizing the current result set.
Proposed work
Following the established atomic layering (atoms → molecules → organisms; see 8453911 / 9fe67d2):
- Atoms (
@schemaforge/react/atoms), each with an Atoms/<Name> Storybook story:
KpiStat — a labeled metric tile (label + value + optional trend glyph; trend uses glyph + sr-only word + color, never color alone).
MeterBar / StackedBar — proportional bars (can reuse/promote the existing Meter atom).
- Pure helper (
@schemaforge/client): parse a widgets: string[] spec into { kind: "count"|"sum"|"avg"|…, field?: string }[], and compute the aggregates over the fetched rows. Pure + unit-testable.
- Organism
KpiRow (or fold into the list page): render one tile per parsed widget above the table/board, in both List and Board views.
- Wire into
apps/console/src/pages/entity-list.tsx using meta.data.dashboard.widgets.
Open questions
- Aggregates over the current page vs. the whole result set?
count already has total_count from the list envelope; sum/avg over only the fetched page would be misleading. May need a server-side aggregation endpoint, or compute over the full set when small. Flag/log the scope so a page-only aggregate never reads as a total.
- Currency/format-aware tile values via the shared
/format helpers.
a11y
Per the project's 508 posture (these are OSS packages, conformance is on us): tiles need real accessible names, trend conveyed by glyph + sr-only text, AA contrast.
Context
The list page now consumes most of the
@dashboard(...)annotation:layout:"kanban"drives a list↔board toggle (#commit0973ef2) andsort_defaultseeds the initial sort (2aa7584). The one part still unconsumed iswidgets.The demo schema declares, e.g. on
Deal:widgetsis a list of aggregate specs —count,sum:<field>,avg:<field>(and likelymin/max) — that imply a row of KPI tiles above the list/board summarizing the current result set.Proposed work
Following the established atomic layering (atoms → molecules → organisms; see
8453911/9fe67d2):@schemaforge/react/atoms), each with anAtoms/<Name>Storybook story:KpiStat— a labeled metric tile (label + value + optional trend glyph; trend uses glyph + sr-only word + color, never color alone).MeterBar/StackedBar— proportional bars (can reuse/promote the existingMeteratom).@schemaforge/client): parse awidgets: string[]spec into{ kind: "count"|"sum"|"avg"|…, field?: string }[], and compute the aggregates over the fetched rows. Pure + unit-testable.KpiRow(or fold into the list page): render one tile per parsed widget above the table/board, in both List and Board views.apps/console/src/pages/entity-list.tsxusingmeta.data.dashboard.widgets.Open questions
countalready hastotal_countfrom the list envelope;sum/avgover only the fetched page would be misleading. May need a server-side aggregation endpoint, or compute over the full set when small. Flag/logthe scope so a page-only aggregate never reads as a total./formathelpers.a11y
Per the project's 508 posture (these are OSS packages, conformance is on us): tiles need real accessible names, trend conveyed by glyph + sr-only text, AA contrast.