@dlh.io/bideux 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +90 -0
  3. package/dist/all.d.ts +14 -0
  4. package/dist/all.js +15 -0
  5. package/dist/all.js.map +1 -0
  6. package/dist/chunk-62IQGXLW.js +11470 -0
  7. package/dist/chunk-62IQGXLW.js.map +1 -0
  8. package/dist/chunk-75CRTQK7.js +315 -0
  9. package/dist/chunk-75CRTQK7.js.map +1 -0
  10. package/dist/chunk-FVO6E22Z.js +225 -0
  11. package/dist/chunk-FVO6E22Z.js.map +1 -0
  12. package/dist/chunk-GRITOB4M.js +337 -0
  13. package/dist/chunk-GRITOB4M.js.map +1 -0
  14. package/dist/chunk-HPFHIZWO.js +40 -0
  15. package/dist/chunk-HPFHIZWO.js.map +1 -0
  16. package/dist/chunk-IMNUQGHE.js +2864 -0
  17. package/dist/chunk-IMNUQGHE.js.map +1 -0
  18. package/dist/chunk-LHD445PJ.js +571 -0
  19. package/dist/chunk-LHD445PJ.js.map +1 -0
  20. package/dist/chunk-LPLBBHOW.js +386 -0
  21. package/dist/chunk-LPLBBHOW.js.map +1 -0
  22. package/dist/chunk-NGM5R3LW.js +881 -0
  23. package/dist/chunk-NGM5R3LW.js.map +1 -0
  24. package/dist/chunk-OMPR32AR.js +1320 -0
  25. package/dist/chunk-OMPR32AR.js.map +1 -0
  26. package/dist/chunk-QDQ5VVTC.js +255 -0
  27. package/dist/chunk-QDQ5VVTC.js.map +1 -0
  28. package/dist/chunk-RRWZKNDZ.js +1004 -0
  29. package/dist/chunk-RRWZKNDZ.js.map +1 -0
  30. package/dist/chunk-SRWIBMEB.js +178 -0
  31. package/dist/chunk-SRWIBMEB.js.map +1 -0
  32. package/dist/element/chunk-AOKCBPMV.js +1646 -0
  33. package/dist/element/chunk-AOKCBPMV.js.map +1 -0
  34. package/dist/element/chunk-B67SYRQP.js +281 -0
  35. package/dist/element/chunk-B67SYRQP.js.map +1 -0
  36. package/dist/element/chunk-FNRVFA2C.js +55 -0
  37. package/dist/element/chunk-FNRVFA2C.js.map +1 -0
  38. package/dist/element/chunk-G3C722QP.js +4707 -0
  39. package/dist/element/chunk-G3C722QP.js.map +1 -0
  40. package/dist/element/chunk-H5IFOSQP.js +346 -0
  41. package/dist/element/chunk-H5IFOSQP.js.map +1 -0
  42. package/dist/element/chunk-LXR3CLCN.js +30 -0
  43. package/dist/element/chunk-LXR3CLCN.js.map +1 -0
  44. package/dist/element/chunk-TFV4CJR4.js +183 -0
  45. package/dist/element/chunk-TFV4CJR4.js.map +1 -0
  46. package/dist/element/chunk-TXSK3CIN.js +859 -0
  47. package/dist/element/chunk-TXSK3CIN.js.map +1 -0
  48. package/dist/element/chunk-WDTTBY3S.js +45 -0
  49. package/dist/element/chunk-WDTTBY3S.js.map +1 -0
  50. package/dist/element/chunk-ZI3RYCAR.js +233 -0
  51. package/dist/element/chunk-ZI3RYCAR.js.map +1 -0
  52. package/dist/element/element.d.ts +3044 -0
  53. package/dist/element/element.js +146554 -0
  54. package/dist/element/element.js.map +1 -0
  55. package/dist/element/revo-grid.entry-7FHEBN3O.js +4817 -0
  56. package/dist/element/revo-grid.entry-7FHEBN3O.js.map +1 -0
  57. package/dist/element/revogr-attribution_7.entry-LSOFVZRA.js +1328 -0
  58. package/dist/element/revogr-attribution_7.entry-LSOFVZRA.js.map +1 -0
  59. package/dist/element/revogr-clipboard_3.entry-V74UIBPJ.js +494 -0
  60. package/dist/element/revogr-clipboard_3.entry-V74UIBPJ.js.map +1 -0
  61. package/dist/element/revogr-data_4.entry-2UBOKTFN.js +1041 -0
  62. package/dist/element/revogr-data_4.entry-2UBOKTFN.js.map +1 -0
  63. package/dist/element/revogr-filter-panel.entry-B24PLQU4.js +552 -0
  64. package/dist/element/revogr-filter-panel.entry-B24PLQU4.js.map +1 -0
  65. package/dist/index.d.ts +1041 -0
  66. package/dist/index.js +10 -0
  67. package/dist/index.js.map +1 -0
  68. package/dist/react.d.ts +1915 -0
  69. package/dist/react.js +14 -0
  70. package/dist/react.js.map +1 -0
  71. package/dist/renderers/echarts.d.ts +44 -0
  72. package/dist/renderers/echarts.js +6 -0
  73. package/dist/renderers/echarts.js.map +1 -0
  74. package/dist/renderers/index.d.ts +48 -0
  75. package/dist/renderers/index.js +12 -0
  76. package/dist/renderers/index.js.map +1 -0
  77. package/dist/renderers/revogrid.d.ts +76 -0
  78. package/dist/renderers/revogrid.js +6 -0
  79. package/dist/renderers/revogrid.js.map +1 -0
  80. package/dist/renderers/tabulator.d.ts +37 -0
  81. package/dist/renderers/tabulator.js +6 -0
  82. package/dist/renderers/tabulator.js.map +1 -0
  83. package/dist/result-table-CPls-277.d.ts +1885 -0
  84. package/dist/schema/dashboard.schema.json +4374 -0
  85. package/dist/schema/semantic-model.schema.json +1200 -0
  86. package/dist/schema/widget.schema.json +1793 -0
  87. package/dist/styles.css +156 -0
  88. package/dist/theme.css +1789 -0
  89. package/dist/types-CHFSsU_X.d.ts +1007 -0
  90. package/package.json +119 -0
