@aintela/bi 0.2.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 (175) hide show
  1. package/README.md +299 -0
  2. package/dist/BiClientProvider-CWJochvi.js +219 -0
  3. package/dist/BiClientProvider-CWJochvi.js.map +1 -0
  4. package/dist/ChartCardDefaultsContext-Cl5T25H0.js +32 -0
  5. package/dist/ChartCardDefaultsContext-Cl5T25H0.js.map +1 -0
  6. package/dist/ChartContext-C_f_6khG.js +14 -0
  7. package/dist/ChartContext-C_f_6khG.js.map +1 -0
  8. package/dist/DashboardParametersContext-Clv--79U.js +39 -0
  9. package/dist/DashboardParametersContext-Clv--79U.js.map +1 -0
  10. package/dist/cards/ChartCard.d.ts +62 -0
  11. package/dist/cards/DataTableCard.d.ts +55 -0
  12. package/dist/cards/GaugeCard.d.ts +20 -0
  13. package/dist/cards/GaugeGroup.d.ts +12 -0
  14. package/dist/cards/MapBubbles.d.ts +35 -0
  15. package/dist/cards/MapConnections.d.ts +28 -0
  16. package/dist/cards/MetricCard.d.ts +15 -0
  17. package/dist/cards/MetricGroupCard.d.ts +10 -0
  18. package/dist/cards/TreeMapCard.d.ts +15 -0
  19. package/dist/cards/geoLayers.d.ts +23 -0
  20. package/dist/cards/index.d.ts +24 -0
  21. package/dist/cards/licenseGuard.d.ts +9 -0
  22. package/dist/cards/mapUtils.d.ts +23 -0
  23. package/dist/cards/useContainerRectangle.d.ts +9 -0
  24. package/dist/cards/worldMapPath.d.ts +7 -0
  25. package/dist/cards.d.ts +2 -0
  26. package/dist/cards.js +28 -0
  27. package/dist/cards.js.map +1 -0
  28. package/dist/client/BiClient.d.ts +160 -0
  29. package/dist/client/BiClientProvider.d.ts +21 -0
  30. package/dist/client/index.d.ts +4 -0
  31. package/dist/client.d.ts +2 -0
  32. package/dist/client.js +11 -0
  33. package/dist/client.js.map +1 -0
  34. package/dist/composer/environment/environmentDom.d.ts +31 -0
  35. package/dist/composer/environment/types.d.ts +67 -0
  36. package/dist/composer/icons/cardTypeIcons.d.ts +31 -0
  37. package/dist/composer/index.d.ts +66 -0
  38. package/dist/composer/llm/ExampleCardSketch.d.ts +22 -0
  39. package/dist/composer/llm/ExamplePad.d.ts +18 -0
  40. package/dist/composer/llm/PrototypePad.d.ts +13 -0
  41. package/dist/composer/llm/useDashboardPad.d.ts +25 -0
  42. package/dist/composer/models/catalog.d.ts +33 -0
  43. package/dist/composer/models/sketchModels.d.ts +102 -0
  44. package/dist/composer/models/utils.d.ts +9 -0
  45. package/dist/composer/pad/CardSketch.d.ts +25 -0
  46. package/dist/composer/pad/ClonedComponent.d.ts +13 -0
  47. package/dist/composer/pad/DashboardPad.d.ts +38 -0
  48. package/dist/composer/pad/DashboardPadEditor.d.ts +35 -0
  49. package/dist/composer/pad/DashboardPadSketch.d.ts +31 -0
  50. package/dist/composer/pad/DatasetParameterizationControls.d.ts +34 -0
  51. package/dist/composer/pad/FilterSketch.d.ts +10 -0
  52. package/dist/composer/pad/HoverButton.d.ts +12 -0
  53. package/dist/composer/pad/TitleSketch.d.ts +19 -0
  54. package/dist/composer/pad/ToolBox.d.ts +11 -0
  55. package/dist/composer/store/ComposerProvider.d.ts +36 -0
  56. package/dist/composer/store/createComposerStore.d.ts +107 -0
  57. package/dist/composer/store/drafts.d.ts +20 -0
  58. package/dist/composer/view/ComposerChatBinding.d.ts +10 -0
  59. package/dist/composer/view/ComposerView.d.ts +49 -0
  60. package/dist/composer/view/DashboardPin.d.ts +3 -0
  61. package/dist/composer/view/DashboardSidePanel.d.ts +10 -0
  62. package/dist/composer/view/DrawablePrompt.d.ts +22 -0
  63. package/dist/composer/view/EntryEmptyState.d.ts +22 -0
  64. package/dist/composer/view/SpotlightOverlay.d.ts +21 -0
  65. package/dist/composer/view/composerAnimations.d.ts +11 -0
  66. package/dist/composer/view/composerTypes.d.ts +18 -0
  67. package/dist/composer/view/data/suggestions.d.ts +10 -0
  68. package/dist/composer/view/data/templates.d.ts +33 -0
  69. package/dist/composer/view/surfaces.d.ts +19 -0
  70. package/dist/composer/view/useComposerChatBridge.d.ts +43 -0
  71. package/dist/composer.d.ts +2 -0
  72. package/dist/composer.js +99 -0
  73. package/dist/composer.js.map +1 -0
  74. package/dist/createBiTheme-TyUv_UHM.js +93 -0
  75. package/dist/createBiTheme-TyUv_UHM.js.map +1 -0
  76. package/dist/data/ChartCardDefaultsContext.d.ts +43 -0
  77. package/dist/data/dataUtils.d.ts +152 -0
  78. package/dist/data/index.d.ts +5 -0
  79. package/dist/data/queryModel.d.ts +23 -0
  80. package/dist/data.d.ts +2 -0
  81. package/dist/data.js +37 -0
  82. package/dist/data.js.map +1 -0
  83. package/dist/dataUtils-CAUE5uZY.js +372 -0
  84. package/dist/dataUtils-CAUE5uZY.js.map +1 -0
  85. package/dist/filters/VizAutoComplete.d.ts +23 -0
  86. package/dist/filters/VizDatePicker.d.ts +9 -0
  87. package/dist/filters/VizDateRangePicker.d.ts +14 -0
  88. package/dist/filters/VizSelect.d.ts +12 -0
  89. package/dist/filters/VizTextField.d.ts +8 -0
  90. package/dist/filters/VizTriggerButton.d.ts +9 -0
  91. package/dist/filters/filterFactory.d.ts +30 -0
  92. package/dist/filters/friendlyName.d.ts +4 -0
  93. package/dist/filters/index.d.ts +15 -0
  94. package/dist/filters.d.ts +2 -0
  95. package/dist/filters.js +15 -0
  96. package/dist/filters.js.map +1 -0
  97. package/dist/grid/BiErrorBoundary.d.ts +24 -0
  98. package/dist/grid/ChartContext.d.ts +14 -0
  99. package/dist/grid/GridCard.d.ts +45 -0
  100. package/dist/grid/GridCardPlaceHolder.d.ts +8 -0
  101. package/dist/grid/GridLayout.d.ts +147 -0
  102. package/dist/grid/gridModels.d.ts +33 -0
  103. package/dist/grid/index.d.ts +14 -0
  104. package/dist/grid/types.d.ts +23 -0
  105. package/dist/grid/useGridConfigTranslator.d.ts +72 -0
  106. package/dist/grid.d.ts +2 -0
  107. package/dist/grid.js +20 -0
  108. package/dist/grid.js.map +1 -0
  109. package/dist/hooks/DashboardParametersContext.d.ts +32 -0
  110. package/dist/hooks/index.d.ts +8 -0
  111. package/dist/hooks/useDashboardData.d.ts +20 -0
  112. package/dist/hooks/useDashboardLazyData.d.ts +79 -0
  113. package/dist/hooks.d.ts +2 -0
  114. package/dist/hooks.js +16 -0
  115. package/dist/hooks.js.map +1 -0
  116. package/dist/index-BYc79sSy.js +131 -0
  117. package/dist/index-BYc79sSy.js.map +1 -0
  118. package/dist/index-C6JQ6770.js +4545 -0
  119. package/dist/index-C6JQ6770.js.map +1 -0
  120. package/dist/index-CZbCaXMC.js +15 -0
  121. package/dist/index-CZbCaXMC.js.map +1 -0
  122. package/dist/index-D3OoOPjl.js +259 -0
  123. package/dist/index-D3OoOPjl.js.map +1 -0
  124. package/dist/index-D7Oo_dC-.js +94 -0
  125. package/dist/index-D7Oo_dC-.js.map +1 -0
  126. package/dist/index-D7tVPX8d.js +347 -0
  127. package/dist/index-D7tVPX8d.js.map +1 -0
  128. package/dist/index-DGyvUtY3.js +494 -0
  129. package/dist/index-DGyvUtY3.js.map +1 -0
  130. package/dist/index-DOpx0R4Y.js +41 -0
  131. package/dist/index-DOpx0R4Y.js.map +1 -0
  132. package/dist/index-wtSLspPh.js +1065 -0
  133. package/dist/index-wtSLspPh.js.map +1 -0
  134. package/dist/index.d.ts +12 -0
  135. package/dist/index.js +236 -0
  136. package/dist/index.js.map +1 -0
  137. package/dist/inline/Chart.d.ts +29 -0
  138. package/dist/inline/IFrame.d.ts +19 -0
  139. package/dist/inline/Metric.d.ts +16 -0
  140. package/dist/inline/MetricGroup.d.ts +11 -0
  141. package/dist/inline/index.d.ts +9 -0
  142. package/dist/inline/parseKnownNumbers.d.ts +11 -0
  143. package/dist/inline.d.ts +2 -0
  144. package/dist/inline.js +9 -0
  145. package/dist/inline.js.map +1 -0
  146. package/dist/runtime/IDashboardDefinition.d.ts +22 -0
  147. package/dist/runtime/biModuleSurface.d.ts +2 -0
  148. package/dist/runtime/createBiUiTools.d.ts +74 -0
  149. package/dist/runtime/index.d.ts +9 -0
  150. package/dist/runtime/loadDashboardBundle.d.ts +32 -0
  151. package/dist/runtime/registerBiModules.d.ts +36 -0
  152. package/dist/runtime/version.d.ts +6 -0
  153. package/dist/runtime.d.ts +2 -0
  154. package/dist/runtime.js +19 -0
  155. package/dist/runtime.js.map +1 -0
  156. package/dist/style.css +1 -0
  157. package/dist/theme/BiThemeBridge.d.ts +32 -0
  158. package/dist/theme/biPalette.d.ts +23 -0
  159. package/dist/theme/createBiTheme.d.ts +25 -0
  160. package/dist/theme/index.d.ts +5 -0
  161. package/dist/theme.d.ts +2 -0
  162. package/dist/theme.js +15 -0
  163. package/dist/theme.js.map +1 -0
  164. package/dist/version-DnqajORq.js +83 -0
  165. package/dist/version-DnqajORq.js.map +1 -0
  166. package/dist/viewer/ScriptDashboardViewer.d.ts +82 -0
  167. package/dist/viewer/ScriptDashboardViewerVertical.d.ts +24 -0
  168. package/dist/viewer/cardMetadata.d.ts +15 -0
  169. package/dist/viewer/index.d.ts +8 -0
  170. package/dist/viewer/models.d.ts +67 -0
  171. package/dist/viewer/useDashboardBundle.d.ts +73 -0
  172. package/dist/viewer.d.ts +2 -0
  173. package/dist/viewer.js +9 -0
  174. package/dist/viewer.js.map +1 -0
  175. package/package.json +196 -0
