ObjectStackObjectStack

Dashboard

Dashboard protocol schemas

Color variant for dashboard widgets (e.g., KPI cards).

Source: packages/spec/src/ui/dashboard.zod.ts

TypeScript Usage

import { DashboardSchema, DashboardHeaderSchema, DashboardHeaderActionSchema, DashboardWidgetSchema, DashboardWidgetOptionsSchema, GlobalFilterSchema, GlobalFilterOptionsFromSchema, WidgetActionTypeSchema, WidgetColorVariantSchema } from '@objectstack/spec/ui';
import type { Dashboard, DashboardHeader, DashboardHeaderAction, DashboardWidget, DashboardWidgetOptions, GlobalFilter, GlobalFilterOptionsFrom, WidgetActionType, WidgetColorVariant } from '@objectstack/spec/ui';

// Validate data
const result = DashboardSchema.parse(data);

Dashboard

Properties

PropertyTypeRequiredDescription
namestringDashboard unique name
labelstring | Record<string, string>Dashboard label
descriptionstring | Record<string, string>optionalDashboard description
header{ showTitle: boolean; showDescription: boolean; actions?: object[] }optionalDashboard header configuration
widgets{ id: string; title?: string | Record<string, string>; description?: string | Record<string, string>; type: Enum<'bar' | 'horizontal-bar' | 'column' | 'line' | 'area' | 'pie' | 'donut' | … +13 more>; … }[]Widgets to display
columnsintegeroptionalNumber of grid columns (default 12)
gapintegeroptionalGrid gap in Tailwind spacing units
refreshIntervalnumberoptionalAuto-refresh interval in seconds
dateRange{ field?: string; defaultRange: Enum<'today' | 'yesterday' | 'this_week' | 'last_week' | 'this_month' | 'last_month' | … +8 more>; allowCustomRange: boolean }optionalGlobal dashboard date range filter configuration
globalFilters{ name?: string; field: string; object?: string; label?: string | Record<string, string>; … }[]optionalGlobal filters that apply to all widgets in the dashboard
arianeveroptional[REMOVED] dashboard.aria was removed in @objectstack/spec 17.0.0 (#3896 audit close-out) — no dashboard renderer ever applied it, so declared ARIA attributes silently did not reach the DOM. Delete the key. Run os migrate meta --from 16 to rewrite existing sources automatically.
performanceneveroptional[REMOVED] dashboard.performance was removed in @objectstack/spec 17.0.0 (#3896 audit close-out) — no renderer or runtime read it; dashboard performance tuning was never implemented. Delete the key. Run os migrate meta --from 16 to rewrite existing sources automatically.
protection{ lock: Enum<'none' | 'no-overlay' | 'no-delete' | 'full'>; reason: string; docsUrl?: string }optionalPackage author protection block — lock policy for this dashboard.
_lockEnum<'none' | 'no-overlay' | 'no-delete' | 'full'>optionalItem-level lock — controls overlay & delete (ADR-0010).
_lockReasonstringoptionalHuman-readable reason shown when a write is refused by _lock.
_lockSourceEnum<'artifact' | 'package' | 'env-forced'>optionalLayer that set _lock (artifact | package | env-forced).
_provenanceEnum<'package' | 'org' | 'env-forced'>optionalOrigin of the item (package | org | env-forced).
_packageIdstringoptionalOwning package machine id.
_packageVersionstringoptionalOwning package version.
_lockDocsUrlstringoptionalOptional documentation link surfaced next to _lockReason.

DashboardHeader

Dashboard header configuration

Properties

PropertyTypeRequiredDescription
showTitlebooleanShow dashboard title in header
showDescriptionbooleanShow dashboard description in header
actions{ label: string | Record<string, string>; actionUrl: string; actionType?: Enum<'script' | 'url' | 'modal' | 'flow' | 'api' | 'form'>; icon?: string }[]optionalHeader action buttons

DashboardHeaderAction

Dashboard header action

Properties

PropertyTypeRequiredDescription
labelstring | Record<string, string>Action button label
actionUrlstringURL or target for the action
actionTypeEnum<'script' | 'url' | 'modal' | 'flow' | 'api' | 'form'>optionalType of action
iconstringoptionalIcon identifier for the action button

DashboardWidget

Properties

PropertyTypeRequiredDescription
idstringUnique widget identifier (snake_case)
titlestring | Record<string, string>optionalWidget title
descriptionstring | Record<string, string>optionalWidget description text below the header
typeEnum<'bar' | 'horizontal-bar' | 'column' | 'line' | 'area' | 'pie' | 'donut' | 'funnel' | 'scatter' | 'treemap' | 'sankey' | 'combo' | 'gauge' | 'solid-gauge' | … +6 more>Visualization type
chartConfig{ type: Enum<'bar' | 'horizontal-bar' | 'column' | 'line' | 'area' | 'pie' | 'donut' | … +13 more>; title?: string | Record<string, string>; subtitle?: string | Record<string, string>; description?: string | Record<string, string>; … }optionalChart visualization configuration
colorVariantEnum<'default' | 'blue' | 'teal' | 'orange' | 'purple' | 'success' | 'warning' | 'danger'>optionalWidget color variant for theming
requiresObjectstringoptionalHide the widget unless the named object is registered
requiresServicestringoptionalHide the widget unless the named kernel service is registered
actionUrlneveroptional[REMOVED] dashboard.widgets[].actionUrl was removed in @objectstack/spec 17.0.0 (#5010, ADR-0049 enforce-or-remove) — a dashboard widget has NO action button, and never had one. No renderer draws per-widget chrome for it: every action the dashboard dispatches comes from header.actions[]. The three keys actionUrl / actionType / actionIcon went together; delete all three. Put the affordance on the dashboard header instead — header: { actions: [{ label, actionUrl, actionType, icon }] } — which IS dispatched (DashboardHeaderAction, same vocabulary, and icon is the header spelling of actionIcon). For a per-ROW affordance, the widget to reach for is a table/pivot bound to a dataset: its rows are clickable and drill through the semantic layer. Run os migrate meta --from 16 to rewrite existing sources automatically.
actionTypeneveroptional[REMOVED] dashboard.widgets[].actionType was removed in @objectstack/spec 17.0.0 (#5010, ADR-0049 enforce-or-remove) — a dashboard widget has NO action button, and never had one. No renderer draws per-widget chrome for it: every action the dashboard dispatches comes from header.actions[]. The three keys actionUrl / actionType / actionIcon went together; delete all three. Put the affordance on the dashboard header instead — header: { actions: [{ label, actionUrl, actionType, icon }] } — which IS dispatched (DashboardHeaderAction, same vocabulary, and icon is the header spelling of actionIcon). For a per-ROW affordance, the widget to reach for is a table/pivot bound to a dataset: its rows are clickable and drill through the semantic layer. Run os migrate meta --from 16 to rewrite existing sources automatically.
actionIconneveroptional[REMOVED] dashboard.widgets[].actionIcon was removed in @objectstack/spec 17.0.0 (#5010, ADR-0049 enforce-or-remove) — a dashboard widget has NO action button, and never had one. No renderer draws per-widget chrome for it: every action the dashboard dispatches comes from header.actions[]. The three keys actionUrl / actionType / actionIcon went together; delete all three. Put the affordance on the dashboard header instead — header: { actions: [{ label, actionUrl, actionType, icon }] } — which IS dispatched (DashboardHeaderAction, same vocabulary, and icon is the header spelling of actionIcon). For a per-ROW affordance, the widget to reach for is a table/pivot bound to a dataset: its rows are clickable and drill through the semantic layer. Run os migrate meta --from 16 to rewrite existing sources automatically.
filteranyoptionalPresentation-scope filter (runtimeFilter)
compareTo{ kind: Enum<'previousPeriod' | 'previousYear'>; dimension?: string }optionalPeriod-over-period comparison window ({ kind, dimension? })
datasetstringDataset name to bind (ADR-0021)
dimensionsstring[]optionalDimension names — X/group/split
valuesstring[]Measure names — Y (at least one)
layout{ x: number; y: number; w: number; h: number }optionalGrid layout position (auto-flowed when omitted)
options{ dateGranularity?: Enum<'day' | 'week' | 'month' | 'quarter' | 'year'>; sortBy?: string; sortOrder?: Enum<'asc' | 'desc'>; limit?: integer; … } & Record<string, any>optionalWidget specific configuration
filterBindingsRecord<string, string | false>optionalPer-widget dashboard-filter bindings: filter name → this widget's field, or false to opt out
suppressWarningsstring[]optionalBuild diagnostic rule ids suppressed on this widget
responsiveneveroptional[REMOVED] dashboard.widgets[].responsive was removed in @objectstack/spec 17.0.0 (#4876, ADR-0049 D2) — no renderer ever read it, so per-widget breakpoint overrides were never applied: the value parsed, validated, and then did nothing. The dashboard grid reflows by its own layout rules (columns + gap on the dashboard, the layout box on each widget). Delete the key. The shared ResponsiveConfig shape is NOT gone — it stays live on page.components[].responsive, which objectui useResponsiveConfig really does read; move the layout there if you need breakpoint behaviour today. Run os migrate meta --from 16 to rewrite existing sources automatically.
arianeveroptional[REMOVED] dashboard.widgets[].aria was removed in @objectstack/spec 17.0.0 (#5010, ADR-0049 D2) — no renderer ever applied it, so ARIA attributes declared on a widget silently did not reach the DOM: the key promised accessibility compliance it did not deliver. This is the same removal the dashboard-level aria got in 17.0.0 (#3896). Delete the key. The dashboard renderer emits its own aria-* attributes for the widget grid; author a title (and description) on the widget instead — those ARE what the renderer labels the card with. The shared AriaProps shape is NOT gone: it stays live on page.aria, page.components[].aria and the list view aria. Run os migrate meta --from 16 to rewrite existing sources automatically.

Allowed Values: DashboardWidget.type

  • bar
  • horizontal-bar
  • column
  • line
  • area
  • pie
  • donut
  • funnel
  • scatter
  • treemap
  • sankey
  • combo
  • gauge
  • solid-gauge
  • metric
  • kpi
  • bullet
  • radar
  • table
  • pivot

DashboardWidgetOptions

Widget configuration — declared query keys + open renderer extras

Properties

PropertyTypeRequiredDescription
dateGranularityEnum<'day' | 'week' | 'month' | 'quarter' | 'year'>optionalBucket selected date dimensions (day/week/month/quarter/year)
sortBystringoptionalDimension/measure name to order by
sortOrderEnum<'asc' | 'desc'>optionalSort direction for sortBy
limitintegeroptionalMax rows (applied after ordering)
stageOrder(string | number | boolean)[]optionalExplicit category order for funnel/pyramid stages (stored values)

GlobalFilter

Properties

PropertyTypeRequiredDescription
namestringoptionalStable filter name (variable key); defaults to field
fieldstringField name to filter on
objectstringoptionalObject whose fields.<object>.<field> translation-bundle entry resolves this filter's field label and option labels (#7804)
labelstring | Record<string, string>optionalDisplay label for the filter
typeEnum<'text' | 'select' | 'date' | 'number' | 'lookup'>optionalFilter input type
options{ value: string | number | boolean; label: string | Record<string, string> }[]optionalStatic filter options
optionsFrom{ object: string; valueField: string; labelField: string; filter?: any }optionalDynamic filter options from object
defaultValuestring | number | booleanoptionalDefault filter value
scopeEnum<'dashboard' | 'widget'>Filter application scope
targetWidgetsstring[]optionalWidget IDs to apply this filter to

GlobalFilterOptionsFrom

Dynamic filter options from object

Properties

PropertyTypeRequiredDescription
objectstringSource object name
valueFieldstringField to use as option value
labelFieldstringField to use as option label
filteranyoptionalFilter to apply to source object

WidgetActionType

Widget action type

Allowed Values

  • script
  • url
  • modal
  • flow
  • api
  • form

WidgetColorVariant

Widget color variant

Allowed Values

  • default
  • blue
  • teal
  • orange
  • purple
  • success
  • warning
  • danger

On this page