@@ -0,0 +1,1915 @@
1
+ import { F as DashboardModelDiagnostics, V as ModelMarker, L as DashboardSpec, aa as ResponsiveLayouts, c as Breakpoint, ag as WidgetColumn, x as DashboardGridConfig, U as LayoutKey, w as DashboardFilterPanelConfig, i as BuilderDataset, q as BuilderRelationship, n as BuilderModelMetric, h as BuilderDataStore, K as DashboardSectionConfig, ab as ResultTable, t as BuilderWidget, o as BuilderPivot, p as BuilderPivotMeasure } from './result-table-CPls-277.js';
2
+ export { O as FilterControl, Q as FilterModel, R as FilterOption, S as LAYOUT_BREAKPOINT_WIDTHS, am as buildFilterModel, an as cellText, ap as dashboardTabs, as as defaultTabId, at as describeFilter, aw as filterOptions, ax as formatTableCsv, aF as layoutKeyForWidth, aZ as resolveResponsive, a_ as resultColumns, a$ as resultRows, b0 as tabWidgetIds } from './result-table-CPls-277.js';
3
+ import * as react_jsx_runtime from 'react/jsx-runtime';
4
+ import * as react from 'react';
5
+ import { ComponentType, ReactNode, CSSProperties, HTMLAttributes } from 'react';
6
+ import { aw as WidgetSpec, av as WidgetResult, q as PivotDetailResult, an as WidgetInteraction, ao as WidgetInteractionContext, S as RendererContext, c as DrillStackItem, h as KpiRendererModel, aa as TableRendererModel, ac as TableSortState, ax as WidgetTheme, L as LabelBlock } from './types-CHFSsU_X.js';
7
+ import { DefaultRenderersOptions } from './renderers/index.js';
8
+ import 'yaml';
9
+ import './renderers/echarts.js';
10
+ import 'echarts';
11
+ import './renderers/tabulator.js';
12
+ import 'tabulator-tables';
13
+ import './renderers/revogrid.js';
14
+ import '@revolist/revogrid';
15
+
16
+ /**
17
+ * The authoring side of the transport seam.
18
+ *
19
+ * Same rule as the reader: no fetch, no URL and no host client is written
20
+ * inside the package, and every call carries the scope it acts on rather than
21
+ * reading one from an ambient session. Nothing here returns a host database
22
+ * model: a widget arrives as its YAML text and a preview as plain rows.
23
+ */
24
+ interface WidgetDocumentRequest {
25
+ dashboardId: string;
26
+ widgetId: string;
27
+ signal?: AbortSignal;
28
+ }
29
+ interface WidgetDocument {
30
+ widgetId: string;
31
+ specYaml: string;
32
+ }
33
+ interface WidgetSaveRequest {
34
+ dashboardId: string;
35
+ widgetId: string;
36
+ specYaml: string;
37
+ }
38
+ interface WidgetCreateRequest {
39
+ dashboardId: string;
40
+ specYaml: string;
41
+ }
42
+ interface WidgetDeleteRequest {
43
+ dashboardId: string;
44
+ widgetId: string;
45
+ }
46
+ interface DashboardDocumentRequest {
47
+ dashboardId: string;
48
+ signal?: AbortSignal;
49
+ }
50
+ /** The dashboard document as YAML text, which is all the YAML editor needs. */
51
+ interface DashboardDocument {
52
+ dashboardId: string;
53
+ specYaml: string;
54
+ /** The version stamp the host uses for optimistic concurrency, if it has one. */
55
+ updatedAt?: string;
56
+ }
57
+ interface DashboardDocumentSaveRequest {
58
+ dashboardId: string;
59
+ specYaml: string;
60
+ expectedUpdatedAt?: string;
61
+ }
62
+ /** Name and description edits made inline on the page header. */
63
+ interface DashboardMetadataSaveRequest {
64
+ dashboardId: string;
65
+ name?: string;
66
+ description?: string;
67
+ }
68
+ interface DashboardCopyRequest {
69
+ dashboardId: string;
70
+ name?: string;
71
+ }
72
+ interface DashboardCopyResponse {
73
+ /** How the host addresses the copy, so the page can navigate to it. */
74
+ dashboardId: string;
75
+ }
76
+ interface WidgetInventoryRequest {
77
+ dashboardId: string;
78
+ signal?: AbortSignal;
79
+ }
80
+ interface WidgetInventoryResponse {
81
+ widgets: Record<string, WidgetSpec>;
82
+ /** Widgets belonging to the dashboard that no tab places on its grid. */
83
+ unplacedWidgetIds: string[];
84
+ }
85
+ interface WidgetDiagnosticsRequest {
86
+ dashboardId: string;
87
+ widgetId: string;
88
+ filters?: Record<string, unknown>;
89
+ signal?: AbortSignal;
90
+ }
91
+ /** One query a widget ran, as the engine reports it. */
92
+ interface WidgetQueryDiagnostic {
93
+ kind: string;
94
+ sql: string;
95
+ params: Record<string, unknown>;
96
+ dataStoreId: string | null;
97
+ filterField: string | null;
98
+ /** The scope the query was narrowed to, or null when it was not narrowed. */
99
+ effectiveLocations: string[] | null;
100
+ note?: string;
101
+ returnedColumns?: string[];
102
+ rowCount?: number;
103
+ cache?: string;
104
+ cacheTtlSeconds?: number;
105
+ }
106
+ interface WidgetMappingDiagnostic {
107
+ rowCount: number;
108
+ availableColumns: string[];
109
+ mappedFields: Record<string, string>;
110
+ issues: string[];
111
+ }
112
+ interface WidgetDiagnosticsResponse {
113
+ widgetId: string;
114
+ component: string;
115
+ queries: WidgetQueryDiagnostic[];
116
+ mapping?: WidgetMappingDiagnostic;
117
+ notes?: string[];
118
+ error?: string;
119
+ }
120
+ interface ModelLoadRequest {
121
+ signal?: AbortSignal;
122
+ }
123
+ interface ModelDocument {
124
+ specYaml: string;
125
+ version: number | null;
126
+ /** False when the caller may read the model but not write it. */
127
+ editable: boolean;
128
+ }
129
+ interface ModelSaveRequest {
130
+ specYaml: string;
131
+ note?: string;
132
+ }
133
+ interface ModelValidateRequest {
134
+ specYaml: string;
135
+ signal?: AbortSignal;
136
+ }
137
+ interface ModelVersionSummary {
138
+ version: number;
139
+ createdAt: string;
140
+ sizeBytes: number;
141
+ datasetCount: number;
142
+ note: string | null;
143
+ /** True when this version is exactly what the model says now. */
144
+ isCurrent: boolean;
145
+ }
146
+ interface ModelVersionRequest {
147
+ version: number;
148
+ signal?: AbortSignal;
149
+ }
150
+ interface ModelVersionRestoreRequest {
151
+ version: number;
152
+ note?: string;
153
+ }
154
+ /** A warehouse connection the host offers, named without exposing its record. */
155
+ interface DataModelConnection {
156
+ id: string;
157
+ label: string;
158
+ vendor: string | null;
159
+ }
160
+ interface WarehouseColumn {
161
+ name: string;
162
+ dataType: string;
163
+ }
164
+ interface WarehouseTable {
165
+ schemaName: string;
166
+ tableName: string;
167
+ tableType: string;
168
+ columns: WarehouseColumn[];
169
+ }
170
+ interface WarehouseSchemaRequest {
171
+ connectionId: string | null;
172
+ signal?: AbortSignal;
173
+ }
174
+ interface DatasetPreviewRequest {
175
+ /** The model text as it stands in the editor, saved or not. */
176
+ specYaml: string;
177
+ datasetId: string;
178
+ limit: number;
179
+ columns?: string[];
180
+ signal?: AbortSignal;
181
+ }
182
+ interface DatasetPreviewResult {
183
+ columns: string[];
184
+ rows: Record<string, unknown>[];
185
+ rowCount: number;
186
+ /** The scope the preview ran under, or null when it was not narrowed. */
187
+ effectiveLocations: string[] | null;
188
+ sql: string | null;
189
+ }
190
+ /** A change an assistant proposes, which an author reads before applying it. */
191
+ interface AuthoringProposal {
192
+ id: string;
193
+ summary: string;
194
+ specYaml: string;
195
+ }
196
+ interface ProposalRequest {
197
+ dashboardId: string;
198
+ widgetId: string | null;
199
+ instruction: string;
200
+ specYaml: string;
201
+ signal?: AbortSignal;
202
+ }
203
+ interface ProposalOutcomeRequest {
204
+ proposalId: string;
205
+ applied: boolean;
206
+ }
207
+ interface LayoutWidgetRequest {
208
+ dashboardId: string;
209
+ widgetId: string;
210
+ }
211
+ interface AuthoringTransport {
212
+ loadWidgetDocument: (request: WidgetDocumentRequest) => Promise<WidgetDocument>;
213
+ saveWidget: (request: WidgetSaveRequest) => Promise<void>;
214
+ createWidget: (request: WidgetCreateRequest) => Promise<WidgetDocument>;
215
+ deleteWidget: (request: WidgetDeleteRequest) => Promise<void>;
216
+ listWidgets: (request: WidgetInventoryRequest) => Promise<WidgetInventoryResponse>;
217
+ diagnoseWidget: (request: WidgetDiagnosticsRequest) => Promise<WidgetDiagnosticsResponse>;
218
+ loadModel: (request: ModelLoadRequest) => Promise<ModelDocument>;
219
+ saveModel: (request: ModelSaveRequest) => Promise<ModelDocument>;
220
+ validateModel: (request: ModelValidateRequest) => Promise<DashboardModelDiagnostics>;
221
+ listModelVersions: (request: {
222
+ signal?: AbortSignal;
223
+ }) => Promise<ModelVersionSummary[]>;
224
+ loadModelVersion: (request: ModelVersionRequest) => Promise<ModelDocument>;
225
+ restoreModelVersion: (request: ModelVersionRestoreRequest) => Promise<ModelDocument>;
226
+ listConnections: (request: {
227
+ signal?: AbortSignal;
228
+ }) => Promise<DataModelConnection[]>;
229
+ listWarehouseTables: (request: WarehouseSchemaRequest) => Promise<WarehouseTable[]>;
230
+ previewDataset: (request: DatasetPreviewRequest) => Promise<DatasetPreviewResult>;
231
+ /** Places an existing widget on the dashboard grid. */
232
+ addWidgetToLayout: (request: LayoutWidgetRequest) => Promise<void>;
233
+ /** Takes a widget off the grid without deleting the widget itself. */
234
+ removeWidgetFromLayout: (request: LayoutWidgetRequest) => Promise<void>;
235
+ /** Optional: the dashboard document itself, for the dashboard YAML editor. */
236
+ loadDashboardDocument?: (request: DashboardDocumentRequest) => Promise<DashboardDocument>;
237
+ saveDashboardDocument?: (request: DashboardDocumentSaveRequest) => Promise<DashboardDocument>;
238
+ /** Optional: inline rename and description edits on the page header. */
239
+ saveDashboardMetadata?: (request: DashboardMetadataSaveRequest) => Promise<void>;
240
+ /** Optional: Make a copy. */
241
+ copyDashboard?: (request: DashboardCopyRequest) => Promise<DashboardCopyResponse>;
242
+ /** Optional: an assistant that writes a document from a sentence. */
243
+ proposeDocument?: (request: ProposalRequest) => Promise<AuthoringProposal>;
244
+ /** Optional: tells the host whether a proposal was kept. */
245
+ recordProposalOutcome?: (request: ProposalOutcomeRequest) => Promise<void>;
246
+ }
247
+ interface CodeEditorProps {
248
+ value: string;
249
+ onChange: (value: string) => void;
250
+ language: "yaml";
251
+ readOnly?: boolean | undefined;
252
+ markers?: ModelMarker[] | undefined;
253
+ ariaLabel?: string | undefined;
254
+ className?: string | undefined;
255
+ }
256
+ /**
257
+ * The editor seam. A host passes Monaco, CodeMirror or anything else, and the
258
+ * package falls back to a plain textarea, so no editor is bundled here.
259
+ */
260
+ type CodeEditor = ComponentType<CodeEditorProps>;
261
+
262
+ /**
263
+ * Every glyph the reader and builder draw. `defaultIcons` covers them all with
264
+ * inline SVG; a host maps any subset onto its own icon library and the rest
265
+ * fall back to the built-in glyphs.
266
+ */
267
+ type IconName = "activity" | "alert" | "arrowDown" | "arrowLeft" | "arrowUp" | "arrowUpDown" | "building" | "calendar" | "check" | "chevronDown" | "chevronLeft" | "chevronRight" | "close" | "code" | "copy" | "download" | "expand" | "eye" | "filter" | "grip" | "help" | "info" | "layers" | "loader" | "lock" | "minus" | "more" | "plus" | "refresh" | "save" | "search" | "settings" | "share" | "sliders" | "sparkles" | "spreadsheet" | "trash" | "trendDown" | "trendFlat" | "trendUp" | "undo" | "users";
268
+ interface IconProps {
269
+ className?: string | undefined;
270
+ title?: string | undefined;
271
+ }
272
+ type IconSet = Record<IconName, ComponentType<IconProps>>;
273
+ interface UiButtonProps {
274
+ children?: ReactNode;
275
+ className?: string | undefined;
276
+ disabled?: boolean | undefined;
277
+ onClick?: (() => void) | undefined;
278
+ title?: string | undefined;
279
+ ariaLabel?: string | undefined;
280
+ variant?: "primary" | "secondary" | "ghost" | "link" | undefined;
281
+ size?: "sm" | "md" | undefined;
282
+ type?: "button" | "submit" | undefined;
283
+ }
284
+ interface UiTooltipProps {
285
+ label: ReactNode;
286
+ children: ReactNode;
287
+ side?: "top" | "bottom" | "left" | "right" | undefined;
288
+ }
289
+ interface UiPopoverProps {
290
+ open: boolean;
291
+ onOpenChange: (open: boolean) => void;
292
+ trigger: ReactNode;
293
+ children: ReactNode;
294
+ align?: "start" | "center" | "end" | undefined;
295
+ className?: string | undefined;
296
+ }
297
+ interface UiModalProps {
298
+ open: boolean;
299
+ onOpenChange: (open: boolean) => void;
300
+ title: ReactNode;
301
+ description?: ReactNode;
302
+ /** Replaces the plain title row, for a modal that carries its own navigation. */
303
+ header?: ReactNode;
304
+ footer?: ReactNode;
305
+ children: ReactNode;
306
+ size?: "md" | "lg" | "xl" | undefined;
307
+ }
308
+ interface UiSelectOption {
309
+ value: string;
310
+ label: string;
311
+ disabled?: boolean | undefined;
312
+ }
313
+ interface UiSelectProps {
314
+ value: string;
315
+ options: UiSelectOption[];
316
+ onChange: (value: string) => void;
317
+ placeholder?: string | undefined;
318
+ disabled?: boolean | undefined;
319
+ ariaLabel?: string | undefined;
320
+ className?: string | undefined;
321
+ }
322
+ interface UiTextInputProps {
323
+ value: string;
324
+ onChange: (value: string) => void;
325
+ placeholder?: string | undefined;
326
+ disabled?: boolean | undefined;
327
+ ariaLabel?: string | undefined;
328
+ className?: string | undefined;
329
+ type?: "text" | "number" | "date" | "search" | undefined;
330
+ onCommit?: (() => void) | undefined;
331
+ }
332
+ interface UiCheckboxProps {
333
+ checked: boolean;
334
+ onChange: (checked: boolean) => void;
335
+ label: ReactNode;
336
+ disabled?: boolean | undefined;
337
+ className?: string | undefined;
338
+ }
339
+ interface UiBadgeProps {
340
+ children: ReactNode;
341
+ tone?: "neutral" | "info" | "success" | "warning" | "danger" | undefined;
342
+ className?: string | undefined;
343
+ title?: string | undefined;
344
+ }
345
+ interface UiSkeletonProps {
346
+ className?: string | undefined;
347
+ style?: CSSProperties | undefined;
348
+ }
349
+ interface UiMenuItem {
350
+ id: string;
351
+ label: string;
352
+ icon?: IconName | undefined;
353
+ disabled?: boolean | undefined;
354
+ onSelect: () => void;
355
+ }
356
+ interface UiMenuProps {
357
+ items: UiMenuItem[];
358
+ trigger: ReactNode;
359
+ ariaLabel?: string | undefined;
360
+ }
361
+ /**
362
+ * The design system seam. A host passes its own primitives, so the reader runs
363
+ * unchanged on shadcn, on Material, or on the plain elements the reference host
364
+ * uses to prove the package carries no design system of its own.
365
+ */
366
+ interface UiKit {
367
+ Badge: ComponentType<UiBadgeProps>;
368
+ Button: ComponentType<UiButtonProps>;
369
+ Checkbox: ComponentType<UiCheckboxProps>;
370
+ Menu: ComponentType<UiMenuProps>;
371
+ Modal: ComponentType<UiModalProps>;
372
+ Popover: ComponentType<UiPopoverProps>;
373
+ Select: ComponentType<UiSelectProps>;
374
+ Skeleton: ComponentType<UiSkeletonProps>;
375
+ TextInput: ComponentType<UiTextInputProps>;
376
+ Tooltip: ComponentType<UiTooltipProps>;
377
+ }
378
+ interface AssetResolver {
379
+ /** Turns a stored image reference into something an img tag can load. */
380
+ resolve: (reference: string) => string;
381
+ }
382
+ interface HostLinkProps {
383
+ href: string;
384
+ children: ReactNode;
385
+ className?: string | undefined;
386
+ target?: "_blank" | "_self" | undefined;
387
+ onNavigate?: (() => void) | undefined;
388
+ }
389
+ interface HostLinks {
390
+ Link: ComponentType<HostLinkProps>;
391
+ /** The route the reader currently sits on, when the host tracks one. */
392
+ currentHref?: string | undefined;
393
+ navigate?: (href: string, options?: {
394
+ newTab?: boolean;
395
+ params?: Record<string, unknown>;
396
+ }) => void;
397
+ }
398
+ interface Notice {
399
+ tone: "info" | "success" | "warning" | "error";
400
+ message: string;
401
+ detail?: string;
402
+ }
403
+ type NoticeSink = (notice: Notice) => void;
404
+ interface DashboardRunRequest {
405
+ dashboardId: string;
406
+ filters?: Record<string, unknown>;
407
+ signal?: AbortSignal;
408
+ }
409
+ interface DashboardRunResponse {
410
+ results: Record<string, WidgetResult>;
411
+ /** Present when the caller did not already hold the specs, as a drill does. */
412
+ dashboard: DashboardSpec;
413
+ widgets: Record<string, WidgetSpec>;
414
+ name?: string;
415
+ errors?: Record<string, string>;
416
+ }
417
+ interface WidgetRunRequest {
418
+ dashboardId: string;
419
+ widgetId: string;
420
+ filters?: Record<string, unknown>;
421
+ signal?: AbortSignal;
422
+ }
423
+ interface WidgetDetailRequest extends WidgetRunRequest {
424
+ /** The clicked cell, named by the labels the pivot printed. */
425
+ cell: Record<string, string>;
426
+ label?: string;
427
+ limit?: number;
428
+ }
429
+ interface DrillRunRequest {
430
+ dashboardId: string;
431
+ widgetId: string;
432
+ interaction: WidgetInteraction;
433
+ context: WidgetInteractionContext;
434
+ filters?: Record<string, unknown>;
435
+ signal?: AbortSignal;
436
+ }
437
+ interface DrillRunResponse {
438
+ columns: string[];
439
+ rows: Record<string, unknown>[];
440
+ truncated?: boolean;
441
+ }
442
+ interface LayoutSaveRequest {
443
+ dashboardId: string;
444
+ /** Positions per breakpoint key (`lg`, `md`, `sm`, `xs`, `xxs`). */
445
+ layouts: ResponsiveLayouts;
446
+ /** Row height and column overrides per breakpoint, when the author changed them. */
447
+ gridOverrides?: Partial<Record<Breakpoint, {
448
+ rowHeight?: number;
449
+ cols?: number;
450
+ }>>;
451
+ /** Widgets kept off the grid without being deleted. */
452
+ unplacedWidgetIds?: string[];
453
+ /** The row limit after any Add rows the author clicked. */
454
+ maxRows?: number;
455
+ /** A breakpoint name that caps the dashboard width, or `null` to lift the cap. */
456
+ maxLayoutWidth?: string | null;
457
+ /** Dashboard level grid behaviour the author toggled in the Grid popover. */
458
+ grid?: {
459
+ isBounded?: boolean;
460
+ preventCollision?: boolean;
461
+ };
462
+ /** The data store widgets query by default, or `null` for the host default. */
463
+ dataModelId?: string | null;
464
+ /**
465
+ * The dashboard's `updatedAt` when editing began. A host that supports
466
+ * optimistic concurrency rejects the save with `LayoutConflictError` when a
467
+ * newer version exists.
468
+ */
469
+ expectedUpdatedAt?: string;
470
+ signal?: AbortSignal;
471
+ }
472
+ interface LayoutSaveResponse {
473
+ /** The dashboard's version stamp after the save, for the next request. */
474
+ updatedAt?: string;
475
+ }
476
+ /**
477
+ * Thrown by `saveLayout` when someone else saved first. The reader offers to
478
+ * overwrite or to reload rather than silently losing either side's work.
479
+ */
480
+ declare class LayoutConflictError extends Error {
481
+ readonly conflict = true;
482
+ constructor(message?: string);
483
+ }
484
+ declare function isLayoutConflict(error: unknown): boolean;
485
+ /**
486
+ * The only way the reader reaches a server. No fetch, no server action and no
487
+ * URL is written inside the package.
488
+ */
489
+ interface DashboardTransport {
490
+ runDashboard: (request: DashboardRunRequest) => Promise<DashboardRunResponse>;
491
+ runWidget: (request: WidgetRunRequest) => Promise<WidgetResult>;
492
+ runWidgetDetail?: (request: WidgetDetailRequest) => Promise<PivotDetailResult>;
493
+ runDrill?: (request: DrillRunRequest) => Promise<DrillRunResponse>;
494
+ saveLayout?: (request: LayoutSaveRequest) => Promise<LayoutSaveResponse | void>;
495
+ }
496
+ /**
497
+ * Structural copy of the lifecycle the browser renderer packages return. It is
498
+ * declared here rather than imported so the React package keeps its dependency
499
+ * on the concrete renderers optional and host owned.
500
+ */
501
+ interface ReaderRenderer {
502
+ update: (input: RendererMountInput) => void;
503
+ resize: () => void;
504
+ destroy: () => void;
505
+ }
506
+ interface RendererMountCallbacks {
507
+ onInteraction?: (interaction: WidgetInteraction, context: WidgetInteractionContext) => void;
508
+ onRetry?: () => void;
509
+ onFilterChange?: (widgetId: string, value: unknown) => void;
510
+ onFilterLabelChange?: (widgetId: string, label: string) => void;
511
+ onError?: (error: Error) => void;
512
+ onPivotDetail?: (payload: PivotDetailPayload) => void;
513
+ onPivotView?: (widgetId: string, view: Record<string, unknown>) => void;
514
+ onExport?: (request: RendererExportRequest) => void | Promise<void>;
515
+ }
516
+ /** A CSV or Excel export a concrete renderer's toolbar asked the reader for. */
517
+ interface RendererExportRequest {
518
+ widgetId: string;
519
+ format: "csv" | "excel";
520
+ filename: string;
521
+ }
522
+ /**
523
+ * A pivot cell a reader asked to see behind, exactly as the concrete pivot
524
+ * renderer raises it: the cell is named by the dimension labels the pivot
525
+ * printed, because the labels are all the browser holds.
526
+ */
527
+ interface PivotDetailPayload {
528
+ widgetId: string;
529
+ /** The clicked cell in words, which titles the detail modal. */
530
+ label: string;
531
+ filters: Record<string, string>;
532
+ }
533
+ interface RendererMountInput {
534
+ element: HTMLElement;
535
+ widget: WidgetSpec;
536
+ result?: WidgetResult;
537
+ context?: RendererContext;
538
+ filterValue?: unknown;
539
+ callbacks?: RendererMountCallbacks;
540
+ theme?: Record<string, unknown>;
541
+ }
542
+ type RendererFactory = (input: RendererMountInput) => ReaderRenderer | Promise<ReaderRenderer>;
543
+ /**
544
+ * Renderer factories keyed by widget component. Hosts wire the phase 8 packages
545
+ * here: createEChartsRenderer for charts, createTabulatorRenderer for grids,
546
+ * createRevoGridRenderer for pivots, createNativeWidgetRenderer for the rest.
547
+ */
548
+ type RendererFactories = Partial<Record<string, RendererFactory>> & {
549
+ default?: RendererFactory;
550
+ };
551
+
552
+ /**
553
+ * The authoring seam, kept separate from the reader context on purpose.
554
+ *
555
+ * A reader host wires nothing new to keep reading, and an authoring host adds
556
+ * one provider. The two nest, so a builder rendered inside a reader still has
557
+ * the reader's transport for its preview.
558
+ */
559
+ interface DashboardAuthoringContextValue {
560
+ transport: AuthoringTransport;
561
+ ui: UiKit;
562
+ icons: IconSet;
563
+ editor: CodeEditor;
564
+ onNotice: NoticeSink;
565
+ /** The dashboard every authoring call is scoped to. */
566
+ dashboardId: string;
567
+ /** False when the caller may look at the documents but not write them. */
568
+ canEdit: boolean;
569
+ }
570
+ interface DashboardAuthoringProviderProps {
571
+ transport: AuthoringTransport;
572
+ /** Any subset of the kit; the built-in primitives fill the rest. */
573
+ ui?: Partial<UiKit>;
574
+ /** Any subset of the glyphs; the built-in SVGs fill the rest. */
575
+ icons?: Partial<IconSet>;
576
+ dashboardId: string;
577
+ editor?: CodeEditor;
578
+ onNotice?: NoticeSink;
579
+ canEdit?: boolean;
580
+ children: ReactNode;
581
+ }
582
+ declare function DashboardAuthoringProvider({ transport, ui, icons, dashboardId, editor, onNotice, canEdit, children, }: DashboardAuthoringProviderProps): react_jsx_runtime.JSX.Element;
583
+ declare function useAuthoring(): DashboardAuthoringContextValue;
584
+
585
+ interface AutoFitTextProps {
586
+ children: ReactNode;
587
+ className?: string;
588
+ max?: number;
589
+ min?: number;
590
+ style?: CSSProperties;
591
+ }
592
+ /**
593
+ * Shrinks a single line until it fits its box. KPI values are unpredictable in
594
+ * length and the card must not clip the number it exists to show.
595
+ */
596
+ declare function AutoFitText({ children, className, max, min, style, }: AutoFitTextProps): react_jsx_runtime.JSX.Element;
597
+
598
+ interface BreadcrumbItem {
599
+ label: string;
600
+ href?: string;
601
+ }
602
+ interface DashboardBreadcrumbProps {
603
+ items: BreadcrumbItem[];
604
+ className?: string;
605
+ }
606
+ /** Where the reader is, as links the host renders. */
607
+ declare function DashboardBreadcrumb({ items, className, }: DashboardBreadcrumbProps): react_jsx_runtime.JSX.Element | null;
608
+
609
+ /** Value a mapping dropdown uses for "leave this unset". */
610
+ declare const UNSET = "__unset__";
611
+ /** The question mark beside a label, for wording that is not self-evident. */
612
+ declare function Info({ text }: {
613
+ text: string;
614
+ }): react_jsx_runtime.JSX.Element;
615
+ /** A small heading with its own explanation on hover. */
616
+ declare function FieldLabel({ text, help, }: {
617
+ text: string;
618
+ help?: string | undefined;
619
+ }): react_jsx_runtime.JSX.Element;
620
+ /** A text field that types like a text field and saves when you leave it. */
621
+ declare function TextField({ label, value, placeholder, hint, help, mono, readOnly, onCommit, }: {
622
+ label: string;
623
+ value: string;
624
+ placeholder: string;
625
+ hint?: string | undefined;
626
+ help?: string | undefined;
627
+ mono?: boolean | undefined;
628
+ readOnly: boolean;
629
+ onCommit: (value: string) => void;
630
+ }): react_jsx_runtime.JSX.Element;
631
+ /** An on/off setting, with its own explanation on hover. */
632
+ declare function ToggleField({ label, help, hint, checked, readOnly, onToggle, }: {
633
+ label: string;
634
+ help?: string | undefined;
635
+ hint?: string | undefined;
636
+ checked: boolean;
637
+ readOnly: boolean;
638
+ onToggle: (checked: boolean) => void;
639
+ }): react_jsx_runtime.JSX.Element;
640
+ /** A whole number field that keeps an empty box meaning "the default". */
641
+ declare function NumberField({ label, value, placeholder, hint, help, min, max, readOnly, onCommit, }: {
642
+ label: string;
643
+ value: number | null;
644
+ placeholder: string;
645
+ hint?: string | undefined;
646
+ help?: string | undefined;
647
+ min: number;
648
+ max: number;
649
+ readOnly: boolean;
650
+ onCommit: (value: number | null) => void;
651
+ }): react_jsx_runtime.JSX.Element;
652
+ /** A dropdown that is always ready to use, with no click-to-edit step. */
653
+ declare function ChoiceField({ label, value, options, placeholder, hint, help, readOnly, onPick, }: {
654
+ label: string;
655
+ value: string | null;
656
+ options: {
657
+ value: string;
658
+ label: string;
659
+ }[];
660
+ placeholder: string;
661
+ hint?: string | undefined;
662
+ help?: string | undefined;
663
+ readOnly: boolean;
664
+ onPick: (value: string) => void;
665
+ }): react_jsx_runtime.JSX.Element;
666
+ /** A row of choices that commits on one click, with no edit mode in between. */
667
+ declare function PickList<T extends string>({ options, value, readOnly, columns, onPick, }: {
668
+ options: {
669
+ id: T;
670
+ label: string;
671
+ blurb?: string | undefined;
672
+ }[];
673
+ value: T | null;
674
+ readOnly: boolean;
675
+ columns?: number;
676
+ onPick: (id: T) => void;
677
+ }): react_jsx_runtime.JSX.Element;
678
+ declare function ColumnPicker({ title, empty, help, columns, selected, readOnly, onToggle, }: {
679
+ title: string;
680
+ empty: string;
681
+ help?: string | undefined;
682
+ columns: WidgetColumn[];
683
+ selected: string[];
684
+ readOnly: boolean;
685
+ onToggle: (key: string, checked: boolean) => void;
686
+ }): react_jsx_runtime.JSX.Element;
687
+ /** The YAML a builder panel produces, so the format is learned, not hidden. */
688
+ declare function BuilderYamlStrip({ fragment }: {
689
+ fragment: string;
690
+ }): react_jsx_runtime.JSX.Element | null;
691
+ /** Keys the builder has no editor for, named rather than silently dropped. */
692
+ declare function PreservedKeysNote({ keys, blocking, }: {
693
+ keys: string[];
694
+ blocking?: boolean | undefined;
695
+ }): react_jsx_runtime.JSX.Element | null;
696
+ declare function StepFrame({ anchor, number, title, blurb, help, done, children, }: {
697
+ anchor: string;
698
+ number: number;
699
+ title: string;
700
+ blurb?: string | undefined;
701
+ help?: string | undefined;
702
+ done?: boolean | undefined;
703
+ children: ReactNode;
704
+ }): react_jsx_runtime.JSX.Element;
705
+
706
+ /** Per breakpoint overrides an author previews with, before the dashboard saves them. */
707
+ type GridOverrides = Partial<Record<Breakpoint, {
708
+ rowHeight?: number;
709
+ cols?: number;
710
+ }>>;
711
+ interface DashboardCanvasProps {
712
+ dashboard: DashboardSpec;
713
+ widgets: Record<string, WidgetSpec>;
714
+ results?: Record<string, WidgetResult>;
715
+ /** Widget ids the reader is still waiting on, drawn as skeletons. */
716
+ loadingWidgetIds?: string[];
717
+ loading?: boolean;
718
+ className?: string;
719
+ style?: CSSProperties;
720
+ /** Overrides the measured width, which is how tests and exports fix a size. */
721
+ viewportWidth?: number;
722
+ /** Tiles can be dragged and resized, and carry the edit bar. */
723
+ editMode?: boolean;
724
+ /**
725
+ * Snap on compacts vertically and pushes neighbours aside; snap off places
726
+ * freely and refuses a drop on top of another tile.
727
+ */
728
+ snap?: boolean;
729
+ /** Positions being edited, in place of the ones the widget specs declare. */
730
+ draftLayout?: ResponsiveLayouts;
731
+ gridOverrides?: GridOverrides;
732
+ /** Grid settings being edited, layered over the dashboard's `config.grid`. */
733
+ gridConfig?: Pick<DashboardGridConfig, "isBounded" | "preventCollision" | "maxLayoutWidth" | "maxRows">;
734
+ /** Widgets kept off the grid without being deleted. */
735
+ unplacedWidgetIds?: string[];
736
+ widgetActions?: (widget: WidgetSpec) => ReactNode;
737
+ onLayoutKeyChange?: (key: LayoutKey) => void;
738
+ onBreakpointChange?: (breakpoint: Breakpoint) => void;
739
+ /** Every breakpoint after a drag or resize, plus the key that was edited. */
740
+ onLayoutChange?: (layouts: ResponsiveLayouts, activeKey: LayoutKey) => void;
741
+ onEditWidget?: (widgetId: string) => void;
742
+ onAskWidget?: (widgetId: string) => void;
743
+ onRemoveWidget?: (widgetId: string) => void;
744
+ onDiagnoseWidget?: (widgetId: string) => void;
745
+ /** The author asked for more rows; the next value to save as `maxRows`. */
746
+ onIncreaseMaxRows?: (nextRows: number) => void;
747
+ onInteraction?: (interaction: WidgetInteraction, context: WidgetInteractionContext) => void;
748
+ onRetryWidget?: (widgetId: string) => void;
749
+ /** Rerun one widget, which is what the tile's refresh action asks for. */
750
+ onRefreshWidget?: (widgetId: string) => void;
751
+ onPivotDetail?: (payload: PivotDetailPayload) => void;
752
+ }
753
+ /**
754
+ * The dashboard grid, read or edited.
755
+ *
756
+ * Positions come from the same layout maths the builder saves, drawn by
757
+ * react-grid-layout so that a tile reads and drags at the same pixel. Reading
758
+ * stacks phones into one column; editing keeps the authored grid because an
759
+ * author dragging tiles has to see the positions that will be saved.
760
+ */
761
+ declare function DashboardCanvas({ dashboard, widgets, results, loadingWidgetIds, loading, className, style, viewportWidth, editMode, snap, draftLayout, gridOverrides, gridConfig: gridConfigDraft, unplacedWidgetIds, widgetActions, onLayoutKeyChange, onBreakpointChange, onLayoutChange, onEditWidget, onAskWidget, onRemoveWidget, onDiagnoseWidget, onIncreaseMaxRows, onInteraction, onRetryWidget, onRefreshWidget, onPivotDetail, }: DashboardCanvasProps): react_jsx_runtime.JSX.Element;
762
+
763
+ declare function cn(...values: (string | false | null | undefined)[]): string | undefined;
764
+
765
+ /**
766
+ * The editor a host gets when it passes none.
767
+ *
768
+ * Monaco is what the origin application uses, and it is a megabyte of host choice, so the
769
+ * package ships a textarea that behaves correctly instead: the text edits, and
770
+ * the markers that Monaco would underline are listed under it with their line
771
+ * numbers, which keeps the diagnostics readable without an editor library.
772
+ */
773
+ declare function PlainCodeEditor({ value, onChange, readOnly, markers, ariaLabel, className, }: CodeEditorProps): react_jsx_runtime.JSX.Element;
774
+
775
+ interface DashboardReaderContextValue {
776
+ transport: DashboardTransport;
777
+ ui: UiKit;
778
+ icons: IconSet;
779
+ assets: AssetResolver;
780
+ links: HostLinks;
781
+ renderers: RendererFactories;
782
+ onNotice: NoticeSink;
783
+ /** Capture mode drops hover chrome so exporters photograph a clean canvas. */
784
+ capture: boolean;
785
+ embedded: boolean;
786
+ reducedMotion: boolean;
787
+ }
788
+ interface DashboardReaderProviderProps {
789
+ transport: DashboardTransport;
790
+ /** Any subset of the kit; the built-in primitives fill the rest. */
791
+ ui?: Partial<UiKit>;
792
+ /** Any subset of the glyphs; the built-in SVGs fill the rest. */
793
+ icons?: Partial<IconSet>;
794
+ assets?: AssetResolver;
795
+ links?: HostLinks;
796
+ renderers?: RendererFactories;
797
+ onNotice?: NoticeSink;
798
+ capture?: boolean;
799
+ embedded?: boolean;
800
+ reducedMotion?: boolean;
801
+ children: ReactNode;
802
+ }
803
+ declare function DashboardReaderProvider({ transport, ui, icons, assets, links, renderers, onNotice, capture, embedded, reducedMotion, children, }: DashboardReaderProviderProps): react_jsx_runtime.JSX.Element;
804
+ declare function useDashboardReader(): DashboardReaderContextValue;
805
+ declare function useUiKit(): UiKit;
806
+ declare function useIcons(): IconSet;
807
+
808
+ interface DashboardYamlEditorProps {
809
+ open: boolean;
810
+ onOpenChange: (open: boolean) => void;
811
+ /** Runs after a successful save so the page can redraw in place. */
812
+ onSaved: () => void | Promise<void>;
813
+ }
814
+ /**
815
+ * The whole dashboard document as text: pages, widget order, grid and filter
816
+ * panel settings. Widgets keep their own editor, so the refs listed here are
817
+ * checked against the inventory but their bodies are not shown.
818
+ *
819
+ * Appears only when the host wired `loadDashboardDocument` and
820
+ * `saveDashboardDocument`.
821
+ */
822
+ declare function DashboardYamlEditor({ open, onOpenChange, onSaved, }: DashboardYamlEditorProps): react_jsx_runtime.JSX.Element;
823
+
824
+ /**
825
+ * Add a column to a hand-written expression without needing a cursor.
826
+ *
827
+ * The inline field has no caret to insert at, so the rule is stated in the UI:
828
+ * an empty expression becomes an aggregation of the column, and anything else
829
+ * gets the column appended where an operator or bracket left off.
830
+ */
831
+ declare function appendColumn(expression: string, column: string): string;
832
+ interface DatasetBuilderPanelProps {
833
+ specYaml: string;
834
+ onChange: (specYaml: string) => void;
835
+ readOnly: boolean;
836
+ connections: DataModelConnection[];
837
+ /** False while the connection list is still in flight. */
838
+ connectionsReady: boolean;
839
+ onEditInYaml: () => void;
840
+ }
841
+ /**
842
+ * One named source of rows plus the fields widgets may ask for.
843
+ *
844
+ * A dataset the builder has no form for is shown rather than edited, because
845
+ * rewriting a document whose keys are not understood is how an author loses
846
+ * work. Everything unsupported is named, never dropped.
847
+ */
848
+ declare function DatasetBuilderPanel({ specYaml, onChange, readOnly, connections, connectionsReady, onEditInYaml, }: DatasetBuilderPanelProps): react_jsx_runtime.JSX.Element;
849
+
850
+ interface DrilldownModalProps {
851
+ dashboardId: string;
852
+ dashboardName: string;
853
+ initialFilters?: Record<string, unknown>;
854
+ parentStack?: DrillStackItem[];
855
+ open: boolean;
856
+ onOpenChange: (open: boolean) => void;
857
+ }
858
+ /**
859
+ * A dashboard opened from a widget, in a modal, with a stack behind it.
860
+ *
861
+ * Where the frozen reader called a server action and read `window.location`,
862
+ * this asks the injected transport and the injected links, so the same modal
863
+ * works under any router.
864
+ */
865
+ declare function DrilldownModal({ dashboardId, dashboardName, initialFilters, parentStack, open, onOpenChange, }: DrilldownModalProps): react_jsx_runtime.JSX.Element;
866
+
867
+ interface DashboardFilterBarProps {
868
+ className?: string;
869
+ onRefresh?: () => void;
870
+ refreshing?: boolean;
871
+ }
872
+ /** The one line summary of what the reader is currently looking at. */
873
+ declare function DashboardFilterBar({ className, onRefresh, refreshing, }: DashboardFilterBarProps): react_jsx_runtime.JSX.Element;
874
+
875
+ interface DashboardFilterPanelProps {
876
+ widgets: WidgetSpec[];
877
+ config: DashboardFilterPanelConfig;
878
+ results?: Record<string, WidgetResult>;
879
+ className?: string;
880
+ style?: CSSProperties;
881
+ /**
882
+ * Draw the panel across the top or down the side regardless of the configured
883
+ * position, which is how a side panel folds above the grid on a phone.
884
+ */
885
+ orientation?: "horizontal" | "vertical";
886
+ }
887
+ declare function DashboardFilterPanel({ widgets, config, results, className, style, orientation, }: DashboardFilterPanelProps): react_jsx_runtime.JSX.Element | null;
888
+
889
+ interface FilterWidgetProps {
890
+ widget: WidgetSpec;
891
+ result?: WidgetResult;
892
+ value?: unknown;
893
+ onChange: (widgetId: string, value: unknown, label: string) => void;
894
+ /**
895
+ * Receives the human readable summary of the value currently shown,
896
+ * including the default before anyone touches the control, so a heading
897
+ * that reads `{{filter:...}}` says "All" or "last 90 days" from the first
898
+ * paint rather than after the first change.
899
+ */
900
+ onLabel?: (widgetId: string, label: string) => void;
901
+ className?: string;
902
+ disabled?: boolean;
903
+ }
904
+ /**
905
+ * One filter control, driven by the dashboard filter state rather than by any
906
+ * store of its own. Every change leaves through onChange with the label the
907
+ * filter bar shows, exactly as the frozen reader does.
908
+ */
909
+ declare function FilterWidget({ widget, result, value, onChange, onLabel, className, disabled, }: FilterWidgetProps): react_jsx_runtime.JSX.Element;
910
+
911
+ interface DashboardFiltersValue {
912
+ filters: Record<string, unknown>;
913
+ setFilter: (id: string, value: unknown) => void;
914
+ /**
915
+ * What each control is showing for its current value, keyed by filter id. A
916
+ * location filter sends a key and displays a name, and written content that
917
+ * echoes the selection needs the name.
918
+ */
919
+ labels: Record<string, string>;
920
+ setFilterLabel: (id: string, label: string) => void;
921
+ clearFilters: () => void;
922
+ }
923
+ interface DashboardFiltersProviderProps {
924
+ children: ReactNode;
925
+ filters?: Record<string, unknown>;
926
+ setFilter?: (id: string, value: unknown) => void;
927
+ onFilterChange?: (id: string, value: unknown) => void;
928
+ initialFilters?: Record<string, unknown>;
929
+ }
930
+ declare function DashboardFiltersProvider({ children, filters: controlledFilters, setFilter: controlledSetFilter, onFilterChange, initialFilters, }: DashboardFiltersProviderProps): react_jsx_runtime.JSX.Element;
931
+ declare function useDashboardFilters(): DashboardFiltersValue;
932
+
933
+ interface LayoutDraftDocuments {
934
+ dashboard: DashboardSpec;
935
+ widgets: Record<string, WidgetSpec>;
936
+ /** Widgets the saved documents keep off the grid. */
937
+ unplacedWidgetIds: string[];
938
+ /** The saved version stamp, sent back as `expectedUpdatedAt`. */
939
+ updatedAt?: string;
940
+ }
941
+ interface UseLayoutDraftOptions {
942
+ dashboardId: string;
943
+ /** The documents as last loaded, or null before the first load. */
944
+ documents: LayoutDraftDocuments | null;
945
+ saveLayout?: (request: LayoutSaveRequest) => Promise<LayoutSaveResponse | void>;
946
+ /**
947
+ * Where an unsaved draft survives a reload. Pass null to keep drafts in
948
+ * memory only. Hosts usually pass `window.localStorage`.
949
+ */
950
+ storage?: Pick<Storage, "getItem" | "setItem" | "removeItem"> | null;
951
+ /** Runs after a successful save so the page can redraw from the server. */
952
+ onSaved?: () => void | Promise<void>;
953
+ onError?: (message: string) => void;
954
+ }
955
+ /**
956
+ * The dashboard level grid settings the Grid popover edits: they live in
957
+ * `spec.config.grid` (and `spec.config.dataModelId`) rather than per
958
+ * breakpoint, and reach the server with Save layout like everything else.
959
+ */
960
+ interface LayoutGridConfigDraft {
961
+ isBounded?: boolean;
962
+ preventCollision?: boolean;
963
+ /** `null` clears a cap the dashboard had. */
964
+ maxLayoutWidth?: Breakpoint | null;
965
+ /** `null` returns to the host's default store. */
966
+ dataModelId?: string | null;
967
+ }
968
+ type LayoutExitTarget = "edit" | "back";
969
+ interface LayoutDraft {
970
+ editMode: boolean;
971
+ /** Turns editing on, or asks about unsaved work before turning it off. */
972
+ setEditMode: (next: boolean) => void;
973
+ /** Leaves the page, or asks about unsaved work first. */
974
+ requestExit: (leave: () => void) => void;
975
+ draftLayout: ResponsiveLayouts | undefined;
976
+ draftMaxRows: number | undefined;
977
+ gridOverrides: GridOverrides;
978
+ /** Dashboard level grid settings changed since the last save. */
979
+ gridConfig: LayoutGridConfigDraft;
980
+ unplacedWidgetIds: string[];
981
+ activeLayoutKey: LayoutKey;
982
+ setActiveLayoutKey: (key: LayoutKey) => void;
983
+ hasUnsavedChanges: boolean;
984
+ saving: boolean;
985
+ onLayoutChange: (layouts: ResponsiveLayouts, activeKey: LayoutKey) => void;
986
+ onIncreaseMaxRows: (nextRows: number) => void;
987
+ setGridOverride: (breakpoint: Breakpoint, override: {
988
+ rowHeight?: number;
989
+ cols?: number;
990
+ }) => void;
991
+ setGridConfig: (update: LayoutGridConfigDraft) => void;
992
+ /** Keeps a widget in the draft but off the grid until the next save. */
993
+ removeFromGrid: (widgetId: string) => void;
994
+ /** Puts a widget the saved documents left unplaced back on the draft grid. */
995
+ placeOnGrid: (widgetId: string) => void;
996
+ save: (options?: {
997
+ force?: boolean;
998
+ }) => Promise<boolean>;
999
+ reset: () => void;
1000
+ /** Set while the host should show the unsaved changes dialog. */
1001
+ unsavedDialogOpen: boolean;
1002
+ saveAndExit: () => void;
1003
+ discardAndExit: () => void;
1004
+ keepEditing: () => void;
1005
+ /** Set while the host should show the conflict dialog. */
1006
+ conflictDialogOpen: boolean;
1007
+ overwriteAfterConflict: () => void;
1008
+ reloadAfterConflict: () => void;
1009
+ }
1010
+ /**
1011
+ * The lifecycle behind Edit mode: the draft the grid edits, Save layout, Reset
1012
+ * layout, the unsaved changes dialog on exit and the conflict dialog when
1013
+ * someone else saved first. Nothing here draws; a host composes its own
1014
+ * toolbar and dialogs around the flags.
1015
+ */
1016
+ declare function useLayoutDraft({ dashboardId, documents, saveLayout, storage, onSaved, onError, }: UseLayoutDraftOptions): LayoutDraft;
1017
+
1018
+ /** A data store the author can point the dashboard at. */
1019
+ interface GridSettingsDataStore {
1020
+ id: string;
1021
+ name: string;
1022
+ vendor?: string | undefined;
1023
+ }
1024
+ interface GridSettingsPanelProps {
1025
+ dashboard: DashboardSpec;
1026
+ /** The breakpoint the canvas is showing, whose columns and row height are edited. */
1027
+ breakpoint: Breakpoint;
1028
+ draft: Pick<LayoutDraft, "gridOverrides" | "gridConfig" | "setGridOverride" | "setGridConfig">;
1029
+ /**
1030
+ * Stores the Data store select offers. Leave undefined to hide the select,
1031
+ * which is right for a host with a single store.
1032
+ */
1033
+ dataStores?: GridSettingsDataStore[] | undefined;
1034
+ className?: string | undefined;
1035
+ }
1036
+ /** The cell sizes the origin application offers, as columns per row. */
1037
+ declare const CELL_SIZE_OPTIONS: ReadonlyArray<{
1038
+ label: string;
1039
+ cols: number;
1040
+ }>;
1041
+ /**
1042
+ * The body of the Grid popover: data store, row height, columns, cell size,
1043
+ * bounded drag, prevent collision and max layout width, wired to the layout
1044
+ * draft so every change waits for Save layout. Drawn with the authoring
1045
+ * provider's primitives; the host supplies the popover and the button that
1046
+ * opens it.
1047
+ */
1048
+ declare function GridSettingsPanel({ dashboard, breakpoint, draft, dataStores, className, }: GridSettingsPanelProps): react_jsx_runtime.JSX.Element;
1049
+
1050
+ interface InlineTextProps {
1051
+ label: string;
1052
+ value: string | null;
1053
+ /** What the field says when it holds nothing, for example "Set a label". */
1054
+ empty: string;
1055
+ placeholder?: string | undefined;
1056
+ hint?: string | undefined;
1057
+ readOnly?: boolean | undefined;
1058
+ mono?: boolean | undefined;
1059
+ /**
1060
+ * Opens straight into the input, for a thing the author just created: reading
1061
+ * a field that has never held anything is not worth a click.
1062
+ */
1063
+ startOpen?: boolean | undefined;
1064
+ onCommit: (value: string) => void;
1065
+ }
1066
+ declare function InlineText({ label, value, empty, placeholder, hint, readOnly, mono, startOpen, onCommit, }: InlineTextProps): react_jsx_runtime.JSX.Element;
1067
+ interface InlineOption {
1068
+ value: string;
1069
+ label: string;
1070
+ }
1071
+ interface InlineSelectProps {
1072
+ label: string;
1073
+ value: string | null;
1074
+ options: InlineOption[];
1075
+ empty: string;
1076
+ hint?: string | undefined;
1077
+ readOnly?: boolean | undefined;
1078
+ onCommit: (value: string) => void;
1079
+ }
1080
+ declare function InlineSelect({ label, value, options, empty, hint, readOnly, onCommit, }: InlineSelectProps): react_jsx_runtime.JSX.Element;
1081
+
1082
+ interface KpiCardProps {
1083
+ model: KpiRendererModel;
1084
+ className?: string;
1085
+ /** Fires when the card is clicked and the widget declares a click interaction. */
1086
+ onClick?: (() => void) | undefined;
1087
+ }
1088
+ declare function KpiCard({ model, className, onClick }: KpiCardProps): react_jsx_runtime.JSX.Element;
1089
+
1090
+ interface LayoutDraftDialogsProps {
1091
+ draft: Pick<LayoutDraft, "unsavedDialogOpen" | "saveAndExit" | "discardAndExit" | "keepEditing" | "conflictDialogOpen" | "overwriteAfterConflict" | "reloadAfterConflict" | "saving">;
1092
+ }
1093
+ /**
1094
+ * The two questions Edit mode asks on the way out: keep or drop unsaved
1095
+ * changes, and overwrite or reload when someone else saved first. Drawn with
1096
+ * the host's modal so they look like every other dialog on the page.
1097
+ */
1098
+ declare function LayoutDraftDialogs({ draft }: LayoutDraftDialogsProps): react_jsx_runtime.JSX.Element;
1099
+
1100
+ interface MetricBuilderPanelProps {
1101
+ specYaml: string;
1102
+ onChange: (specYaml: string) => void;
1103
+ readOnly: boolean;
1104
+ datasets: BuilderDataset[];
1105
+ relationships: BuilderRelationship[];
1106
+ metrics: BuilderModelMetric[];
1107
+ onEditInYaml: () => void;
1108
+ }
1109
+ /**
1110
+ * Metrics that span datasets, such as labor cost over net sales.
1111
+ *
1112
+ * A ratio is offered as two pickers rather than as SQL, because the two ways a
1113
+ * ratio goes wrong are both structural: dividing by zero, and asking the
1114
+ * warehouse for percentage points when the card multiplies by 100 itself.
1115
+ */
1116
+ declare function MetricBuilderPanel({ specYaml, onChange, readOnly, datasets, relationships, metrics, onEditInYaml, }: MetricBuilderPanelProps): react_jsx_runtime.JSX.Element;
1117
+
1118
+ type ModelLayer = "data_stores" | "datasets" | "relationships" | "metrics";
1119
+ interface ModelBuilderProps {
1120
+ specYaml: string;
1121
+ onChange: (specYaml: string) => void;
1122
+ readOnly: boolean;
1123
+ /** Sends the author to the YAML tab for anything the builder cannot edit. */
1124
+ onEditInYaml: () => void;
1125
+ }
1126
+ /**
1127
+ * The semantic model in four layers, each of which can only break the next.
1128
+ *
1129
+ * The rail carries counts and a badge for anything already broken, because a
1130
+ * dataset with no location column or a join that cannot resolve is exactly what
1131
+ * makes a widget error later, and it should be visible without pressing
1132
+ * anything.
1133
+ */
1134
+ declare function ModelBuilder({ specYaml, onChange, readOnly, onEditInYaml, }: ModelBuilderProps): react_jsx_runtime.JSX.Element;
1135
+
1136
+ type ModelEditorMode = "builder" | "yaml";
1137
+ declare const DEFAULT_MODEL_YAML = "# Shared semantic model\n# Reusable data stores, datasets, relationships, and metrics.\n# Dashboards reference it with spec.semantic_model_ref: default.\nversion: \"1.0\"\nkind: semantic_model\nname: default\ndata_stores: []\ndatasets: []\nrelationships: []\nmetrics: []\n";
1138
+ declare function modelIssueLines(diagnostics: DashboardModelDiagnostics): string[];
1139
+ declare function modelNoteLines(diagnostics: DashboardModelDiagnostics): string[];
1140
+ interface ModelEditorProps {
1141
+ open: boolean;
1142
+ onOpenChange: (open: boolean) => void;
1143
+ onSaved?: (() => void | Promise<void>) | undefined;
1144
+ }
1145
+ /**
1146
+ * The semantic model, edited as a form or as text, on one document.
1147
+ *
1148
+ * Builder and YAML edit the same string, so switching keeps comments and
1149
+ * anything the builder does not show. A save validates first, because saving a
1150
+ * broken model breaks every dashboard that reads it, and the second click saves
1151
+ * anyway so deliberate work in progress is not trapped behind a checker.
1152
+ */
1153
+ declare function ModelEditor({ open, onOpenChange, onSaved }: ModelEditorProps): react_jsx_runtime.JSX.Element;
1154
+
1155
+ /**
1156
+ * Labels for the model history list.
1157
+ *
1158
+ * A row has to answer "is this the one I want" without opening it, so it carries
1159
+ * when it was replaced, how big it was, how many datasets it declared, and any
1160
+ * note the host recorded with it.
1161
+ */
1162
+ interface VersionRowLabel {
1163
+ title: string;
1164
+ detail: string;
1165
+ }
1166
+ /** Relative age, coarse on purpose: a version list is scanned, not measured. */
1167
+ declare function formatAge(iso: string, now?: Date): string;
1168
+ declare function versionRowLabel(version: ModelVersionSummary, now?: Date): VersionRowLabel;
1169
+
1170
+ interface PivotDetailModalProps {
1171
+ open: boolean;
1172
+ onOpenChange: (open: boolean) => void;
1173
+ /** The clicked cell, in words: its row path and column values. */
1174
+ cellLabel: string;
1175
+ loading: boolean;
1176
+ error: string | null;
1177
+ result: PivotDetailResult | null;
1178
+ }
1179
+ /**
1180
+ * The rows behind one pivot cell, as a plain list.
1181
+ *
1182
+ * The pivot shows an aggregate; this shows what it aggregated, under the same
1183
+ * dashboard filters. The server caps the list, and the cap is said out loud
1184
+ * rather than passing a partial list off as the whole answer.
1185
+ */
1186
+ declare function PivotDetailModal({ open, onOpenChange, cellLabel, loading, error, result, }: PivotDetailModalProps): react_jsx_runtime.JSX.Element;
1187
+
1188
+ interface DashboardReaderProps {
1189
+ dashboard: DashboardSpec;
1190
+ /** How the host addresses this dashboard, when that is not the document id. */
1191
+ dashboardId?: string;
1192
+ widgets: Record<string, WidgetSpec>;
1193
+ results?: Record<string, WidgetResult>;
1194
+ /** Results the host already has, so the reader draws before it runs. */
1195
+ initialResults?: Record<string, WidgetResult>;
1196
+ /** Filters the host has already applied, for a controlled reader. */
1197
+ filters?: Record<string, unknown>;
1198
+ onFiltersChange?: (filters: Record<string, unknown>) => void;
1199
+ loading?: boolean;
1200
+ /** Rerun the dashboard through the transport when a filter changes. */
1201
+ autoRun?: boolean;
1202
+ header?: ReactNode;
1203
+ className?: string;
1204
+ /** Overrides the measured width, for exports and for tests. */
1205
+ viewportWidth?: number;
1206
+ /**
1207
+ * Edit mode and its callbacks, handed straight to the canvas. The reader
1208
+ * keeps its filters and results while these change, so entering edit mode
1209
+ * or dragging a tile never reruns a query.
1210
+ */
1211
+ canvas?: DashboardCanvasEditProps;
1212
+ /** Hide the reader's own refresh bar when the host toolbar carries one. */
1213
+ showFilterBar?: boolean;
1214
+ /** Which tab is open, for a host that wants to drive or remember it. */
1215
+ activeTab?: string;
1216
+ onActiveTabChange?: (tabId: string) => void;
1217
+ /** Fires with every dashboard run, so a host can mirror a busy state. */
1218
+ onRunningChange?: (running: boolean) => void;
1219
+ }
1220
+ type DashboardCanvasEditProps = Pick<DashboardCanvasProps, "editMode" | "snap" | "draftLayout" | "gridOverrides" | "gridConfig" | "unplacedWidgetIds" | "onLayoutChange" | "onBreakpointChange" | "onLayoutKeyChange" | "onEditWidget" | "onAskWidget" | "onRemoveWidget" | "onDiagnoseWidget" | "onIncreaseMaxRows">;
1221
+ /**
1222
+ * A saved dashboard, read. Filters, tiles, drill and pivot detail, over the
1223
+ * transport and the design system the host injected.
1224
+ */
1225
+ declare function DashboardReader({ dashboard, dashboardId, widgets, results: providedResults, initialResults, filters: controlledFilters, onFiltersChange, loading: providedLoading, autoRun, header, className, viewportWidth, canvas, showFilterBar, activeTab: controlledTab, onActiveTabChange, onRunningChange, }: DashboardReaderProps): react_jsx_runtime.JSX.Element;
1226
+
1227
+ interface LoadedDashboard {
1228
+ dashboard: DashboardSpec;
1229
+ widgets: Record<string, WidgetSpec>;
1230
+ results: Record<string, WidgetResult>;
1231
+ }
1232
+ interface DashboardReaderLoaderProps extends Pick<DashboardReaderProps, "canvas" | "showFilterBar" | "activeTab" | "onActiveTabChange" | "onRunningChange"> {
1233
+ dashboardId: string;
1234
+ filters?: Record<string, unknown>;
1235
+ /** Fires as the reader's filters change, so a host can mirror them in its URL or exports. */
1236
+ onFiltersChange?: (filters: Record<string, unknown>) => void;
1237
+ header?: ReactNode;
1238
+ className?: string;
1239
+ viewportWidth?: number;
1240
+ /**
1241
+ * Bump to fetch the documents and results again without unmounting the
1242
+ * reader, which is how a host redraws after saving a widget or a layout.
1243
+ * The current filters, tab and scroll position all survive.
1244
+ */
1245
+ reloadToken?: number;
1246
+ /** The documents once they are known, and again after every reload. */
1247
+ onLoaded?: (loaded: LoadedDashboard) => void;
1248
+ }
1249
+ /**
1250
+ * A reader for a host that holds an identifier rather than the documents. The
1251
+ * transport answers with both the documents and the first results, so a host
1252
+ * needs no loader of its own.
1253
+ */
1254
+ declare function DashboardReaderLoader({ dashboardId, filters, onFiltersChange, header, className, viewportWidth, reloadToken, onLoaded, canvas, showFilterBar, activeTab, onActiveTabChange, onRunningChange, }: DashboardReaderLoaderProps): react_jsx_runtime.JSX.Element;
1255
+
1256
+ /** Columns of a dataset worth joining on: what it declares it can read. */
1257
+ declare function joinableColumns(dataset: BuilderDataset | undefined): string[];
1258
+ interface RelationshipBuilderPanelProps {
1259
+ specYaml: string;
1260
+ onChange: (specYaml: string) => void;
1261
+ readOnly: boolean;
1262
+ datasets: BuilderDataset[];
1263
+ stores: BuilderDataStore[];
1264
+ relationships: BuilderRelationship[];
1265
+ onEditInYaml: () => void;
1266
+ }
1267
+ /**
1268
+ * How two datasets line up.
1269
+ *
1270
+ * A widget that asks for columns from both makes the engine build this join, so
1271
+ * nothing here needs SQL. What it does need is honesty about cardinality: a
1272
+ * join that fans out repeats the left row and double counts its totals.
1273
+ */
1274
+ declare function RelationshipBuilderPanel({ specYaml, onChange, readOnly, datasets, stores, relationships, onEditInYaml, }: RelationshipBuilderPanelProps): react_jsx_runtime.JSX.Element;
1275
+
1276
+ interface RendererMountProps {
1277
+ factory: RendererFactory;
1278
+ input: Omit<RendererMountInput, "element">;
1279
+ className?: string;
1280
+ style?: React.CSSProperties;
1281
+ }
1282
+ /**
1283
+ * Mounts one of the framework neutral renderers into a div and drives its
1284
+ * lifecycle from React: create once, update on new input, resize with the
1285
+ * element, destroy on unmount. The chart, grid and pivot behaviour stays in the
1286
+ * renderer packages and is never rebuilt here.
1287
+ */
1288
+ declare function RendererMount({ factory, input, className, style, }: RendererMountProps): react_jsx_runtime.JSX.Element;
1289
+
1290
+ interface DashboardSectionProps {
1291
+ section: DashboardSectionConfig;
1292
+ results?: Record<string, WidgetResult>;
1293
+ className?: string;
1294
+ style?: CSSProperties;
1295
+ }
1296
+ /** The dashboard header and footer strips, which hold content, not data tiles. */
1297
+ declare function DashboardSection({ section, results, className, style, }: DashboardSectionProps): react_jsx_runtime.JSX.Element | null;
1298
+
1299
+ type StyleValue = string | number | boolean | null | undefined;
1300
+ /**
1301
+ * Build a style object from generated spec values.
1302
+ *
1303
+ * The generated document types carry `null` for an unset value and name their
1304
+ * property types loosely, so the values are narrowed here once rather than cast
1305
+ * at every call site.
1306
+ */
1307
+ declare function cssProps(values: Record<string, StyleValue>): CSSProperties;
1308
+ declare function present<T>(value: T | null | undefined): T | undefined;
1309
+
1310
+ /**
1311
+ * Ease a KPI number from its previous value to the new one.
1312
+ *
1313
+ * A card that snaps from 12,400 to 9,100 gives no sign that anything happened,
1314
+ * which matters most on the widget people look at first. The first value and
1315
+ * any non-finite value land immediately, and the whole thing is skipped when
1316
+ * the host asked for reduced motion or is capturing a still image.
1317
+ */
1318
+ declare function useCountUp(target: number | undefined, duration?: number): number | undefined;
1319
+
1320
+ type TableExportFormat = "csv" | "excel";
1321
+ interface TableExportRequest {
1322
+ format: TableExportFormat;
1323
+ table: ResultTable;
1324
+ /** File name without extension, from the widget's export settings. */
1325
+ filename: string;
1326
+ }
1327
+ /**
1328
+ * Hosts that want Excel, or that route downloads through their own storage,
1329
+ * implement this. The reader handles CSV itself when no exporter is given.
1330
+ */
1331
+ type TableExporter = (request: TableExportRequest) => void;
1332
+ /** Save a UTF-8 CSV of the table through the browser's download flow. */
1333
+ declare function downloadTableCsv(table: ResultTable, filename: string): void;
1334
+
1335
+ interface TableViewProps {
1336
+ model: TableRendererModel;
1337
+ onSortChange?: (sort: TableSortState | null) => void;
1338
+ onPageChange?: (page: number) => void;
1339
+ onRowClick?: (row: Record<string, unknown>) => void;
1340
+ /** Export buttons and the like, drawn above the grid when no header carries them. */
1341
+ toolbar?: ReactNode;
1342
+ className?: string;
1343
+ }
1344
+ /**
1345
+ * The plain table the reader draws itself. Grid engines (Tabulator, RevoGrid)
1346
+ * arrive as renderer factories instead, so nothing here reimplements them.
1347
+ */
1348
+ declare function TableView({ model, onSortChange, onPageChange, onRowClick, toolbar, className, }: TableViewProps): react_jsx_runtime.JSX.Element;
1349
+
1350
+ interface WidgetActionsProps {
1351
+ widget: WidgetSpec;
1352
+ result?: WidgetResult;
1353
+ /** Filter widget id to its name, so an applied filter reads as its label. */
1354
+ filterNames?: Record<string, string>;
1355
+ /** Rerun this widget alone, through the host transport. */
1356
+ onRefresh?: () => void;
1357
+ className?: string;
1358
+ }
1359
+ /**
1360
+ * Reader actions on the card: what the query answered, that answer as a table,
1361
+ * and that table on the clipboard. Editing, asking and removing belong to the
1362
+ * builder and are absent here.
1363
+ */
1364
+ declare function WidgetActions({ widget, result, filterNames, onRefresh, className, }: WidgetActionsProps): react_jsx_runtime.JSX.Element | null;
1365
+
1366
+ interface WidgetAskPanelProps {
1367
+ widgetId: string | null;
1368
+ /** The text in the editor, which is what the proposal is asked to change. */
1369
+ specYaml: string;
1370
+ unsaved: boolean;
1371
+ onApply: (specYaml: string, proposalId: string) => void;
1372
+ onBuildByHand: () => void;
1373
+ }
1374
+ /**
1375
+ * Describe the widget in a sentence and read what comes back before keeping it.
1376
+ *
1377
+ * The assistant itself is the host's: this panel only calls the proposal port,
1378
+ * shows the document it returns, and hands the text to the editor when the
1379
+ * author applies it. Nothing is written until the author saves, so a proposal
1380
+ * is a suggestion rather than an edit.
1381
+ */
1382
+ declare function WidgetAskPanel({ widgetId, specYaml, unsaved, onApply, onBuildByHand, }: WidgetAskPanelProps): react_jsx_runtime.JSX.Element;
1383
+
1384
+ interface WidgetBuilderProps {
1385
+ specYaml: string;
1386
+ onChange: (specYaml: string) => void;
1387
+ readOnly: boolean;
1388
+ /** Sends the author to the YAML tab for anything the builder cannot edit. */
1389
+ onEditInYaml: () => void;
1390
+ }
1391
+ /**
1392
+ * Build a widget by clicking, with the YAML still authoritative.
1393
+ *
1394
+ * The panel is a sequence of steps rather than a form, because the order is
1395
+ * what makes the result safe: a mapping can only name a column the widget
1396
+ * selects, and a column can only be one the chosen dataset can answer. That is
1397
+ * the blank chart removed at the source rather than diagnosed after the fact.
1398
+ */
1399
+ declare function WidgetBuilder({ specYaml, onChange, readOnly, onEditInYaml, }: WidgetBuilderProps): react_jsx_runtime.JSX.Element;
1400
+
1401
+ /**
1402
+ * The edits the widget builder makes, as plain functions on a document object.
1403
+ *
1404
+ * They live apart from the panel because they are where the correctness is: a
1405
+ * mapping that names a column the query does not return is exactly what draws
1406
+ * an empty card, so dropping a column has to drop everything pointing at it.
1407
+ */
1408
+ declare function toggleColumn(widget: BuilderWidget, key: string, checked: boolean): BuilderWidget;
1409
+ declare function setMapping(widget: BuilderWidget, slot: keyof BuilderWidget["mappings"], value: string): BuilderWidget;
1410
+ /**
1411
+ * The axis column, written to both `x` and `category`.
1412
+ *
1413
+ * A chart with named series groups its points by `category`, and one without
1414
+ * them lays them out along `x`. Setting only one is how a chart ends up drawing
1415
+ * against a column the author never picked.
1416
+ */
1417
+ declare function setAxis(widget: BuilderWidget, value: string): BuilderWidget;
1418
+ /** A dataset change clears what belonged to the old dataset. */
1419
+ declare function setDataset(widget: BuilderWidget, datasetId: string): BuilderWidget;
1420
+ declare function addSeries(widget: BuilderWidget, field: string): BuilderWidget;
1421
+ declare function updateSeries(widget: BuilderWidget, index: number, entry: BuilderWidget["series"][number]): BuilderWidget;
1422
+ declare function removeSeries(widget: BuilderWidget, index: number): BuilderWidget;
1423
+ /** The first selected measure no series covers yet. */
1424
+ declare function nextSeriesField(widget: BuilderWidget, numbers: WidgetColumn[]): string | null;
1425
+ declare function addMeasure(pivot: BuilderPivot, field: string): BuilderPivot;
1426
+ declare function updateMeasure(pivot: BuilderPivot, index: number, measure: BuilderPivotMeasure): BuilderPivot;
1427
+ declare function removeMeasure(pivot: BuilderPivot, index: number): BuilderPivot;
1428
+ declare function isMapped(widget: BuilderWidget, column: string): boolean;
1429
+ declare const STEP_TITLES: string[];
1430
+ interface StepState {
1431
+ identity: {
1432
+ id: string;
1433
+ name: string | null;
1434
+ component: string;
1435
+ };
1436
+ widget: BuilderWidget | null;
1437
+ issues: string[];
1438
+ }
1439
+ /** Which of the seven steps read as done, in the order the strip shows them. */
1440
+ declare function builderStepsDone({ identity, widget, issues, }: StepState): boolean[];
1441
+
1442
+ interface WidgetDiagnosticsProps {
1443
+ widgetId: string | null;
1444
+ filters?: Record<string, unknown> | undefined;
1445
+ open: boolean;
1446
+ onOpenChange: (open: boolean) => void;
1447
+ }
1448
+ /**
1449
+ * What a widget actually asked the warehouse, in the author's own words.
1450
+ *
1451
+ * This is the answer to "why is this card empty": the SQL, the scope it was
1452
+ * narrowed to, the columns that came back, and which of them the mappings
1453
+ * found. The port returns rows and text, never a host record.
1454
+ */
1455
+ declare function WidgetDiagnostics({ widgetId, filters, open, onOpenChange, }: WidgetDiagnosticsProps): react_jsx_runtime.JSX.Element;
1456
+
1457
+ declare function frameStyle(theme: WidgetTheme): CSSProperties;
1458
+ /** Height of the edit bar drawn over the top of the card while the grid is editable. */
1459
+ declare const EDIT_BAR_HEIGHT = 28;
1460
+ interface WidgetFrameProps extends HTMLAttributes<HTMLDivElement> {
1461
+ widget: WidgetSpec;
1462
+ /** Reader actions for this card, revealed on hover. Absent while editing. */
1463
+ actions?: ReactNode;
1464
+ theme?: WidgetTheme;
1465
+ /** Draws the drag bar and the edit buttons over the card. */
1466
+ editMode?: boolean;
1467
+ onEdit?: (widgetId: string) => void;
1468
+ onRemove?: (widgetId: string) => void;
1469
+ onDiagnose?: (widgetId: string) => void;
1470
+ /** Opens the editor straight on the assistant. Absent where asking makes no sense. */
1471
+ onAsk?: (widgetId: string) => void;
1472
+ }
1473
+ /**
1474
+ * The widget card. In the reader it is a plain themed box with hover actions;
1475
+ * in edit mode it also carries the origin application's drag bar (`.custom-drag-handle`)
1476
+ * with the widget name and the diagnostics, AI, properties and remove buttons,
1477
+ * whose class names match the dashboard's `draggableHandle` and
1478
+ * `draggableCancel` selectors.
1479
+ */
1480
+ declare const WidgetFrame: react.ForwardRefExoticComponent<WidgetFrameProps & react.RefAttributes<HTMLDivElement>>;
1481
+
1482
+ interface WidgetHeaderProps {
1483
+ widget: WidgetSpec;
1484
+ className?: string;
1485
+ actions?: ReactNode;
1486
+ }
1487
+ declare function WidgetHeader({ widget, className, actions, }: WidgetHeaderProps): react_jsx_runtime.JSX.Element | null;
1488
+
1489
+ interface WidgetInventoryProps {
1490
+ widgets: Record<string, WidgetSpec>;
1491
+ unplacedWidgetIds: string[];
1492
+ open: boolean;
1493
+ onOpenChange: (open: boolean) => void;
1494
+ onEdit: (widgetId: string) => void;
1495
+ onAdd: (widgetId: string) => void;
1496
+ onRemove: (widgetId: string) => void;
1497
+ onDelete: (widgetId: string) => Promise<void>;
1498
+ onCreated: (widgetId: string) => void | Promise<void>;
1499
+ /** Opens the assistant, which writes the whole widget instead of a blank one. */
1500
+ onCreateWithAssistant?: (() => void) | undefined;
1501
+ onEditWithAssistant?: ((widgetId: string) => void) | undefined;
1502
+ }
1503
+ /**
1504
+ * Everything belonging to one dashboard, placed or not.
1505
+ *
1506
+ * A widget exists whether or not the layout references it, which is what lets
1507
+ * an author park a half-built card without it appearing on the grid. Blank
1508
+ * widgets are written from the core templates, so a new widget always parses.
1509
+ */
1510
+ declare function WidgetInventory({ widgets, unplacedWidgetIds, open, onOpenChange, onEdit, onAdd, onRemove, onDelete, onCreated, onCreateWithAssistant, onEditWithAssistant, }: WidgetInventoryProps): react_jsx_runtime.JSX.Element;
1511
+
1512
+ /** A label with its text resolved, which the generated block leaves optional. */
1513
+ interface NormalizedLabel {
1514
+ text: string;
1515
+ icon?: string | undefined;
1516
+ tooltip?: string | undefined;
1517
+ position?: string | undefined;
1518
+ }
1519
+ declare function normalizeLabel(label: string | LabelBlock | NormalizedLabel | null | undefined, fallback?: string): NormalizedLabel | undefined;
1520
+ interface WidgetLabelProps {
1521
+ label?: string | LabelBlock | NormalizedLabel | null;
1522
+ fallback?: string;
1523
+ className?: string;
1524
+ style?: CSSProperties;
1525
+ actions?: ReactNode;
1526
+ }
1527
+ declare function WidgetLabel({ label, fallback, className, style, actions, }: WidgetLabelProps): react_jsx_runtime.JSX.Element | null;
1528
+
1529
+ interface WidgetRendererProps {
1530
+ widget: WidgetSpec;
1531
+ result?: WidgetResult;
1532
+ context?: RendererContext;
1533
+ loading?: boolean;
1534
+ className?: string;
1535
+ style?: CSSProperties;
1536
+ actions?: ReactNode;
1537
+ onInteraction?: (interaction: WidgetInteraction, context: WidgetInteractionContext) => void;
1538
+ onRetry?: () => void;
1539
+ onPivotDetail?: (payload: PivotDetailPayload) => void;
1540
+ /**
1541
+ * Handles table exports. Without one the reader downloads CSV itself and
1542
+ * hides the Excel button, since building a workbook is the host's business.
1543
+ */
1544
+ onExport?: TableExporter;
1545
+ /** Draws the frame's drag bar and edit buttons. */
1546
+ editMode?: boolean;
1547
+ onEdit?: (widgetId: string) => void;
1548
+ onAsk?: (widgetId: string) => void;
1549
+ onRemove?: (widgetId: string) => void;
1550
+ onDiagnose?: (widgetId: string) => void;
1551
+ }
1552
+ declare function WidgetRenderer({ widget, result, context, loading, className, style, actions, onInteraction, onRetry, onPivotDetail, onExport, editMode, onEdit, onAsk, onRemove, onDiagnose, }: WidgetRendererProps): react_jsx_runtime.JSX.Element;
1553
+
1554
+ interface DashboardLoadingBarProps {
1555
+ loading: boolean;
1556
+ className?: string;
1557
+ }
1558
+ declare function DashboardLoadingBar({ loading, className, }: DashboardLoadingBarProps): react_jsx_runtime.JSX.Element | null;
1559
+ interface WidgetLoadingProps {
1560
+ skeleton: "kpi" | "chart" | "content";
1561
+ message?: string;
1562
+ }
1563
+ declare function WidgetLoading({ skeleton, message }: WidgetLoadingProps): react_jsx_runtime.JSX.Element;
1564
+ interface WidgetErrorProps {
1565
+ message: string;
1566
+ hint?: string;
1567
+ retryable?: boolean;
1568
+ onRetry?: () => void;
1569
+ }
1570
+ declare function WidgetError({ message, hint, retryable, onRetry, }: WidgetErrorProps): react_jsx_runtime.JSX.Element;
1571
+ interface WidgetNoticeProps {
1572
+ message: string;
1573
+ children?: ReactNode;
1574
+ }
1575
+ declare function WidgetNotice({ message, children }: WidgetNoticeProps): react_jsx_runtime.JSX.Element;
1576
+ interface WidgetRefreshingProps {
1577
+ active: boolean;
1578
+ children: ReactNode;
1579
+ className?: string;
1580
+ style?: CSSProperties;
1581
+ }
1582
+ /**
1583
+ * Hold the previous answer on screen while the next query runs. The card is
1584
+ * dimmed and marked busy, so the numbers still on it read as the previous
1585
+ * filters' answer rather than the new one.
1586
+ */
1587
+ declare function WidgetRefreshing({ active, children, className, style, }: WidgetRefreshingProps): react_jsx_runtime.JSX.Element;
1588
+ interface WidgetEmptyProps {
1589
+ message?: string;
1590
+ hint?: string;
1591
+ }
1592
+ declare function WidgetEmpty({ message, hint }: WidgetEmptyProps): react_jsx_runtime.JSX.Element;
1593
+ interface VisibilityBadgeProps {
1594
+ visibility: "private" | "shared" | "public" | "organisation";
1595
+ className?: string;
1596
+ }
1597
+ declare function VisibilityBadge({ visibility, className, }: VisibilityBadgeProps): react_jsx_runtime.JSX.Element;
1598
+
1599
+ type WidgetEditorMode = "ask" | "builder" | "yaml";
1600
+ interface WidgetYamlEditorProps {
1601
+ widgetId: string | null;
1602
+ open: boolean;
1603
+ /** Which tab to land on. The host owns remembering a preference. */
1604
+ initialMode?: WidgetEditorMode;
1605
+ onOpenChange: (open: boolean) => void;
1606
+ onSaved: () => void | Promise<void>;
1607
+ onAddToLayout?: (widgetId: string) => void;
1608
+ }
1609
+ /**
1610
+ * One widget, edited three ways over the same text.
1611
+ *
1612
+ * Builder and YAML are two views of one document, so switching keeps comments
1613
+ * and every key the builder has no form for. Ask appears only when the host
1614
+ * wired a proposal port, because an assistant is a host capability rather than
1615
+ * something this package can assume.
1616
+ */
1617
+ declare function WidgetYamlEditor({ widgetId, open, initialMode, onOpenChange, onSaved, onAddToLayout, }: WidgetYamlEditorProps): react_jsx_runtime.JSX.Element;
1618
+
1619
+ /** Every `IconName`, drawn inline. Spread and override to replace a few. */
1620
+ declare const defaultIcons: IconSet;
1621
+ /** The built-in glyphs with a host's own laid over the top. */
1622
+ declare function mergeIcons(overrides?: Partial<IconSet>): IconSet;
1623
+
1624
+ /** The complete built-in kit. */
1625
+ declare const defaultUiKit: UiKit;
1626
+ /**
1627
+ * The built-in kit with a host's own primitives laid over the top, so a host
1628
+ * replaces one control (its Button, its Modal) without writing the other nine.
1629
+ */
1630
+ declare function createDefaultUiKit(overrides?: Partial<UiKit>): UiKit;
1631
+
1632
+ /**
1633
+ * The dashboard management seam: listing, creating, describing, sharing and
1634
+ * exporting dashboards. The reader and builder never touch it; the ready-made
1635
+ * list page, workspace toolbar, share dialog and export menu do.
1636
+ *
1637
+ * Who may see what is the host's decision, made on the server. This port only
1638
+ * carries the answer: a `DashboardSummary` already says what the caller may do
1639
+ * with it, and the share dialog offers whatever principals `searchPrincipals`
1640
+ * returns, or a typed identifier when the host offers no lookup.
1641
+ */
1642
+ /** Who the dashboard is visible to. Hosts may add their own values. */
1643
+ type DashboardVisibility = "personal" | "shared" | "org" | string;
1644
+ interface DashboardSummary {
1645
+ dashboardId: string;
1646
+ name: string;
1647
+ description: string | null;
1648
+ visibility: DashboardVisibility;
1649
+ /** The owner as the host names them, for the list cards. */
1650
+ ownerName: string | null;
1651
+ /** The caller's permission as the host names it, for example `owner`, `edit`, `view`. */
1652
+ permission: string;
1653
+ canRead: boolean;
1654
+ canWrite: boolean;
1655
+ isOwner: boolean;
1656
+ sharedWithCount: number;
1657
+ updatedAt: string | null;
1658
+ }
1659
+ interface DashboardShare {
1660
+ principalId: string;
1661
+ permission: string;
1662
+ displayName: string | null;
1663
+ }
1664
+ interface DashboardDetail extends DashboardSummary {
1665
+ /** Empty unless the caller is the owner. */
1666
+ shares: DashboardShare[];
1667
+ /** Whether the caller may publish this dashboard to the organisation. */
1668
+ canPublish: boolean;
1669
+ }
1670
+ /** Someone or something a dashboard may be shared with. */
1671
+ interface Principal {
1672
+ principalId: string;
1673
+ displayName: string;
1674
+ /** A qualifier for the picker, for example a role or team name. */
1675
+ detail?: string | undefined;
1676
+ }
1677
+ interface ShareGrant {
1678
+ principalId: string;
1679
+ permission: string;
1680
+ }
1681
+ interface ReportFormat {
1682
+ format: string;
1683
+ label: string;
1684
+ mimeType: string;
1685
+ }
1686
+ interface DownloadedReport {
1687
+ filename: string;
1688
+ format: string;
1689
+ mimeType: string;
1690
+ blob: Blob;
1691
+ }
1692
+ interface DashboardManagementTransport {
1693
+ listDashboards: (input: {
1694
+ signal?: AbortSignal | undefined;
1695
+ }) => Promise<DashboardSummary[]>;
1696
+ loadDashboard: (input: {
1697
+ dashboardId: string;
1698
+ signal?: AbortSignal | undefined;
1699
+ }) => Promise<DashboardDetail>;
1700
+ /** Absent when the caller may not create dashboards; the list hides the button. */
1701
+ createDashboard?: (input: {
1702
+ name: string;
1703
+ description: string | null;
1704
+ /** A preferred identifier; the host may grant another and return it. */
1705
+ dashboardId?: string | undefined;
1706
+ specYaml?: string | undefined;
1707
+ visibility?: DashboardVisibility | undefined;
1708
+ }) => Promise<DashboardSummary>;
1709
+ deleteDashboard?: (input: {
1710
+ dashboardId: string;
1711
+ }) => Promise<void>;
1712
+ replaceShares?: (input: {
1713
+ dashboardId: string;
1714
+ grants: ShareGrant[];
1715
+ }) => Promise<DashboardDetail>;
1716
+ revokeShare?: (input: {
1717
+ dashboardId: string;
1718
+ principalId: string;
1719
+ }) => Promise<DashboardDetail>;
1720
+ setVisibility?: (input: {
1721
+ dashboardId: string;
1722
+ visibility: DashboardVisibility;
1723
+ }) => Promise<DashboardDetail>;
1724
+ /** People and roles a dashboard may be shared with; without it the share dialog takes a typed identifier. */
1725
+ searchPrincipals?: (input: {
1726
+ query: string;
1727
+ signal?: AbortSignal | undefined;
1728
+ }) => Promise<Principal[]>;
1729
+ /** The export menu appears only when both report methods exist. */
1730
+ listReportFormats?: (input: {
1731
+ signal?: AbortSignal | undefined;
1732
+ }) => Promise<ReportFormat[]>;
1733
+ downloadReport?: (input: {
1734
+ dashboardId: string;
1735
+ format: string;
1736
+ filters: Record<string, unknown>;
1737
+ }) => Promise<DownloadedReport>;
1738
+ }
1739
+
1740
+ interface Resource<T> {
1741
+ readonly data: T | null;
1742
+ readonly error: string | null;
1743
+ readonly loading: boolean;
1744
+ readonly reload: () => void;
1745
+ }
1746
+ /**
1747
+ * Loads once per dependency change and offers a reload. The load in flight is
1748
+ * abandoned when the dependencies move on, so a stale answer never lands.
1749
+ */
1750
+ declare function useResource<T>(loader: (signal: AbortSignal) => Promise<T>, deps: readonly unknown[]): Resource<T>;
1751
+
1752
+ declare function NoticeList({ notices }: {
1753
+ notices: readonly Notice[];
1754
+ }): react_jsx_runtime.JSX.Element | null;
1755
+ /** Hands a downloaded report to the browser's download folder. */
1756
+ declare function saveBlob(blob: Blob, filename: string): void;
1757
+ interface ExportMenuProps {
1758
+ dashboardId: string;
1759
+ transport: Pick<DashboardManagementTransport, "listReportFormats" | "downloadReport">;
1760
+ /** The filters currently applied to the reader, sent with the report run. */
1761
+ filters?: Record<string, unknown> | undefined;
1762
+ onNotice: NoticeSink;
1763
+ }
1764
+ /** Download as ... with the formats the host's report port offers. */
1765
+ declare function ExportMenu({ dashboardId, transport, filters, onNotice, }: ExportMenuProps): react_jsx_runtime.JSX.Element | null;
1766
+ interface ShareDialogProps {
1767
+ open: boolean;
1768
+ onOpenChange: (open: boolean) => void;
1769
+ dashboard: DashboardDetail;
1770
+ transport: Pick<DashboardManagementTransport, "replaceShares" | "revokeShare" | "setVisibility" | "searchPrincipals">;
1771
+ onChanged: (detail: DashboardDetail) => void;
1772
+ }
1773
+ /**
1774
+ * Visibility, the people with access and an add row. With
1775
+ * `searchPrincipals` the add row is a search box over the host's directory;
1776
+ * without it the caller types a principal identifier the host understands.
1777
+ */
1778
+ declare function ShareDialog({ open, onOpenChange, dashboard, transport, onChanged, }: ShareDialogProps): react_jsx_runtime.JSX.Element;
1779
+
1780
+ type AssistantIntent = "create" | "edit";
1781
+ interface DashboardWorkspaceProps {
1782
+ dashboardId: string;
1783
+ /** The reader's data client. */
1784
+ transport: DashboardTransport;
1785
+ /** Without it the page is read only: no edit mode, editors or inventory. */
1786
+ authoringTransport?: AuthoringTransport | undefined;
1787
+ /** Detail, sharing and exports. */
1788
+ management: DashboardManagementTransport;
1789
+ ui?: Partial<UiKit> | undefined;
1790
+ icons?: Partial<IconSet> | undefined;
1791
+ renderers?: RendererFactories | undefined;
1792
+ links?: HostLinks | undefined;
1793
+ assets?: AssetResolver | undefined;
1794
+ editor?: CodeEditor | undefined;
1795
+ /** Shows the Semantic model button in edit mode. */
1796
+ canEditModel?: boolean | undefined;
1797
+ /** Opens in edit mode when the caller may write, for a freshly created dashboard. */
1798
+ startInEditMode?: boolean | undefined;
1799
+ filters?: Record<string, unknown> | undefined;
1800
+ onFiltersChange?: ((filters: Record<string, unknown>) => void) | undefined;
1801
+ /** Where unsaved drafts survive a reload; defaults to localStorage, null keeps them in memory. */
1802
+ storage?: Pick<Storage, "getItem" | "setItem" | "removeItem"> | null | undefined;
1803
+ /** The Dashboards button; hidden when the host gives no way back. */
1804
+ onBack?: (() => void) | undefined;
1805
+ /** Runs after Make a copy with the new identifier. */
1806
+ onOpenDashboard?: ((dashboardId: string) => void) | undefined;
1807
+ /** Create with AI and Edit with AI; hidden when the host has no assistant. */
1808
+ onAssistant?: ((intent: AssistantIntent, dashboardId: string) => void) | undefined;
1809
+ /** Notices also reach the host, for its own toasts or logs. */
1810
+ onNotice?: NoticeSink | undefined;
1811
+ /** Host buttons placed at the end of the toolbar, a Schedule button for example. */
1812
+ toolbarExtra?: ReactNode;
1813
+ className?: string | undefined;
1814
+ }
1815
+ declare function DashboardWorkspace(props: DashboardWorkspaceProps): react_jsx_runtime.JSX.Element;
1816
+
1817
+ interface DashboardShelf {
1818
+ /** Whether a dashboard sits on this shelf; the first shelf that holds it wins. */
1819
+ holds: (item: DashboardSummary) => boolean;
1820
+ title: string;
1821
+ blurb?: string | undefined;
1822
+ }
1823
+ /** A dashboard the caller owns is theirs wherever it is shared, so ownership is checked before reach. */
1824
+ declare const DEFAULT_SHELVES: readonly DashboardShelf[];
1825
+ interface DashboardListProps {
1826
+ management: DashboardManagementTransport;
1827
+ /** Opens a dashboard; `editing` is set for a dashboard just created. */
1828
+ onOpen: (dashboardId: string, options: {
1829
+ editing: boolean;
1830
+ }) => void;
1831
+ ui?: Partial<UiKit> | undefined;
1832
+ icons?: Partial<IconSet> | undefined;
1833
+ shelves?: readonly DashboardShelf[] | undefined;
1834
+ title?: string | undefined;
1835
+ description?: string | undefined;
1836
+ /** Extra header actions beside New dashboard. */
1837
+ actions?: ReactNode;
1838
+ /** The visibility a new dashboard starts with. */
1839
+ newVisibility?: string | undefined;
1840
+ className?: string | undefined;
1841
+ }
1842
+ /** A URL safe identifier from a name; the host may still grant another. */
1843
+ declare function slugify(name: string): string;
1844
+ declare function DashboardList({ management, onOpen, ui, icons, shelves, title, description, actions, newVisibility, className, }: DashboardListProps): react_jsx_runtime.JSX.Element;
1845
+
1846
+ interface HttpTransportOptions {
1847
+ /** The dashboards prefix, for example `/api/custom-dashboards`. */
1848
+ readonly baseUrl: string;
1849
+ /** The authoring prefix; defaults to `${baseUrl}/authoring`. */
1850
+ readonly authoringUrl?: string;
1851
+ /** Defaults to the global `fetch`. */
1852
+ readonly fetch?: typeof fetch;
1853
+ /**
1854
+ * Last word on every request: add an Authorization header, a tenant query
1855
+ * parameter, credentials, whatever the host's API expects.
1856
+ */
1857
+ readonly prepare?: (url: string, init: RequestInit) => RequestInit | void;
1858
+ /** Extra query parameters appended to every URL, for example `{ person }`. */
1859
+ readonly query?: Readonly<Record<string, string>>;
1860
+ }
1861
+ declare function httpRefusal(response: Response): Promise<string>;
1862
+ /** The reader's data client over the `/{id}/reader`, `/reader/{widget}` and `/layout` routes. */
1863
+ declare function createHttpDashboardTransport(options: HttpTransportOptions): DashboardTransport;
1864
+ /** The builder's client over the `/authoring/*` routes, snake case on the wire. */
1865
+ declare function createHttpAuthoringTransport(options: HttpTransportOptions): AuthoringTransport;
1866
+ interface HttpManagementOptions extends HttpTransportOptions {
1867
+ /** The reports prefix; defaults to `${baseUrl}/reports`. */
1868
+ readonly reportsUrl?: string;
1869
+ /** Route groups the host serves; the matching optional methods are omitted otherwise. */
1870
+ readonly features?: {
1871
+ /** `DELETE {baseUrl}/{id}`. */
1872
+ readonly delete?: boolean;
1873
+ /** `GET {baseUrl}/principals?q=`. */
1874
+ readonly principals?: boolean;
1875
+ /** `GET {reportsUrl}/formats` and `POST {reportsUrl}/{id}/{format}`. */
1876
+ readonly reports?: boolean;
1877
+ };
1878
+ }
1879
+ /**
1880
+ * Listing, detail, create, sharing, visibility and reports over the route
1881
+ * shape both example hosts serve: `GET/POST {baseUrl}`, `GET {baseUrl}/{id}`,
1882
+ * `POST {baseUrl}/{id}/shares|shares/revoke|visibility`, `PATCH {baseUrl}/{id}`,
1883
+ * `POST {baseUrl}/{id}/copy`, plus the optional groups in `features`.
1884
+ */
1885
+ declare function createHttpManagementTransport(options: HttpManagementOptions): DashboardManagementTransport;
1886
+
1887
+ /** How the component reaches the host's API when no transport is given. */
1888
+ interface BideuxHttpOptions extends HttpManagementOptions {
1889
+ /** Set to false for a read only page that never builds an authoring transport. */
1890
+ readonly authoring?: boolean;
1891
+ }
1892
+ type WorkspaceRest = Omit<DashboardWorkspaceProps, "transport" | "authoringTransport" | "management" | "renderers">;
1893
+ interface BideuxDashboardProps extends WorkspaceRest {
1894
+ /** The dashboards prefix, for example `/api/custom-dashboards`; the transports are built from it. */
1895
+ baseUrl?: string | undefined;
1896
+ /** Everything about the HTTP client: fetch, prepare, query, reports URL, features. */
1897
+ http?: Omit<BideuxHttpOptions, "baseUrl"> | undefined;
1898
+ /** Custom clients; each one given replaces the HTTP one for that role. */
1899
+ transport?: DashboardTransport | undefined;
1900
+ authoringTransport?: AuthoringTransport | undefined;
1901
+ management?: DashboardManagementTransport | undefined;
1902
+ /** Widget renderers; defaults to ECharts, Tabulator, RevoGrid and the DOM renderer. */
1903
+ renderers?: DashboardWorkspaceProps["renderers"];
1904
+ /** Theme and overrides for the default renderers when `renderers` is not given. */
1905
+ rendererOptions?: DefaultRenderersOptions | undefined;
1906
+ }
1907
+ declare function BideuxDashboard({ baseUrl, http, transport, authoringTransport, management, renderers, rendererOptions, ...rest }: BideuxDashboardProps): react_jsx_runtime.JSX.Element;
1908
+ interface BideuxDashboardListProps extends Omit<DashboardListProps, "management"> {
1909
+ baseUrl?: string | undefined;
1910
+ http?: Omit<HttpManagementOptions, "baseUrl"> | undefined;
1911
+ management?: DashboardManagementTransport | undefined;
1912
+ }
1913
+ declare function BideuxDashboardList({ baseUrl, http, management, ...rest }: BideuxDashboardListProps): react_jsx_runtime.JSX.Element;
1914
+
1915
+ export { type AssetResolver, type AssistantIntent, type AuthoringProposal, type AuthoringTransport, AutoFitText, type AutoFitTextProps, BideuxDashboard, BideuxDashboardList, type BideuxDashboardListProps, type BideuxDashboardProps, type BideuxHttpOptions, type BreadcrumbItem, BuilderYamlStrip, CELL_SIZE_OPTIONS, ChoiceField, type CodeEditor, type CodeEditorProps, ColumnPicker, DEFAULT_MODEL_YAML, DEFAULT_SHELVES, type DashboardAuthoringContextValue, DashboardAuthoringProvider, type DashboardAuthoringProviderProps, DashboardBreadcrumb, type DashboardBreadcrumbProps, DashboardCanvas, type DashboardCanvasEditProps, type DashboardCanvasProps, type DashboardCopyRequest, type DashboardCopyResponse, type DashboardDetail, type DashboardDocument, type DashboardDocumentRequest, type DashboardDocumentSaveRequest, DashboardFilterBar, type DashboardFilterBarProps, DashboardFilterPanel, type DashboardFilterPanelProps, DashboardFiltersProvider, type DashboardFiltersProviderProps, type DashboardFiltersValue, DashboardList, type DashboardListProps, DashboardLoadingBar, type DashboardLoadingBarProps, type DashboardManagementTransport, type DashboardMetadataSaveRequest, DashboardReader, type DashboardReaderContextValue, DashboardReaderLoader, type DashboardReaderLoaderProps, type DashboardReaderProps, DashboardReaderProvider, type DashboardReaderProviderProps, type DashboardRunRequest, type DashboardRunResponse, DashboardSection, type DashboardSectionProps, type DashboardShare, type DashboardShelf, type DashboardSummary, type DashboardTransport, type DashboardVisibility, DashboardWorkspace, type DashboardWorkspaceProps, DashboardYamlEditor, type DashboardYamlEditorProps, type DataModelConnection, DatasetBuilderPanel, type DatasetBuilderPanelProps, type DatasetPreviewRequest, type DatasetPreviewResult, type DownloadedReport, type DrillRunRequest, type DrillRunResponse, DrilldownModal, type DrilldownModalProps, EDIT_BAR_HEIGHT, ExportMenu, type ExportMenuProps, FieldLabel, FilterWidget, type FilterWidgetProps, type GridOverrides, type GridSettingsDataStore, GridSettingsPanel, type GridSettingsPanelProps, type HostLinkProps, type HostLinks, type HttpManagementOptions, type HttpTransportOptions, type IconName, type IconProps, type IconSet, Info, type InlineOption, InlineSelect, type InlineSelectProps, InlineText, type InlineTextProps, KpiCard, type KpiCardProps, LayoutConflictError, type LayoutDraft, LayoutDraftDialogs, type LayoutDraftDialogsProps, type LayoutDraftDocuments, type LayoutExitTarget, type LayoutGridConfigDraft, LayoutKey, type LayoutSaveRequest, type LayoutSaveResponse, type LayoutWidgetRequest, type LoadedDashboard, MetricBuilderPanel, type MetricBuilderPanelProps, ModelBuilder, type ModelBuilderProps, type ModelDocument, ModelEditor, type ModelEditorMode, type ModelEditorProps, type ModelLayer, type ModelLoadRequest, type ModelSaveRequest, type ModelValidateRequest, type ModelVersionRequest, type ModelVersionRestoreRequest, type ModelVersionSummary, type NormalizedLabel, type Notice, NoticeList, type NoticeSink, NumberField, PickList, PivotDetailModal, type PivotDetailModalProps, type PivotDetailPayload, PlainCodeEditor, PreservedKeysNote, type Principal, type ProposalOutcomeRequest, type ProposalRequest, type ReaderRenderer, RelationshipBuilderPanel, type RelationshipBuilderPanelProps, type RendererExportRequest, type RendererFactories, type RendererFactory, RendererMount, type RendererMountCallbacks, type RendererMountInput, type RendererMountProps, type ReportFormat, type Resource, ResultTable, STEP_TITLES, ShareDialog, type ShareDialogProps, type ShareGrant, StepFrame, type StepState, type StyleValue, type TableExportFormat, type TableExportRequest, type TableExporter, TableView, type TableViewProps, TextField, ToggleField, UNSET, type UiBadgeProps, type UiButtonProps, type UiCheckboxProps, type UiKit, type UiMenuItem, type UiMenuProps, type UiModalProps, type UiPopoverProps, type UiSelectOption, type UiSelectProps, type UiSkeletonProps, type UiTextInputProps, type UiTooltipProps, type UseLayoutDraftOptions, type VersionRowLabel, VisibilityBadge, type VisibilityBadgeProps, type WarehouseColumn, type WarehouseSchemaRequest, type WarehouseTable, WidgetActions, type WidgetActionsProps, WidgetAskPanel, type WidgetAskPanelProps, WidgetBuilder, type WidgetBuilderProps, type WidgetCreateRequest, type WidgetDeleteRequest, type WidgetDetailRequest, WidgetDiagnostics, type WidgetDiagnosticsProps, type WidgetDiagnosticsRequest, type WidgetDiagnosticsResponse, type WidgetDocument, type WidgetDocumentRequest, type WidgetEditorMode, WidgetEmpty, type WidgetEmptyProps, WidgetError, type WidgetErrorProps, WidgetFrame, type WidgetFrameProps, WidgetHeader, type WidgetHeaderProps, WidgetInventory, type WidgetInventoryProps, type WidgetInventoryRequest, type WidgetInventoryResponse, WidgetLabel, type WidgetLabelProps, WidgetLoading, type WidgetLoadingProps, type WidgetMappingDiagnostic, WidgetNotice, type WidgetNoticeProps, type WidgetQueryDiagnostic, WidgetRefreshing, type WidgetRefreshingProps, WidgetRenderer, type WidgetRendererProps, type WidgetRunRequest, type WidgetSaveRequest, WidgetYamlEditor, type WidgetYamlEditorProps, addMeasure, addSeries, appendColumn, builderStepsDone, cn, createDefaultUiKit, createHttpAuthoringTransport, createHttpDashboardTransport, createHttpManagementTransport, cssProps, defaultIcons, defaultUiKit, downloadTableCsv, formatAge, frameStyle, httpRefusal, isLayoutConflict, isMapped, joinableColumns, mergeIcons, modelIssueLines, modelNoteLines, nextSeriesField, normalizeLabel, present, removeMeasure, removeSeries, saveBlob, setAxis, setDataset, setMapping, slugify, toggleColumn, updateMeasure, updateSeries, useAuthoring, useCountUp, useDashboardFilters, useDashboardReader, useIcons, useLayoutDraft, useResource, useUiKit, versionRowLabel };