Skip to Content
ReferenceSDKsDashboard Configuration

Dashboard Configuration

Dashboard config files (*-config.json) define the default layout and widget tree for each dashboard view. They are loaded as the initial state when a user has no persisted dashboard data in localStorage.

All config files follow the DashboardStorageSchema TypeScript type. A standalone JSON Schema is available at /schemas/dashboard-config.schema.json.

Top-level Structure

FieldTypeRequiredDescription
version2 (constant)YesSchema version for migrations.
namestringYesDashboard display name.
widgetsWidget[]YesRoot-level widgets (recursive tree).
preferencesobjectYesUser preferences (e.g., editMode).

Grid System

The dashboard uses a 24-column grid powered by react-grid-layout. Every widget has a layout object that positions it on this grid.

PropertyTypeDescription
istringLayout identifier — must match the widget’s id.
xintegerColumn position (0–23).
yintegerRow position (0-based, grows downward).
wintegerWidth in columns (1–24).
hintegerHeight in rows (1+).
minWinteger?Minimum width constraint.
minHinteger?Minimum height constraint.
maxWinteger?Maximum width constraint.
maxHinteger?Maximum height constraint.

Widgets cannot exceed column 24 (x + w ≤ 24). There is no maximum row limit — the dashboard scrolls vertically.

Widget Structure

Every element in the dashboard — containers, cards, tables — is a Widget. Widgets form a recursive tree via the children array.

FieldTypeRequiredDescription
idstring (UUID)YesUnique identifier.
componentIdstring (enum)YesReferences a dashlet in the registry.
layoutGridLayoutItemYesPosition and size on the grid.
configobjectYesDashlet-specific configuration.
childrenWidget[]NoNested widgets (container types only).
createdAtstring (ISO 8601)YesCreation timestamp.
updatedAtstring (ISO 8601)YesLast update timestamp.

Available Dashlets

Containers

componentIdDescriptionhasChildrenhasSettings
containerMulti-purpose container with two variants: bento-box (grid layout) and labeled-group (labeled section).YesYes
info_cardCard that can hold nested child widgets.YesYes

Nesting rules:

  • A bento-box container cannot be nested inside another bento-box.
  • A labeled-group container can be nested anywhere.
  • At root level, containers default to the bento-box variant. When nested, they default to labeled-group.

Data Display

componentIdDescriptionhasChildrenhasSettings
cardSimple data card.NoYes
labeled-dataKey-value labeled data display.NoYes
percentage_valuePercentage metric with visual indicator.NoYes
stat_detailedDetailed statistic with breakdown.NoYes
stat_gradientStat with gradient background.NoYes
stat_iconStat with icon accent.NoYes
stat_circularCircular progress indicator stat.NoYes
stat_expandableExpandable stat with detail toggle.NoYes
stat_progressLinear progress bar stat.NoYes
stat_stackedStacked bar or segmented stat.NoYes
stat_sparklineStat with inline sparkline chart.NoYes
stat_sensitiveStat with masked/sensitive value.NoYes
stat_statusStatus indicator stat.NoYes
data_tableTabular data display.NoYes
data_listScrollable data list.NoYes
text_cardRich text or AI-generated insight card.NoYes

Config Examples

Minimal dashboard

{ "version": 2, "name": "Empty Dashboard", "widgets": [], "preferences": { "editMode": false } }

Single widget

{ "version": 2, "name": "Simple Dashboard", "widgets": [ { "id": "a1b2c3d4-0000-0000-0000-000000000001", "componentId": "stat_icon", "layout": { "i": "a1b2c3d4-0000-0000-0000-000000000001", "x": 0, "y": 0, "w": 6, "h": 3 }, "config": { "title": "Active Vehicles", "value": "{{data_provider.active_count}}", "icon": "truck" }, "createdAt": "2025-01-01T00:00:00.000Z", "updatedAt": "2025-01-01T00:00:00.000Z" } ], "preferences": { "editMode": false } }

Nested widgets (container with children)

{ "version": 2, "name": "Nested Dashboard", "widgets": [ { "id": "a1b2c3d4-0001-4000-8000-000000000001", "componentId": "container", "layout": { "i": "a1b2c3d4-0001-4000-8000-000000000001", "x": 0, "y": 0, "w": 24, "h": 8 }, "config": { "variant": "bento-box" }, "children": [ { "id": "a1b2c3d4-0002-4000-8000-000000000002", "componentId": "stat_progress", "layout": { "i": "a1b2c3d4-0002-4000-8000-000000000002", "x": 0, "y": 0, "w": 8, "h": 4 }, "config": { "title": "Compliance", "value": "{{data_provider.compliance_pct}}", "max": 100 }, "createdAt": "2025-01-01T00:00:00.000Z", "updatedAt": "2025-01-01T00:00:00.000Z" } ], "createdAt": "2025-01-01T00:00:00.000Z", "updatedAt": "2025-01-01T00:00:00.000Z" } ], "preferences": { "editMode": false } }

Default Configurations

The project ships seven default dashboard configs located in apps/app/src/features/dashboard/defaults/:

FileDashboard View
dashboard-config.jsonMain overview dashboard with fleet summary widgets.
generalInfo-config.jsonAdministrative metrics: compliance, contracts, fleet composition.
fleetUsage-config.jsonFleet utilization: total km, deviation, intensity, fuel efficiency.
maintenanceStatus-config.jsonVehicle maintenance schedules and status.
operativeEvents-config.jsonActive operational events and incidents.
devicesAndTelemetry-config.jsonDevice connectivity and telemetry monitoring.
vehicleTechnicalHealth-config.jsonTechnical diagnostics and system health metrics.

Data Provider Pattern

Widget config values support Handlebars-style template strings that are resolved at runtime from a data provider:

{{data_provider.key}}

For example, a stat widget might define:

{ "title": "Active Vehicles", "value": "{{data_provider.active_count}}" }

At render time, {{data_provider.active_count}} is replaced with the live value from the backend. This allows the same config structure to work across different tenants and data sets without code changes.

Last updated on