@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.
- package/README.md +299 -0
- package/dist/BiClientProvider-CWJochvi.js +219 -0
- package/dist/BiClientProvider-CWJochvi.js.map +1 -0
- package/dist/ChartCardDefaultsContext-Cl5T25H0.js +32 -0
- package/dist/ChartCardDefaultsContext-Cl5T25H0.js.map +1 -0
- package/dist/ChartContext-C_f_6khG.js +14 -0
- package/dist/ChartContext-C_f_6khG.js.map +1 -0
- package/dist/DashboardParametersContext-Clv--79U.js +39 -0
- package/dist/DashboardParametersContext-Clv--79U.js.map +1 -0
- package/dist/cards/ChartCard.d.ts +62 -0
- package/dist/cards/DataTableCard.d.ts +55 -0
- package/dist/cards/GaugeCard.d.ts +20 -0
- package/dist/cards/GaugeGroup.d.ts +12 -0
- package/dist/cards/MapBubbles.d.ts +35 -0
- package/dist/cards/MapConnections.d.ts +28 -0
- package/dist/cards/MetricCard.d.ts +15 -0
- package/dist/cards/MetricGroupCard.d.ts +10 -0
- package/dist/cards/TreeMapCard.d.ts +15 -0
- package/dist/cards/geoLayers.d.ts +23 -0
- package/dist/cards/index.d.ts +24 -0
- package/dist/cards/licenseGuard.d.ts +9 -0
- package/dist/cards/mapUtils.d.ts +23 -0
- package/dist/cards/useContainerRectangle.d.ts +9 -0
- package/dist/cards/worldMapPath.d.ts +7 -0
- package/dist/cards.d.ts +2 -0
- package/dist/cards.js +28 -0
- package/dist/cards.js.map +1 -0
- package/dist/client/BiClient.d.ts +160 -0
- package/dist/client/BiClientProvider.d.ts +21 -0
- package/dist/client/index.d.ts +4 -0
- package/dist/client.d.ts +2 -0
- package/dist/client.js +11 -0
- package/dist/client.js.map +1 -0
- package/dist/composer/environment/environmentDom.d.ts +31 -0
- package/dist/composer/environment/types.d.ts +67 -0
- package/dist/composer/icons/cardTypeIcons.d.ts +31 -0
- package/dist/composer/index.d.ts +66 -0
- package/dist/composer/llm/ExampleCardSketch.d.ts +22 -0
- package/dist/composer/llm/ExamplePad.d.ts +18 -0
- package/dist/composer/llm/PrototypePad.d.ts +13 -0
- package/dist/composer/llm/useDashboardPad.d.ts +25 -0
- package/dist/composer/models/catalog.d.ts +33 -0
- package/dist/composer/models/sketchModels.d.ts +102 -0
- package/dist/composer/models/utils.d.ts +9 -0
- package/dist/composer/pad/CardSketch.d.ts +25 -0
- package/dist/composer/pad/ClonedComponent.d.ts +13 -0
- package/dist/composer/pad/DashboardPad.d.ts +38 -0
- package/dist/composer/pad/DashboardPadEditor.d.ts +35 -0
- package/dist/composer/pad/DashboardPadSketch.d.ts +31 -0
- package/dist/composer/pad/DatasetParameterizationControls.d.ts +34 -0
- package/dist/composer/pad/FilterSketch.d.ts +10 -0
- package/dist/composer/pad/HoverButton.d.ts +12 -0
- package/dist/composer/pad/TitleSketch.d.ts +19 -0
- package/dist/composer/pad/ToolBox.d.ts +11 -0
- package/dist/composer/store/ComposerProvider.d.ts +36 -0
- package/dist/composer/store/createComposerStore.d.ts +107 -0
- package/dist/composer/store/drafts.d.ts +20 -0
- package/dist/composer/view/ComposerChatBinding.d.ts +10 -0
- package/dist/composer/view/ComposerView.d.ts +49 -0
- package/dist/composer/view/DashboardPin.d.ts +3 -0
- package/dist/composer/view/DashboardSidePanel.d.ts +10 -0
- package/dist/composer/view/DrawablePrompt.d.ts +22 -0
- package/dist/composer/view/EntryEmptyState.d.ts +22 -0
- package/dist/composer/view/SpotlightOverlay.d.ts +21 -0
- package/dist/composer/view/composerAnimations.d.ts +11 -0
- package/dist/composer/view/composerTypes.d.ts +18 -0
- package/dist/composer/view/data/suggestions.d.ts +10 -0
- package/dist/composer/view/data/templates.d.ts +33 -0
- package/dist/composer/view/surfaces.d.ts +19 -0
- package/dist/composer/view/useComposerChatBridge.d.ts +43 -0
- package/dist/composer.d.ts +2 -0
- package/dist/composer.js +99 -0
- package/dist/composer.js.map +1 -0
- package/dist/createBiTheme-TyUv_UHM.js +93 -0
- package/dist/createBiTheme-TyUv_UHM.js.map +1 -0
- package/dist/data/ChartCardDefaultsContext.d.ts +43 -0
- package/dist/data/dataUtils.d.ts +152 -0
- package/dist/data/index.d.ts +5 -0
- package/dist/data/queryModel.d.ts +23 -0
- package/dist/data.d.ts +2 -0
- package/dist/data.js +37 -0
- package/dist/data.js.map +1 -0
- package/dist/dataUtils-CAUE5uZY.js +372 -0
- package/dist/dataUtils-CAUE5uZY.js.map +1 -0
- package/dist/filters/VizAutoComplete.d.ts +23 -0
- package/dist/filters/VizDatePicker.d.ts +9 -0
- package/dist/filters/VizDateRangePicker.d.ts +14 -0
- package/dist/filters/VizSelect.d.ts +12 -0
- package/dist/filters/VizTextField.d.ts +8 -0
- package/dist/filters/VizTriggerButton.d.ts +9 -0
- package/dist/filters/filterFactory.d.ts +30 -0
- package/dist/filters/friendlyName.d.ts +4 -0
- package/dist/filters/index.d.ts +15 -0
- package/dist/filters.d.ts +2 -0
- package/dist/filters.js +15 -0
- package/dist/filters.js.map +1 -0
- package/dist/grid/BiErrorBoundary.d.ts +24 -0
- package/dist/grid/ChartContext.d.ts +14 -0
- package/dist/grid/GridCard.d.ts +45 -0
- package/dist/grid/GridCardPlaceHolder.d.ts +8 -0
- package/dist/grid/GridLayout.d.ts +147 -0
- package/dist/grid/gridModels.d.ts +33 -0
- package/dist/grid/index.d.ts +14 -0
- package/dist/grid/types.d.ts +23 -0
- package/dist/grid/useGridConfigTranslator.d.ts +72 -0
- package/dist/grid.d.ts +2 -0
- package/dist/grid.js +20 -0
- package/dist/grid.js.map +1 -0
- package/dist/hooks/DashboardParametersContext.d.ts +32 -0
- package/dist/hooks/index.d.ts +8 -0
- package/dist/hooks/useDashboardData.d.ts +20 -0
- package/dist/hooks/useDashboardLazyData.d.ts +79 -0
- package/dist/hooks.d.ts +2 -0
- package/dist/hooks.js +16 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index-BYc79sSy.js +131 -0
- package/dist/index-BYc79sSy.js.map +1 -0
- package/dist/index-C6JQ6770.js +4545 -0
- package/dist/index-C6JQ6770.js.map +1 -0
- package/dist/index-CZbCaXMC.js +15 -0
- package/dist/index-CZbCaXMC.js.map +1 -0
- package/dist/index-D3OoOPjl.js +259 -0
- package/dist/index-D3OoOPjl.js.map +1 -0
- package/dist/index-D7Oo_dC-.js +94 -0
- package/dist/index-D7Oo_dC-.js.map +1 -0
- package/dist/index-D7tVPX8d.js +347 -0
- package/dist/index-D7tVPX8d.js.map +1 -0
- package/dist/index-DGyvUtY3.js +494 -0
- package/dist/index-DGyvUtY3.js.map +1 -0
- package/dist/index-DOpx0R4Y.js +41 -0
- package/dist/index-DOpx0R4Y.js.map +1 -0
- package/dist/index-wtSLspPh.js +1065 -0
- package/dist/index-wtSLspPh.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +236 -0
- package/dist/index.js.map +1 -0
- package/dist/inline/Chart.d.ts +29 -0
- package/dist/inline/IFrame.d.ts +19 -0
- package/dist/inline/Metric.d.ts +16 -0
- package/dist/inline/MetricGroup.d.ts +11 -0
- package/dist/inline/index.d.ts +9 -0
- package/dist/inline/parseKnownNumbers.d.ts +11 -0
- package/dist/inline.d.ts +2 -0
- package/dist/inline.js +9 -0
- package/dist/inline.js.map +1 -0
- package/dist/runtime/IDashboardDefinition.d.ts +22 -0
- package/dist/runtime/biModuleSurface.d.ts +2 -0
- package/dist/runtime/createBiUiTools.d.ts +74 -0
- package/dist/runtime/index.d.ts +9 -0
- package/dist/runtime/loadDashboardBundle.d.ts +32 -0
- package/dist/runtime/registerBiModules.d.ts +36 -0
- package/dist/runtime/version.d.ts +6 -0
- package/dist/runtime.d.ts +2 -0
- package/dist/runtime.js +19 -0
- package/dist/runtime.js.map +1 -0
- package/dist/style.css +1 -0
- package/dist/theme/BiThemeBridge.d.ts +32 -0
- package/dist/theme/biPalette.d.ts +23 -0
- package/dist/theme/createBiTheme.d.ts +25 -0
- package/dist/theme/index.d.ts +5 -0
- package/dist/theme.d.ts +2 -0
- package/dist/theme.js +15 -0
- package/dist/theme.js.map +1 -0
- package/dist/version-DnqajORq.js +83 -0
- package/dist/version-DnqajORq.js.map +1 -0
- package/dist/viewer/ScriptDashboardViewer.d.ts +82 -0
- package/dist/viewer/ScriptDashboardViewerVertical.d.ts +24 -0
- package/dist/viewer/cardMetadata.d.ts +15 -0
- package/dist/viewer/index.d.ts +8 -0
- package/dist/viewer/models.d.ts +67 -0
- package/dist/viewer/useDashboardBundle.d.ts +73 -0
- package/dist/viewer.d.ts +2 -0
- package/dist/viewer.js +9 -0
- package/dist/viewer.js.map +1 -0
- 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;"}
|