DashboardStore
The framework-agnostic state machine every UI wrapper is built on: owns the
DashboardConfig, filter values, licensing state, and per-widget query results.
Subscribe to it directly if you're building custom UI (as Vue/Angular do today instead of a
full toolbar).
ts
const store = new DashboardStore({
config: DashboardConfig,
data: QueryRow[],
engine: QueryEngine, // JsQueryEngine today
license?: LicenseValidationResult // defaults to a safe 1k-row trial
});
store.getState(): DashboardStoreState;
store.subscribe(listener: (state) => void): () => void; // returns an unsubscribe fn
State shape
ts
interface DashboardStoreState {
config: DashboardConfig;
filterValues: FilterValue[];
results: Record<string, QueryResult>; // widget id -> { rows, total }
license: LicenseValidationResult;
rowCapApplied: boolean;
fullRowCount: number;
cappedRowCount: number;
}
Mutation methods
| Method | What it does |
|---|---|
| setFilterValue(id, value) | Sets a global filter's value; only recomputes widgets that reference it |
| toggleFilterValue(id, value) | Adds/removes a value in a multi_select filter — the primitive behind click-to-filter |
| setData(rows) | Replaces the dataset (re-applies the license row cap) |
| setLicense(license) | Applies a resolved checkLicense() result |
| addWidget / updateWidget / removeWidget / duplicateWidget | Widget CRUD |
| moveResizeWidget(id, grid) | Applies a new grid position via the headless grid engine (collision + compaction) |
| toggleLock / toggleHidden | Per-widget edit-mode flags |
| addCalculatedField / updateCalculatedField / removeCalculatedField | Derived-column CRUD |
| setColumnLabel(field, label) | Sets (or clears, with an empty string) a dataset-wide display label |
| updateSettings(patch) | Merges into config.settings (title, theme, numberFormat, …) |
| getData() | Rows with calculated fields merged in, after the license row cap |
| getConfig() / getLicense() | Current config / license snapshot |
mountDashboard()
Renders a store's widgets into a DOM element with no framework at all — what Vue, Angular, and the custom element all call internally.
ts
const renderer = mountDashboard(containerEl, { store, data: rows, mode: 'edit' });
renderer.setData(newRows);
renderer.destroy();
The container dispatches a ds-action CustomEvent for row-click
drill-down and chart click-to-filter — listen with
containerEl.addEventListener('ds-action', e => ...).