@miragon/mcp-toolkit-ui 2.6.0 → 2.8.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 +14 -5
- package/dist/app/adapt-data-widget.d.ts +1 -22
- package/dist/app/adapt-data-widget.d.ts.map +1 -1
- package/dist/app/adapt-data-widget.js +1 -35
- package/dist/app/adapt-data-widget.js.map +1 -1
- package/dist/app/builder/BuilderBanners.d.ts +7 -2
- package/dist/app/builder/BuilderBanners.d.ts.map +1 -1
- package/dist/app/builder/BuilderBanners.js +8 -3
- package/dist/app/builder/BuilderBanners.js.map +1 -1
- package/dist/app/builder/CanvasRow.d.ts +4 -2
- package/dist/app/builder/CanvasRow.d.ts.map +1 -1
- package/dist/app/builder/CanvasRow.js +29 -17
- package/dist/app/builder/CanvasRow.js.map +1 -1
- package/dist/app/builder/CatalogueSheet.d.ts.map +1 -1
- package/dist/app/builder/CatalogueSheet.js +14 -6
- package/dist/app/builder/CatalogueSheet.js.map +1 -1
- package/dist/app/builder/CellPropsSheet.d.ts +7 -3
- package/dist/app/builder/CellPropsSheet.d.ts.map +1 -1
- package/dist/app/builder/CellPropsSheet.js +10 -3
- package/dist/app/builder/CellPropsSheet.js.map +1 -1
- package/dist/app/builder/DiscardDialog.d.ts +18 -0
- package/dist/app/builder/DiscardDialog.d.ts.map +1 -0
- package/dist/app/builder/DiscardDialog.js +18 -0
- package/dist/app/builder/DiscardDialog.js.map +1 -0
- package/dist/app/builder/EmptyHint.d.ts +4 -0
- package/dist/app/builder/EmptyHint.d.ts.map +1 -1
- package/dist/app/builder/EmptyHint.js +6 -1
- package/dist/app/builder/EmptyHint.js.map +1 -1
- package/dist/app/builder/LayoutSurface.d.ts +33 -9
- package/dist/app/builder/LayoutSurface.d.ts.map +1 -1
- package/dist/app/builder/LayoutSurface.js +74 -23
- package/dist/app/builder/LayoutSurface.js.map +1 -1
- package/dist/app/builder/PipelineStrip.d.ts +5 -2
- package/dist/app/builder/PipelineStrip.d.ts.map +1 -1
- package/dist/app/builder/PipelineStrip.js +33 -15
- package/dist/app/builder/PipelineStrip.js.map +1 -1
- package/dist/app/builder/SaveDialog.d.ts +9 -1
- package/dist/app/builder/SaveDialog.d.ts.map +1 -1
- package/dist/app/builder/SaveDialog.js +9 -3
- package/dist/app/builder/SaveDialog.js.map +1 -1
- package/dist/app/builder/Toolbar.d.ts +14 -4
- package/dist/app/builder/Toolbar.d.ts.map +1 -1
- package/dist/app/builder/Toolbar.js +24 -7
- package/dist/app/builder/Toolbar.js.map +1 -1
- package/dist/app/builder/Workspace.d.ts +23 -3
- package/dist/app/builder/Workspace.d.ts.map +1 -1
- package/dist/app/builder/Workspace.js +58 -8
- package/dist/app/builder/Workspace.js.map +1 -1
- package/dist/app/builder/builder-model.d.ts +146 -3
- package/dist/app/builder/builder-model.d.ts.map +1 -1
- package/dist/app/builder/builder-model.js +196 -5
- package/dist/app/builder/builder-model.js.map +1 -1
- package/dist/app/builder/labels.d.ts +13 -62
- package/dist/app/builder/labels.d.ts.map +1 -1
- package/dist/app/builder/labels.js +9 -58
- package/dist/app/builder/labels.js.map +1 -1
- package/dist/app/builder/reveal.d.ts +10 -0
- package/dist/app/builder/reveal.d.ts.map +1 -0
- package/dist/app/builder/reveal.js +10 -0
- package/dist/app/builder/reveal.js.map +1 -0
- package/dist/app/builder/status-chip.d.ts.map +1 -1
- package/dist/app/builder/status-chip.js +3 -2
- package/dist/app/builder/status-chip.js.map +1 -1
- package/dist/app/builder/use-builder-catalogue.d.ts +5 -1
- package/dist/app/builder/use-builder-catalogue.d.ts.map +1 -1
- package/dist/app/builder/use-builder-catalogue.js +50 -17
- package/dist/app/builder/use-builder-catalogue.js.map +1 -1
- package/dist/app/builder/use-builder-session.d.ts +30 -0
- package/dist/app/builder/use-builder-session.d.ts.map +1 -0
- package/dist/app/builder/use-builder-session.js +58 -0
- package/dist/app/builder/use-builder-session.js.map +1 -0
- package/dist/app/builder/use-display-resolver.d.ts +17 -0
- package/dist/app/builder/use-display-resolver.d.ts.map +1 -0
- package/dist/app/builder/use-display-resolver.js +16 -0
- package/dist/app/builder/use-display-resolver.js.map +1 -0
- package/dist/app/builder/use-save-dashboard.d.ts +3 -1
- package/dist/app/builder/use-save-dashboard.d.ts.map +1 -1
- package/dist/app/builder/use-save-dashboard.js +3 -1
- package/dist/app/builder/use-save-dashboard.js.map +1 -1
- package/dist/app/index.d.ts +8 -3
- package/dist/app/index.d.ts.map +1 -1
- package/dist/app/index.js +8 -2
- package/dist/app/index.js.map +1 -1
- package/dist/app/layout-builder.d.ts +18 -25
- package/dist/app/layout-builder.d.ts.map +1 -1
- package/dist/app/layout-builder.js +84 -78
- package/dist/app/layout-builder.js.map +1 -1
- package/dist/app/mcp-app-view-chrome.d.ts +103 -20
- package/dist/app/mcp-app-view-chrome.d.ts.map +1 -1
- package/dist/app/mcp-app-view-chrome.js +125 -40
- package/dist/app/mcp-app-view-chrome.js.map +1 -1
- package/dist/app/mcp-app-view-states.d.ts +23 -0
- package/dist/app/mcp-app-view-states.d.ts.map +1 -0
- package/dist/app/mcp-app-view-states.js +55 -0
- package/dist/app/mcp-app-view-states.js.map +1 -0
- package/dist/app/mcp-app-view.d.ts +72 -5
- package/dist/app/mcp-app-view.d.ts.map +1 -1
- package/dist/app/mcp-app-view.js +241 -141
- package/dist/app/mcp-app-view.js.map +1 -1
- package/dist/app/mcp-toolkit-app.d.ts +8 -2
- package/dist/app/mcp-toolkit-app.d.ts.map +1 -1
- package/dist/app/mcp-toolkit-app.js +33 -4
- package/dist/app/mcp-toolkit-app.js.map +1 -1
- package/dist/app/mcp-use-host-bridge.d.ts +15 -6
- package/dist/app/mcp-use-host-bridge.d.ts.map +1 -1
- package/dist/app/mcp-use-host-bridge.js +51 -22
- package/dist/app/mcp-use-host-bridge.js.map +1 -1
- package/dist/app/model-context.d.ts +71 -0
- package/dist/app/model-context.d.ts.map +1 -0
- package/dist/app/model-context.js +101 -0
- package/dist/app/model-context.js.map +1 -0
- package/dist/app/use-build-mode-focus.d.ts +33 -0
- package/dist/app/use-build-mode-focus.d.ts.map +1 -0
- package/dist/app/use-build-mode-focus.js +59 -0
- package/dist/app/use-build-mode-focus.js.map +1 -0
- package/dist/app/use-view-actions.d.ts +31 -0
- package/dist/app/use-view-actions.d.ts.map +1 -0
- package/dist/app/use-view-actions.js +81 -0
- package/dist/app/use-view-actions.js.map +1 -0
- package/dist/app/use-view-lifecycle.d.ts +42 -0
- package/dist/app/use-view-lifecycle.d.ts.map +1 -0
- package/dist/app/use-view-lifecycle.js +81 -0
- package/dist/app/use-view-lifecycle.js.map +1 -0
- package/dist/app/view-lifecycle.d.ts +185 -0
- package/dist/app/view-lifecycle.d.ts.map +1 -0
- package/dist/app/view-lifecycle.js +207 -0
- package/dist/app/view-lifecycle.js.map +1 -0
- package/dist/app/widget-fixture.d.ts +10 -3
- package/dist/app/widget-fixture.d.ts.map +1 -1
- package/dist/app/widget-fixture.js +21 -8
- package/dist/app/widget-fixture.js.map +1 -1
- package/dist/app/widget-props-sheet.d.ts +6 -10
- package/dist/app/widget-props-sheet.d.ts.map +1 -1
- package/dist/app/widget-props-sheet.js +25 -20
- package/dist/app/widget-props-sheet.js.map +1 -1
- package/dist/app/widget-renderer.d.ts +41 -1
- package/dist/app/widget-renderer.d.ts.map +1 -1
- package/dist/app/widget-renderer.js +82 -31
- package/dist/app/widget-renderer.js.map +1 -1
- package/dist/components/DrillButton.d.ts +9 -6
- package/dist/components/DrillButton.d.ts.map +1 -1
- package/dist/components/DrillButton.js +9 -6
- package/dist/components/DrillButton.js.map +1 -1
- package/dist/components/EmptyState.d.ts +33 -0
- package/dist/components/EmptyState.d.ts.map +1 -0
- package/dist/components/EmptyState.js +19 -0
- package/dist/components/EmptyState.js.map +1 -0
- package/dist/components/ErrorState.d.ts +53 -0
- package/dist/components/ErrorState.d.ts.map +1 -0
- package/dist/components/ErrorState.js +77 -0
- package/dist/components/ErrorState.js.map +1 -0
- package/dist/components/FilterBar.d.ts +16 -5
- package/dist/components/FilterBar.d.ts.map +1 -1
- package/dist/components/FilterBar.js +13 -5
- package/dist/components/FilterBar.js.map +1 -1
- package/dist/components/GroupCard.d.ts.map +1 -1
- package/dist/components/GroupCard.js +2 -1
- package/dist/components/GroupCard.js.map +1 -1
- package/dist/components/KpiGrid.d.ts +70 -18
- package/dist/components/KpiGrid.d.ts.map +1 -1
- package/dist/components/KpiGrid.js +112 -23
- package/dist/components/KpiGrid.js.map +1 -1
- package/dist/components/ListFooter.d.ts +32 -4
- package/dist/components/ListFooter.d.ts.map +1 -1
- package/dist/components/ListFooter.js +35 -6
- package/dist/components/ListFooter.js.map +1 -1
- package/dist/components/PagedListFooter.d.ts +57 -0
- package/dist/components/PagedListFooter.d.ts.map +1 -0
- package/dist/components/PagedListFooter.js +27 -0
- package/dist/components/PagedListFooter.js.map +1 -0
- package/dist/components/Pills.d.ts +36 -12
- package/dist/components/Pills.d.ts.map +1 -1
- package/dist/components/Pills.js +29 -8
- package/dist/components/Pills.js.map +1 -1
- package/dist/components/SectionHeading.d.ts +3 -1
- package/dist/components/SectionHeading.d.ts.map +1 -1
- package/dist/components/SectionHeading.js +6 -2
- package/dist/components/SectionHeading.js.map +1 -1
- package/dist/components/Toast.d.ts +43 -0
- package/dist/components/Toast.d.ts.map +1 -0
- package/dist/components/Toast.js +106 -0
- package/dist/components/Toast.js.map +1 -0
- package/dist/components/WidgetHeader.d.ts +34 -10
- package/dist/components/WidgetHeader.d.ts.map +1 -1
- package/dist/components/WidgetHeader.js +11 -6
- package/dist/components/WidgetHeader.js.map +1 -1
- package/dist/hooks/index.d.ts +4 -4
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -1
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/tool-result-recovery-model.d.ts +155 -0
- package/dist/hooks/tool-result-recovery-model.d.ts.map +1 -0
- package/dist/hooks/tool-result-recovery-model.js +273 -0
- package/dist/hooks/tool-result-recovery-model.js.map +1 -0
- package/dist/hooks/use-tool-query.d.ts +56 -14
- package/dist/hooks/use-tool-query.d.ts.map +1 -1
- package/dist/hooks/use-tool-query.js +102 -25
- package/dist/hooks/use-tool-query.js.map +1 -1
- package/dist/hooks/use-tool-result-recovery.d.ts +61 -44
- package/dist/hooks/use-tool-result-recovery.d.ts.map +1 -1
- package/dist/hooks/use-tool-result-recovery.js +62 -110
- package/dist/hooks/use-tool-result-recovery.js.map +1 -1
- package/dist/hooks/use-view-data.d.ts +55 -7
- package/dist/hooks/use-view-data.d.ts.map +1 -1
- package/dist/hooks/use-view-data.js +81 -11
- package/dist/hooks/use-view-data.js.map +1 -1
- package/dist/hooks/use-view-tool-query.d.ts +12 -7
- package/dist/hooks/use-view-tool-query.d.ts.map +1 -1
- package/dist/hooks/use-view-tool-query.js +15 -14
- package/dist/hooks/use-view-tool-query.js.map +1 -1
- package/dist/index.d.ts +27 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -7
- package/dist/index.js.map +1 -1
- package/dist/lib/focus-return.d.ts +61 -0
- package/dist/lib/focus-return.d.ts.map +1 -0
- package/dist/lib/focus-return.js +46 -0
- package/dist/lib/focus-return.js.map +1 -0
- package/dist/lib/focus-ring.d.ts +18 -0
- package/dist/lib/focus-ring.d.ts.map +1 -0
- package/dist/lib/focus-ring.js +18 -0
- package/dist/lib/focus-ring.js.map +1 -0
- package/dist/lib/icon-stroke.d.ts +12 -0
- package/dist/lib/icon-stroke.d.ts.map +1 -0
- package/dist/lib/icon-stroke.js +12 -0
- package/dist/lib/icon-stroke.js.map +1 -0
- package/dist/lib/parse-tool-result.d.ts +23 -1
- package/dist/lib/parse-tool-result.d.ts.map +1 -1
- package/dist/lib/parse-tool-result.js +38 -2
- package/dist/lib/parse-tool-result.js.map +1 -1
- package/dist/lib/toast-model.d.ts +86 -0
- package/dist/lib/toast-model.d.ts.map +1 -0
- package/dist/lib/toast-model.js +102 -0
- package/dist/lib/toast-model.js.map +1 -0
- package/dist/lib/tone-utils.d.ts +95 -9
- package/dist/lib/tone-utils.d.ts.map +1 -1
- package/dist/lib/tone-utils.js +100 -9
- package/dist/lib/tone-utils.js.map +1 -1
- package/dist/lib/tool-query.d.ts +107 -0
- package/dist/lib/tool-query.d.ts.map +1 -0
- package/dist/lib/tool-query.js +182 -0
- package/dist/lib/tool-query.js.map +1 -0
- package/dist/lib/tool-result-observer.d.ts +108 -0
- package/dist/lib/tool-result-observer.d.ts.map +1 -0
- package/dist/lib/tool-result-observer.js +158 -0
- package/dist/lib/tool-result-observer.js.map +1 -0
- package/dist/lib/typography.d.ts +37 -0
- package/dist/lib/typography.d.ts.map +1 -0
- package/dist/lib/typography.js +41 -0
- package/dist/lib/typography.js.map +1 -0
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +11 -1
- package/dist/lib/utils.js.map +1 -1
- package/dist/locale/index.d.ts +3 -1
- package/dist/locale/index.d.ts.map +1 -1
- package/dist/locale/index.js +2 -1
- package/dist/locale/index.js.map +1 -1
- package/dist/locale/locale-provider.d.ts +42 -1
- package/dist/locale/locale-provider.d.ts.map +1 -1
- package/dist/locale/locale-provider.js +44 -3
- package/dist/locale/locale-provider.js.map +1 -1
- package/dist/locale/message-types.d.ts +336 -0
- package/dist/locale/message-types.d.ts.map +1 -0
- package/dist/locale/message-types.js +7 -0
- package/dist/locale/message-types.js.map +1 -0
- package/dist/locale/messages-de.d.ts +9 -0
- package/dist/locale/messages-de.d.ts.map +1 -0
- package/dist/locale/messages-de.js +185 -0
- package/dist/locale/messages-de.js.map +1 -0
- package/dist/locale/messages-en.d.ts +8 -0
- package/dist/locale/messages-en.d.ts.map +1 -0
- package/dist/locale/messages-en.js +184 -0
- package/dist/locale/messages-en.js.map +1 -0
- package/dist/locale/toolkit-messages.d.ts +57 -0
- package/dist/locale/toolkit-messages.d.ts.map +1 -0
- package/dist/locale/toolkit-messages.js +103 -0
- package/dist/locale/toolkit-messages.js.map +1 -0
- package/dist/primitives/alert.d.ts +1 -1
- package/dist/primitives/alert.d.ts.map +1 -1
- package/dist/primitives/alert.js +6 -2
- package/dist/primitives/alert.js.map +1 -1
- package/dist/primitives/badge.d.ts +1 -1
- package/dist/primitives/badge.d.ts.map +1 -1
- package/dist/primitives/badge.js +19 -6
- package/dist/primitives/badge.js.map +1 -1
- package/dist/primitives/button.d.ts +1 -1
- package/dist/primitives/button.d.ts.map +1 -1
- package/dist/primitives/button.js +12 -8
- package/dist/primitives/button.js.map +1 -1
- package/dist/primitives/card.js +4 -4
- package/dist/primitives/card.js.map +1 -1
- package/dist/primitives/dialog.d.ts +7 -3
- package/dist/primitives/dialog.d.ts.map +1 -1
- package/dist/primitives/dialog.js +22 -8
- package/dist/primitives/dialog.js.map +1 -1
- package/dist/primitives/input.d.ts.map +1 -1
- package/dist/primitives/input.js +4 -1
- package/dist/primitives/input.js.map +1 -1
- package/dist/primitives/scroll-area.js +1 -1
- package/dist/primitives/scroll-area.js.map +1 -1
- package/dist/primitives/select.d.ts.map +1 -1
- package/dist/primitives/select.js +6 -3
- package/dist/primitives/select.js.map +1 -1
- package/dist/primitives/sheet.d.ts +3 -1
- package/dist/primitives/sheet.d.ts.map +1 -1
- package/dist/primitives/sheet.js +17 -7
- package/dist/primitives/sheet.js.map +1 -1
- package/dist/primitives/skeleton.js +1 -1
- package/dist/primitives/skeleton.js.map +1 -1
- package/dist/primitives/switch.d.ts.map +1 -1
- package/dist/primitives/switch.js +2 -1
- package/dist/primitives/switch.js.map +1 -1
- package/dist/primitives/tabs.d.ts.map +1 -1
- package/dist/primitives/tabs.js +5 -3
- package/dist/primitives/tabs.js.map +1 -1
- package/dist/providers/query-provider.d.ts +32 -1
- package/dist/providers/query-provider.d.ts.map +1 -1
- package/dist/providers/query-provider.js +53 -4
- package/dist/providers/query-provider.js.map +1 -1
- package/dist/render-cases-primitives.js +1 -1
- package/dist/render-cases-primitives.js.map +1 -1
- package/dist/render-cases.d.ts.map +1 -1
- package/dist/render-cases.js +48 -6
- package/dist/render-cases.js.map +1 -1
- package/dist/render-effects.d.ts +42 -0
- package/dist/render-effects.d.ts.map +1 -0
- package/dist/render-effects.js +81 -0
- package/dist/render-effects.js.map +1 -0
- package/dist/render-scan.d.ts +25 -0
- package/dist/render-scan.d.ts.map +1 -0
- package/dist/render-scan.js +66 -0
- package/dist/render-scan.js.map +1 -0
- package/dist/theme/cd-tokens.d.ts +66 -0
- package/dist/theme/cd-tokens.d.ts.map +1 -0
- package/dist/theme/cd-tokens.js +64 -0
- package/dist/theme/cd-tokens.js.map +1 -0
- package/dist/theme/create-theme.d.ts +214 -39
- package/dist/theme/create-theme.d.ts.map +1 -1
- package/dist/theme/create-theme.js +204 -13
- package/dist/theme/create-theme.js.map +1 -1
- package/dist/theme/fonts.d.ts +38 -0
- package/dist/theme/fonts.d.ts.map +1 -0
- package/dist/theme/fonts.js +56 -0
- package/dist/theme/fonts.js.map +1 -0
- package/dist/theme/host-fonts.d.ts +39 -0
- package/dist/theme/host-fonts.d.ts.map +1 -0
- package/dist/theme/host-fonts.js +44 -0
- package/dist/theme/host-fonts.js.map +1 -0
- package/dist/theme/index.d.ts +8 -1
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/theme/index.js +5 -1
- package/dist/theme/index.js.map +1 -1
- package/dist/theme/portal-container.d.ts +16 -0
- package/dist/theme/portal-container.d.ts.map +1 -0
- package/dist/theme/portal-container.js +19 -0
- package/dist/theme/portal-container.js.map +1 -0
- package/dist/theme/presets.d.ts +24 -9
- package/dist/theme/presets.d.ts.map +1 -1
- package/dist/theme/presets.js +44 -11
- package/dist/theme/presets.js.map +1 -1
- package/dist/theme/theme-provider.d.ts +27 -9
- package/dist/theme/theme-provider.d.ts.map +1 -1
- package/dist/theme/theme-provider.js +42 -20
- package/dist/theme/theme-provider.js.map +1 -1
- package/package.json +11 -5
- package/src/app/adapt-data-widget.tsx +2 -42
- package/src/app/builder/BuilderBanners.tsx +26 -13
- package/src/app/builder/CanvasRow.tsx +79 -32
- package/src/app/builder/CatalogueSheet.tsx +58 -35
- package/src/app/builder/CellPropsSheet.tsx +17 -2
- package/src/app/builder/DiscardDialog.tsx +59 -0
- package/src/app/builder/EmptyHint.tsx +16 -11
- package/src/app/builder/LayoutSurface.tsx +207 -67
- package/src/app/builder/PipelineStrip.tsx +265 -156
- package/src/app/builder/SaveDialog.tsx +25 -14
- package/src/app/builder/Toolbar.tsx +154 -57
- package/src/app/builder/Workspace.tsx +226 -56
- package/src/app/builder/builder-feedback.test.tsx +75 -0
- package/src/app/builder/builder-model.test.ts +5 -0
- package/src/app/builder/builder-model.ts +346 -6
- package/src/app/builder/builder-model.ux.test.ts +456 -0
- package/src/app/builder/builder-ux.test.tsx +844 -0
- package/src/app/builder/labels.ts +15 -121
- package/src/app/builder/reveal.ts +10 -0
- package/src/app/builder/status-chip.tsx +8 -4
- package/src/app/builder/use-builder-catalogue.ts +62 -19
- package/src/app/builder/use-builder-session.ts +68 -0
- package/src/app/builder/use-display-resolver.ts +24 -0
- package/src/app/builder/use-save-dashboard.ts +5 -0
- package/src/app/index.ts +20 -3
- package/src/app/layout-builder.tsx +193 -186
- package/src/app/mcp-app-view-chrome.test.tsx +487 -14
- package/src/app/mcp-app-view-chrome.tsx +328 -100
- package/src/app/mcp-app-view-states.tsx +140 -0
- package/src/app/mcp-app-view.effects.test.tsx +292 -0
- package/src/app/mcp-app-view.test.tsx +478 -0
- package/src/app/mcp-app-view.tsx +447 -190
- package/src/app/mcp-toolkit-app.test.tsx +40 -0
- package/src/app/mcp-toolkit-app.tsx +39 -8
- package/src/app/mcp-use-host-bridge.test.tsx +180 -0
- package/src/app/mcp-use-host-bridge.tsx +67 -24
- package/src/app/model-context.test.tsx +116 -0
- package/src/app/model-context.tsx +125 -0
- package/src/app/use-build-mode-focus.ts +62 -0
- package/src/app/use-view-actions.ts +89 -0
- package/src/app/use-view-lifecycle.ts +122 -0
- package/src/app/view-lifecycle.test.ts +443 -0
- package/src/app/view-lifecycle.ts +334 -0
- package/src/app/widget-fixture.effects.test.tsx +51 -0
- package/src/app/widget-fixture.render.test.tsx +81 -0
- package/src/app/widget-fixture.tsx +34 -11
- package/src/app/widget-props-sheet.tsx +67 -39
- package/src/app/widget-renderer.render.test.tsx +131 -0
- package/src/app/widget-renderer.tsx +136 -38
- package/src/components/DrillButton.tsx +24 -10
- package/src/components/EmptyState.tsx +83 -0
- package/src/components/ErrorState.tsx +204 -0
- package/src/components/FilterBar.test.tsx +82 -0
- package/src/components/FilterBar.tsx +56 -27
- package/src/components/GroupCard.tsx +3 -2
- package/src/components/KpiGrid.test.tsx +279 -0
- package/src/components/KpiGrid.tsx +329 -91
- package/src/components/ListFooter.test.tsx +116 -0
- package/src/components/ListFooter.tsx +110 -12
- package/src/components/PagedListFooter.test.tsx +140 -0
- package/src/components/PagedListFooter.tsx +107 -0
- package/src/components/Pills.test.tsx +77 -0
- package/src/components/Pills.tsx +78 -16
- package/src/components/SectionHeading.tsx +9 -3
- package/src/components/Toast.tsx +206 -0
- package/src/components/WidgetHeader.test.tsx +78 -0
- package/src/components/WidgetHeader.tsx +63 -16
- package/src/components/feedback-states.test.tsx +314 -0
- package/src/components/tone-figures.test.tsx +58 -0
- package/src/fonts.css +19 -0
- package/src/globals.css +9 -165
- package/src/hooks/index.ts +6 -3
- package/src/hooks/tool-result-recovery-model.test.ts +744 -0
- package/src/hooks/tool-result-recovery-model.ts +418 -0
- package/src/hooks/use-tool-query.effects.test.tsx +205 -0
- package/src/hooks/use-tool-query.ts +156 -33
- package/src/hooks/use-tool-result-recovery.effects.test.tsx +141 -0
- package/src/hooks/use-tool-result-recovery.test.ts +28 -5
- package/src/hooks/use-tool-result-recovery.ts +101 -131
- package/src/hooks/use-view-data.test.tsx +169 -0
- package/src/hooks/use-view-data.ts +131 -10
- package/src/hooks/use-view-tool-query.ts +25 -19
- package/src/i18n-coverage.test.tsx +425 -0
- package/src/index.ts +102 -13
- package/src/lib/focus-return.test.ts +288 -0
- package/src/lib/focus-return.ts +96 -0
- package/src/lib/focus-ring.ts +20 -0
- package/src/lib/icon-stroke.test.ts +59 -0
- package/src/lib/icon-stroke.ts +13 -0
- package/src/lib/parse-tool-result.test.ts +46 -1
- package/src/lib/parse-tool-result.ts +40 -2
- package/src/lib/toast-model.test.ts +233 -0
- package/src/lib/toast-model.ts +165 -0
- package/src/lib/tone-utils.test.ts +125 -16
- package/src/lib/tone-utils.ts +144 -15
- package/src/lib/tool-query.test.ts +569 -0
- package/src/lib/tool-query.ts +253 -0
- package/src/lib/tool-result-observer.test.ts +296 -0
- package/src/lib/tool-result-observer.ts +211 -0
- package/src/lib/typography.test.ts +45 -0
- package/src/lib/typography.ts +47 -0
- package/src/lib/utils.ts +12 -1
- package/src/locale/index.ts +14 -1
- package/src/locale/locale-provider.test.tsx +87 -0
- package/src/locale/locale-provider.tsx +90 -3
- package/src/locale/message-types.ts +337 -0
- package/src/locale/messages-de.ts +198 -0
- package/src/locale/messages-en.ts +196 -0
- package/src/locale/toolkit-messages.test.ts +349 -0
- package/src/locale/toolkit-messages.ts +143 -0
- package/src/no-hardcoded-copy.test.ts +432 -0
- package/src/primitives/alert.tsx +7 -2
- package/src/primitives/badge.tsx +19 -7
- package/src/primitives/button.tsx +13 -8
- package/src/primitives/card.tsx +4 -4
- package/src/primitives/dialog.tsx +42 -8
- package/src/primitives/input.tsx +5 -3
- package/src/primitives/scroll-area.tsx +1 -1
- package/src/primitives/select.tsx +7 -4
- package/src/primitives/sheet.tsx +33 -6
- package/src/primitives/skeleton.tsx +1 -1
- package/src/primitives/switch.tsx +4 -2
- package/src/primitives/tabs.tsx +9 -6
- package/src/providers/query-provider.test.tsx +154 -0
- package/src/providers/query-provider.tsx +66 -5
- package/src/render-cases-primitives.tsx +1 -1
- package/src/render-cases.tsx +82 -6
- package/src/render-effects.tsx +96 -0
- package/src/render-scan.ts +75 -0
- package/src/theme/cd-tokens.generated.css +48 -0
- package/src/theme/cd-tokens.test.ts +109 -0
- package/src/theme/cd-tokens.ts +67 -0
- package/src/theme/create-theme.test.ts +253 -5
- package/src/theme/create-theme.ts +341 -41
- package/src/theme/fonts.test.ts +85 -0
- package/src/theme/fonts.ts +72 -0
- package/src/theme/host-fonts.test.ts +135 -0
- package/src/theme/host-fonts.ts +52 -0
- package/src/theme/index.ts +15 -1
- package/src/theme/portal-container.ts +20 -0
- package/src/theme/presets.ts +44 -11
- package/src/theme/theme-css.test.ts +619 -0
- package/src/theme/theme-provider.test.tsx +82 -0
- package/src/theme/theme-provider.tsx +60 -24
- package/src/theme.css +344 -0
- package/ui-catalog.json +783 -49
|
@@ -1,26 +1,40 @@
|
|
|
1
1
|
import { useCallback, useMemo, useReducer, useState } from "react"
|
|
2
2
|
import { Eye, Layers, SlidersHorizontal } from "lucide-react"
|
|
3
3
|
import type { LayoutConfig, PipelineStepRef, RowDef, WidgetProps } from "@miragon/mcp-toolkit-core"
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
builderLeave,
|
|
6
|
+
builderSnapshot,
|
|
7
|
+
draftHasCells,
|
|
8
|
+
initDraft,
|
|
9
|
+
sizeToSpan,
|
|
10
|
+
toExitCommit,
|
|
11
|
+
type BuilderExitCommit,
|
|
12
|
+
type BuilderView,
|
|
13
|
+
} from "./builder/builder-model.js"
|
|
5
14
|
import {
|
|
6
15
|
draftReducer,
|
|
7
16
|
initBuilderState,
|
|
8
17
|
type BuilderDraftState,
|
|
9
18
|
} from "./builder/builder-reducer.js"
|
|
10
|
-
import {
|
|
19
|
+
import type { LayoutBuilderLabels } from "./builder/labels.js"
|
|
11
20
|
import { Toolbar } from "./builder/Toolbar.js"
|
|
12
21
|
import { PipelineStrip } from "./builder/PipelineStrip.js"
|
|
13
22
|
import { CatalogueSheet } from "./builder/CatalogueSheet.js"
|
|
14
23
|
import { SaveDialog } from "./builder/SaveDialog.js"
|
|
24
|
+
import { DiscardDialog } from "./builder/DiscardDialog.js"
|
|
15
25
|
import { PreviewPane } from "./builder/PreviewPane.js"
|
|
16
26
|
import { LayoutSurface } from "./builder/LayoutSurface.js"
|
|
17
27
|
import { BuilderBanners } from "./builder/BuilderBanners.js"
|
|
18
28
|
import { EmptyHint } from "./builder/EmptyHint.js"
|
|
19
29
|
import { CellPropsSheet } from "./builder/CellPropsSheet.js"
|
|
20
30
|
import { useBuilderCatalogue } from "./builder/use-builder-catalogue.js"
|
|
31
|
+
import { useBuilderMode, useDraftStatus, useRenameFeedback } from "./builder/use-builder-session.js"
|
|
21
32
|
import { useKeyStepEntries } from "./builder/use-key-step-entries.js"
|
|
22
33
|
import { useSaveDashboard } from "./builder/use-save-dashboard.js"
|
|
23
34
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "../primitives/tabs.js"
|
|
35
|
+
import { ToastProvider, useToast } from "../components/Toast.js"
|
|
36
|
+
import { useToolkitMessages } from "../locale/locale-provider.js"
|
|
37
|
+
import { builderMountFocusTarget, useFocusOnMount } from "./use-build-mode-focus.js"
|
|
24
38
|
import { type WidgetComponent } from "./widget-renderer.js"
|
|
25
39
|
|
|
26
40
|
// -------------------------------------------------------------------------- //
|
|
@@ -48,32 +62,62 @@ export interface LayoutBuilderProps {
|
|
|
48
62
|
labels?: LayoutBuilderLabels
|
|
49
63
|
onSaved?: (result: { id: string; name: string }) => void
|
|
50
64
|
/**
|
|
51
|
-
*
|
|
52
|
-
* the
|
|
53
|
-
* the
|
|
65
|
+
* Leaves the builder. "Apply" calls it WITH the final draft (`commit`) so
|
|
66
|
+
* the parent swaps the just-built layout into its view; "Discard" calls it
|
|
67
|
+
* WITHOUT one, so the parent keeps the view as it was before editing (after
|
|
68
|
+
* a confirmation when the draft changed it). Without `onExit` the builder
|
|
69
|
+
* has no Apply, and Discard resets the draft in place.
|
|
54
70
|
*/
|
|
55
|
-
onExit?: (commit?:
|
|
56
|
-
layout: LayoutConfig
|
|
57
|
-
keys?: Record<string, unknown>
|
|
58
|
-
steps?: PipelineStepRef[]
|
|
59
|
-
title?: string
|
|
60
|
-
context?: {
|
|
61
|
-
keys: Record<string, unknown>
|
|
62
|
-
stepIds: string[]
|
|
63
|
-
stepData: Record<
|
|
64
|
-
string,
|
|
65
|
-
{ data: unknown; keys: Record<string, unknown>; _app: string; _dataType: string }
|
|
66
|
-
>
|
|
67
|
-
errors: { stepId: string; reason: string }[]
|
|
68
|
-
}
|
|
69
|
-
}) => void
|
|
71
|
+
onExit?: (commit?: BuilderExitCommit) => void
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
// -------------------------------------------------------------------------- //
|
|
73
75
|
// Main component
|
|
74
76
|
// -------------------------------------------------------------------------- //
|
|
75
77
|
|
|
76
|
-
|
|
78
|
+
/**
|
|
79
|
+
* The visual view builder. People see widgets and steps by their titles
|
|
80
|
+
* (`title`/`titleKey` of the definitions, else the id); the data sources, the
|
|
81
|
+
* catalogue and the technical ids sit behind "Advanced". "Apply" shows the
|
|
82
|
+
* draft in the view, "Save as dashboard" stores it, "Discard" restores the
|
|
83
|
+
* view as it was. Confirms a successful save with a toast (it mounts a
|
|
84
|
+
* `ToastProvider` when none is above it — inside `McpAppView` it shares the
|
|
85
|
+
* view's). Every caption follows the active locale (`labels` overrides).
|
|
86
|
+
*/
|
|
87
|
+
export function LayoutBuilder(props: LayoutBuilderProps) {
|
|
88
|
+
// Discard without an `onExit` restores the initial props by remounting.
|
|
89
|
+
const [generation, setGeneration] = useState(0)
|
|
90
|
+
const reset = useCallback(() => setGeneration((g) => g + 1), [])
|
|
91
|
+
return (
|
|
92
|
+
<ToastProvider>
|
|
93
|
+
<LayoutBuilderImpl
|
|
94
|
+
key={generation}
|
|
95
|
+
{...props}
|
|
96
|
+
onReset={reset}
|
|
97
|
+
mountFocus={builderMountFocusTarget(generation)}
|
|
98
|
+
/>
|
|
99
|
+
</ToastProvider>
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* The catalog strings, overrides merged; a `labels` override of the deprecated
|
|
105
|
+
* `done` still labels Apply (a catalog override of it already did, in
|
|
106
|
+
* `resolveToolkitMessages`).
|
|
107
|
+
*/
|
|
108
|
+
function useBuilderLabels(labels: LayoutBuilderLabels | undefined): Required<LayoutBuilderLabels> {
|
|
109
|
+
const messages = useToolkitMessages()
|
|
110
|
+
return useMemo(
|
|
111
|
+
() => ({
|
|
112
|
+
...messages.builder,
|
|
113
|
+
...labels,
|
|
114
|
+
apply: labels?.apply ?? labels?.done ?? messages.builder.apply,
|
|
115
|
+
}),
|
|
116
|
+
[messages.builder, labels],
|
|
117
|
+
)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function LayoutBuilderImpl({
|
|
77
121
|
initialLayout,
|
|
78
122
|
title,
|
|
79
123
|
initialKeys,
|
|
@@ -86,14 +130,16 @@ export function LayoutBuilder({
|
|
|
86
130
|
labels,
|
|
87
131
|
onSaved,
|
|
88
132
|
onExit,
|
|
89
|
-
|
|
90
|
-
|
|
133
|
+
onReset,
|
|
134
|
+
mountFocus,
|
|
135
|
+
}: LayoutBuilderProps & { onReset: () => void; mountFocus: string | null }) {
|
|
136
|
+
const L = useBuilderLabels(labels)
|
|
137
|
+
const toast = useToast()
|
|
138
|
+
|
|
139
|
+
// A reset remounts the builder: the element that had the focus is gone.
|
|
140
|
+
const rootRef = useFocusOnMount<HTMLDivElement>(mountFocus)
|
|
91
141
|
|
|
92
142
|
// ── Draft layout (pure reducer) ─────────────────────────────────────────
|
|
93
|
-
// The draft plus the UI indices coupled to draft mutations
|
|
94
|
-
// (activeTabIndex / focusedRowIndex / editingTabIdx) live in a single pure
|
|
95
|
-
// reducer (see ./builder/builder-reducer.ts) so every mutation is testable
|
|
96
|
-
// and the old setState-in-updater pattern is gone.
|
|
97
143
|
const [builderState, dispatch] = useReducer(
|
|
98
144
|
draftReducer,
|
|
99
145
|
initialLayout,
|
|
@@ -111,63 +157,28 @@ export function LayoutBuilder({
|
|
|
111
157
|
const setEditingTabIdx = useCallback((idx: number | null) => {
|
|
112
158
|
dispatch(idx === null ? { type: "stopEditingTab" } : { type: "startEditingTab", tabIdx: idx })
|
|
113
159
|
}, [])
|
|
114
|
-
const
|
|
160
|
+
const { advanced, view, setView, toggleAdvanced, openDataSources } = useBuilderMode()
|
|
115
161
|
const [catalogueOpen, setCatalogueOpen] = useState(false)
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
// The reducer rejects duplicate tab labels and bumps `renameRejectedAt`
|
|
119
|
-
// (Phase 1 signal). Mirror each bump into a transient flag so the rename
|
|
120
|
-
// input can show "name already exists" inline (Finding [3]). Tracked via
|
|
121
|
-
// the render-phase setState pattern used elsewhere in this codebase; cleared
|
|
122
|
-
// when the inline editor closes (editingTabIdx → null).
|
|
123
|
-
const [renameRejected, setRenameRejected] = useState(false)
|
|
124
|
-
const [prevRenameRejectedAt, setPrevRenameRejectedAt] = useState(renameRejectedAt)
|
|
125
|
-
if (renameRejectedAt !== prevRenameRejectedAt) {
|
|
126
|
-
setPrevRenameRejectedAt(renameRejectedAt)
|
|
127
|
-
setRenameRejected(true)
|
|
128
|
-
}
|
|
129
|
-
const [prevEditingTabIdx, setPrevEditingTabIdx] = useState(editingTabIdx)
|
|
130
|
-
if (editingTabIdx !== prevEditingTabIdx) {
|
|
131
|
-
setPrevEditingTabIdx(editingTabIdx)
|
|
132
|
-
if (editingTabIdx === null) setRenameRejected(false)
|
|
133
|
-
}
|
|
162
|
+
const [discardOpen, setDiscardOpen] = useState(false)
|
|
163
|
+
const renameRejected = useRenameFeedback(renameRejectedAt, editingTabIdx)
|
|
134
164
|
|
|
135
165
|
// ── Keys + steps editor state ───────────────────────────────────────────
|
|
136
166
|
const { keyEntries, stepEntries, addKey, updateKey, removeKey, addStep, updateStep, removeStep } =
|
|
137
167
|
useKeyStepEntries({ initialKeys, initialSteps })
|
|
138
168
|
|
|
169
|
+
// ── Draft status: what Apply / Discard / the unsaved marker compare ─────
|
|
170
|
+
const snapshot = useMemo(
|
|
171
|
+
() => builderSnapshot(draft, keyEntries, stepEntries),
|
|
172
|
+
[draft, keyEntries, stepEntries],
|
|
173
|
+
)
|
|
174
|
+
const draftState = useDraftStatus(snapshot)
|
|
175
|
+
|
|
139
176
|
// ── Catalogue fetch (mount + on key/step edits) ─────────────────────────
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const {
|
|
143
|
-
liveReachable,
|
|
144
|
-
liveUnreachable,
|
|
145
|
-
liveCatalog,
|
|
146
|
-
liveSteps,
|
|
147
|
-
liveContext,
|
|
148
|
-
validationIssues,
|
|
149
|
-
status,
|
|
150
|
-
refreshError,
|
|
151
|
-
widgetById,
|
|
152
|
-
propsSchemaByWidgetId,
|
|
153
|
-
paletteByApp,
|
|
154
|
-
liveKeyCount,
|
|
155
|
-
stepsByApp,
|
|
156
|
-
} = useBuilderCatalogue({ callTool, catalogueToolName, keyEntries, stepEntries })
|
|
177
|
+
const catalogue = useBuilderCatalogue({ callTool, catalogueToolName, keyEntries, stepEntries })
|
|
178
|
+
const { liveReachable, liveCatalog, liveContext, widgetById } = catalogue
|
|
157
179
|
|
|
158
180
|
// ── Save dialog ─────────────────────────────────────────────────────────
|
|
159
|
-
const {
|
|
160
|
-
isBusy,
|
|
161
|
-
saveOpen,
|
|
162
|
-
setSaveOpen,
|
|
163
|
-
saveName,
|
|
164
|
-
setSaveName,
|
|
165
|
-
saveDescription,
|
|
166
|
-
setSaveDescription,
|
|
167
|
-
saveError,
|
|
168
|
-
setSaveError,
|
|
169
|
-
saveDraft,
|
|
170
|
-
} = useSaveDashboard({
|
|
181
|
+
const save = useSaveDashboard({
|
|
171
182
|
callTool,
|
|
172
183
|
saveToolName,
|
|
173
184
|
dashboardId,
|
|
@@ -176,16 +187,14 @@ export function LayoutBuilder({
|
|
|
176
187
|
stepEntries,
|
|
177
188
|
draft,
|
|
178
189
|
onSaved,
|
|
190
|
+
onSuccess: (name) => {
|
|
191
|
+
draftState.markSaved(snapshot)
|
|
192
|
+
toast.show({ tone: "success", title: L.saved(name) })
|
|
193
|
+
},
|
|
179
194
|
})
|
|
180
195
|
|
|
181
|
-
// ── DnD
|
|
196
|
+
// ── DnD + the cell whose props are being configured ─────────────────────
|
|
182
197
|
const [dragOverRow, setDragOverRow] = useState<number | null>(null)
|
|
183
|
-
|
|
184
|
-
// Which cell (if any) is having its props configured. The
|
|
185
|
-
// WidgetPropsSheet is mounted once at the LayoutBuilder root so that
|
|
186
|
-
// exactly one editor can be open at a time across the entire workspace
|
|
187
|
-
// — including across tabs. Stored as `{ rowIdx, cellIdx }` against the
|
|
188
|
-
// currently active draft surface (rows or active tab's rows).
|
|
189
198
|
const [configuringCell, setConfiguringCell] = useState<{
|
|
190
199
|
rowIdx: number
|
|
191
200
|
cellIdx: number
|
|
@@ -208,47 +217,34 @@ export function LayoutBuilder({
|
|
|
208
217
|
},
|
|
209
218
|
[widgetById],
|
|
210
219
|
)
|
|
211
|
-
|
|
212
220
|
const addRow = useCallback(() => dispatch({ type: "addRow" }), [])
|
|
213
|
-
|
|
214
221
|
const removeRow = useCallback((rowIdx: number) => dispatch({ type: "removeRow", rowIdx }), [])
|
|
215
|
-
|
|
216
222
|
const moveRow = useCallback(
|
|
217
223
|
(rowIdx: number, direction: -1 | 1) => dispatch({ type: "moveRow", rowIdx, direction }),
|
|
218
224
|
[],
|
|
219
225
|
)
|
|
220
|
-
|
|
221
226
|
const setCellSpan = useCallback(
|
|
222
227
|
(rowIdx: number, cellIdx: number, span: number) =>
|
|
223
228
|
dispatch({ type: "setCellSpan", rowIdx, cellIdx, span }),
|
|
224
229
|
[],
|
|
225
230
|
)
|
|
226
|
-
|
|
227
231
|
const removeCell = useCallback(
|
|
228
232
|
(rowIdx: number, cellIdx: number) => dispatch({ type: "removeCell", rowIdx, cellIdx }),
|
|
229
233
|
[],
|
|
230
234
|
)
|
|
231
|
-
|
|
232
|
-
//
|
|
233
|
-
// a cell. Triggered by the WidgetPropsSheet's Apply button. Storing
|
|
234
|
-
// `undefined` rather than `{}` keeps the saved layout's wire format
|
|
235
|
-
// identical to one a hand-coded LLM call would produce — the field is
|
|
236
|
-
// simply absent.
|
|
235
|
+
// Sets (or clears, when `next` is undefined) a cell's per-instance `props`
|
|
236
|
+
// from the props sheet's Apply; `undefined` keeps the field absent on the wire.
|
|
237
237
|
const setCellProps = useCallback(
|
|
238
238
|
(rowIdx: number, cellIdx: number, next: Record<string, unknown> | undefined) =>
|
|
239
239
|
dispatch({ type: "setCellProps", rowIdx, cellIdx, next }),
|
|
240
240
|
[],
|
|
241
241
|
)
|
|
242
|
-
|
|
243
242
|
const addTab = useCallback(() => dispatch({ type: "addTab" }), [])
|
|
244
|
-
|
|
245
|
-
//
|
|
246
|
-
//
|
|
247
|
-
// collides with another tab so the reducer's rejection (`renameRejectedAt`)
|
|
248
|
-
// can drive the inline "name already exists" feedback instead of the editor
|
|
249
|
-
// silently snapping shut on the old label.
|
|
243
|
+
// Commit an inline tab rename. A label that collides with another tab keeps
|
|
244
|
+
// the editor open (the reducer's rejection drives the inline error); the
|
|
245
|
+
// return value tells the field whether it closed.
|
|
250
246
|
const commitRename = useCallback(
|
|
251
|
-
(tabIdx: number, label: string) => {
|
|
247
|
+
(tabIdx: number, label: string): boolean => {
|
|
252
248
|
dispatch({ type: "renameTab", tabIdx, label })
|
|
253
249
|
const trimmed = label.trim()
|
|
254
250
|
const isDuplicate =
|
|
@@ -256,10 +252,10 @@ export function LayoutBuilder({
|
|
|
256
252
|
trimmed.length > 0 &&
|
|
257
253
|
draft.tabs.some((t, i) => i !== tabIdx && t.label === trimmed)
|
|
258
254
|
if (!isDuplicate) setEditingTabIdx(null)
|
|
255
|
+
return !isDuplicate
|
|
259
256
|
},
|
|
260
257
|
[draft, setEditingTabIdx],
|
|
261
258
|
)
|
|
262
|
-
|
|
263
259
|
const removeTab = useCallback((tabIdx: number) => dispatch({ type: "removeTab", tabIdx }), [])
|
|
264
260
|
|
|
265
261
|
// ── Smart action: add a producing step for a missing key ────────────────
|
|
@@ -272,86 +268,77 @@ export function LayoutBuilder({
|
|
|
272
268
|
[addStep, liveCatalog],
|
|
273
269
|
)
|
|
274
270
|
|
|
271
|
+
// ── Leaving: Apply commits, Discard restores (asking first when the view loses changes) ─
|
|
272
|
+
const leave = builderLeave({
|
|
273
|
+
changed: draftState.changed,
|
|
274
|
+
onExit,
|
|
275
|
+
onReset,
|
|
276
|
+
commit: () => toExitCommit(draft, keyEntries, stepEntries, title, liveContext),
|
|
277
|
+
confirm: () => setDiscardOpen(true),
|
|
278
|
+
})
|
|
279
|
+
|
|
275
280
|
const widgetProps: WidgetProps = useMemo(
|
|
276
281
|
() => ({ keys: liveContext.keys, context: liveContext }),
|
|
277
282
|
[liveContext],
|
|
278
283
|
)
|
|
279
|
-
const hasAnyCell =
|
|
280
|
-
const liveKeysMap = liveContext.keys
|
|
284
|
+
const hasAnyCell = draftHasCells(draft)
|
|
281
285
|
|
|
282
286
|
return (
|
|
283
|
-
<div className="flex min-h-[60vh] flex-col gap-4 p-1">
|
|
287
|
+
<div ref={rootRef} className="flex min-h-[60vh] flex-col gap-4 p-1">
|
|
284
288
|
<Toolbar
|
|
285
289
|
L={L}
|
|
286
290
|
previewMode={view === "preview"}
|
|
287
|
-
isBusy={isBusy}
|
|
288
|
-
status={status}
|
|
289
|
-
liveKeys={liveKeyCount}
|
|
291
|
+
isBusy={save.isBusy}
|
|
292
|
+
status={catalogue.status}
|
|
293
|
+
liveKeys={catalogue.liveKeyCount}
|
|
290
294
|
reachableCount={liveReachable.length}
|
|
291
|
-
unreachableCount={liveUnreachable.length}
|
|
295
|
+
unreachableCount={catalogue.liveUnreachable.length}
|
|
296
|
+
advanced={advanced}
|
|
297
|
+
onToggleAdvanced={toggleAdvanced}
|
|
298
|
+
unsaved={draftState.unsaved}
|
|
292
299
|
onOpenCatalogue={() => setCatalogueOpen(true)}
|
|
293
|
-
onOpenSave={() => setSaveOpen(true)}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
? () =>
|
|
297
|
-
onExit({
|
|
298
|
-
layout: draftToLayout(draft),
|
|
299
|
-
keys: entriesToKeys(keyEntries),
|
|
300
|
-
steps: stepEntries.filter((s) => s.step.trim().length > 0),
|
|
301
|
-
title,
|
|
302
|
-
context: {
|
|
303
|
-
keys: liveContext.keys,
|
|
304
|
-
stepIds: Object.keys(liveContext.steps),
|
|
305
|
-
stepData: Object.fromEntries(
|
|
306
|
-
Object.entries(liveContext.steps).map(([id, result]) => [
|
|
307
|
-
id,
|
|
308
|
-
{
|
|
309
|
-
data: result.data,
|
|
310
|
-
keys: result.keys,
|
|
311
|
-
_app: result._app,
|
|
312
|
-
_dataType: result._dataType,
|
|
313
|
-
},
|
|
314
|
-
]),
|
|
315
|
-
),
|
|
316
|
-
errors: liveContext.errors,
|
|
317
|
-
},
|
|
318
|
-
})
|
|
319
|
-
: undefined
|
|
320
|
-
}
|
|
300
|
+
onOpenSave={() => save.setSaveOpen(true)}
|
|
301
|
+
onDiscard={leave.discard}
|
|
302
|
+
onApply={leave.apply}
|
|
321
303
|
hasAnyCell={hasAnyCell}
|
|
322
304
|
/>
|
|
323
305
|
|
|
324
306
|
<BuilderBanners
|
|
325
307
|
L={L}
|
|
326
308
|
catalogueToolName={catalogueToolName}
|
|
327
|
-
refreshError={refreshError}
|
|
328
|
-
validationIssues={validationIssues}
|
|
309
|
+
refreshError={catalogue.refreshError}
|
|
310
|
+
validationIssues={catalogue.validationIssues}
|
|
311
|
+
onRetry={catalogue.retryCatalogue}
|
|
329
312
|
/>
|
|
330
313
|
|
|
331
|
-
<Tabs value={view} onValueChange={(v) => setView(v as
|
|
314
|
+
<Tabs value={view} onValueChange={(v) => setView(v as BuilderView)}>
|
|
332
315
|
<TabsList>
|
|
333
316
|
<TabsTrigger value="layout">
|
|
334
|
-
<Layers className="size-3.5" />
|
|
317
|
+
<Layers aria-hidden="true" className="size-3.5" />
|
|
335
318
|
{L.viewLayoutTab}
|
|
336
319
|
</TabsTrigger>
|
|
337
|
-
|
|
338
|
-
<
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
320
|
+
{advanced && (
|
|
321
|
+
<TabsTrigger value="pipeline">
|
|
322
|
+
<SlidersHorizontal aria-hidden="true" className="size-3.5" />
|
|
323
|
+
{L.viewPipelineTab}
|
|
324
|
+
{(keyEntries.length > 0 || stepEntries.length > 0) && (
|
|
325
|
+
<span className="bg-muted text-muted-foreground text-small ml-1 rounded px-1 tabular-nums">
|
|
326
|
+
{keyEntries.length}/{stepEntries.length}
|
|
327
|
+
</span>
|
|
328
|
+
)}
|
|
329
|
+
</TabsTrigger>
|
|
330
|
+
)}
|
|
346
331
|
<TabsTrigger value="preview" disabled={!hasAnyCell}>
|
|
347
|
-
<Eye className="size-3.5" />
|
|
332
|
+
<Eye aria-hidden="true" className="size-3.5" />
|
|
348
333
|
{L.viewPreviewTab}
|
|
349
334
|
</TabsTrigger>
|
|
350
335
|
</TabsList>
|
|
351
336
|
|
|
352
337
|
<TabsContent value="layout" className="mt-4">
|
|
353
|
-
{
|
|
354
|
-
|
|
338
|
+
{/* Until the catalogue answers, the palette shows a loading state
|
|
339
|
+
(an empty state now would flash on every open). */}
|
|
340
|
+
{catalogue.loaded && liveReachable.length === 0 && !hasAnyCell ? (
|
|
341
|
+
<EmptyHint L={L} onGotoPipeline={openDataSources} />
|
|
355
342
|
) : (
|
|
356
343
|
<LayoutSurface
|
|
357
344
|
L={L}
|
|
@@ -366,8 +353,11 @@ export function LayoutBuilder({
|
|
|
366
353
|
onRemoveTab={removeTab}
|
|
367
354
|
workspace={{
|
|
368
355
|
L,
|
|
369
|
-
paletteByApp,
|
|
356
|
+
paletteByApp: catalogue.paletteByApp,
|
|
357
|
+
appDisplayByName: catalogue.appDisplayByName,
|
|
370
358
|
paletteCount: liveReachable.length,
|
|
359
|
+
paletteLoading: !catalogue.loaded,
|
|
360
|
+
onOpenDataSources: openDataSources,
|
|
371
361
|
activeRows,
|
|
372
362
|
focusedRowIndex,
|
|
373
363
|
setFocusedRowIndex,
|
|
@@ -380,7 +370,9 @@ export function LayoutBuilder({
|
|
|
380
370
|
onRemoveCell: removeCell,
|
|
381
371
|
onAddWidget: addWidgetToRow,
|
|
382
372
|
onConfigureCell: (rowIdx, cellIdx) => setConfiguringCell({ rowIdx, cellIdx }),
|
|
383
|
-
propsSchemaByWidgetId,
|
|
373
|
+
propsSchemaByWidgetId: catalogue.propsSchemaByWidgetId,
|
|
374
|
+
displayByWidgetId: catalogue.displayByWidgetId,
|
|
375
|
+
advanced,
|
|
384
376
|
widgets,
|
|
385
377
|
widgetProps,
|
|
386
378
|
}}
|
|
@@ -388,24 +380,26 @@ export function LayoutBuilder({
|
|
|
388
380
|
)}
|
|
389
381
|
</TabsContent>
|
|
390
382
|
|
|
391
|
-
|
|
392
|
-
<
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
383
|
+
{advanced && (
|
|
384
|
+
<TabsContent value="pipeline" className="mt-4">
|
|
385
|
+
<PipelineStrip
|
|
386
|
+
L={L}
|
|
387
|
+
keyEntries={keyEntries}
|
|
388
|
+
stepEntries={stepEntries}
|
|
389
|
+
keyCatalog={liveCatalog}
|
|
390
|
+
availableSteps={catalogue.liveSteps}
|
|
391
|
+
stepsByApp={catalogue.stepsByApp}
|
|
392
|
+
liveKeys={liveContext.keys}
|
|
393
|
+
onAddKey={addKey}
|
|
394
|
+
onUpdateKey={updateKey}
|
|
395
|
+
onRemoveKey={removeKey}
|
|
396
|
+
onAddStep={addStep}
|
|
397
|
+
onUpdateStep={updateStep}
|
|
398
|
+
onRemoveStep={removeStep}
|
|
399
|
+
status={catalogue.status}
|
|
400
|
+
/>
|
|
401
|
+
</TabsContent>
|
|
402
|
+
)}
|
|
409
403
|
|
|
410
404
|
<TabsContent value="preview" className="mt-4">
|
|
411
405
|
<PreviewPane
|
|
@@ -423,8 +417,8 @@ export function LayoutBuilder({
|
|
|
423
417
|
open={catalogueOpen}
|
|
424
418
|
onOpenChange={setCatalogueOpen}
|
|
425
419
|
keyCatalog={liveCatalog}
|
|
426
|
-
availableSteps={liveSteps}
|
|
427
|
-
unreachableWidgets={liveUnreachable}
|
|
420
|
+
availableSteps={catalogue.liveSteps}
|
|
421
|
+
unreachableWidgets={catalogue.liveUnreachable}
|
|
428
422
|
onSeedKey={(name) => {
|
|
429
423
|
addKey(name)
|
|
430
424
|
setCatalogueOpen(false)
|
|
@@ -439,26 +433,39 @@ export function LayoutBuilder({
|
|
|
439
433
|
|
|
440
434
|
<SaveDialog
|
|
441
435
|
L={L}
|
|
442
|
-
open={saveOpen}
|
|
436
|
+
open={save.saveOpen}
|
|
437
|
+
canApply={onExit !== undefined}
|
|
443
438
|
onOpenChange={(open) => {
|
|
444
439
|
// Clear any stale save error whenever the dialog is opened or
|
|
445
440
|
// dismissed so a fresh attempt starts clean.
|
|
446
|
-
setSaveError(null)
|
|
447
|
-
setSaveOpen(open)
|
|
441
|
+
save.setSaveError(null)
|
|
442
|
+
save.setSaveOpen(open)
|
|
443
|
+
}}
|
|
444
|
+
name={save.saveName}
|
|
445
|
+
setName={save.setSaveName}
|
|
446
|
+
description={save.saveDescription}
|
|
447
|
+
setDescription={save.setSaveDescription}
|
|
448
|
+
onSubmit={save.saveDraft}
|
|
449
|
+
busy={save.isBusy}
|
|
450
|
+
error={save.saveError}
|
|
451
|
+
/>
|
|
452
|
+
|
|
453
|
+
<DiscardDialog
|
|
454
|
+
L={L}
|
|
455
|
+
open={discardOpen}
|
|
456
|
+
onOpenChange={setDiscardOpen}
|
|
457
|
+
changesSaved={!draftState.unsaved}
|
|
458
|
+
onConfirm={() => {
|
|
459
|
+
setDiscardOpen(false)
|
|
460
|
+
leave.discardNow()
|
|
448
461
|
}}
|
|
449
|
-
name={saveName}
|
|
450
|
-
setName={setSaveName}
|
|
451
|
-
description={saveDescription}
|
|
452
|
-
setDescription={setSaveDescription}
|
|
453
|
-
onSubmit={saveDraft}
|
|
454
|
-
busy={isBusy}
|
|
455
|
-
error={saveError}
|
|
456
462
|
/>
|
|
457
463
|
|
|
458
464
|
<CellPropsSheet
|
|
459
465
|
configuringCell={configuringCell}
|
|
460
466
|
activeRows={activeRows}
|
|
461
|
-
propsSchemaByWidgetId={propsSchemaByWidgetId}
|
|
467
|
+
propsSchemaByWidgetId={catalogue.propsSchemaByWidgetId}
|
|
468
|
+
displayByWidgetId={catalogue.displayByWidgetId}
|
|
462
469
|
onApply={setCellProps}
|
|
463
470
|
onClose={() => setConfiguringCell(null)}
|
|
464
471
|
/>
|