@miragon/mcp-toolkit-ui 2.7.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 +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 +9 -6
- package/dist/components/DrillButton.d.ts.map +1 -1
- package/dist/components/DrillButton.js +8 -6
- 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.tsx +23 -10
- 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
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest"
|
|
2
|
+
import { createTranslator, type PipelineContext } from "@miragon/mcp-toolkit-core"
|
|
3
|
+
import {
|
|
4
|
+
builderLeave,
|
|
5
|
+
builderSnapshot,
|
|
6
|
+
builderViews,
|
|
7
|
+
createTabRefocus,
|
|
8
|
+
displayLabel,
|
|
9
|
+
draftHasCells,
|
|
10
|
+
draftStatus,
|
|
11
|
+
initDraft,
|
|
12
|
+
keyResolverFrom,
|
|
13
|
+
propFieldText,
|
|
14
|
+
renameFieldKeyAction,
|
|
15
|
+
tabTriggerKeyAction,
|
|
16
|
+
toExitCommit,
|
|
17
|
+
viewAfterAdvancedToggle,
|
|
18
|
+
type BuilderExitCommit,
|
|
19
|
+
type DraftLayout,
|
|
20
|
+
} from "./builder-model.js"
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The builder's UX model (U18, toolkit#13/#14): human titles with the id as
|
|
24
|
+
* the fallback, props-field labels, the draft status behind Apply / Discard /
|
|
25
|
+
* the unsaved marker, the keyboard rename, and the "Advanced" views.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
const translate = createTranslator({
|
|
29
|
+
en: { "orders.title": "Orders", "orders.summary": "Every open order.", blank: " " },
|
|
30
|
+
de: { "orders.title": "Bestellungen", "orders.summary": "Alle offenen Bestellungen." },
|
|
31
|
+
})
|
|
32
|
+
const deKeys = keyResolverFrom((key) => translate("de", key))
|
|
33
|
+
|
|
34
|
+
describe("keyResolverFrom", () => {
|
|
35
|
+
it("returns the translation of a known key, trimmed", () => {
|
|
36
|
+
expect(deKeys("orders.title")).toBe("Bestellungen")
|
|
37
|
+
expect(keyResolverFrom(() => " Padded ")("k")).toBe("Padded")
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it("treats the echoed key (the translator's 'unknown') and blank text as unknown", () => {
|
|
41
|
+
expect(deKeys("orders.missing")).toBeUndefined()
|
|
42
|
+
expect(keyResolverFrom((key) => translate("en", key))("blank")).toBeUndefined()
|
|
43
|
+
expect(keyResolverFrom(() => "")("k")).toBeUndefined()
|
|
44
|
+
})
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
describe("displayLabel", () => {
|
|
48
|
+
it("falls back to the id when there is no title, with no hint and no summary", () => {
|
|
49
|
+
expect(displayLabel({}, "demo:raw", "de")).toEqual({ label: "demo:raw" })
|
|
50
|
+
expect(displayLabel({ title: " " }, "demo:raw", "de")).toEqual({ label: "demo:raw" })
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it("shows the title in the locale, the id as the hint, and the summary", () => {
|
|
54
|
+
const entry = {
|
|
55
|
+
title: { en: "Orders", de: "Bestellungen" },
|
|
56
|
+
summary: { en: "Every open order.", de: "Alle offenen Bestellungen." },
|
|
57
|
+
}
|
|
58
|
+
expect(displayLabel(entry, "demo:orders", "de-DE")).toEqual({
|
|
59
|
+
label: "Bestellungen",
|
|
60
|
+
hint: "demo:orders",
|
|
61
|
+
summary: "Alle offenen Bestellungen.",
|
|
62
|
+
})
|
|
63
|
+
expect(displayLabel(entry, "demo:orders", "en")).toEqual({
|
|
64
|
+
label: "Orders",
|
|
65
|
+
hint: "demo:orders",
|
|
66
|
+
summary: "Every open order.",
|
|
67
|
+
})
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
it("keeps a summary without a title (the id stays the label, no hint)", () => {
|
|
71
|
+
expect(displayLabel({ summary: "Every open order." }, "demo:orders", "en")).toEqual({
|
|
72
|
+
label: "demo:orders",
|
|
73
|
+
summary: "Every open order.",
|
|
74
|
+
})
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
it("never shows the id twice when the title equals it", () => {
|
|
78
|
+
expect(displayLabel({ title: "demo:orders" }, "demo:orders", "en")).toEqual({
|
|
79
|
+
label: "demo:orders",
|
|
80
|
+
})
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
it("resolves the i18n keys first and falls back to the inline text when a key is unknown", () => {
|
|
84
|
+
expect(
|
|
85
|
+
displayLabel(
|
|
86
|
+
{ titleKey: "orders.title", summaryKey: "orders.summary", title: "Inline" },
|
|
87
|
+
"demo:orders",
|
|
88
|
+
"de",
|
|
89
|
+
deKeys,
|
|
90
|
+
),
|
|
91
|
+
).toEqual({ label: "Bestellungen", hint: "demo:orders", summary: "Alle offenen Bestellungen." })
|
|
92
|
+
expect(
|
|
93
|
+
displayLabel(
|
|
94
|
+
{ titleKey: "orders.missing", title: "Inline", summaryKey: "nope", summary: "Text" },
|
|
95
|
+
"demo:orders",
|
|
96
|
+
"de",
|
|
97
|
+
deKeys,
|
|
98
|
+
),
|
|
99
|
+
).toEqual({ label: "Inline", hint: "demo:orders", summary: "Text" })
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
it("ignores the keys without a resolver", () => {
|
|
103
|
+
expect(displayLabel({ titleKey: "orders.title" }, "demo:orders", "de")).toEqual({
|
|
104
|
+
label: "demo:orders",
|
|
105
|
+
})
|
|
106
|
+
})
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
describe("propFieldText", () => {
|
|
110
|
+
it("labels a bare property with its name, without a hint or help", () => {
|
|
111
|
+
expect(propFieldText("dataKey", { type: "string" }, "de")).toEqual({ label: "dataKey" })
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
it("uses the JSON Schema title and description, with the name as the hint", () => {
|
|
115
|
+
expect(
|
|
116
|
+
propFieldText(
|
|
117
|
+
"dataKey",
|
|
118
|
+
{ type: "string", title: "Data key", description: "Where the cells live." },
|
|
119
|
+
"de",
|
|
120
|
+
),
|
|
121
|
+
).toEqual({ label: "Data key", hint: "dataKey", help: "Where the cells live." })
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
it("prefers the x-display title and summary (per locale) over the schema's", () => {
|
|
125
|
+
const prop = {
|
|
126
|
+
type: "string",
|
|
127
|
+
title: "Data key",
|
|
128
|
+
description: "Context key holding the KPI cells.",
|
|
129
|
+
"x-display": {
|
|
130
|
+
title: { en: "Data source", de: "Datenquelle" },
|
|
131
|
+
summary: { en: "Where the figures come from.", de: "Woher die Zahlen kommen." },
|
|
132
|
+
},
|
|
133
|
+
}
|
|
134
|
+
expect(propFieldText("dataKey", prop, "de")).toEqual({
|
|
135
|
+
label: "Datenquelle",
|
|
136
|
+
hint: "dataKey",
|
|
137
|
+
help: "Woher die Zahlen kommen.",
|
|
138
|
+
})
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
it("resolves the x-display keys through the translator first", () => {
|
|
142
|
+
const prop = {
|
|
143
|
+
"x-display": { titleKey: "orders.title", summaryKey: "orders.summary", title: "Inline" },
|
|
144
|
+
}
|
|
145
|
+
expect(propFieldText("key", prop, "de", deKeys)).toEqual({
|
|
146
|
+
label: "Bestellungen",
|
|
147
|
+
hint: "key",
|
|
148
|
+
help: "Alle offenen Bestellungen.",
|
|
149
|
+
})
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
it("ignores a malformed x-display and non-string schema keywords", () => {
|
|
153
|
+
for (const display of [null, "Datenquelle", ["x"], 3]) {
|
|
154
|
+
expect(
|
|
155
|
+
propFieldText("dataKey", { "x-display": display, title: 7, description: false }, "de"),
|
|
156
|
+
).toEqual({ label: "dataKey" })
|
|
157
|
+
}
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
it("ignores x-display keys that are not strings instead of handing them to the translator", () => {
|
|
161
|
+
const throwing = (key: string) => {
|
|
162
|
+
if (typeof key !== "string") throw new TypeError("not a key")
|
|
163
|
+
return deKeys(key)
|
|
164
|
+
}
|
|
165
|
+
const prop = { "x-display": { titleKey: 42, summaryKey: {}, title: "Daten" } }
|
|
166
|
+
expect(propFieldText("dataKey", prop, "de", throwing)).toEqual({
|
|
167
|
+
label: "Daten",
|
|
168
|
+
hint: "dataKey",
|
|
169
|
+
})
|
|
170
|
+
expect(displayLabel({ titleKey: 7 as unknown as string }, "demo:raw", "de", throwing)).toEqual({
|
|
171
|
+
label: "demo:raw",
|
|
172
|
+
})
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
it("has no hint when the resolved label is the property name", () => {
|
|
176
|
+
expect(propFieldText("boxed", { title: "boxed", description: "Card frame." }, "en")).toEqual({
|
|
177
|
+
label: "boxed",
|
|
178
|
+
help: "Card frame.",
|
|
179
|
+
})
|
|
180
|
+
})
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
describe("builderSnapshot + draftStatus", () => {
|
|
184
|
+
const draft = initDraft({ rows: [{ row: [{ widget: "demo:a", span: 6 }] }] })
|
|
185
|
+
const keys = [{ name: "demo:id", rawValue: "42" }]
|
|
186
|
+
const steps = [{ id: "s", step: "demo:load" }]
|
|
187
|
+
const base = builderSnapshot(draft, keys, steps)
|
|
188
|
+
|
|
189
|
+
it("is the JSON of what Apply and Save hand on", () => {
|
|
190
|
+
expect(JSON.parse(base)).toEqual({
|
|
191
|
+
layout: { rows: [{ row: [{ widget: "demo:a", span: 6 }] }] },
|
|
192
|
+
keys: { "demo:id": "42" },
|
|
193
|
+
steps: [{ id: "s", step: "demo:load" }],
|
|
194
|
+
})
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
it("ignores key and step rows the user has not filled in", () => {
|
|
198
|
+
expect(
|
|
199
|
+
builderSnapshot(
|
|
200
|
+
draft,
|
|
201
|
+
[...keys, { name: " ", rawValue: "x" }],
|
|
202
|
+
[...steps, { id: "step-2", step: " " }],
|
|
203
|
+
),
|
|
204
|
+
).toBe(base)
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
it("changes with the layout, a key value and a step", () => {
|
|
208
|
+
const moved: DraftLayout = { kind: "rows", rows: [{ row: [{ widget: "demo:a", span: 4 }] }] }
|
|
209
|
+
expect(builderSnapshot(moved, keys, steps)).not.toBe(base)
|
|
210
|
+
expect(builderSnapshot(draft, [{ name: "demo:id", rawValue: "43" }], steps)).not.toBe(base)
|
|
211
|
+
expect(builderSnapshot(draft, keys, [{ id: "s", step: "demo:other" }])).not.toBe(base)
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
it("is unchanged and saved before any edit", () => {
|
|
215
|
+
expect(draftStatus(base, base, null)).toEqual({ changed: false, unsaved: false })
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
it("is changed and unsaved after an edit", () => {
|
|
219
|
+
expect(draftStatus("edited", base, null)).toEqual({ changed: true, unsaved: true })
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
it("stays changed but no longer unsaved once that draft was saved as a dashboard", () => {
|
|
223
|
+
expect(draftStatus("edited", base, "edited")).toEqual({ changed: true, unsaved: false })
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
it("is unsaved again after an edit past the saved dashboard", () => {
|
|
227
|
+
expect(draftStatus("edited-more", base, "edited")).toEqual({ changed: true, unsaved: true })
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
it("going back to the pre-edit state after a save loses nothing: neither changed nor unsaved", () => {
|
|
231
|
+
expect(draftStatus(base, base, "edited")).toEqual({ changed: false, unsaved: false })
|
|
232
|
+
})
|
|
233
|
+
|
|
234
|
+
it("is never unsaved without being changed (the view holds a draft equal to it)", () => {
|
|
235
|
+
for (const saved of [null, base, "edited"]) {
|
|
236
|
+
expect(draftStatus(base, base, saved).unsaved).toBe(false)
|
|
237
|
+
}
|
|
238
|
+
})
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
describe("builderLeave: Apply commits, Discard restores the view", () => {
|
|
242
|
+
const commit: BuilderExitCommit = { layout: { rows: [{ row: [{ widget: "demo:a" }] }] } }
|
|
243
|
+
|
|
244
|
+
function leave(changed: boolean, withExit = true) {
|
|
245
|
+
const onExit = vi.fn<(c?: BuilderExitCommit) => void>()
|
|
246
|
+
const onReset = vi.fn<() => void>()
|
|
247
|
+
const confirm = vi.fn<() => void>()
|
|
248
|
+
const actions = builderLeave({
|
|
249
|
+
changed,
|
|
250
|
+
onExit: withExit ? onExit : undefined,
|
|
251
|
+
onReset,
|
|
252
|
+
commit: () => commit,
|
|
253
|
+
confirm,
|
|
254
|
+
})
|
|
255
|
+
return { actions, onExit, onReset, confirm }
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
it("Apply hands the draft's commit to onExit, and nothing else happens", () => {
|
|
259
|
+
const { actions, onExit, onReset, confirm } = leave(true)
|
|
260
|
+
actions.apply?.()
|
|
261
|
+
expect(onExit).toHaveBeenCalledExactlyOnceWith(commit)
|
|
262
|
+
expect(onReset).not.toHaveBeenCalled()
|
|
263
|
+
expect(confirm).not.toHaveBeenCalled()
|
|
264
|
+
})
|
|
265
|
+
|
|
266
|
+
it("Discard asks first when the draft changed the view, and leaves nothing yet", () => {
|
|
267
|
+
const { actions, onExit, onReset, confirm } = leave(true)
|
|
268
|
+
actions.discard()
|
|
269
|
+
expect(confirm).toHaveBeenCalledOnce()
|
|
270
|
+
expect(onExit).not.toHaveBeenCalled()
|
|
271
|
+
expect(onReset).not.toHaveBeenCalled()
|
|
272
|
+
})
|
|
273
|
+
|
|
274
|
+
it("Discard leaves at once, WITHOUT a commit, when the view loses nothing", () => {
|
|
275
|
+
const { actions, onExit, onReset, confirm } = leave(false)
|
|
276
|
+
actions.discard()
|
|
277
|
+
expect(onExit).toHaveBeenCalledExactlyOnceWith()
|
|
278
|
+
expect(confirm).not.toHaveBeenCalled()
|
|
279
|
+
expect(onReset).not.toHaveBeenCalled()
|
|
280
|
+
})
|
|
281
|
+
|
|
282
|
+
it("the confirmation's Discard leaves without a commit", () => {
|
|
283
|
+
const { actions, onExit, confirm } = leave(true)
|
|
284
|
+
actions.discardNow()
|
|
285
|
+
expect(onExit).toHaveBeenCalledExactlyOnceWith()
|
|
286
|
+
expect(confirm).not.toHaveBeenCalled()
|
|
287
|
+
})
|
|
288
|
+
|
|
289
|
+
it("never hands a click event on as the commit", () => {
|
|
290
|
+
const click = { type: "click" }
|
|
291
|
+
const clean = leave(false)
|
|
292
|
+
;(clean.actions.discard as (event: unknown) => void)(click)
|
|
293
|
+
expect(clean.onExit).toHaveBeenCalledExactlyOnceWith()
|
|
294
|
+
const confirmed = leave(true)
|
|
295
|
+
;(confirmed.actions.discardNow as (event: unknown) => void)(click)
|
|
296
|
+
expect(confirmed.onExit).toHaveBeenCalledExactlyOnceWith()
|
|
297
|
+
})
|
|
298
|
+
|
|
299
|
+
it("without onExit there is no Apply, and Discard resets in place (asking first when changed)", () => {
|
|
300
|
+
const clean = leave(false, false)
|
|
301
|
+
expect(clean.actions.apply).toBeUndefined()
|
|
302
|
+
clean.actions.discard()
|
|
303
|
+
expect(clean.onReset).toHaveBeenCalledOnce()
|
|
304
|
+
expect(clean.confirm).not.toHaveBeenCalled()
|
|
305
|
+
|
|
306
|
+
const changed = leave(true, false)
|
|
307
|
+
changed.actions.discard()
|
|
308
|
+
expect(changed.onReset).not.toHaveBeenCalled()
|
|
309
|
+
expect(changed.confirm).toHaveBeenCalledOnce()
|
|
310
|
+
changed.actions.discardNow()
|
|
311
|
+
expect(changed.onReset).toHaveBeenCalledOnce()
|
|
312
|
+
expect(changed.onExit).not.toHaveBeenCalled()
|
|
313
|
+
})
|
|
314
|
+
})
|
|
315
|
+
|
|
316
|
+
describe("createTabRefocus: the focus comes back to a renamed tab", () => {
|
|
317
|
+
const focusable = () => ({ focus: vi.fn<() => void>() })
|
|
318
|
+
|
|
319
|
+
it("focuses the requested tab's trigger once, also when a NEW element attaches for it", () => {
|
|
320
|
+
const refocus = createTabRefocus()
|
|
321
|
+
const before = focusable()
|
|
322
|
+
const other = focusable()
|
|
323
|
+
const renamed = focusable()
|
|
324
|
+
refocus.attach(1, before) // no request yet
|
|
325
|
+
refocus.request(1)
|
|
326
|
+
refocus.attach(0, other) // another tab
|
|
327
|
+
refocus.attach(1, null) // the old trigger detaching (a rename remounts the tab)
|
|
328
|
+
refocus.attach(1, renamed) // the new trigger
|
|
329
|
+
refocus.attach(1, renamed) // a later re-render
|
|
330
|
+
expect(before.focus).not.toHaveBeenCalled()
|
|
331
|
+
expect(other.focus).not.toHaveBeenCalled()
|
|
332
|
+
expect(renamed.focus).toHaveBeenCalledOnce()
|
|
333
|
+
})
|
|
334
|
+
|
|
335
|
+
it("keeps only the latest request", () => {
|
|
336
|
+
const refocus = createTabRefocus()
|
|
337
|
+
const first = focusable()
|
|
338
|
+
const second = focusable()
|
|
339
|
+
refocus.request(0)
|
|
340
|
+
refocus.request(2)
|
|
341
|
+
refocus.attach(0, first)
|
|
342
|
+
refocus.attach(2, second)
|
|
343
|
+
expect(first.focus).not.toHaveBeenCalled()
|
|
344
|
+
expect(second.focus).toHaveBeenCalledOnce()
|
|
345
|
+
})
|
|
346
|
+
|
|
347
|
+
it("forTab wires a tab's request and its trigger to the same index", () => {
|
|
348
|
+
const refocus = createTabRefocus()
|
|
349
|
+
const one = refocus.forTab(1)
|
|
350
|
+
const zero = refocus.forTab(0)
|
|
351
|
+
const el = focusable()
|
|
352
|
+
one.onRefocus()
|
|
353
|
+
zero.triggerRef(el)
|
|
354
|
+
expect(el.focus).not.toHaveBeenCalled()
|
|
355
|
+
// A fresh forTab(1), as a remounted tab gets it, still takes the open request.
|
|
356
|
+
refocus.forTab(1).triggerRef(el)
|
|
357
|
+
expect(el.focus).toHaveBeenCalledOnce()
|
|
358
|
+
})
|
|
359
|
+
})
|
|
360
|
+
|
|
361
|
+
describe("toExitCommit", () => {
|
|
362
|
+
it("hands on the layout, parsed keys, filled steps, the title and the wire context", () => {
|
|
363
|
+
const live: PipelineContext = {
|
|
364
|
+
keys: { "demo:id": "42" },
|
|
365
|
+
steps: {
|
|
366
|
+
s: { data: { n: 1 }, keys: { k: 1 }, _app: "demo", _step: "s", _dataType: "demo:t" },
|
|
367
|
+
},
|
|
368
|
+
errors: [{ stepId: "t", reason: "down" }],
|
|
369
|
+
}
|
|
370
|
+
expect(
|
|
371
|
+
toExitCommit(
|
|
372
|
+
initDraft({ tabs: [{ label: "A", rows: [{ row: [{ widget: "demo:a" }] }] }] }),
|
|
373
|
+
[
|
|
374
|
+
{ name: "demo:id", rawValue: "42" },
|
|
375
|
+
{ name: "", rawValue: "x" },
|
|
376
|
+
],
|
|
377
|
+
[
|
|
378
|
+
{ id: "s", step: "demo:load" },
|
|
379
|
+
{ id: "step-2", step: "" },
|
|
380
|
+
],
|
|
381
|
+
"Ops",
|
|
382
|
+
live,
|
|
383
|
+
),
|
|
384
|
+
).toEqual({
|
|
385
|
+
layout: { tabs: [{ label: "A", rows: [{ row: [{ widget: "demo:a" }] }] }] },
|
|
386
|
+
keys: { "demo:id": "42" },
|
|
387
|
+
steps: [{ id: "s", step: "demo:load" }],
|
|
388
|
+
title: "Ops",
|
|
389
|
+
context: {
|
|
390
|
+
keys: { "demo:id": "42" },
|
|
391
|
+
stepIds: ["s"],
|
|
392
|
+
stepData: { s: { data: { n: 1 }, keys: { k: 1 }, _app: "demo", _dataType: "demo:t" } },
|
|
393
|
+
errors: [{ stepId: "t", reason: "down" }],
|
|
394
|
+
},
|
|
395
|
+
})
|
|
396
|
+
})
|
|
397
|
+
})
|
|
398
|
+
|
|
399
|
+
describe("keyboard rename", () => {
|
|
400
|
+
it("F2 renames any tab; Enter renames only the active one", () => {
|
|
401
|
+
expect(tabTriggerKeyAction("F2", false)).toBe("rename")
|
|
402
|
+
expect(tabTriggerKeyAction("F2", true)).toBe("rename")
|
|
403
|
+
expect(tabTriggerKeyAction("Enter", true)).toBe("rename")
|
|
404
|
+
expect(tabTriggerKeyAction("Enter", false)).toBeNull()
|
|
405
|
+
})
|
|
406
|
+
|
|
407
|
+
it("leaves every other key to the tabs", () => {
|
|
408
|
+
for (const key of [" ", "ArrowRight", "Delete", "f2", "Escape"]) {
|
|
409
|
+
expect(tabTriggerKeyAction(key, true)).toBeNull()
|
|
410
|
+
}
|
|
411
|
+
})
|
|
412
|
+
|
|
413
|
+
it("commits on Enter, cancels on Escape, ignores the rest in the field", () => {
|
|
414
|
+
expect(renameFieldKeyAction("Enter")).toBe("commit")
|
|
415
|
+
expect(renameFieldKeyAction("Escape")).toBe("cancel")
|
|
416
|
+
for (const key of ["a", "Tab", "F2", " "]) expect(renameFieldKeyAction(key)).toBeNull()
|
|
417
|
+
})
|
|
418
|
+
})
|
|
419
|
+
|
|
420
|
+
describe("draftHasCells", () => {
|
|
421
|
+
it("is false for an empty draft and true once a row holds an element", () => {
|
|
422
|
+
expect(draftHasCells(initDraft(undefined))).toBe(false)
|
|
423
|
+
expect(draftHasCells(initDraft({ rows: [{ row: [] }, { row: [{ widget: "demo:a" }] }] }))).toBe(
|
|
424
|
+
true,
|
|
425
|
+
)
|
|
426
|
+
})
|
|
427
|
+
|
|
428
|
+
it("looks at every tab, not only the active one", () => {
|
|
429
|
+
const tabs: DraftLayout = {
|
|
430
|
+
kind: "tabs",
|
|
431
|
+
tabs: [
|
|
432
|
+
{ label: "Overview", rows: [{ row: [{ widget: "demo:a" }] }] },
|
|
433
|
+
{ label: "New", rows: [{ row: [] }] },
|
|
434
|
+
],
|
|
435
|
+
}
|
|
436
|
+
expect(draftHasCells(tabs)).toBe(true)
|
|
437
|
+
expect(draftHasCells({ kind: "tabs", tabs: [{ label: "Empty", rows: [{ row: [] }] }] })).toBe(
|
|
438
|
+
false,
|
|
439
|
+
)
|
|
440
|
+
})
|
|
441
|
+
})
|
|
442
|
+
|
|
443
|
+
describe("builder views", () => {
|
|
444
|
+
it("shows the data sources only in advanced mode", () => {
|
|
445
|
+
expect(builderViews(false)).toEqual(["layout", "preview"])
|
|
446
|
+
expect(builderViews(true)).toEqual(["layout", "pipeline", "preview"])
|
|
447
|
+
})
|
|
448
|
+
|
|
449
|
+
it("keeps a still visible view and moves off the hidden data sources", () => {
|
|
450
|
+
expect(viewAfterAdvancedToggle("preview", false)).toBe("preview")
|
|
451
|
+
expect(viewAfterAdvancedToggle("layout", false)).toBe("layout")
|
|
452
|
+
expect(viewAfterAdvancedToggle("pipeline", false)).toBe("layout")
|
|
453
|
+
expect(viewAfterAdvancedToggle("pipeline", true)).toBe("pipeline")
|
|
454
|
+
expect(viewAfterAdvancedToggle("preview", true)).toBe("preview")
|
|
455
|
+
})
|
|
456
|
+
})
|