Appearance
Business widgets
Business widgets are Organisms under organisms/widgets/ — one flat folder per Figma master pattern. They compose a chart primitive (or a table) with a header, optional objective footer, loading / error / empty states, and a filters popover. They are props-driven skeletons: no fetch, no store.
Live demos
The links below open each widget's Storybook page on Chromatic. Run Storybook locally with bun run storybook (default http://localhost:6006).
Master widgets
| Widget | Role | Primitive | Storybook |
|---|---|---|---|
RoKPIWidget | KPI value + sparkline (compact 1x1 variant) | sparkline | Open |
RoGaugeWidget | Gauge toward an objective (SLA, CSAT, QoS) | RoGauge | Open |
RoDonutWidget | Proportional breakdown | RoDonutChart | Open |
RoBarChartWidget | Comparison by period / category | RoBarChart | Open |
RoLineChartWidget | Temporal trend | RoLineChart | Open |
RoHeatmapWidget | Day x hour intensity | RoHeatmap | Open |
RoTableWidget | Multi-column table (sort, filters, virtualization) | RoTable (ringo-ui) | Open |
RoLeaderboardWidget | Agent / group ranking | — | Open |
RoSankeyWidget | Flow between stages (IVR -> group -> agent) | RoSankey | Open |
RoWorldMapWidget | Geographic distribution | RoWorldMap | Open |
RoTextWidget | Rich text / team note (TipTap) | — | Open |
RoTimelineWidget | Agent activity timeline (daily gantt-style view) | — | Open |
RoCallActivityWidget | Compact 1x1 single-metric tile | — | Open |
RoQueueListWidget | Queue waiting KPI + breakdown | — | Open |
RoAgentIrregularitiesWidget | Agent irregularities table | — | Open |
Catalog types are not components
Platform catalog types (kpi-calls, service-level, omnichannel-view, …) are serialized configurations in saved views, not distinct components. The app's COMPONENT_BY_TYPE registry maps each type to one of the master widgets above. The library never sees catalog types — it receives display props. See Architecture.
Widget shell contract
Every widget composes RoWidgetCard for chrome. Hosts drive the shell through these props / slots:
| Prop / slot | Purpose |
|---|---|
title | Widget title. |
availableFilters | Business filter kinds for the kebab popover; the shell auto-derives the header meta line. |
menuItems | Overflow menu items (buildWidgetMenuItems([...])). |
objective | Optional RoObjectiveFooter payload { label, progress, progressLabel?, level? }. |
loading, errorMessage, empty | Data-state flags — the shell renders the matching state. |
#actions slot | Inline header chips / range pickers. |
showExpandButton / @expand | Optional header expand button (default false; table-style widgets opt in). |
#filters slot | Filters form inside the popover; receives { close }. |
v-model:filtersOpen | External control of the filters popover. |
RoWidgetCard owns the chrome: padding 12 / 20 / 32 (top / horizontal / bottom), 1px border, 16px radius, position: relative, overflow: hidden, and the four interaction states (enable / hover / focused / focus+hover). Widget organisms ship no chrome CSS of their own.
Filters, channels and alerts
- Channel = stats domain. A channel maps to a
POST /statisticsdomain(calls,sms,whatsapp,videoconference), not awhere[]predicate. Thechannelsfilter only surfaces on multi-domain (omnichannel) widgets; the library hides it when fewer than 2 channel options exist. - Alerts. Widgets carry a rich
RoAlertConfig(operators, two severities, cooldown).evaluateRoAlert(config, value)returns'warning' | 'critical' | null;RoWidgetCardpaints the matching ring on the tile.
Sizing
Widgets are sized in cols on the 8-column dashboard grid. See Grid sizing for the canonical slots and exported pixel values.
RoKPIWidget is polymorphic: variant: 'standard' | 'compact'. The host picks the variant via the prop — standard renders with a sparkline, compact is the 1×1 tile without one.