package/README.md ADDED
@@ -0,0 +1,299 @@
1
+ # `@aintela/bi`
2
+
3
+ React BI components for the AIA platform, extracted from Envision's dashboard app (Issue 1210, plan in
4
+ `AIA-Solution/Docs/BI/BiLibrary_ExtractionPlan.md` §1.2). It pairs with `@aintela/chat`: the chat library runs the
5
+ LLM-emitted TSX, this package is what that TSX imports.
6
+
7
+ ```
8
+ @aintela/bi flat union of every subpath — what LLM code imports
9
+ @aintela/bi/data DataResult, defineSchema / InferModel, coercers, formatters, computeDomain/Ticks, trend helpers
10
+ @aintela/bi/cards ChartCard, DataTableCard (MUI X Pro), MetricCard, MetricGroupCard, GaugeCard, GaugeGroup, TreeMapCard, MapBubblesCard, MapConnectionsCard
11
+ @aintela/bi/grid GridLayout, GridCard, GridCardPlaceHolder, useGridConfigTranslator, BiErrorBoundary
12
+ @aintela/bi/inline Chart (PNG artifact card), Metric, MetricGroup, IFrame — the explorer's present_* vocabulary
13
+ @aintela/bi/hooks useDashboardData, useDashboardLazyData, DashboardParametersProvider
14
+ @aintela/bi/filters VizAutoComplete, VizDateRangePicker, VizDatePicker, VizSelect, VizTextField, VizTriggerButton, createFilterComponent
15
+ @aintela/bi/viewer useDashboardBundle (headless), ScriptDashboardViewer, ScriptDashboardViewerVertical
16
+ @aintela/bi/runtime registerBiModules, createBiUiTools, loadDashboardBundle / instantiateDashboardBundle, BI_RUNTIME_VERSION
17
+ @aintela/bi/theme createBiTheme / withBiPalette, useBiPalette, biSeriesColor, BiThemeBridge, biLightPalette, biDarkPalette
18
+ @aintela/bi/client createBiClient, BiClientProvider, useBiClient (+ the Dashboard / DashboardFolder document routes)
19
+ @aintela/bi/composer ComposerView, DashboardPad, DashboardPadSketch, ComposerProvider / useComposer, the LLM pad helpers, the environment API
20
+ @aintela/bi/style.css the grid + inline + composer stylesheet (token-driven, no colours of its own)
21
+ ```
22
+
23
+ ## Install
24
+
25
+ ```bash
26
+ npm i @aintela/bi @aintela/chat
27
+ ```
28
+
29
+ Peer dependencies (the host installs them, this package never bundles them):
30
+
31
+ | peer | version | note |
32
+ |---|---|---|
33
+ | `react`, `react-dom` | ^18.2 | React 18 — `@types/react` must be 18 too |
34
+ | `@mui/material`, `@mui/icons-material` | ^7 | |
35
+ | `@emotion/react`, `@emotion/styled` | ^11.14 | |
36
+ | `@mui/x-data-grid-pro` | ^8 | **Pro** — see the licence note |
37
+ | `@mui/x-date-pickers`, `@mui/x-date-pickers-pro` | ^8 | optional; only the `filters` subpath needs them |
38
+ | `recharts` | ^2.15 | |
39
+ | `react-grid-layout` | ^2.2 | the 2.x major with the `/core` subpath |
40
+ | `react-simple-maps` | ^3 | |
41
+ | `dayjs` | ^1.11 | |
42
+ | `zustand` | ^5 | optional for every other subpath; the `composer` subpath creates its store with it |
43
+ | `framer-motion` | ^11.18 \|\| ^12 | optional; only the `composer` subpath imports it (the splash ↔ execution morph, the side panel, the sketch chips) |
44
+ | `@aintela/chat` | ^0.4.25 | the `runtime` subpath (registry, uiTools) and the `composer` subpath (`PromptV2`, `EnvironmentProvider`, the v2 icons) import it at runtime |
45
+
46
+ Bundler note: dedupe `react`, `react-dom`, `@mui/material`, `@mui/material/styles`, `@mui/icons-material`,
47
+ `@emotion/react`, `@emotion/styled`, `zustand` across `@aintela/bi` and `@aintela/chat` (obtapp's `vite.config.ts` already
48
+ does this for the chat library — add `@aintela/bi`). Otherwise `useTheme()` reads a different `ThemeContext` than the
49
+ one you created the theme in.
50
+
51
+ ### MUI X licence
52
+
53
+ `DataTableCard` is MUI X **DataGrid Pro**. The licence key is the host's, set once before the first render:
54
+
55
+ ```ts
56
+ import { LicenseInfo } from '@mui/x-license';
57
+ LicenseInfo.setLicenseKey(import.meta.env.VITE_MUI_LICENSE_KEY);
58
+ ```
59
+
60
+ This package ships no key. If none is set the grid renders MUI's watermark and the card logs one
61
+ `[@aintela/bi] MUI X licence key not set …` warning per session.
62
+
63
+ ## Wiring a host
64
+
65
+ ```tsx
66
+ import { LicenseInfo } from '@mui/x-license';
67
+ import { ThemeProvider, createTheme } from '@mui/material/styles';
68
+ import { AiChatProvider } from '@aintela/chat';
69
+ import { createBiClient, BiClientProvider, createBiTheme, BiThemeBridge, registerBiModules, createBiUiTools } from '@aintela/bi';
70
+ import '@aintela/bi/style.css';
71
+
72
+ LicenseInfo.setLicenseKey(MUI_KEY);
73
+
74
+ // 1. Make the library resolvable from LLM-generated code (once, at boot).
75
+ registerBiModules({ specifiers: ['@aintela/bi'] });
76
+ // envision-abi keeps its legacy keys alive forever:
77
+ // registerBiModules({ specifiers: ['@aintela/bi', '@envision/ui-library', '@envision/ui-library/components', '@envision/aichat'], extraScope: VizLibraryShim });
78
+
79
+ // 2. One client per server. Routes default to the legacy WSServer layout; override what differs.
80
+ const bi = createBiClient({
81
+ baseUrl: import.meta.env.VITE_BI_BASE_URL,
82
+ getAuthHeader: () => `Bearer ${getAccessToken()}`,
83
+ routes: { artifact: (src, { sessionId }) => `${AGENTS_URL}/artifacts/${sessionId}/${src}` },
84
+ });
85
+
86
+ // 3. present_chart / present_metric / present_metric_group / present_iframe; the host adds the rest.
87
+ const uiTools = createBiUiTools({ client: bi })
88
+ .render('present_dashboard', (a) => <ScriptDashboardViewer dashboardId={a.id} />)
89
+ .build();
90
+
91
+ // 4. Theme: your theme + the BI palette (light and dark defaults ship; set `palette.bi` to override).
92
+ const theme = createBiTheme(createTheme({ palette: { mode: 'light', primary: { main: BRAND } } }));
93
+
94
+ <ThemeProvider theme={theme}>
95
+ <BiThemeBridge> {/* publishes the --bi-* CSS variables the stylesheet reads */}
96
+ <BiClientProvider client={bi} sessionId={sessionId}>
97
+ <AiChatProvider uiTools={uiTools} …/>
98
+ </BiClientProvider>
99
+ </BiThemeBridge>
100
+ </ThemeProvider>
101
+ ```
102
+
103
+ `registerBiModules` calls the chat library's `extendModuleRegistry(specifier, surface)` once per specifier,
104
+ `extendDefaultScope(surface)` once, and seeds the dashboard-bundle loader's `require()` map under the same strings.
105
+ `BI_RUNTIME_VERSION` is the package version — log a mismatch against the server's `AIntelA.Bi.Agents` at handshake.
106
+
107
+ ### `BiClientProvider` / `createBiClient`
108
+
109
+ Every server call in the package goes through one `BiClient`: `useDashboardData`, `useDashboardLazyData` (page,
110
+ distinct values, CSV/XLSX export), `VizAutoComplete` options, `useDashboardBundle` (dashboard document, bundle code,
111
+ sub-agent status) and the inline `Chart` / `IFrame` URLs (`client.artifactUrl(src, { sessionId?, dashboardId? })`).
112
+ Nothing reads `process.env`, `import.meta.env` or a hard-coded host. `fetch` is injectable (tests, custom transports);
113
+ `getAuthHeader` may be async.
114
+
115
+ ### Data hooks
116
+
117
+ ```tsx
118
+ const { toDataResult, loading } = useDashboardData('<query hash>'); // inside a DashboardParametersProvider
119
+ const data = toDataResult({ month: 'date', spend: 'number' });
120
+ <ChartCard data={data} type="barV" xAxis="month" series={[{ dataKey: 'spend' }]} loading={loading} />
121
+
122
+ const lazy = useDashboardLazyData('<view id>', { airline: { type: 'string', values: 'distinct' }, total: 'number' });
123
+ <DataTableCard lazyData={lazy} /> // server-side page / sort / filter / export
124
+ ```
125
+
126
+ ## Theming contract (plan §2.3, decision D8)
127
+
128
+ **No colour literal exists in this package outside `src/theme/biPalette.ts`.** Components read the MUI theme
129
+ (`theme.palette.divider`, `text.secondary`, `action.hover`, `background.paper`, `alpha(text.primary, 0.08)` for
130
+ translucent overlays, `error/warning/success` for gauge bands); the two stylesheets read `--bi-*` custom properties
131
+ that `<BiThemeBridge/>` (or `useBiCssVars()`) derives from the theme; DataGrid Pro is styled through `sx` tokens.
132
+
133
+ The series palette is a theme augmentation:
134
+
135
+ ```ts
136
+ declare module '@mui/material/styles' {
137
+ interface Palette { bi: { series: string[]; positive: string; negative: string; neutral: string } }
138
+ }
139
+ ```
140
+
141
+ `createBiTheme(theme)` / `withBiPalette(theme)` fill `palette.bi` from `biLightPalette` or `biDarkPalette` by
142
+ `palette.mode` when the host did not set it; `useBiPalette()` and `biSeriesColor(theme, i)` read it;
143
+ `ChartCardDefaultsProvider palette={…}` is the per-dashboard override.
144
+
145
+ Enforced three ways: ESLint `no-restricted-syntax` on `#hex` / `rgb(a)` / `hsl(a)` literals in `.ts/.tsx`
146
+ (`src/theme/biPalette.ts` is the only override), stylelint `color-no-hex` + `color-named: never` +
147
+ `function-disallowed-list` on `.css`, and `tests/theme/colourLiterals.test.ts`, which walks `src/` and fails on any
148
+ literal outside the palette file.
149
+
150
+ ## Composer (`@aintela/bi/composer`)
151
+
152
+ The authoring UI extracted from the dashboard app's `components/dashboardPad/**` + `views/composer/**` (plan §1.2, Phase 4
153
+ item 20): the sketch pad the user draws a dashboard on, the composer screen around it, and the DOM "environment" the
154
+ dashboard agent drives through action tools and live TSX.
155
+
156
+ ### Providers and what the host still owns
157
+
158
+ ```tsx
159
+ import { AiChatProvider, AiChatV2Pane, RunProgressPanelV2, RunProgressStripV2, EnvironmentProvider, LiveTsxConfigProvider } from '@aintela/chat/components';
160
+ import { BiClientProvider, createBiClient, createBiUiTools } from '@aintela/bi';
161
+ import { ComposerProvider, ComposerView, ComposerChatBinding, useComposerChatBridge, useComposerEnvironment } from '@aintela/bi/composer';
162
+
163
+ function ComposerScreen({ routeSessionId, navigate }) {
164
+ return (
165
+ <BiClientProvider client={bi}>
166
+ <ComposerProvider> {/* one zustand store per instance — no module singleton */}
167
+ <ComposerHost routeSessionId={routeSessionId} navigate={navigate} />
168
+ </ComposerProvider>
169
+ </BiClientProvider>
170
+ );
171
+ }
172
+
173
+ function ComposerHost({ routeSessionId, navigate }) {
174
+ const bridge = useComposerChatBridge(); // onRenderPrompt / onTurnOpen / onTurnComplete / ingestToolEvent / environment
175
+ const uiTools = useMemo(() => createBiUiTools({ client: bi, environment: bridge.environment })
176
+ .render('present_dashboard', (a) => <ScriptDashboardViewer dashboardId={a.id} />)
177
+ .build(), [bridge.environment]);
178
+
179
+ return (
180
+ <LiveTsxConfigProvider maxCharsForFull={10000}>
181
+ <AiChatProvider
182
+ key={routeSessionId ?? 'new'}
183
+ agentContext={{ agentConfig: { id: DASHBOARD_AGENT_ID, name: 'Dashboard Agent' }, customer }} // the host picks the agent
184
+ serverBaseUrl={SERVER} sessionId={routeSessionId} user={user} storageService={storage} eventBusService={bus}
185
+ uiTools={uiTools} hidePromptInput autoCreateSession
186
+ onRenderPrompt={bridge.onRenderPrompt} onTurnOpen={bridge.onTurnOpen} onTurnComplete={bridge.onTurnComplete}
187
+ >
188
+ <EnvironmentProvider value={bridge.environment}>
189
+ <ComposerChatBinding /> {/* mirrors the live session id + forwards gateway tool events */}
190
+ <ComposerView
191
+ routeSessionId={routeSessionId}
192
+ sessionId={liveSessionId} {/* or let ComposerChatBinding set it in the store */}
193
+ chatPane={<AiChatV2Pane hideHeader />}
194
+ renderProgressPanel={({ hasDashboard, dashboardCollapsed, turnOpen }) => (
195
+ <RunProgressPanelV2 width={hasDashboard ? '22%' : '30%'} defaultCollapsed={(!dashboardCollapsed || !turnOpen) && hasDashboard} />
196
+ )}
197
+ progressStrip={<RunProgressStripV2 />}
198
+ onSelectSession={(sid) => navigate(`/composer/${sid}`)}
199
+ onDashboardNameChange={setBreadcrumb}
200
+ datasetControls={isAdmin && <DatasetParameterizationControls orientation="column" datasets={datasets} agents={agents} agentId={agentId} onAgentChange={pickAgent} />}
201
+ />
202
+ </EnvironmentProvider>
203
+ </AiChatProvider>
204
+ </LiveTsxConfigProvider>
205
+ );
206
+ }
207
+ ```
208
+
209
+ What the **host** owns, deliberately: `AiChatProvider` / `AiChatV2Pane` / the progress panel (the chat is not inside the
210
+ package); the **agent ids** (`agentContext`) — the legacy `DEFAULT_DASHBOARD_AGENT_ID` and the customer/Envision agent pair
211
+ are gone, `DatasetParameterizationControls` takes `agents` + `agentId` + `onAgentChange`; routing (`routeSessionId` in,
212
+ `onSelectSession` / `onSearchAllSessions` out); the breadcrumb (`onDashboardNameChange`); `isAdmin` (render
213
+ `datasetControls` or not); `LiveTsxConfigProvider`; the `pt-BR` `dayjs` locale (the composer never calls `dayjs.locale`);
214
+ the "Abrir" picker body on `DashboardPad` (`renderDashboardPicker`); Markdown for card descriptions (`renderDescription`
215
+ — default is plain text).
216
+
217
+ ### Components
218
+
219
+ | export | what it is | key props |
220
+ |---|---|---|
221
+ | `ComposerView` | splash → execution layout, drafts, guided tour | `chatPane` (required), `sessionId`, `routeSessionId`, `renderProgressPanel`, `progressStrip`, `onBeforeSend`, `resolveGuideElement`, `suggestions`, `templates`, `recentSessions`, `onSelectSession`, `onSearchAllSessions`, `onDashboardNameChange`, `datasetControls`, `renderDescription`, `sidePanelWidth` |
222
+ | `DashboardPad` | the V1 pad: toolbar (Sketch/Dashboard, ToolBox, Novo/Salvar/Atualizar/Abrir/Compose) + sketch or viewer | `sessionId`, `dashboardId`, `turnOpen`, `onCompose`, `onChange`, `onBack`, `renderDashboardPicker`, `showDebug`, `headerExtra`, `renderDescription` |
223
+ | `DashboardPadSketch` | the grid of `CardSketch` cells + filter chips (ref: `DashboardPadHandle` = `addGenericCell` / `addTypedCell` / `handleAddFilter`) | `hideInternalHeader`, `hideFiltersInSketch`, `zoomLevel`, `onAddCard`, `headerExtra`, `renderDescription` |
224
+ | `CardSketch` (alias `CardScketch`), `FilterSketch`, `TitleSketch` (aliases `TextSketh`, `TitleSkath`), `ToolBox`, `HoverButton`, `ClonedComponent` | the pad's pieces | |
225
+ | `DashboardPadEditor` | tabbed shell (`DashboardPadEditorHandle`) | `renderContent`, `addMenuItems`, `tabs`, `onTab*` |
226
+ | `DatasetParameterizationControls` | admin block: "DataSet Dinâmico" toggle + default dataset + agent picker | `orientation`, `datasets`, `defaultTemplateDataset`, `agents`, `agentId`, `recommendedAgentId`, `onAgentChange` |
227
+ | `DrawablePrompt` | `PromptV2` with the sketch in its `topSlot` (rail + pad, the sketch chips, the queued-changes chip) | `onCreateSketch`, `onBeforeSend`, `sketchExpanded`, `onSketchExpandedChange`, `seedDraft`, `compact`, `zoomLevel`, `datasetControls` |
228
+ | `EntryEmptyState`, `SpotlightOverlay`, `DashboardSidePanel`, `DashboardPin` | the splash, the tour, the two dashboard surfaces | `suggestions`/`templates`/`onSearchAllSessions`; `steps`/`resolveElement`; `width`/`defaultCollapsed` |
229
+ | `CardTypeIconsProvider` / `useCardTypeIcons` | swap the pad's icons (`category` / `specificType` / `filterType` maps; MUI defaults) | |
230
+
231
+ Data that used to be hardcoded is now a default you can replace: `defaultComposerSuggestions` (`{ label, prompt }[]`),
232
+ `defaultComposerTemplates` (+ `seedFromTemplate`, `TEMPLATE_KIND_TO_SKETCH`), `CARD_TYPE_CATALOG`, `FILTER_TYPE_CATALOG` —
233
+ all Portuguese travel-BI text.
234
+
235
+ ### Store — `ComposerProvider`, `useComposer()`
236
+
237
+ `ComposerProvider` creates one zustand store (`createComposerStore`) per mount; `useComposer(selector)` subscribes,
238
+ `useComposerStore()` gives the API for `getState()` in handlers, `useComposerEnvironment()` returns the
239
+ `DashboardEnvironment`. The store keeps the legacy semantics: `dashboardDefinition` (live), `publishedDashboard` (what the
240
+ viewer renders — advances `VIEWER_COMMIT_DEBOUNCE_MS` = 3 s after the last edit, never mid-turn, immediately on
241
+ `commitForSend()` / load / `dashboardGenerated` / `refreshDashboard`), `lastSentDashboard` (the queued-changes chip's
242
+ baseline), `renderGeneration` (bundle CODE changed → `codeGeneration`), `llmCounter` (→ `llmRenderCount`), `agentPulseTick`,
243
+ `todosByCardKey`, `recordSketchChange` / `clearClientSideChanges` (the per-turn hint the prompt carries), the guide state,
244
+ and the autosave (`DRAFT_SAVE_DEBOUNCE_MS` = 800 ms, POST `/Dashboard` through the `BiClient`; `client={null}` disables it).
245
+
246
+ ### The environment object
247
+
248
+ `DashboardEnvironment` = `highlightComponent(target, { durationMs, scrollIntoView })`, `cloneComponent(target, { includeHidden })`,
249
+ `createDashboardPad(def)`, `updateDashboardPad(def)`, `refreshDashboard()`, `showGuide(steps, options)`, `dismissGuide()`.
250
+ Targets resolve against `[data-env-id]`, `[data-env-key]`, `[data-env-name]`, `#id`, `.class` or a raw selector
251
+ (`resolveEnvironmentElements`, `resolveGuideElement`). Pass it to `EnvironmentProvider` (live TSX calls `useEnvironment()`),
252
+ and to `createBiUiTools({ environment })`, which then also registers the agent's three ACTION tools: `refresh_dashboard`,
253
+ `present_dashboard_pad` (`{ definitionJson, mode: 'create' | 'update' }`) and `present_guide` (`{ stepsJson }`).
254
+ `getBiModuleSurface()` exposes the whole subpath, so LLM code reaches `ExamplePad`, `ExampleCardSketh` (legacy spelling kept
255
+ as an alias of `ExampleCardSketch`), `PrototypePad`, `useDashboardPad`, `c`, `dateRange`, `datePicker`, `autoComplete`,
256
+ `EnvironmentProvider`, `useEnvironment` under every registered specifier.
257
+
258
+ ### Theming
259
+
260
+ Same contract as the rest of the package. `composer.css` reads `--bi-*` only; the bridge gained `--bi-secondary`,
261
+ `--bi-secondary-soft`, `--bi-sketch-dash`, `--bi-sketch-dash-faint`, `--bi-sketch-selection` (`alpha(primary, .12)`),
262
+ `--bi-scrim`, `--bi-highlight-outline`, `--bi-highlight-glow`. The v2 chat theme's extra tokens (`palette.surface.raised`,
263
+ `palette.surface.hover`, `palette.border.soft`, `typography.fontFamilyMono`) are read when present and fall back to
264
+ `background.paper` / `action.hover` / `divider` / a monospace stack (`resolveComposerSurfaces`). Framer-motion timings are
265
+ unchanged; every animated colour is a theme token.
266
+
267
+ ## What changed from the dashboard app
268
+
269
+ - **Providers now required**: `BiClientProvider` (or a `client` prop) for every hook / viewer / inline component;
270
+ `DashboardParametersProvider` around cards (as before); `BiThemeBridge` for the stylesheets to have colours.
271
+ - **Removed exports**: `CHART_COLORS`, `chartColor`, `chartShade` (from `data`; `chartShade` lives in `cards`,
272
+ built on MUI `alpha()`), `GEO_URL` / `DEFAULT_GEO_LAYERS` (now `GEO_URL_WORLD` / `worldGeoLayers` /
273
+ `brazilGeoLayers` + `GeoLayersProvider`), the `VizLibrary` compat pieces, `ContainTable`, `DataAnalysis`.
274
+ - **Signature changes**: `loadDashboardBundle(client, sessionId, id)` / `instantiateDashboardBundle(client, …)`
275
+ take the client first; `Chart` lost `partial`, `runaround`, `showHeader`, `eventBusService`, `parentComponent`
276
+ and gained `onExpand`; `IFrame` gained `onExpand` / `height`; `VizTriggerButton` requires `onTrigger`;
277
+ `VizDatePicker` / `VizSelect` / `VizTextField` read `DashboardParametersContext` (the Python `DashboardContext` is gone).
278
+ - **Viewer**: `ScriptDashboardViewer` takes `onExportPdf`, `onSchedule`, `onEdit`, `onLayoutCommit`, `datasetOverride`,
279
+ `isAdmin`, `datasetOverrideControl`, `resolveCardIcon`, `isPrintPreview` instead of reading the composer / app
280
+ stores, `react-router`, `react-js-cron`, `useCustomers` and the PDF endpoint. `headerRender` is unchanged.
281
+ `dashboardWaiting` gained `sessionId`.
282
+ - Map cards default to the world base layer only; pass `geoUrl={brazilGeoLayers}` (or a `GeoLayersProvider`) for the
283
+ legacy world + Brazil-states pair.
284
+ - `loading` is optional on every card (default `false`).
285
+ - `Metric.description` renders as plain text (the app rendered Markdown).
286
+ - Portuguese UI strings are kept as they were.
287
+ - **Composer**: `useComposerViewStore` (module singleton, `devtools`) → a per-`ComposerProvider` store; `DashboardService`
288
+ → `BiClient` (`listDashboards`, `getDashboardBySession`, `upsertDashboard`, `updateDashboard`, `deleteDashboard`,
289
+ `dashboardAction`, `listFolders` / `getFolder` / `createFolder` / `updateFolder` / `deleteFolder` / `folderAction`,
290
+ `getDashboardHierarchy`; the draft envelope lives in `toDraftPayload` / `fromUpsertResponse`); `ComposerViewV2` →
291
+ `ComposerView` + `useComposerChatBridge` (no `AiChatProvider`, no router, no `useDashboardAppStore`); `ExampleFilterSketch`
292
+ and `TestCard` were not carried over (unused); `CardSketch` renders the description as plain text unless
293
+ `renderDescription` is given (was `react-markdown`); `DashboardPad`'s debug panel is a `<pre>` (was `MarkdownExtended`);
294
+ the "Buscar todas as sessões" link fires `onSearchAllSessions` instead of clicking `[data-v2-search-trigger]`;
295
+ `SketchCardItem.muiIconName` now stores the icon's export name (was the constant `'SvgIcon'`).
296
+
297
+ ## Scripts
298
+
299
+ `npm run build` (vite lib + `.d.ts`) · `npm test` · `npm run lint` (eslint + stylelint) · `npm run typecheck`.
@@ -0,0 +1,219 @@
1
+ var m = Object.defineProperty;
2
+ var o = (d, l) => m(d, "name", { value: l, configurable: !0 });
3
+ import { jsx as E } from "react/jsx-runtime";
4
+ import { useMemo as g, useContext as w, createContext as x } from "react";
5
+ function C(d) {
6
+ return d.endsWith("/") ? d.slice(0, -1) : d;
7
+ }
8
+ o(C, "trimSlash");
9
+ function u(d) {
10
+ return encodeURIComponent(d);
11
+ }
12
+ o(u, "enc");
13
+ function S(d, l) {
14
+ const i = C(d), n = /* @__PURE__ */ o(() => l ? `?t=${Date.now()}` : "", "bust");
15
+ return {
16
+ query: /* @__PURE__ */ o((r, a, { noCache: h }) => `${i}/Query/${u(r)}/${u(a)}${h ? "?noCache=true" : ""}`, "query"),
17
+ queryPage: /* @__PURE__ */ o((r, a) => `${i}/Query/${u(r)}/${u(a)}/page`, "queryPage"),
18
+ queryDistinct: /* @__PURE__ */ o((r, a, h) => `${i}/Query/${u(r)}/${u(a)}/distinct/${u(h)}`, "queryDistinct"),
19
+ queryExport: /* @__PURE__ */ o((r, a, h) => `${i}/Query/${u(r)}/${u(a)}/${h === "xlsx" ? "export-xlsx" : "export"}`, "queryExport"),
20
+ filterOptions: /* @__PURE__ */ o((r, a) => `${i}/Query/${u(r)}/${u(a)}`, "filterOptions"),
21
+ dashboard: /* @__PURE__ */ o((r) => `${i}/Dashboard/${u(r)}/draft`, "dashboard"),
22
+ subAgentStatus: /* @__PURE__ */ o((r, a) => `${i}/SubAgent/${u(r)}/${u(a)}`, "subAgentStatus"),
23
+ dashboardBundle: /* @__PURE__ */ o((r, a) => `${i}/open/dashboard/${u(r)}/${u(a)}/true`, "dashboardBundle"),
24
+ artifact: /* @__PURE__ */ o((r, a) => {
25
+ const h = a.dashboardId ? `dashboard/${u(a.dashboardId)}` : a.sessionId ? u(a.sessionId) : void 0;
26
+ return `${i}/open/getImage/${h ? `${h}/` : ""}${r}${n()}`;
27
+ }, "artifact"),
28
+ htmlArtifact: /* @__PURE__ */ o((r, a) => `${i}/open/dashboard/${a.sessionId ? `${u(a.sessionId)}/` : ""}${r}/true`, "htmlArtifact"),
29
+ dashboardList: /* @__PURE__ */ o(() => `${i}/Dashboard/List`, "dashboardList"),
30
+ dashboardBySession: /* @__PURE__ */ o((r) => `${i}/Dashboard/session/${u(r)}/draft`, "dashboardBySession"),
31
+ dashboardUpsert: /* @__PURE__ */ o(() => `${i}/Dashboard`, "dashboardUpsert"),
32
+ dashboardUpdate: /* @__PURE__ */ o((r) => `${i}/Dashboard/${u(r)}`, "dashboardUpdate"),
33
+ dashboardDelete: /* @__PURE__ */ o((r) => `${i}/Dashboard/${u(r)}`, "dashboardDelete"),
34
+ dashboardAction: /* @__PURE__ */ o((r, a) => `${i}/Dashboard/${u(r)}/${a}`, "dashboardAction"),
35
+ folders: /* @__PURE__ */ o(() => `${i}/DashboardFolder`, "folders"),
36
+ folder: /* @__PURE__ */ o((r) => `${i}/DashboardFolder/${u(r)}`, "folder"),
37
+ folderAction: /* @__PURE__ */ o((r, a) => `${i}/DashboardFolder/${u(r)}/${a}`, "folderAction"),
38
+ folderHierarchy: /* @__PURE__ */ o(() => `${i}/DashboardFolder/hierarchy`, "folderHierarchy")
39
+ };
40
+ }
41
+ o(S, "defaultBiRoutes");
42
+ function f(d, l) {
43
+ if (typeof l == "string" && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})?$/.test(l)) {
44
+ const i = new Date(l);
45
+ if (!Number.isNaN(i.getTime())) return i;
46
+ }
47
+ return l;
48
+ }
49
+ o(f, "biDateReviver");
50
+ function T(d) {
51
+ const l = C(d.baseUrl), i = d.fetch ?? ((t, e) => globalThis.fetch(t, e)), n = { ...S(l, d.cacheBustArtifacts ?? !1), ...d.routes ?? {} };
52
+ async function r(t, e = {}) {
53
+ const s = /^https?:\/\//i.test(t) ? t : `${l}${t.startsWith("/") ? "" : "/"}${t}`, c = new Headers(e.headers ?? {});
54
+ for (const [p, B] of Object.entries(d.headers ?? {})) c.has(p) || c.set(p, B);
55
+ const b = d.getAuthHeader ? await d.getAuthHeader() : void 0;
56
+ return b && !c.has("Authorization") && c.set("Authorization", b), i(s, { ...e, headers: c });
57
+ }
58
+ o(r, "request");
59
+ async function a(t, e) {
60
+ const s = await r(t, e);
61
+ if (!s.ok) {
62
+ const c = await s.text().catch(() => "");
63
+ throw new Error(`[BiClient] ${(e == null ? void 0 : e.method) ?? "GET"} ${t} failed (${s.status})${c ? `: ${c.slice(0, 300)}` : ""}`);
64
+ }
65
+ return s;
66
+ }
67
+ o(a, "requestOk");
68
+ const h = /* @__PURE__ */ o((t, e) => ({
69
+ method: "POST",
70
+ headers: { "Content-Type": "application/json" },
71
+ body: JSON.stringify(t),
72
+ ...e
73
+ }), "json"), $ = { "Cache-Control": "no-cache", Pragma: "no-cache", Expires: "0" };
74
+ return {
75
+ baseUrl: l,
76
+ routes: n,
77
+ request: r,
78
+ requestOk: a,
79
+ async runQuery(t, e, s, c) {
80
+ return (await a(n.query(t, e, { noCache: c == null ? void 0 : c.noCache }), h(s, { signal: c == null ? void 0 : c.signal }))).json();
81
+ },
82
+ async getQueryPage(t, e, s) {
83
+ return (await a(n.queryPage(t, e), h(s))).json();
84
+ },
85
+ async getDistinctValues(t, e, s, c) {
86
+ const b = await r(n.queryDistinct(t, e, s), h(c));
87
+ return b.ok ? b.json() : null;
88
+ },
89
+ async exportQuery(t, e, s, c) {
90
+ return (await a(n.queryExport(t, e, s), h(c))).blob();
91
+ },
92
+ async getFilterOptions(t, e) {
93
+ const s = await r(n.filterOptions(t, e), { method: "GET" });
94
+ if (s.status === 404) return null;
95
+ if (!s.ok) throw new Error(`[BiClient] filter options failed (${s.status})`);
96
+ return s.json();
97
+ },
98
+ async getDashboard(t) {
99
+ const e = await r(n.dashboard(t), { method: "GET", headers: $ });
100
+ if (e.status === 404) throw new Error(`Dashboard with ID '${t}' not found`);
101
+ if (!e.ok) throw new Error(`[BiClient] dashboard fetch failed (${e.status})`);
102
+ return JSON.parse(await e.text(), f);
103
+ },
104
+ async getSubAgentStatus(t, e) {
105
+ const s = await r(n.subAgentStatus(t, e), { method: "GET", headers: $ });
106
+ if (s.status === 404) return null;
107
+ if (!s.ok) throw new Error(`Failed to fetch sub-agent status (HTTP ${s.status})`);
108
+ return JSON.parse(await s.text(), f);
109
+ },
110
+ async fetchDashboardBundle(t, e) {
111
+ const s = await r(n.dashboardBundle(t, e), { method: "GET", cache: "no-store" });
112
+ if (!s.ok) throw new Error(`Failed to fetch dashboard bundle (${s.status}): ${n.dashboardBundle(t, e)}`);
113
+ return s.text();
114
+ },
115
+ artifactUrl(t, e = {}) {
116
+ return n.artifact(t, e);
117
+ },
118
+ iframeUrl(t, e = {}) {
119
+ return n.htmlArtifact(t, e);
120
+ },
121
+ async listDashboards() {
122
+ const t = await a(n.dashboardList(), { method: "GET", headers: $ });
123
+ return JSON.parse(await t.text(), f);
124
+ },
125
+ async getDashboardBySession(t) {
126
+ const e = await r(n.dashboardBySession(t), { method: "GET", headers: $ });
127
+ if (e.status === 404) return null;
128
+ if (!e.ok) throw new Error(`[BiClient] dashboard-by-session fetch failed (${e.status})`);
129
+ return JSON.parse(await e.text(), f);
130
+ },
131
+ async upsertDashboard(t) {
132
+ const e = await a(n.dashboardUpsert(), h(t, { headers: { "Content-Type": "application/json", ...$ } }));
133
+ return JSON.parse(await e.text(), f);
134
+ },
135
+ async updateDashboard(t, e) {
136
+ await a(n.dashboardUpdate(t), h(e));
137
+ },
138
+ async deleteDashboard(t) {
139
+ const e = await r(n.dashboardDelete(t), { method: "DELETE" });
140
+ if (e.status === 404) return !1;
141
+ if (!e.ok) throw new Error(`[BiClient] dashboard delete failed (${e.status})`);
142
+ return !0;
143
+ },
144
+ async dashboardAction(t, e) {
145
+ const s = await r(n.dashboardAction(t, e), { method: "POST" });
146
+ if (!s.ok) {
147
+ const c = await s.text().catch(() => "");
148
+ throw new Error(c || `[BiClient] dashboard ${e} failed (${s.status})`);
149
+ }
150
+ },
151
+ async listFolders() {
152
+ const t = await a(n.folders(), { method: "GET", headers: $ });
153
+ return JSON.parse(await t.text(), f);
154
+ },
155
+ async getFolder(t) {
156
+ const e = await r(n.folder(t), { method: "GET", headers: $ });
157
+ if (e.status === 404) throw new Error(`Folder '${t}' not found`);
158
+ if (!e.ok) throw new Error(`[BiClient] folder fetch failed (${e.status})`);
159
+ return JSON.parse(await e.text(), f);
160
+ },
161
+ async createFolder(t, e) {
162
+ const s = await a(n.folders(), h({ name: t, description: e }));
163
+ return JSON.parse(await s.text(), f);
164
+ },
165
+ async updateFolder(t, e) {
166
+ const s = await a(n.folder(t), h(e, { method: "PATCH" }));
167
+ return JSON.parse(await s.text(), f);
168
+ },
169
+ async deleteFolder(t) {
170
+ const e = await r(n.folder(t), { method: "DELETE" });
171
+ if (e.status === 404) return !1;
172
+ if (!e.ok) throw new Error(`[BiClient] folder delete failed (${e.status})`);
173
+ return !0;
174
+ },
175
+ async folderAction(t, e) {
176
+ await a(n.folderAction(t, e), { method: "POST" });
177
+ },
178
+ async getDashboardHierarchy() {
179
+ const t = await a(n.folderHierarchy(), { method: "GET", headers: $ });
180
+ return JSON.parse(await t.text(), f);
181
+ }
182
+ };
183
+ }
184
+ o(T, "createBiClient");
185
+ const y = x(null), D = x(void 0), N = /* @__PURE__ */ o(({ client: d, options: l, sessionId: i, children: n }) => {
186
+ const r = g(() => {
187
+ if (d) return d;
188
+ if (l) return T(l);
189
+ throw new Error("[@aintela/bi] BiClientProvider needs either `client` or `options`.");
190
+ }, [d, l]);
191
+ return /* @__PURE__ */ E(y.Provider, { value: r, children: /* @__PURE__ */ E(D.Provider, { value: i, children: n }) });
192
+ }, "BiClientProvider");
193
+ function P() {
194
+ const d = w(y);
195
+ if (!d)
196
+ throw new Error(
197
+ "[@aintela/bi] No BiClient in scope. Wrap the BI surface in <BiClientProvider client={createBiClient({ baseUrl })}>."
198
+ );
199
+ return d;
200
+ }
201
+ o(P, "useBiClient");
202
+ function F() {
203
+ return w(y);
204
+ }
205
+ o(F, "useBiClientOptional");
206
+ function J() {
207
+ return w(D);
208
+ }
209
+ o(J, "useBiSessionId");
210
+ export {
211
+ N as B,
212
+ F as a,
213
+ f as b,
214
+ T as c,
215
+ S as d,
216
+ J as e,
217
+ P as u
218
+ };
219
+ //# sourceMappingURL=BiClientProvider-CWJochvi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BiClientProvider-CWJochvi.js","sources":["../src/client/BiClient.ts","../src/client/BiClientProvider.tsx"],"sourcesContent":["/**\n * The one seam between this package and a server. Every hook, viewer and\n * inline component reaches the network through a `BiClient`; nothing in the\n * package reads `process.env`, `import.meta.env` or a hard-coded host.\n *\n * `createBiClient({ baseUrl })` gives you the default REST layout the legacy\n * .NET WSServer exposes (`/Query/...`, `/Dashboard/...`, `/SubAgent/...`,\n * `/open/...`). Every route is a function on `routes`, so a host whose server\n * lays the endpoints out differently (the AIA `aia-bi` API, an AgentsServer\n * artifact route) overrides just the routes it changes.\n */\n\nexport type BiFetch = (input: string, init?: RequestInit) => Promise<Response>;\n\nexport interface ArtifactUrlScope {\n /** Chat session that produced the artifact (the default scope). */\n sessionId?: string;\n /** When set, takes priority over `sessionId` — the artifact belongs to a saved dashboard. */\n dashboardId?: string;\n}\n\nexport interface QueryExecutionBody {\n parameters?: Record<string, unknown>;\n /** Admin-only runtime dataset override (parameterised dashboards). */\n datasetOverride?: string;\n}\n\nexport interface PagedQueryBody extends QueryExecutionBody {\n page: number;\n pageSize: number;\n sort: Array<{ field: string; dir: 'asc' | 'desc' }>;\n filter: Array<{ field: string; op: string; value: unknown }>;\n}\n\nexport interface ExportQueryBody extends QueryExecutionBody {\n sort: Array<{ field: string; dir: 'asc' | 'desc' }>;\n filter: Array<{ field: string; op: string; value: unknown }>;\n}\n\nexport interface BiRoutes {\n /** POST — run a registered query (by hash) for a dashboard. */\n query(dashboardId: string, queryHash: string, opts: { noCache?: boolean }): string;\n /** POST — one page of a server-side view. */\n queryPage(dashboardId: string, viewId: string): string;\n /** POST — distinct values of one column of a view (filter dropdowns). */\n queryDistinct(dashboardId: string, viewId: string, field: string): string;\n /** POST — full-rowset export of a view. */\n queryExport(dashboardId: string, viewId: string, format: 'csv' | 'xlsx'): string;\n /** GET — the option rows behind an auto-complete filter. */\n filterOptions(dashboardId: string, filterId: string): string;\n /** GET — a dashboard document (draft). */\n dashboard(dashboardId: string): string;\n /** GET — sub-agent status while a dashboard is being generated. */\n subAgentStatus(sessionId: string, subAgentId: string): string;\n /** GET — the compiled CJS dashboard bundle. */\n dashboardBundle(sessionId: string, scriptFileName: string): string;\n /** URL of an image artifact (matplotlib PNG) for `<img src>`. */\n artifact(src: string, scope: ArtifactUrlScope): string;\n /** URL of an HTML artifact for `<iframe src>`. */\n htmlArtifact(src: string, scope: ArtifactUrlScope): string;\n\n // ── Dashboard documents + folders (the composer's authoring calls) ──\n /** GET — every dashboard the caller can see (lean list). */\n dashboardList(): string;\n /** GET — the draft whose `originalSessionId` is `sessionId` (404 when none). */\n dashboardBySession(sessionId: string): string;\n /** POST — create or update a dashboard document (`{ ...metadata, draft: {...} }`). */\n dashboardUpsert(): string;\n /** POST — overwrite one dashboard (move to folder, rename, …). */\n dashboardUpdate(dashboardId: string): string;\n /** DELETE — remove a dashboard. */\n dashboardDelete(dashboardId: string): string;\n /** POST — one of the verb routes: share / unshare / pin / unpin / publishAsDefault / unpublishAsDefault. */\n dashboardAction(dashboardId: string, action: DashboardActionName): string;\n /** GET (list) / POST (create) — dashboard folders. */\n folders(): string;\n /** GET / PATCH / DELETE — one folder. */\n folder(folderId: string): string;\n /** POST — share / unshare a folder (cascades to its dashboards). */\n folderAction(folderId: string, action: FolderActionName): string;\n /** GET — folders with their dashboards plus the root-level dashboards. */\n folderHierarchy(): string;\n}\n\nexport type DashboardActionName = 'share' | 'unshare' | 'pin' | 'unpin' | 'publishAsDefault' | 'unpublishAsDefault';\nexport type FolderActionName = 'share' | 'unshare';\n\nexport interface BiClientOptions {\n /** Server origin, e.g. `https://bi.example.com`. No trailing slash needed. */\n baseUrl: string;\n /** `fetch` implementation (defaults to `globalThis.fetch`); inject for tests or a custom transport. */\n fetch?: BiFetch;\n /** Returns the `Authorization` header value (`Bearer …`) or `undefined` for none. May be async. */\n getAuthHeader?: () => string | undefined | Promise<string | undefined>;\n /** Extra headers on every request. */\n headers?: Record<string, string>;\n /** Route overrides — any subset of {@link BiRoutes}. */\n routes?: Partial<BiRoutes>;\n /**\n * Legacy image URLs carried a `?t=<now>` cache-buster because the proxy\n * served mutable files. Off by default; a host fronting a mutable store\n * can turn it back on.\n */\n cacheBustArtifacts?: boolean;\n}\n\nexport interface BiClient {\n readonly baseUrl: string;\n readonly routes: BiRoutes;\n /** Low-level request: prefixes `baseUrl` on relative paths and adds auth + default headers. */\n request(path: string, init?: RequestInit): Promise<Response>;\n /** Same as `request`, but throws a descriptive `Error` on a non-2xx status. */\n requestOk(path: string, init?: RequestInit): Promise<Response>;\n\n runQuery<T = unknown>(dashboardId: string, queryHash: string, body: QueryExecutionBody, opts?: { noCache?: boolean; signal?: AbortSignal }): Promise<T>;\n getQueryPage<T = unknown>(dashboardId: string, viewId: string, body: PagedQueryBody): Promise<T>;\n getDistinctValues(dashboardId: string, viewId: string, field: string, body: QueryExecutionBody): Promise<{ values: Array<string | null>; truncated?: boolean } | null>;\n exportQuery(dashboardId: string, viewId: string, format: 'csv' | 'xlsx', body: ExportQueryBody): Promise<Blob>;\n getFilterOptions<T = unknown>(dashboardId: string, filterId: string): Promise<T | null>;\n getDashboard<T = unknown>(dashboardId: string): Promise<T>;\n getSubAgentStatus<T = unknown>(sessionId: string, subAgentId: string): Promise<T | null>;\n fetchDashboardBundle(sessionId: string, scriptFileName: string): Promise<string>;\n\n artifactUrl(src: string, scope?: ArtifactUrlScope): string;\n iframeUrl(src: string, scope?: ArtifactUrlScope): string;\n\n // ── Dashboard documents + folders (used by `@aintela/bi/composer`) ──\n listDashboards<T = unknown>(): Promise<T[]>;\n /** `null` when no dashboard is bound to the session. */\n getDashboardBySession<T = unknown>(sessionId: string): Promise<T | null>;\n /** POST the upsert payload; resolves to the server's document (raw, un-flattened). */\n upsertDashboard<T = unknown>(payload: unknown): Promise<T>;\n updateDashboard(dashboardId: string, dashboard: unknown): Promise<void>;\n /** `false` when the server answered 404. */\n deleteDashboard(dashboardId: string): Promise<boolean>;\n dashboardAction(dashboardId: string, action: DashboardActionName): Promise<void>;\n listFolders<T = unknown>(): Promise<T[]>;\n getFolder<T = unknown>(folderId: string): Promise<T>;\n createFolder<T = unknown>(name: string, description?: string): Promise<T>;\n updateFolder<T = unknown>(folderId: string, patch: unknown): Promise<T>;\n deleteFolder(folderId: string): Promise<boolean>;\n folderAction(folderId: string, action: FolderActionName): Promise<void>;\n getDashboardHierarchy<T = unknown>(): Promise<T>;\n}\n\nfunction trimSlash(s: string): string {\n return s.endsWith('/') ? s.slice(0, -1) : s;\n}\n\nfunction enc(s: string): string {\n return encodeURIComponent(s);\n}\n\n/** The legacy WSServer / Express layout. Override per route through `BiClientOptions.routes`. */\nexport function defaultBiRoutes(baseUrl: string, cacheBust: boolean): BiRoutes {\n const base = trimSlash(baseUrl);\n const bust = () => (cacheBust ? `?t=${Date.now()}` : '');\n return {\n query: (d, h, { noCache }) => `${base}/Query/${enc(d)}/${enc(h)}${noCache ? '?noCache=true' : ''}`,\n queryPage: (d, v) => `${base}/Query/${enc(d)}/${enc(v)}/page`,\n queryDistinct: (d, v, f) => `${base}/Query/${enc(d)}/${enc(v)}/distinct/${enc(f)}`,\n queryExport: (d, v, fmt) => `${base}/Query/${enc(d)}/${enc(v)}/${fmt === 'xlsx' ? 'export-xlsx' : 'export'}`,\n filterOptions: (d, f) => `${base}/Query/${enc(d)}/${enc(f)}`,\n dashboard: (d) => `${base}/Dashboard/${enc(d)}/draft`,\n subAgentStatus: (s, a) => `${base}/SubAgent/${enc(s)}/${enc(a)}`,\n dashboardBundle: (s, f) => `${base}/open/dashboard/${enc(s)}/${enc(f)}/true`,\n artifact: (src, scope) => {\n const prefix = scope.dashboardId ? `dashboard/${enc(scope.dashboardId)}` : scope.sessionId ? enc(scope.sessionId) : undefined;\n return `${base}/open/getImage/${prefix ? `${prefix}/` : ''}${src}${bust()}`;\n },\n htmlArtifact: (src, scope) => `${base}/open/dashboard/${scope.sessionId ? `${enc(scope.sessionId)}/` : ''}${src}/true`,\n dashboardList: () => `${base}/Dashboard/List`,\n dashboardBySession: (s) => `${base}/Dashboard/session/${enc(s)}/draft`,\n dashboardUpsert: () => `${base}/Dashboard`,\n dashboardUpdate: (d) => `${base}/Dashboard/${enc(d)}`,\n dashboardDelete: (d) => `${base}/Dashboard/${enc(d)}`,\n dashboardAction: (d, a) => `${base}/Dashboard/${enc(d)}/${a}`,\n folders: () => `${base}/DashboardFolder`,\n folder: (f) => `${base}/DashboardFolder/${enc(f)}`,\n folderAction: (f, a) => `${base}/DashboardFolder/${enc(f)}/${a}`,\n folderHierarchy: () => `${base}/DashboardFolder/hierarchy`,\n };\n}\n\n/**\n * ISO-8601 date strings → `Date` on JSON parse (the .NET server serialises\n * `DateTime` as ISO). Same shape as the chat library's `dateReviver`, kept\n * local so this subpath has no runtime dependency on it.\n */\nexport function biDateReviver(_key: string, value: unknown): unknown {\n if (typeof value === 'string' && /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[+-]\\d{2}:\\d{2})?$/.test(value)) {\n const d = new Date(value);\n if (!Number.isNaN(d.getTime())) return d;\n }\n return value;\n}\n\nexport function createBiClient(options: BiClientOptions): BiClient {\n const baseUrl = trimSlash(options.baseUrl);\n const doFetch: BiFetch = options.fetch ?? ((input, init) => globalThis.fetch(input, init));\n const routes: BiRoutes = { ...defaultBiRoutes(baseUrl, options.cacheBustArtifacts ?? false), ...(options.routes ?? {}) };\n\n async function request(path: string, init: RequestInit = {}): Promise<Response> {\n const url = /^https?:\\/\\//i.test(path) ? path : `${baseUrl}${path.startsWith('/') ? '' : '/'}${path}`;\n const headers = new Headers(init.headers ?? {});\n for (const [k, v] of Object.entries(options.headers ?? {})) if (!headers.has(k)) headers.set(k, v);\n const auth = options.getAuthHeader ? await options.getAuthHeader() : undefined;\n if (auth && !headers.has('Authorization')) headers.set('Authorization', auth);\n return doFetch(url, { ...init, headers });\n }\n\n async function requestOk(path: string, init?: RequestInit): Promise<Response> {\n const resp = await request(path, init);\n if (!resp.ok) {\n const text = await resp.text().catch(() => '');\n throw new Error(`[BiClient] ${init?.method ?? 'GET'} ${path} failed (${resp.status})${text ? `: ${text.slice(0, 300)}` : ''}`);\n }\n return resp;\n }\n\n const json = (body: unknown, extra?: RequestInit): RequestInit => ({\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n ...extra,\n });\n\n const noCacheHeaders = { 'Cache-Control': 'no-cache', Pragma: 'no-cache', Expires: '0' };\n\n return {\n baseUrl,\n routes,\n request,\n requestOk,\n\n async runQuery(dashboardId, queryHash, body, opts) {\n const resp = await requestOk(routes.query(dashboardId, queryHash, { noCache: opts?.noCache }), json(body, { signal: opts?.signal }));\n return resp.json();\n },\n async getQueryPage(dashboardId, viewId, body) {\n const resp = await requestOk(routes.queryPage(dashboardId, viewId), json(body));\n return resp.json();\n },\n async getDistinctValues(dashboardId, viewId, field, body) {\n const resp = await request(routes.queryDistinct(dashboardId, viewId, field), json(body));\n if (!resp.ok) return null;\n return resp.json();\n },\n async exportQuery(dashboardId, viewId, format, body) {\n const resp = await requestOk(routes.queryExport(dashboardId, viewId, format), json(body));\n return resp.blob();\n },\n async getFilterOptions(dashboardId, filterId) {\n const resp = await request(routes.filterOptions(dashboardId, filterId), { method: 'GET' });\n if (resp.status === 404) return null;\n if (!resp.ok) throw new Error(`[BiClient] filter options failed (${resp.status})`);\n return resp.json();\n },\n async getDashboard(dashboardId) {\n const resp = await request(routes.dashboard(dashboardId), { method: 'GET', headers: noCacheHeaders });\n if (resp.status === 404) throw new Error(`Dashboard with ID '${dashboardId}' not found`);\n if (!resp.ok) throw new Error(`[BiClient] dashboard fetch failed (${resp.status})`);\n return JSON.parse(await resp.text(), biDateReviver);\n },\n async getSubAgentStatus(sessionId, subAgentId) {\n const resp = await request(routes.subAgentStatus(sessionId, subAgentId), { method: 'GET', headers: noCacheHeaders });\n if (resp.status === 404) return null;\n if (!resp.ok) throw new Error(`Failed to fetch sub-agent status (HTTP ${resp.status})`);\n return JSON.parse(await resp.text(), biDateReviver);\n },\n async fetchDashboardBundle(sessionId, scriptFileName) {\n // `no-store` bypasses every browser cache layer; the compiled-bundle\n // cache in the runtime is keyed on the bytes, so a stale fetch can\n // never resolve a regenerated bundle to old code.\n const resp = await request(routes.dashboardBundle(sessionId, scriptFileName), { method: 'GET', cache: 'no-store' });\n if (!resp.ok) throw new Error(`Failed to fetch dashboard bundle (${resp.status}): ${routes.dashboardBundle(sessionId, scriptFileName)}`);\n return resp.text();\n },\n\n artifactUrl(src, scope = {}) {\n return routes.artifact(src, scope);\n },\n iframeUrl(src, scope = {}) {\n return routes.htmlArtifact(src, scope);\n },\n\n async listDashboards() {\n const resp = await requestOk(routes.dashboardList(), { method: 'GET', headers: noCacheHeaders });\n return JSON.parse(await resp.text(), biDateReviver);\n },\n async getDashboardBySession(sessionId) {\n const resp = await request(routes.dashboardBySession(sessionId), { method: 'GET', headers: noCacheHeaders });\n if (resp.status === 404) return null;\n if (!resp.ok) throw new Error(`[BiClient] dashboard-by-session fetch failed (${resp.status})`);\n return JSON.parse(await resp.text(), biDateReviver);\n },\n async upsertDashboard(payload) {\n const resp = await requestOk(routes.dashboardUpsert(), json(payload, { headers: { 'Content-Type': 'application/json', ...noCacheHeaders } }));\n return JSON.parse(await resp.text(), biDateReviver);\n },\n async updateDashboard(dashboardId, dashboard) {\n await requestOk(routes.dashboardUpdate(dashboardId), json(dashboard));\n },\n async deleteDashboard(dashboardId) {\n const resp = await request(routes.dashboardDelete(dashboardId), { method: 'DELETE' });\n if (resp.status === 404) return false;\n if (!resp.ok) throw new Error(`[BiClient] dashboard delete failed (${resp.status})`);\n return true;\n },\n async dashboardAction(dashboardId, action) {\n const resp = await request(routes.dashboardAction(dashboardId, action), { method: 'POST' });\n if (!resp.ok) {\n const text = await resp.text().catch(() => '');\n throw new Error(text || `[BiClient] dashboard ${action} failed (${resp.status})`);\n }\n },\n async listFolders() {\n const resp = await requestOk(routes.folders(), { method: 'GET', headers: noCacheHeaders });\n return JSON.parse(await resp.text(), biDateReviver);\n },\n async getFolder(folderId) {\n const resp = await request(routes.folder(folderId), { method: 'GET', headers: noCacheHeaders });\n if (resp.status === 404) throw new Error(`Folder '${folderId}' not found`);\n if (!resp.ok) throw new Error(`[BiClient] folder fetch failed (${resp.status})`);\n return JSON.parse(await resp.text(), biDateReviver);\n },\n async createFolder(name, description) {\n const resp = await requestOk(routes.folders(), json({ name, description }));\n return JSON.parse(await resp.text(), biDateReviver);\n },\n async updateFolder(folderId, patch) {\n const resp = await requestOk(routes.folder(folderId), json(patch, { method: 'PATCH' }));\n return JSON.parse(await resp.text(), biDateReviver);\n },\n async deleteFolder(folderId) {\n const resp = await request(routes.folder(folderId), { method: 'DELETE' });\n if (resp.status === 404) return false;\n if (!resp.ok) throw new Error(`[BiClient] folder delete failed (${resp.status})`);\n return true;\n },\n async folderAction(folderId, action) {\n await requestOk(routes.folderAction(folderId, action), { method: 'POST' });\n },\n async getDashboardHierarchy() {\n const resp = await requestOk(routes.folderHierarchy(), { method: 'GET', headers: noCacheHeaders });\n return JSON.parse(await resp.text(), biDateReviver);\n },\n };\n}\n","import React, { createContext, useContext, useMemo } from 'react';\nimport { createBiClient, type BiClient, type BiClientOptions } from './BiClient';\n\nconst BiClientContext = createContext<BiClient | null>(null);\n\nexport interface BiClientProviderProps {\n /** A ready client — or pass `options` and let the provider build one. */\n client?: BiClient;\n options?: BiClientOptions;\n /**\n * Session the inline components (`Chart`, `IFrame`) scope their artifact\n * URLs to when the tool call did not name one. Typically the active chat\n * session id.\n */\n sessionId?: string;\n children: React.ReactNode;\n}\n\nconst BiSessionContext = createContext<string | undefined>(undefined);\n\nexport const BiClientProvider: React.FC<BiClientProviderProps> = ({ client, options, sessionId, children }) => {\n const value = useMemo(() => {\n if (client) return client;\n if (options) return createBiClient(options);\n throw new Error('[@aintela/bi] BiClientProvider needs either `client` or `options`.');\n }, [client, options]);\n return (\n <BiClientContext.Provider value={value}>\n <BiSessionContext.Provider value={sessionId}>{children}</BiSessionContext.Provider>\n </BiClientContext.Provider>\n );\n};\n\n/** The ambient client. Throws with a clear message when no provider is mounted. */\nexport function useBiClient(): BiClient {\n const client = useContext(BiClientContext);\n if (!client) {\n throw new Error(\n '[@aintela/bi] No BiClient in scope. Wrap the BI surface in <BiClientProvider client={createBiClient({ baseUrl })}>.',\n );\n }\n return client;\n}\n\n/** Same as {@link useBiClient} but returns `null` instead of throwing. */\nexport function useBiClientOptional(): BiClient | null {\n return useContext(BiClientContext);\n}\n\n/** The session id the nearest `BiClientProvider` was given, if any. */\nexport function useBiSessionId(): string | undefined {\n return useContext(BiSessionContext);\n}\n"],"names":["trimSlash","s","__name","enc","defaultBiRoutes","baseUrl","cacheBust","base","bust","d","h","noCache","v","f","fmt","src","scope","prefix","biDateReviver","_key","value","createBiClient","options","doFetch","input","init","routes","request","path","url","headers","k","auth","requestOk","resp","text","json","body","extra","noCacheHeaders","dashboardId","queryHash","opts","viewId","field","format","filterId","sessionId","subAgentId","scriptFileName","payload","dashboard","action","folderId","name","description","patch","BiClientContext","createContext","BiSessionContext","BiClientProvider","client","children","useMemo","jsx","useBiClient","useContext","useBiClientOptional","useBiSessionId"],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ var c = Object.defineProperty;
2
+ var e = (t, r) => c(t, "name", { value: r, configurable: !0 });
3
+ import { jsx as C } from "react/jsx-runtime";
4
+ import { createContext as f, useRef as l, useMemo as i, useContext as x } from "react";
5
+ const s = f({});
6
+ function D() {
7
+ return x(s);
8
+ }
9
+ e(D, "useChartCardDefaults");
10
+ const h = /* @__PURE__ */ e(({
11
+ palette: t,
12
+ monoShadePerCategory: r,
13
+ rotateBasePerChart: o,
14
+ children: u
15
+ }) => {
16
+ const a = l(0), n = i(
17
+ () => ({
18
+ palette: t,
19
+ monoShadePerCategory: r,
20
+ rotateBasePerChart: o,
21
+ allocateChartSlot: /* @__PURE__ */ e(() => a.current++, "allocateChartSlot")
22
+ }),
23
+ [t, r, o]
24
+ );
25
+ return /* @__PURE__ */ C(s.Provider, { value: n, children: u });
26
+ }, "ChartCardDefaultsProvider");
27
+ export {
28
+ s as C,
29
+ h as a,
30
+ D as u
31
+ };
32
+ //# sourceMappingURL=ChartCardDefaultsContext-Cl5T25H0.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChartCardDefaultsContext-Cl5T25H0.js","sources":["../src/data/ChartCardDefaultsContext.tsx"],"sourcesContent":["import React, { createContext, useContext, useMemo, useRef } from 'react';\n\n/**\n * Chart defaults — a host (or a dashboard viewer) can override the series\n * palette for a subtree and turn on \"mono-shade per category\" so single-series\n * bar charts use shades of one hue instead of the categorical palette.\n *\n * `palette` is the per-dashboard override; when absent, charts read\n * `theme.palette.bi.series` (see `useBiPalette`).\n */\nexport interface ChartCardDefaults {\n /** Replaces `theme.palette.bi.series` for series and pie / donut slice colours. */\n palette?: readonly string[];\n /**\n * When true, single-series bar charts colour each *category* (data row)\n * with a different opacity of the base series colour.\n */\n monoShadePerCategory?: boolean;\n /**\n * When true, each ChartCard mounted under the provider gets a different\n * primer colour from the palette in round-robin mount order.\n */\n rotateBasePerChart?: boolean;\n /**\n * Internal: provider-supplied counter used by ChartCard to claim a slot\n * index on first mount. Use `ChartCardDefaultsProvider` rather than\n * setting this directly.\n */\n allocateChartSlot?: () => number;\n}\n\nexport const ChartCardDefaultsContext = createContext<ChartCardDefaults>({});\n\nexport function useChartCardDefaults(): ChartCardDefaults {\n return useContext(ChartCardDefaultsContext);\n}\n\nexport interface ChartCardDefaultsProviderProps {\n palette?: readonly string[];\n monoShadePerCategory?: boolean;\n rotateBasePerChart?: boolean;\n children: React.ReactNode;\n}\n\n/**\n * Wraps a subtree in a `ChartCardDefaultsContext`. Keeps a monotonically\n * increasing counter across child ChartCard mounts so each captures a stable\n * slot index on first render (not reset on parent re-renders).\n */\nexport const ChartCardDefaultsProvider: React.FC<ChartCardDefaultsProviderProps> = ({\n palette,\n monoShadePerCategory,\n rotateBasePerChart,\n children,\n}) => {\n const counterRef = useRef(0);\n const value = useMemo<ChartCardDefaults>(\n () => ({\n palette,\n monoShadePerCategory,\n rotateBasePerChart,\n allocateChartSlot: () => counterRef.current++,\n }),\n [palette, monoShadePerCategory, rotateBasePerChart],\n );\n return <ChartCardDefaultsContext.Provider value={value}>{children}</ChartCardDefaultsContext.Provider>;\n};\n"],"names":["ChartCardDefaultsContext","createContext","useChartCardDefaults","useContext","__name","ChartCardDefaultsProvider","palette","monoShadePerCategory","rotateBasePerChart","children","counterRef","useRef","value","useMemo","jsx"],"mappings":";;;;AA+BO,MAAMA,IAA2BC,EAAiC,CAAA,CAAE;AAEpE,SAASC,IAA0C;AACtD,SAAOC,EAAWH,CAAwB;AAC9C;AAFgBI,EAAAF,GAAA;AAgBT,MAAMG,IAAsE,gBAAAD,EAAA,CAAC;AAAA,EAChF,SAAAE;AAAA,EACA,sBAAAC;AAAA,EACA,oBAAAC;AAAA,EACA,UAAAC;AACJ,MAAM;AACF,QAAMC,IAAaC,EAAO,CAAC,GACrBC,IAAQC;AAAA,IACV,OAAO;AAAA,MACH,SAAAP;AAAA,MACA,sBAAAC;AAAA,MACA,oBAAAC;AAAA,MACA,mBAAmB,gBAAAJ,EAAA,MAAMM,EAAW,WAAjB;AAAA,IAAiB;AAAA,IAExC,CAACJ,GAASC,GAAsBC,CAAkB;AAAA,EAAA;AAEtD,SAAO,gBAAAM,EAACd,EAAyB,UAAzB,EAAkC,OAAAY,GAAe,UAAAH,EAAA,CAAS;AACtE,GAjBmF;"}