@miragon/mcp-toolkit-ui 2.7.0 → 2.8.1
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 +7 -4
- 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.js +1 -1
- 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 +21 -7
- 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 +11 -4
- 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/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 +2 -1
- package/dist/app/builder/PipelineStrip.d.ts.map +1 -1
- package/dist/app/builder/PipelineStrip.js +26 -13
- 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 +8 -2
- package/dist/app/builder/SaveDialog.js.map +1 -1
- package/dist/app/builder/Toolbar.d.ts +12 -4
- package/dist/app/builder/Toolbar.d.ts.map +1 -1
- package/dist/app/builder/Toolbar.js +18 -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 +143 -1
- package/dist/app/builder/builder-model.d.ts.map +1 -1
- package/dist/app/builder/builder-model.js +191 -1
- package/dist/app/builder/builder-model.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/use-builder-catalogue.d.ts +4 -1
- package/dist/app/builder/use-builder-catalogue.d.ts.map +1 -1
- package/dist/app/builder/use-builder-catalogue.js +44 -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/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 +13 -25
- package/dist/app/layout-builder.d.ts.map +1 -1
- package/dist/app/layout-builder.js +75 -81
- package/dist/app/layout-builder.js.map +1 -1
- package/dist/app/mcp-app-view-chrome.d.ts +12 -3
- package/dist/app/mcp-app-view-chrome.d.ts.map +1 -1
- package/dist/app/mcp-app-view-chrome.js +21 -5
- package/dist/app/mcp-app-view-chrome.js.map +1 -1
- package/dist/app/mcp-app-view-states.d.ts +11 -3
- package/dist/app/mcp-app-view-states.d.ts.map +1 -1
- package/dist/app/mcp-app-view-states.js +29 -8
- package/dist/app/mcp-app-view-states.js.map +1 -1
- package/dist/app/mcp-app-view.d.ts +33 -1
- package/dist/app/mcp-app-view.d.ts.map +1 -1
- package/dist/app/mcp-app-view.js +181 -127
- package/dist/app/mcp-app-view.js.map +1 -1
- package/dist/app/mcp-toolkit-app.d.ts +6 -1
- package/dist/app/mcp-toolkit-app.d.ts.map +1 -1
- package/dist/app/mcp-toolkit-app.js +8 -1
- 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 +4 -0
- package/dist/app/use-view-lifecycle.d.ts.map +1 -1
- package/dist/app/use-view-lifecycle.js +2 -0
- package/dist/app/use-view-lifecycle.js.map +1 -1
- package/dist/app/view-lifecycle.d.ts +80 -4
- package/dist/app/view-lifecycle.d.ts.map +1 -1
- package/dist/app/view-lifecycle.js +90 -3
- package/dist/app/view-lifecycle.js.map +1 -1
- 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 +3 -1
- package/dist/app/widget-props-sheet.d.ts.map +1 -1
- package/dist/app/widget-props-sheet.js +22 -10
- package/dist/app/widget-props-sheet.js.map +1 -1
- package/dist/app/widget-renderer.js +1 -1
- package/dist/app/widget-renderer.js.map +1 -1
- package/dist/components/DrillButton.d.ts +14 -6
- package/dist/components/DrillButton.d.ts.map +1 -1
- package/dist/components/DrillButton.js +14 -7
- package/dist/components/DrillButton.js.map +1 -1
- package/dist/components/EmptyState.d.ts.map +1 -1
- package/dist/components/EmptyState.js +4 -2
- package/dist/components/EmptyState.js.map +1 -1
- package/dist/components/ErrorState.d.ts +5 -2
- package/dist/components/ErrorState.d.ts.map +1 -1
- package/dist/components/ErrorState.js +25 -8
- package/dist/components/ErrorState.js.map +1 -1
- package/dist/components/FilterBar.d.ts +15 -4
- package/dist/components/FilterBar.d.ts.map +1 -1
- package/dist/components/FilterBar.js +11 -6
- package/dist/components/FilterBar.js.map +1 -1
- package/dist/components/KpiGrid.d.ts +66 -21
- package/dist/components/KpiGrid.d.ts.map +1 -1
- package/dist/components/KpiGrid.js +101 -34
- package/dist/components/KpiGrid.js.map +1 -1
- package/dist/components/ListFooter.d.ts +31 -4
- package/dist/components/ListFooter.d.ts.map +1 -1
- package/dist/components/ListFooter.js +30 -11
- 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 +27 -7
- package/dist/components/Pills.d.ts.map +1 -1
- package/dist/components/Pills.js +21 -6
- 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 +9 -3
- package/dist/components/Toast.d.ts.map +1 -1
- package/dist/components/Toast.js +31 -16
- package/dist/components/Toast.js.map +1 -1
- 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 +47 -52
- package/dist/hooks/use-tool-result-recovery.d.ts.map +1 -1
- package/dist/hooks/use-tool-result-recovery.js +58 -120
- package/dist/hooks/use-tool-result-recovery.js.map +1 -1
- package/dist/hooks/use-view-data.d.ts +52 -10
- package/dist/hooks/use-view-data.d.ts.map +1 -1
- package/dist/hooks/use-view-data.js +81 -16
- 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 +17 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -6
- 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/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 +41 -1
- package/dist/lib/toast-model.d.ts.map +1 -1
- package/dist/lib/toast-model.js +67 -1
- package/dist/lib/toast-model.js.map +1 -1
- package/dist/lib/tone-utils.d.ts +58 -6
- package/dist/lib/tone-utils.d.ts.map +1 -1
- package/dist/lib/tone-utils.js +66 -4
- 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 +1 -1
- package/dist/locale/index.d.ts.map +1 -1
- package/dist/locale/message-types.d.ts +117 -4
- package/dist/locale/message-types.d.ts.map +1 -1
- package/dist/locale/messages-de.d.ts.map +1 -1
- package/dist/locale/messages-de.js +44 -10
- package/dist/locale/messages-de.js.map +1 -1
- package/dist/locale/messages-en.d.ts.map +1 -1
- package/dist/locale/messages-en.js +44 -10
- package/dist/locale/messages-en.js.map +1 -1
- package/dist/locale/toolkit-messages.d.ts +19 -1
- package/dist/locale/toolkit-messages.d.ts.map +1 -1
- package/dist/locale/toolkit-messages.js +54 -1
- package/dist/locale/toolkit-messages.js.map +1 -1
- package/dist/primitives/alert.d.ts +1 -1
- package/dist/primitives/alert.d.ts.map +1 -1
- package/dist/primitives/alert.js +2 -0
- 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 +9 -4
- package/dist/primitives/badge.js.map +1 -1
- package/dist/primitives/button.d.ts +1 -1
- package/dist/primitives/button.js +1 -1
- package/dist/primitives/button.js.map +1 -1
- package/dist/primitives/dialog.d.ts +1 -1
- package/dist/primitives/dialog.d.ts.map +1 -1
- package/dist/primitives/dialog.js +10 -3
- package/dist/primitives/dialog.js.map +1 -1
- package/dist/primitives/select.js +1 -1
- package/dist/primitives/select.js.map +1 -1
- package/dist/primitives/sheet.d.ts +1 -1
- package/dist/primitives/sheet.d.ts.map +1 -1
- package/dist/primitives/sheet.js +6 -2
- package/dist/primitives/sheet.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 +30 -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/theme/create-theme.d.ts +19 -1
- package/dist/theme/create-theme.d.ts.map +1 -1
- package/dist/theme/create-theme.js +15 -0
- package/dist/theme/create-theme.js.map +1 -1
- package/package.json +5 -4
- package/src/app/adapt-data-widget.tsx +2 -42
- package/src/app/builder/BuilderBanners.tsx +1 -1
- package/src/app/builder/CanvasRow.tsx +63 -17
- package/src/app/builder/CatalogueSheet.tsx +50 -29
- package/src/app/builder/CellPropsSheet.tsx +17 -2
- package/src/app/builder/DiscardDialog.tsx +59 -0
- package/src/app/builder/LayoutSurface.tsx +206 -66
- package/src/app/builder/PipelineStrip.tsx +253 -153
- package/src/app/builder/SaveDialog.tsx +14 -2
- package/src/app/builder/Toolbar.tsx +144 -59
- package/src/app/builder/Workspace.tsx +226 -58
- package/src/app/builder/builder-model.ts +341 -2
- 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/reveal.ts +10 -0
- package/src/app/builder/use-builder-catalogue.ts +56 -19
- package/src/app/builder/use-builder-session.ts +68 -0
- package/src/app/builder/use-display-resolver.ts +24 -0
- package/src/app/index.ts +12 -2
- package/src/app/layout-builder.tsx +178 -191
- package/src/app/mcp-app-view-chrome.test.tsx +141 -1
- package/src/app/mcp-app-view-chrome.tsx +56 -6
- package/src/app/mcp-app-view-states.tsx +51 -11
- package/src/app/mcp-app-view.effects.test.tsx +292 -0
- package/src/app/mcp-app-view.test.tsx +222 -2
- package/src/app/mcp-app-view.tsx +267 -117
- package/src/app/mcp-toolkit-app.test.tsx +40 -0
- package/src/app/mcp-toolkit-app.tsx +8 -1
- 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 +6 -0
- package/src/app/view-lifecycle.test.ts +216 -0
- package/src/app/view-lifecycle.ts +165 -5
- 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 +57 -16
- package/src/app/widget-renderer.tsx +1 -1
- package/src/components/DrillButton.test.tsx +48 -0
- package/src/components/DrillButton.tsx +26 -11
- package/src/components/EmptyState.tsx +6 -4
- package/src/components/ErrorState.tsx +31 -9
- package/src/components/FilterBar.test.tsx +82 -0
- package/src/components/FilterBar.tsx +52 -26
- package/src/components/KpiGrid.test.tsx +279 -0
- package/src/components/KpiGrid.tsx +297 -90
- package/src/components/ListFooter.test.tsx +116 -0
- package/src/components/ListFooter.tsx +102 -15
- 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 +63 -10
- package/src/components/SectionHeading.tsx +9 -3
- package/src/components/Toast.tsx +37 -19
- package/src/components/WidgetHeader.test.tsx +78 -0
- package/src/components/WidgetHeader.tsx +63 -16
- package/src/components/feedback-states.test.tsx +98 -9
- package/src/components/tone-figures.test.tsx +8 -4
- 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 +3 -4
- package/src/hooks/use-tool-result-recovery.ts +84 -142
- package/src/hooks/use-view-data.test.tsx +118 -9
- package/src/hooks/use-view-data.ts +128 -18
- package/src/hooks/use-view-tool-query.ts +25 -19
- package/src/i18n-coverage.test.tsx +104 -2
- package/src/index.ts +48 -11
- package/src/lib/focus-return.test.ts +288 -0
- package/src/lib/focus-return.ts +96 -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 +166 -1
- package/src/lib/toast-model.ts +104 -2
- package/src/lib/tone-utils.test.ts +86 -10
- package/src/lib/tone-utils.ts +89 -8
- 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 +1 -0
- package/src/locale/message-types.ts +118 -2
- package/src/locale/messages-de.ts +49 -10
- package/src/locale/messages-en.ts +49 -10
- package/src/locale/toolkit-messages.test.ts +133 -0
- package/src/locale/toolkit-messages.ts +63 -2
- package/src/primitives/alert.tsx +3 -0
- package/src/primitives/badge.tsx +9 -4
- package/src/primitives/button.tsx +1 -1
- package/src/primitives/dialog.tsx +10 -1
- package/src/primitives/select.tsx +1 -1
- package/src/primitives/sheet.tsx +7 -0
- 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 +38 -6
- package/src/render-effects.tsx +96 -0
- package/src/theme/cd-tokens.test.ts +3 -1
- package/src/theme/create-theme.test.ts +10 -0
- package/src/theme/create-theme.ts +28 -0
- package/src/theme/theme-css.test.ts +51 -0
- package/src/theme.css +31 -1
- package/ui-catalog.json +448 -41
|
@@ -51,7 +51,7 @@ export function BuilderBanners({
|
|
|
51
51
|
<div
|
|
52
52
|
role="status"
|
|
53
53
|
aria-live="polite"
|
|
54
|
-
className="border-warning bg-warning-soft text-foreground flex items-start gap-2 rounded-md border px-3 py-2
|
|
54
|
+
className="border-warning bg-warning-soft text-foreground text-small flex items-start gap-2 rounded-md border px-3 py-2"
|
|
55
55
|
>
|
|
56
56
|
<AlertTriangle
|
|
57
57
|
className={`mt-0.5 size-3.5 shrink-0 ${TONE_ICON.warning}`}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { memo, useCallback, useRef } from "react"
|
|
2
2
|
import { ChevronDown, ChevronUp, SlidersHorizontal, Trash2, X } from "lucide-react"
|
|
3
|
-
import type { RowDef, WidgetProps } from "@miragon/mcp-toolkit-core"
|
|
3
|
+
import type { DisplayText, RowDef, WidgetProps } from "@miragon/mcp-toolkit-core"
|
|
4
4
|
import { GridItem, GridLayout } from "../../components/GridLayout.js"
|
|
5
5
|
import { Button } from "../../primitives/button.js"
|
|
6
6
|
import {
|
|
@@ -10,10 +10,14 @@ import {
|
|
|
10
10
|
SelectTrigger,
|
|
11
11
|
SelectValue,
|
|
12
12
|
} from "../../primitives/select.js"
|
|
13
|
+
import { FOCUS_RING, FOCUS_RING_INSET } from "../../lib/focus-ring.js"
|
|
13
14
|
import { cn } from "../../lib/utils.js"
|
|
14
15
|
import { RenderedWidget, type WidgetComponent } from "../widget-renderer.js"
|
|
16
|
+
import { displayLabel } from "./builder-model.js"
|
|
15
17
|
import type { LayoutBuilderLabels } from "./labels.js"
|
|
16
18
|
import { WIDGET_DRAG_MIME } from "./labels.js"
|
|
19
|
+
import { REVEAL_ON_INTENT } from "./reveal.js"
|
|
20
|
+
import { useDisplayResolver } from "./use-display-resolver.js"
|
|
17
21
|
|
|
18
22
|
// -------------------------------------------------------------------------- //
|
|
19
23
|
// Canvas row — drop target + per-cell controls + resize handle
|
|
@@ -36,6 +40,8 @@ function CanvasRowImpl({
|
|
|
36
40
|
onAddWidget,
|
|
37
41
|
onConfigureCell,
|
|
38
42
|
propsSchemaByWidgetId,
|
|
43
|
+
displayByWidgetId,
|
|
44
|
+
advanced,
|
|
39
45
|
widgets,
|
|
40
46
|
widgetProps,
|
|
41
47
|
}: {
|
|
@@ -55,14 +61,25 @@ function CanvasRowImpl({
|
|
|
55
61
|
onAddWidget: (widgetId: string, targetRowIdx?: number) => void
|
|
56
62
|
onConfigureCell: (rowIdx: number, cellIdx: number) => void
|
|
57
63
|
propsSchemaByWidgetId: Map<string, Record<string, unknown>>
|
|
64
|
+
displayByWidgetId: Map<string, DisplayText>
|
|
65
|
+
advanced: boolean
|
|
58
66
|
widgets: Record<string, WidgetComponent>
|
|
59
67
|
widgetProps: WidgetProps
|
|
60
68
|
}) {
|
|
61
69
|
const gridRef = useRef<HTMLDivElement | null>(null)
|
|
70
|
+
const { locale, resolveKey } = useDisplayResolver()
|
|
71
|
+
// The target row follows the pointer AND the keyboard: focus moving into a
|
|
72
|
+
// row (its actions, a cell control) makes it the row the palette adds to.
|
|
73
|
+
const target = () => {
|
|
74
|
+
if (!focused) setFocusedRowIndex(rowIdx)
|
|
75
|
+
}
|
|
62
76
|
|
|
63
77
|
return (
|
|
64
78
|
<div
|
|
65
|
-
|
|
79
|
+
data-slot="builder-row"
|
|
80
|
+
data-target={focused ? "" : undefined}
|
|
81
|
+
onClick={target}
|
|
82
|
+
onFocus={target}
|
|
66
83
|
onDragOver={(e) => {
|
|
67
84
|
if (!e.dataTransfer.types.includes(WIDGET_DRAG_MIME)) return
|
|
68
85
|
e.preventDefault()
|
|
@@ -89,14 +106,21 @@ function CanvasRowImpl({
|
|
|
89
106
|
dragOver && "bg-primary/5 border-l-primary",
|
|
90
107
|
)}
|
|
91
108
|
>
|
|
92
|
-
<div className="mb-2 flex items-center justify-between">
|
|
93
|
-
<div className="text-muted-foreground flex items-center gap-2
|
|
94
|
-
<span className="font-
|
|
95
|
-
<span className="bg-muted
|
|
96
|
-
|
|
97
|
-
|
|
109
|
+
<div className="mb-2 flex flex-wrap items-center justify-between gap-2">
|
|
110
|
+
<div className="text-muted-foreground text-small flex flex-wrap items-center gap-2">
|
|
111
|
+
<span className="font-medium">{L.rowLabel(rowIdx + 1)}</span>
|
|
112
|
+
<span className="bg-muted rounded px-1.5 py-0.5">{L.elementCount(row.row.length)}</span>
|
|
113
|
+
{focused && (
|
|
114
|
+
<span className="text-foreground inline-flex items-center gap-1.5">
|
|
115
|
+
<span aria-hidden="true" className="bg-primary size-1.5 rounded-full" />
|
|
116
|
+
{L.rowTarget}
|
|
117
|
+
</span>
|
|
118
|
+
)}
|
|
98
119
|
</div>
|
|
99
|
-
<div
|
|
120
|
+
<div
|
|
121
|
+
data-slot="builder-row-actions"
|
|
122
|
+
className={cn("flex items-center", focused ? "opacity-100" : REVEAL_ON_INTENT)}
|
|
123
|
+
>
|
|
100
124
|
<Button
|
|
101
125
|
variant="ghost"
|
|
102
126
|
size="icon-xs"
|
|
@@ -137,7 +161,7 @@ function CanvasRowImpl({
|
|
|
137
161
|
{row.row.length === 0 ? (
|
|
138
162
|
<div
|
|
139
163
|
className={cn(
|
|
140
|
-
"rounded-md border border-dashed py-6 text-center
|
|
164
|
+
"text-small rounded-md border border-dashed py-6 text-center transition-colors",
|
|
141
165
|
dragOver
|
|
142
166
|
? "border-focus bg-accent text-accent-foreground"
|
|
143
167
|
: "border-input text-muted-foreground",
|
|
@@ -153,13 +177,24 @@ function CanvasRowImpl({
|
|
|
153
177
|
const Widget = widgets[cell.widget]
|
|
154
178
|
const hasPropsSchema = propsSchemaByWidgetId.has(cell.widget)
|
|
155
179
|
const propCount = cell.props ? Object.keys(cell.props).length : 0
|
|
180
|
+
const name = displayLabel(
|
|
181
|
+
displayByWidgetId.get(cell.widget) ?? {},
|
|
182
|
+
cell.widget,
|
|
183
|
+
locale,
|
|
184
|
+
resolveKey,
|
|
185
|
+
)
|
|
156
186
|
return (
|
|
157
187
|
<GridItem key={`${cell.widget}-${cellIdx}`} span={span}>
|
|
158
188
|
<div className="border-border bg-card shadow-1 relative overflow-hidden rounded-md border">
|
|
159
|
-
<div className="text-muted-foreground bg-muted/30 flex items-center justify-between gap-2 border-b px-2 py-1
|
|
160
|
-
<span className="
|
|
189
|
+
<div className="text-muted-foreground bg-muted/30 text-small flex items-center justify-between gap-2 border-b px-2 py-1">
|
|
190
|
+
<span className="flex min-w-0 items-baseline gap-2" title={name.hint}>
|
|
191
|
+
<span className="text-foreground truncate font-medium">{name.label}</span>
|
|
192
|
+
{advanced && name.hint && (
|
|
193
|
+
<span className="truncate font-mono">{name.hint}</span>
|
|
194
|
+
)}
|
|
195
|
+
</span>
|
|
161
196
|
<div className="flex shrink-0 items-center gap-2">
|
|
162
|
-
<label className="text-muted-foreground inline-flex items-center gap-0.5
|
|
197
|
+
<label className="text-muted-foreground inline-flex items-center gap-0.5 tabular-nums">
|
|
163
198
|
<span className="sr-only">{L.columnSpan}</span>
|
|
164
199
|
<Select
|
|
165
200
|
value={String(span)}
|
|
@@ -167,7 +202,11 @@ function CanvasRowImpl({
|
|
|
167
202
|
>
|
|
168
203
|
<SelectTrigger
|
|
169
204
|
size="sm"
|
|
170
|
-
className=
|
|
205
|
+
className={cn(
|
|
206
|
+
"text-small h-6 gap-0.5 border-none bg-transparent px-1 py-0 tabular-nums shadow-none",
|
|
207
|
+
// Borderless, so the input focus edge is gone: the kit ring instead.
|
|
208
|
+
FOCUS_RING,
|
|
209
|
+
)}
|
|
171
210
|
aria-label={L.columnSpan}
|
|
172
211
|
onClick={(e) => e.stopPropagation()}
|
|
173
212
|
>
|
|
@@ -175,7 +214,11 @@ function CanvasRowImpl({
|
|
|
175
214
|
</SelectTrigger>
|
|
176
215
|
<SelectContent>
|
|
177
216
|
{Array.from({ length: 12 }, (_, i) => i + 1).map((n) => (
|
|
178
|
-
<SelectItem
|
|
217
|
+
<SelectItem
|
|
218
|
+
key={n}
|
|
219
|
+
value={String(n)}
|
|
220
|
+
className="text-small tabular-nums"
|
|
221
|
+
>
|
|
179
222
|
{n}
|
|
180
223
|
</SelectItem>
|
|
181
224
|
))}
|
|
@@ -220,7 +263,7 @@ function CanvasRowImpl({
|
|
|
220
263
|
props={widgetProps}
|
|
221
264
|
cellProps={cell.props}
|
|
222
265
|
showEmptyHint
|
|
223
|
-
notBundledClassName="text-muted-foreground rounded border border-dashed p-3 text-center text-
|
|
266
|
+
notBundledClassName="text-muted-foreground rounded border border-dashed p-3 text-center text-small"
|
|
224
267
|
/>
|
|
225
268
|
</div>
|
|
226
269
|
<ResizeHandle
|
|
@@ -305,7 +348,10 @@ function ResizeHandle({
|
|
|
305
348
|
onClick={(e) => e.stopPropagation()}
|
|
306
349
|
onKeyDown={onKeyDown}
|
|
307
350
|
tabIndex={0}
|
|
308
|
-
className=
|
|
351
|
+
className={cn(
|
|
352
|
+
"hover:bg-primary/40 focus-visible:bg-primary/40 absolute top-0 right-0 h-full w-1.5 cursor-col-resize touch-none select-none",
|
|
353
|
+
FOCUS_RING_INSET,
|
|
354
|
+
)}
|
|
309
355
|
aria-label={label}
|
|
310
356
|
role="separator"
|
|
311
357
|
aria-orientation="vertical"
|
|
@@ -13,7 +13,9 @@ import {
|
|
|
13
13
|
} from "../../primitives/sheet.js"
|
|
14
14
|
import { TONE_DOT, TONE_TEXT } from "../../lib/tone-utils.js"
|
|
15
15
|
import { cn } from "../../lib/utils.js"
|
|
16
|
+
import { displayLabel } from "./builder-model.js"
|
|
16
17
|
import type { LayoutBuilderLabels } from "./labels.js"
|
|
18
|
+
import { useDisplayResolver } from "./use-display-resolver.js"
|
|
17
19
|
|
|
18
20
|
// -------------------------------------------------------------------------- //
|
|
19
21
|
// Catalogue Sheet — slides in from the right
|
|
@@ -38,6 +40,7 @@ export function CatalogueSheet({
|
|
|
38
40
|
onSeedKey: (name: string) => void
|
|
39
41
|
onAddProducingStep: (key: string) => void
|
|
40
42
|
}) {
|
|
43
|
+
const { locale, resolveKey } = useDisplayResolver()
|
|
41
44
|
const producerOf = useMemo(() => {
|
|
42
45
|
const map = new Map<string, string | undefined>()
|
|
43
46
|
for (const e of keyCatalog) map.set(e.key, e.producedBySteps[0])
|
|
@@ -60,19 +63,19 @@ export function CatalogueSheet({
|
|
|
60
63
|
<section className="flex flex-col gap-2">
|
|
61
64
|
<CatalogueSectionHeader title={L.catalogueKeys} count={keyCatalog.length} />
|
|
62
65
|
{keyCatalog.length === 0 ? (
|
|
63
|
-
<p className="text-muted-foreground text-
|
|
66
|
+
<p className="text-muted-foreground text-small italic">{L.noKeysRegistered}</p>
|
|
64
67
|
) : (
|
|
65
68
|
<ul className="flex flex-col gap-1">
|
|
66
69
|
{keyCatalog.map((entry) => (
|
|
67
70
|
<li
|
|
68
71
|
key={entry.key}
|
|
69
|
-
className="hover:bg-muted flex flex-col gap-1 rounded-md border px-2 py-1.5
|
|
72
|
+
className="hover:bg-muted text-small flex flex-col gap-1 rounded-md border px-2 py-1.5"
|
|
70
73
|
>
|
|
71
74
|
<div className="flex items-start justify-between gap-2">
|
|
72
75
|
<span className="truncate font-mono">{entry.key}</span>
|
|
73
76
|
<span
|
|
74
77
|
className={cn(
|
|
75
|
-
"inline-flex shrink-0 items-center gap-1
|
|
78
|
+
"text-small inline-flex shrink-0 items-center gap-1",
|
|
76
79
|
entry.inContext ? TONE_TEXT.success : "text-muted-foreground",
|
|
77
80
|
)}
|
|
78
81
|
>
|
|
@@ -91,7 +94,7 @@ export function CatalogueSheet({
|
|
|
91
94
|
{(entry.producedBySteps.length > 0 ||
|
|
92
95
|
entry.consumedBySteps.length > 0 ||
|
|
93
96
|
entry.consumedByWidgets.length > 0) && (
|
|
94
|
-
<div className="text-muted-foreground flex flex-col gap-0.5
|
|
97
|
+
<div className="text-muted-foreground text-small flex flex-col gap-0.5">
|
|
95
98
|
{entry.producedBySteps.length > 0 && (
|
|
96
99
|
<span>
|
|
97
100
|
{L.catalogueProducedBy}{" "}
|
|
@@ -139,25 +142,39 @@ export function CatalogueSheet({
|
|
|
139
142
|
<section className="flex flex-col gap-2">
|
|
140
143
|
<CatalogueSectionHeader title={L.catalogueSteps} count={availableSteps.length} />
|
|
141
144
|
{availableSteps.length === 0 ? (
|
|
142
|
-
<p className="text-muted-foreground text-
|
|
145
|
+
<p className="text-muted-foreground text-small italic">{L.noStepsRegistered}</p>
|
|
143
146
|
) : (
|
|
144
147
|
<ul className="flex flex-col gap-1">
|
|
145
|
-
{availableSteps.map((s) =>
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
<span className="font-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
148
|
+
{availableSteps.map((s) => {
|
|
149
|
+
const name = displayLabel(s, s.id, locale, resolveKey)
|
|
150
|
+
return (
|
|
151
|
+
<li
|
|
152
|
+
key={s.id}
|
|
153
|
+
className="text-small flex flex-col gap-0.5 rounded-md border px-2 py-1.5"
|
|
154
|
+
>
|
|
155
|
+
<span className="truncate font-medium">{name.label}</span>
|
|
156
|
+
{name.hint && (
|
|
157
|
+
<span className="text-muted-foreground truncate font-mono">
|
|
158
|
+
{name.hint}
|
|
159
|
+
</span>
|
|
160
|
+
)}
|
|
161
|
+
<div className="text-muted-foreground flex flex-wrap gap-x-3">
|
|
162
|
+
<span>
|
|
163
|
+
{L.catalogueNeedsKeys}{" "}
|
|
164
|
+
<span className="font-mono">
|
|
165
|
+
{s.requires.length ? s.requires.join(", ") : L.noInputs}
|
|
166
|
+
</span>
|
|
167
|
+
</span>
|
|
168
|
+
<span>
|
|
169
|
+
{L.stepProvides}{" "}
|
|
170
|
+
<span className="font-mono">
|
|
171
|
+
{s.produces.length ? s.produces.join(", ") : L.noOutputs}
|
|
172
|
+
</span>
|
|
173
|
+
</span>
|
|
174
|
+
</div>
|
|
175
|
+
</li>
|
|
176
|
+
)
|
|
177
|
+
})}
|
|
161
178
|
</ul>
|
|
162
179
|
)}
|
|
163
180
|
</section>
|
|
@@ -168,7 +185,7 @@ export function CatalogueSheet({
|
|
|
168
185
|
count={unreachableWidgets.length}
|
|
169
186
|
/>
|
|
170
187
|
{unreachableWidgets.length === 0 ? (
|
|
171
|
-
<p className="text-muted-foreground text-
|
|
188
|
+
<p className="text-muted-foreground text-small italic">
|
|
172
189
|
{L.catalogueUnreachableEmpty}
|
|
173
190
|
</p>
|
|
174
191
|
) : (
|
|
@@ -177,13 +194,19 @@ export function CatalogueSheet({
|
|
|
177
194
|
const candidate = w.missingKeys
|
|
178
195
|
.map((k) => ({ key: k, step: producerOf.get(k) }))
|
|
179
196
|
.find((c) => c.step)
|
|
197
|
+
const name = displayLabel(w, w.id, locale, resolveKey)
|
|
180
198
|
return (
|
|
181
199
|
<li
|
|
182
200
|
key={w.id}
|
|
183
|
-
className="bg-muted/20 flex flex-col gap-1 rounded-md border px-2 py-1.5
|
|
201
|
+
className="bg-muted/20 text-small flex flex-col gap-1 rounded-md border px-2 py-1.5"
|
|
184
202
|
>
|
|
185
|
-
<span className="truncate font-
|
|
186
|
-
|
|
203
|
+
<span className="truncate font-medium">{name.label}</span>
|
|
204
|
+
{name.hint && (
|
|
205
|
+
<span className="text-muted-foreground truncate font-mono">
|
|
206
|
+
{name.hint}
|
|
207
|
+
</span>
|
|
208
|
+
)}
|
|
209
|
+
<span className="text-muted-foreground">
|
|
187
210
|
{L.catalogueNeedsKeys}{" "}
|
|
188
211
|
<span className="font-mono">{w.missingKeys.join(", ")}</span>
|
|
189
212
|
</span>
|
|
@@ -220,11 +243,9 @@ export function CatalogueSheet({
|
|
|
220
243
|
function CatalogueSectionHeader({ title, count }: { title: string; count: number }) {
|
|
221
244
|
return (
|
|
222
245
|
<div className="flex items-center gap-2">
|
|
223
|
-
<
|
|
224
|
-
{title}
|
|
225
|
-
</span>
|
|
246
|
+
<h3 className="text-muted-foreground text-small font-semibold">{title}</h3>
|
|
226
247
|
<span className="bg-border h-px flex-1" aria-hidden="true" />
|
|
227
|
-
<Badge variant="outline" className="px-1.5
|
|
248
|
+
<Badge variant="outline" className="px-1.5">
|
|
228
249
|
{count}
|
|
229
250
|
</Badge>
|
|
230
251
|
</div>
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import type { RowDef } from "@miragon/mcp-toolkit-core"
|
|
1
|
+
import type { DisplayText, RowDef } from "@miragon/mcp-toolkit-core"
|
|
2
2
|
import { WidgetPropsSheet } from "../widget-props-sheet.js"
|
|
3
|
+
import { displayLabel } from "./builder-model.js"
|
|
4
|
+
import { useDisplayResolver } from "./use-display-resolver.js"
|
|
3
5
|
|
|
4
6
|
// -------------------------------------------------------------------------- //
|
|
5
7
|
// Cell props sheet — mounts the WidgetPropsSheet for the configured cell
|
|
@@ -10,25 +12,37 @@ import { WidgetPropsSheet } from "../widget-props-sheet.js"
|
|
|
10
12
|
* can be open at a time across the entire workspace — including across
|
|
11
13
|
* tabs. `configuringCell` addresses `{ rowIdx, cellIdx }` on the currently
|
|
12
14
|
* active draft surface (rows or active tab's rows); renders nothing when no
|
|
13
|
-
* cell is being configured or the address no longer resolves.
|
|
15
|
+
* cell is being configured or the address no longer resolves. The sheet is
|
|
16
|
+
* titled with the widget's name; closing it returns focus to the cell's
|
|
17
|
+
* configure button (the kit's `SheetContent` hands it back to the element
|
|
18
|
+
* that opened it, see `lib/focus-return.ts`).
|
|
14
19
|
*/
|
|
15
20
|
export function CellPropsSheet({
|
|
16
21
|
configuringCell,
|
|
17
22
|
activeRows,
|
|
18
23
|
propsSchemaByWidgetId,
|
|
24
|
+
displayByWidgetId,
|
|
19
25
|
onApply,
|
|
20
26
|
onClose,
|
|
21
27
|
}: {
|
|
22
28
|
configuringCell: { rowIdx: number; cellIdx: number } | null
|
|
23
29
|
activeRows: RowDef[]
|
|
24
30
|
propsSchemaByWidgetId: Map<string, Record<string, unknown>>
|
|
31
|
+
displayByWidgetId: Map<string, DisplayText>
|
|
25
32
|
onApply: (rowIdx: number, cellIdx: number, next: Record<string, unknown> | undefined) => void
|
|
26
33
|
onClose: () => void
|
|
27
34
|
}) {
|
|
35
|
+
const { locale, resolveKey } = useDisplayResolver()
|
|
28
36
|
if (!configuringCell) return null
|
|
29
37
|
const cell = activeRows[configuringCell.rowIdx]?.row[configuringCell.cellIdx]
|
|
30
38
|
if (!cell) return null
|
|
31
39
|
const schema = propsSchemaByWidgetId.get(cell.widget)
|
|
40
|
+
const name = displayLabel(
|
|
41
|
+
displayByWidgetId.get(cell.widget) ?? {},
|
|
42
|
+
cell.widget,
|
|
43
|
+
locale,
|
|
44
|
+
resolveKey,
|
|
45
|
+
)
|
|
32
46
|
return (
|
|
33
47
|
<WidgetPropsSheet
|
|
34
48
|
open
|
|
@@ -36,6 +50,7 @@ export function CellPropsSheet({
|
|
|
36
50
|
if (!open) onClose()
|
|
37
51
|
}}
|
|
38
52
|
widgetId={cell.widget}
|
|
53
|
+
widgetTitle={name.hint ? name.label : undefined}
|
|
39
54
|
schema={schema}
|
|
40
55
|
value={cell.props}
|
|
41
56
|
onApply={(next) => {
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Button } from "../../primitives/button.js"
|
|
2
|
+
import {
|
|
3
|
+
Dialog,
|
|
4
|
+
DialogClose,
|
|
5
|
+
DialogContent,
|
|
6
|
+
DialogDescription,
|
|
7
|
+
DialogFooter,
|
|
8
|
+
DialogHeader,
|
|
9
|
+
DialogTitle,
|
|
10
|
+
} from "../../primitives/dialog.js"
|
|
11
|
+
import type { LayoutBuilderLabels } from "./labels.js"
|
|
12
|
+
|
|
13
|
+
// -------------------------------------------------------------------------- //
|
|
14
|
+
// Discard confirmation
|
|
15
|
+
// -------------------------------------------------------------------------- //
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Asks before Discard takes the changes out of the view (CI §9: confirm
|
|
19
|
+
* before an irreversible action). When a saved dashboard holds them
|
|
20
|
+
* (`changesSaved`), it says so instead of calling them lost. The safe choice
|
|
21
|
+
* comes first in the DOM, so the dialog opens with focus on "Keep editing";
|
|
22
|
+
* closing it returns focus to Discard (the kit's `DialogContent` hands it
|
|
23
|
+
* back to the element that opened it, see `lib/focus-return.ts`).
|
|
24
|
+
*/
|
|
25
|
+
export function DiscardDialog({
|
|
26
|
+
L,
|
|
27
|
+
open,
|
|
28
|
+
onOpenChange,
|
|
29
|
+
changesSaved,
|
|
30
|
+
onConfirm,
|
|
31
|
+
}: {
|
|
32
|
+
L: Required<LayoutBuilderLabels>
|
|
33
|
+
open: boolean
|
|
34
|
+
onOpenChange: (open: boolean) => void
|
|
35
|
+
/** A saved dashboard holds the changes: only the view goes back. */
|
|
36
|
+
changesSaved: boolean
|
|
37
|
+
onConfirm: () => void
|
|
38
|
+
}) {
|
|
39
|
+
return (
|
|
40
|
+
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
41
|
+
<DialogContent>
|
|
42
|
+
<DialogHeader>
|
|
43
|
+
<DialogTitle>{L.discardDialogTitle}</DialogTitle>
|
|
44
|
+
<DialogDescription>
|
|
45
|
+
{changesSaved ? L.discardDialogDescriptionSaved : L.discardDialogDescription}
|
|
46
|
+
</DialogDescription>
|
|
47
|
+
</DialogHeader>
|
|
48
|
+
<DialogFooter>
|
|
49
|
+
<DialogClose asChild>
|
|
50
|
+
<Button variant="outline">{L.keepEditing}</Button>
|
|
51
|
+
</DialogClose>
|
|
52
|
+
<Button variant="destructive" onClick={onConfirm}>
|
|
53
|
+
{L.discardConfirm}
|
|
54
|
+
</Button>
|
|
55
|
+
</DialogFooter>
|
|
56
|
+
</DialogContent>
|
|
57
|
+
</Dialog>
|
|
58
|
+
)
|
|
59
|
+
}
|