@sqlrooms/mosaic 0.29.0-rc.2 → 0.29.0-rc.3
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 +120 -0
- package/dist/MosaicChartBuilder.d.ts +48 -13
- package/dist/MosaicChartBuilder.d.ts.map +1 -1
- package/dist/MosaicChartBuilder.js +28 -30
- package/dist/MosaicChartBuilder.js.map +1 -1
- package/dist/MosaicSlice.d.ts +11 -0
- package/dist/MosaicSlice.d.ts.map +1 -1
- package/dist/MosaicSlice.js +73 -10
- package/dist/MosaicSlice.js.map +1 -1
- package/dist/ResponsivePlot.d.ts +23 -0
- package/dist/ResponsivePlot.d.ts.map +1 -0
- package/dist/ResponsivePlot.js +43 -0
- package/dist/ResponsivePlot.js.map +1 -0
- package/dist/VgPlotChart.d.ts +18 -2
- package/dist/VgPlotChart.d.ts.map +1 -1
- package/dist/VgPlotChart.js +112 -26
- package/dist/VgPlotChart.js.map +1 -1
- package/dist/chart-builders/ChartBuilderActions.d.ts +6 -0
- package/dist/chart-builders/ChartBuilderActions.d.ts.map +1 -0
- package/dist/chart-builders/ChartBuilderActions.js +28 -0
- package/dist/chart-builders/ChartBuilderActions.js.map +1 -0
- package/dist/chart-builders/ChartBuilderContent.d.ts +13 -11
- package/dist/chart-builders/ChartBuilderContent.d.ts.map +1 -1
- package/dist/chart-builders/ChartBuilderContent.js +21 -52
- package/dist/chart-builders/ChartBuilderContent.js.map +1 -1
- package/dist/chart-builders/ChartBuilderContext.d.ts +9 -4
- package/dist/chart-builders/ChartBuilderContext.d.ts.map +1 -1
- package/dist/chart-builders/ChartBuilderContext.js +5 -0
- package/dist/chart-builders/ChartBuilderContext.js.map +1 -1
- package/dist/chart-builders/ChartBuilderDialog.d.ts +31 -6
- package/dist/chart-builders/ChartBuilderDialog.d.ts.map +1 -1
- package/dist/chart-builders/ChartBuilderDialog.js +25 -10
- package/dist/chart-builders/ChartBuilderDialog.js.map +1 -1
- package/dist/chart-builders/ChartBuilderFields.d.ts +6 -0
- package/dist/chart-builders/ChartBuilderFields.d.ts.map +1 -0
- package/dist/chart-builders/ChartBuilderFields.js +25 -0
- package/dist/chart-builders/ChartBuilderFields.js.map +1 -0
- package/dist/chart-builders/ChartBuilderRoot.d.ts +27 -0
- package/dist/chart-builders/ChartBuilderRoot.d.ts.map +1 -0
- package/dist/chart-builders/ChartBuilderRoot.js +61 -0
- package/dist/chart-builders/ChartBuilderRoot.js.map +1 -0
- package/dist/chart-builders/ChartBuilderTypeGrid.d.ts +7 -0
- package/dist/chart-builders/ChartBuilderTypeGrid.d.ts.map +1 -0
- package/dist/chart-builders/ChartBuilderTypeGrid.js +23 -0
- package/dist/chart-builders/ChartBuilderTypeGrid.js.map +1 -0
- package/dist/chart-builders/FieldSelectorInput.d.ts.map +1 -1
- package/dist/chart-builders/FieldSelectorInput.js +2 -2
- package/dist/chart-builders/FieldSelectorInput.js.map +1 -1
- package/dist/chart-builders/builders.d.ts +28 -1
- package/dist/chart-builders/builders.d.ts.map +1 -1
- package/dist/chart-builders/builders.js +44 -273
- package/dist/chart-builders/builders.js.map +1 -1
- package/dist/chart-builders/chartSpecTitle.d.ts +3 -4
- package/dist/chart-builders/chartSpecTitle.d.ts.map +1 -1
- package/dist/chart-builders/chartSpecTitle.js +3 -5
- package/dist/chart-builders/chartSpecTitle.js.map +1 -1
- package/dist/chart-builders/chartTypeUtils.d.ts +17 -0
- package/dist/chart-builders/chartTypeUtils.d.ts.map +1 -0
- package/dist/chart-builders/chartTypeUtils.js +55 -0
- package/dist/chart-builders/chartTypeUtils.js.map +1 -0
- package/dist/chart-builders/constants.d.ts +7 -0
- package/dist/chart-builders/constants.d.ts.map +1 -0
- package/dist/chart-builders/constants.js +34 -0
- package/dist/chart-builders/constants.js.map +1 -0
- package/dist/chart-builders/createChartBuilderStore.d.ts +11 -0
- package/dist/chart-builders/createChartBuilderStore.d.ts.map +1 -0
- package/dist/chart-builders/createChartBuilderStore.js +26 -0
- package/dist/chart-builders/createChartBuilderStore.js.map +1 -0
- package/dist/chart-builders/describeChartSpecs.d.ts +5 -3
- package/dist/chart-builders/describeChartSpecs.d.ts.map +1 -1
- package/dist/chart-builders/describeChartSpecs.js +11 -8
- package/dist/chart-builders/describeChartSpecs.js.map +1 -1
- package/dist/chart-builders/hooks/useChartFieldForm.d.ts +13 -0
- package/dist/chart-builders/hooks/useChartFieldForm.d.ts.map +1 -0
- package/dist/chart-builders/hooks/useChartFieldForm.js +12 -0
- package/dist/chart-builders/hooks/useChartFieldForm.js.map +1 -0
- package/dist/chart-builders/types.d.ts +12 -29
- package/dist/chart-builders/types.d.ts.map +1 -1
- package/dist/chart-builders/types.js +16 -1
- package/dist/chart-builders/types.js.map +1 -1
- package/dist/chart-types/base-types.d.ts +54 -0
- package/dist/chart-types/base-types.d.ts.map +1 -0
- package/dist/chart-types/base-types.js +6 -0
- package/dist/chart-types/base-types.js.map +1 -0
- package/dist/chart-types/box-plot/definition.d.ts +4 -0
- package/dist/chart-types/box-plot/definition.d.ts.map +1 -0
- package/dist/chart-types/box-plot/definition.js +45 -0
- package/dist/chart-types/box-plot/definition.js.map +1 -0
- package/dist/chart-types/box-plot/index.d.ts +3 -0
- package/dist/chart-types/box-plot/index.d.ts.map +1 -0
- package/dist/chart-types/box-plot/index.js +3 -0
- package/dist/chart-types/box-plot/index.js.map +1 -0
- package/dist/chart-types/box-plot/schema.d.ts +17 -0
- package/dist/chart-types/box-plot/schema.d.ts.map +1 -0
- package/dist/chart-types/box-plot/schema.js +12 -0
- package/dist/chart-types/box-plot/schema.js.map +1 -0
- package/dist/chart-types/bubble-chart/definition.d.ts +4 -0
- package/dist/chart-types/bubble-chart/definition.d.ts.map +1 -0
- package/dist/chart-types/bubble-chart/definition.js +48 -0
- package/dist/chart-types/bubble-chart/definition.js.map +1 -0
- package/dist/chart-types/bubble-chart/index.d.ts +3 -0
- package/dist/chart-types/bubble-chart/index.d.ts.map +1 -0
- package/dist/chart-types/bubble-chart/index.js +3 -0
- package/dist/chart-types/bubble-chart/index.js.map +1 -0
- package/dist/chart-types/bubble-chart/schema.d.ts +17 -0
- package/dist/chart-types/bubble-chart/schema.d.ts.map +1 -0
- package/dist/chart-types/bubble-chart/schema.js +12 -0
- package/dist/chart-types/bubble-chart/schema.js.map +1 -0
- package/dist/chart-types/count-plot/definition.d.ts +4 -0
- package/dist/chart-types/count-plot/definition.d.ts.map +1 -0
- package/dist/chart-types/count-plot/definition.js +50 -0
- package/dist/chart-types/count-plot/definition.js.map +1 -0
- package/dist/chart-types/count-plot/index.d.ts +3 -0
- package/dist/chart-types/count-plot/index.d.ts.map +1 -0
- package/dist/chart-types/count-plot/index.js +3 -0
- package/dist/chart-types/count-plot/index.js.map +1 -0
- package/dist/chart-types/count-plot/schema.d.ts +15 -0
- package/dist/chart-types/count-plot/schema.d.ts.map +1 -0
- package/dist/chart-types/count-plot/schema.js +11 -0
- package/dist/chart-types/count-plot/schema.js.map +1 -0
- package/dist/chart-types/custom-spec/definition.d.ts +4 -0
- package/dist/chart-types/custom-spec/definition.d.ts.map +1 -0
- package/dist/chart-types/custom-spec/definition.js +28 -0
- package/dist/chart-types/custom-spec/definition.js.map +1 -0
- package/dist/chart-types/custom-spec/index.d.ts +3 -0
- package/dist/chart-types/custom-spec/index.d.ts.map +1 -0
- package/dist/chart-types/custom-spec/index.js +3 -0
- package/dist/chart-types/custom-spec/index.js.map +1 -0
- package/dist/chart-types/custom-spec/schema.d.ts +11 -0
- package/dist/chart-types/custom-spec/schema.d.ts.map +1 -0
- package/dist/chart-types/custom-spec/schema.js +9 -0
- package/dist/chart-types/custom-spec/schema.js.map +1 -0
- package/dist/chart-types/ecdf/definition.d.ts +4 -0
- package/dist/chart-types/ecdf/definition.d.ts.map +1 -0
- package/dist/chart-types/ecdf/definition.js +47 -0
- package/dist/chart-types/ecdf/definition.js.map +1 -0
- package/dist/chart-types/ecdf/index.d.ts +3 -0
- package/dist/chart-types/ecdf/index.d.ts.map +1 -0
- package/dist/chart-types/ecdf/index.js +3 -0
- package/dist/chart-types/ecdf/index.js.map +1 -0
- package/dist/chart-types/ecdf/schema.d.ts +15 -0
- package/dist/chart-types/ecdf/schema.d.ts.map +1 -0
- package/dist/chart-types/ecdf/schema.js +11 -0
- package/dist/chart-types/ecdf/schema.js.map +1 -0
- package/dist/chart-types/heatmap/definition.d.ts +4 -0
- package/dist/chart-types/heatmap/definition.d.ts.map +1 -0
- package/dist/chart-types/heatmap/definition.js +49 -0
- package/dist/chart-types/heatmap/definition.js.map +1 -0
- package/dist/chart-types/heatmap/index.d.ts +3 -0
- package/dist/chart-types/heatmap/index.d.ts.map +1 -0
- package/dist/chart-types/heatmap/index.js +3 -0
- package/dist/chart-types/heatmap/index.js.map +1 -0
- package/dist/chart-types/heatmap/schema.d.ts +17 -0
- package/dist/chart-types/heatmap/schema.d.ts.map +1 -0
- package/dist/chart-types/heatmap/schema.js +12 -0
- package/dist/chart-types/heatmap/schema.js.map +1 -0
- package/dist/chart-types/histogram/definition.d.ts +4 -0
- package/dist/chart-types/histogram/definition.d.ts.map +1 -0
- package/dist/chart-types/histogram/definition.js +49 -0
- package/dist/chart-types/histogram/definition.js.map +1 -0
- package/dist/chart-types/histogram/index.d.ts +3 -0
- package/dist/chart-types/histogram/index.d.ts.map +1 -0
- package/dist/chart-types/histogram/index.js +3 -0
- package/dist/chart-types/histogram/index.js.map +1 -0
- package/dist/chart-types/histogram/schema.d.ts +15 -0
- package/dist/chart-types/histogram/schema.d.ts.map +1 -0
- package/dist/chart-types/histogram/schema.js +11 -0
- package/dist/chart-types/histogram/schema.js.map +1 -0
- package/dist/chart-types/index.d.ts +109 -0
- package/dist/chart-types/index.d.ts.map +1 -0
- package/dist/chart-types/index.js +70 -0
- package/dist/chart-types/index.js.map +1 -0
- package/dist/chart-types/line-chart/definition.d.ts +4 -0
- package/dist/chart-types/line-chart/definition.d.ts.map +1 -0
- package/dist/chart-types/line-chart/definition.js +46 -0
- package/dist/chart-types/line-chart/definition.js.map +1 -0
- package/dist/chart-types/line-chart/index.d.ts +3 -0
- package/dist/chart-types/line-chart/index.d.ts.map +1 -0
- package/dist/chart-types/line-chart/index.js +3 -0
- package/dist/chart-types/line-chart/index.js.map +1 -0
- package/dist/chart-types/line-chart/schema.d.ts +17 -0
- package/dist/chart-types/line-chart/schema.d.ts.map +1 -0
- package/dist/chart-types/line-chart/schema.js +12 -0
- package/dist/chart-types/line-chart/schema.js.map +1 -0
- package/dist/chart-types/registry.d.ts +5 -0
- package/dist/chart-types/registry.d.ts.map +1 -0
- package/dist/chart-types/registry.js +28 -0
- package/dist/chart-types/registry.js.map +1 -0
- package/dist/dashboard/DashboardPanelErrorBoundary.d.ts +17 -0
- package/dist/dashboard/DashboardPanelErrorBoundary.d.ts.map +1 -0
- package/dist/dashboard/DashboardPanelErrorBoundary.js +21 -0
- package/dist/dashboard/DashboardPanelErrorBoundary.js.map +1 -0
- package/dist/dashboard/MosaicDashboard.d.ts +2 -4
- package/dist/dashboard/MosaicDashboard.d.ts.map +1 -1
- package/dist/dashboard/MosaicDashboard.js +42 -19
- package/dist/dashboard/MosaicDashboard.js.map +1 -1
- package/dist/dashboard/MosaicDashboardContext.d.ts +1 -0
- package/dist/dashboard/MosaicDashboardContext.d.ts.map +1 -1
- package/dist/dashboard/MosaicDashboardContext.js.map +1 -1
- package/dist/dashboard/MosaicDashboardPanel.d.ts +3 -0
- package/dist/dashboard/MosaicDashboardPanel.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboardPanel.js +26 -0
- package/dist/dashboard/MosaicDashboardPanel.js.map +1 -0
- package/dist/dashboard/MosaicDashboardPanelDragOverlay.d.ts +8 -0
- package/dist/dashboard/MosaicDashboardPanelDragOverlay.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboardPanelDragOverlay.js +17 -0
- package/dist/dashboard/MosaicDashboardPanelDragOverlay.js.map +1 -0
- package/dist/dashboard/MosaicDashboardPanelHeader.d.ts +13 -0
- package/dist/dashboard/MosaicDashboardPanelHeader.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboardPanelHeader.js +30 -0
- package/dist/dashboard/MosaicDashboardPanelHeader.js.map +1 -0
- package/dist/dashboard/MosaicDashboardPanelLayout.d.ts +10 -0
- package/dist/dashboard/MosaicDashboardPanelLayout.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboardPanelLayout.js +25 -0
- package/dist/dashboard/MosaicDashboardPanelLayout.js.map +1 -0
- package/dist/dashboard/MosaicDashboardPanels.d.ts +2 -0
- package/dist/dashboard/MosaicDashboardPanels.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboardPanels.js +52 -0
- package/dist/dashboard/MosaicDashboardPanels.js.map +1 -0
- package/dist/dashboard/MosaicDashboardProfilerPanelRenderer.d.ts +3 -0
- package/dist/dashboard/MosaicDashboardProfilerPanelRenderer.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboardProfilerPanelRenderer.js +32 -0
- package/dist/dashboard/MosaicDashboardProfilerPanelRenderer.js.map +1 -0
- package/dist/dashboard/MosaicDashboardSlice.d.ts +482 -27
- package/dist/dashboard/MosaicDashboardSlice.d.ts.map +1 -1
- package/dist/dashboard/MosaicDashboardSlice.js +478 -93
- package/dist/dashboard/MosaicDashboardSlice.js.map +1 -1
- package/dist/dashboard/MosaicDashboardToolbar.d.ts.map +1 -1
- package/dist/dashboard/MosaicDashboardToolbar.js +69 -7
- package/dist/dashboard/MosaicDashboardToolbar.js.map +1 -1
- package/dist/dashboard/MosaicDashboardVgPlotHeaderActions.d.ts +4 -0
- package/dist/dashboard/MosaicDashboardVgPlotHeaderActions.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboardVgPlotHeaderActions.js +29 -0
- package/dist/dashboard/MosaicDashboardVgPlotHeaderActions.js.map +1 -0
- package/dist/dashboard/MosaicDashboardVgPlotPanelRenderer.d.ts +3 -0
- package/dist/dashboard/MosaicDashboardVgPlotPanelRenderer.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboardVgPlotPanelRenderer.js +68 -0
- package/dist/dashboard/MosaicDashboardVgPlotPanelRenderer.js.map +1 -0
- package/dist/dashboard/VgPlotSpecPopoverEditor.d.ts.map +1 -1
- package/dist/dashboard/VgPlotSpecPopoverEditor.js +2 -2
- package/dist/dashboard/VgPlotSpecPopoverEditor.js.map +1 -1
- package/dist/dashboard/chart-settings/ChartSettings.d.ts +39 -0
- package/dist/dashboard/chart-settings/ChartSettings.d.ts.map +1 -0
- package/dist/dashboard/chart-settings/ChartSettings.js +90 -0
- package/dist/dashboard/chart-settings/ChartSettings.js.map +1 -0
- package/dist/dashboard/chart-settings/ChartSettingsContext.d.ts +20 -0
- package/dist/dashboard/chart-settings/ChartSettingsContext.d.ts.map +1 -0
- package/dist/dashboard/chart-settings/ChartSettingsContext.js +14 -0
- package/dist/dashboard/chart-settings/ChartSettingsContext.js.map +1 -0
- package/dist/dashboard/chart-settings/ChartSettingsPanel.d.ts +11 -0
- package/dist/dashboard/chart-settings/ChartSettingsPanel.d.ts.map +1 -0
- package/dist/dashboard/chart-settings/ChartSettingsPanel.js +8 -0
- package/dist/dashboard/chart-settings/ChartSettingsPanel.js.map +1 -0
- package/dist/dashboard/chart-settings/ChartTypeSelector.d.ts +11 -0
- package/dist/dashboard/chart-settings/ChartTypeSelector.d.ts.map +1 -0
- package/dist/dashboard/chart-settings/ChartTypeSelector.js +17 -0
- package/dist/dashboard/chart-settings/ChartTypeSelector.js.map +1 -0
- package/dist/dashboard/chart-settings/DynamicChartSettings.d.ts +11 -0
- package/dist/dashboard/chart-settings/DynamicChartSettings.d.ts.map +1 -0
- package/dist/dashboard/chart-settings/DynamicChartSettings.js +19 -0
- package/dist/dashboard/chart-settings/DynamicChartSettings.js.map +1 -0
- package/dist/dashboard/chart-settings/index.d.ts +6 -0
- package/dist/dashboard/chart-settings/index.d.ts.map +1 -0
- package/dist/dashboard/chart-settings/index.js +6 -0
- package/dist/dashboard/chart-settings/index.js.map +1 -0
- package/dist/dashboard/chart-settings/useTableColumns.d.ts +3 -0
- package/dist/dashboard/chart-settings/useTableColumns.d.ts.map +1 -0
- package/dist/dashboard/chart-settings/useTableColumns.js +12 -0
- package/dist/dashboard/chart-settings/useTableColumns.js.map +1 -0
- package/dist/dashboard/defaultPanelRenderers.d.ts +3 -0
- package/dist/dashboard/defaultPanelRenderers.d.ts.map +1 -0
- package/dist/dashboard/defaultPanelRenderers.js +11 -0
- package/dist/dashboard/defaultPanelRenderers.js.map +1 -0
- package/dist/dashboard/generateMosaicChartSpec.d.ts +15 -0
- package/dist/dashboard/generateMosaicChartSpec.d.ts.map +1 -0
- package/dist/dashboard/generateMosaicChartSpec.js +30 -0
- package/dist/dashboard/generateMosaicChartSpec.js.map +1 -0
- package/dist/editor/MosaicChartDisplay.d.ts.map +1 -1
- package/dist/editor/MosaicChartDisplay.js +6 -1
- package/dist/editor/MosaicChartDisplay.js.map +1 -1
- package/dist/index.d.ts +31 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -2
- package/dist/index.js.map +1 -1
- package/dist/profiler/useMosaicProfiler.d.ts.map +1 -1
- package/dist/profiler/useMosaicProfiler.js.map +1 -1
- package/dist/tableInterop.js.map +1 -1
- package/dist/useMosaicClient.d.ts +4 -15
- package/dist/useMosaicClient.d.ts.map +1 -1
- package/dist/useMosaicClient.js +10 -4
- package/dist/useMosaicClient.js.map +1 -1
- package/package.json +15 -9
- package/dist/chart-builders/createMosaicChartTool.d.ts +0 -45
- package/dist/chart-builders/createMosaicChartTool.d.ts.map +0 -1
- package/dist/chart-builders/createMosaicChartTool.js +0 -109
- package/dist/chart-builders/createMosaicChartTool.js.map +0 -1
- package/dist/dashboard/MosaicDashboardChartPanel.d.ts +0 -3
- package/dist/dashboard/MosaicDashboardChartPanel.d.ts.map +0 -1
- package/dist/dashboard/MosaicDashboardChartPanel.js +0 -49
- package/dist/dashboard/MosaicDashboardChartPanel.js.map +0 -1
- package/dist/dashboard/MosaicDashboardCharts.d.ts +0 -3
- package/dist/dashboard/MosaicDashboardCharts.d.ts.map +0 -1
- package/dist/dashboard/MosaicDashboardCharts.js +0 -45
- package/dist/dashboard/MosaicDashboardCharts.js.map +0 -1
- package/dist/dashboard/MosaicDashboardProfiler.d.ts +0 -3
- package/dist/dashboard/MosaicDashboardProfiler.d.ts.map +0 -1
- package/dist/dashboard/MosaicDashboardProfiler.js +0 -21
- package/dist/dashboard/MosaicDashboardProfiler.js.map +0 -1
- package/dist/use-mosaic.d.ts +0 -11
- package/dist/use-mosaic.d.ts.map +0 -1
- package/dist/use-mosaic.js +0 -42
- package/dist/use-mosaic.js.map +0 -1
|
@@ -1,127 +1,387 @@
|
|
|
1
1
|
import { createId } from '@paralleldrive/cuid2';
|
|
2
|
-
import {
|
|
2
|
+
import { DEFAULT_GRID_COLS, getGridColsForBreakpoint, } from '@sqlrooms/layout';
|
|
3
|
+
import { isLayoutGridNode, isLayoutNodeKey, isLayoutPanelNode, isLayoutSplitNode, LayoutNode as LayoutNodeSchema, } from '@sqlrooms/layout-config';
|
|
3
4
|
import { createSlice, useBaseRoomStore, } from '@sqlrooms/room-store';
|
|
4
5
|
import { produce } from 'immer';
|
|
5
6
|
import { z } from 'zod';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
xLabel: 'Category',
|
|
36
|
-
yLabel: 'Amount',
|
|
37
|
-
width: 560,
|
|
38
|
-
height: 320,
|
|
39
|
-
}, null, 2);
|
|
40
|
-
export const DEFAULT_MOSAIC_DASHBOARD_CHART_SPEC = JSON.parse(DEFAULT_MOSAIC_DASHBOARD_CHART_VGPLOT);
|
|
41
|
-
export const MosaicDashboardChartConfig = z.object({
|
|
7
|
+
import { destroyRetainedVgPlotChart, } from '../VgPlotChart';
|
|
8
|
+
import { VgPlotChartConfig } from '../chart-types';
|
|
9
|
+
/**
|
|
10
|
+
* Panel key used for function-form panel definitions registered by
|
|
11
|
+
* `MosaicDashboardPanels`. Individual dashboard panels are represented as
|
|
12
|
+
* `LayoutPanelNode` entries whose `panel` property carries
|
|
13
|
+
* `{ key: MOSAIC_DASHBOARD_PANEL, meta: { dashboardId, panelId } }`.
|
|
14
|
+
*/
|
|
15
|
+
export const MOSAIC_DASHBOARD_PANEL = 'mosaic-dashboard-panel';
|
|
16
|
+
export const MOSAIC_DASHBOARD_VGPLOT_PANEL_TYPE = 'vgplot';
|
|
17
|
+
export const MOSAIC_DASHBOARD_PROFILER_PANEL_TYPE = 'profiler';
|
|
18
|
+
export const MosaicDashboardLayoutType = z.enum(['dock', 'grid']);
|
|
19
|
+
export const MosaicDashboardPanelSource = z.object({
|
|
20
|
+
tableName: z.string().optional(),
|
|
21
|
+
sqlQuery: z.string().optional(),
|
|
22
|
+
});
|
|
23
|
+
// Profiler panel config
|
|
24
|
+
export const ProfilerPanelConfig = z.object({
|
|
25
|
+
pageSize: z.number().optional(),
|
|
26
|
+
});
|
|
27
|
+
// Panel configs discriminated by type
|
|
28
|
+
export const VgPlotPanelConfig = z.object({
|
|
29
|
+
id: z.string(),
|
|
30
|
+
type: z.literal(MOSAIC_DASHBOARD_VGPLOT_PANEL_TYPE),
|
|
31
|
+
title: z.string().default('Panel'),
|
|
32
|
+
source: MosaicDashboardPanelSource.optional(),
|
|
33
|
+
config: VgPlotChartConfig,
|
|
34
|
+
});
|
|
35
|
+
export const ProfilerPanel = z.object({
|
|
42
36
|
id: z.string(),
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
.default(DEFAULT_MOSAIC_DASHBOARD_CHART_SPEC),
|
|
37
|
+
type: z.literal(MOSAIC_DASHBOARD_PROFILER_PANEL_TYPE),
|
|
38
|
+
title: z.string().default('Panel'),
|
|
39
|
+
source: MosaicDashboardPanelSource.optional(),
|
|
40
|
+
config: ProfilerPanelConfig,
|
|
48
41
|
});
|
|
42
|
+
// Legacy panel for backward compatibility
|
|
43
|
+
export const LegacyPanelConfig = z.object({
|
|
44
|
+
id: z.string(),
|
|
45
|
+
type: z.string(),
|
|
46
|
+
title: z.string().default('Panel'),
|
|
47
|
+
source: MosaicDashboardPanelSource.optional(),
|
|
48
|
+
config: z.record(z.string(), z.unknown()).default({}),
|
|
49
|
+
});
|
|
50
|
+
// Discriminated union of all panel types
|
|
51
|
+
export const MosaicDashboardPanelConfig = z
|
|
52
|
+
.discriminatedUnion('type', [VgPlotPanelConfig, ProfilerPanel])
|
|
53
|
+
.or(LegacyPanelConfig);
|
|
54
|
+
export function createMosaicDashboardVgPlotPanelConfig(title, config, source) {
|
|
55
|
+
return VgPlotPanelConfig.parse({
|
|
56
|
+
id: createId(),
|
|
57
|
+
type: MOSAIC_DASHBOARD_VGPLOT_PANEL_TYPE,
|
|
58
|
+
title,
|
|
59
|
+
source,
|
|
60
|
+
config,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
export function createMosaicDashboardProfilerPanelConfig(options = {}) {
|
|
64
|
+
return {
|
|
65
|
+
id: createId(),
|
|
66
|
+
type: MOSAIC_DASHBOARD_PROFILER_PANEL_TYPE,
|
|
67
|
+
title: options.title ?? 'Profiler',
|
|
68
|
+
source: options.source,
|
|
69
|
+
config: {
|
|
70
|
+
pageSize: options.pageSize ?? 10,
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
49
74
|
export const MosaicDashboardEntry = z.object({
|
|
50
75
|
id: z.string(),
|
|
51
76
|
title: z.string().default('Dashboard'),
|
|
77
|
+
layoutType: MosaicDashboardLayoutType.default('dock'),
|
|
52
78
|
selectedTable: z.string().optional(),
|
|
53
|
-
|
|
54
|
-
layout:
|
|
79
|
+
panels: z.array(MosaicDashboardPanelConfig).default([]),
|
|
80
|
+
layout: LayoutNodeSchema.nullable().default(null),
|
|
55
81
|
updatedAt: z.number().default(0),
|
|
56
82
|
});
|
|
57
83
|
export const MosaicDashboardSliceConfig = z.object({
|
|
58
84
|
dashboardsById: z.record(z.string(), MosaicDashboardEntry).default({}),
|
|
59
85
|
});
|
|
60
|
-
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
// Layout tree helpers (operate on the new LayoutNode types)
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
function createDashboardPanelNode(dashboardId, panelId) {
|
|
90
|
+
return {
|
|
91
|
+
type: 'panel',
|
|
92
|
+
id: getMosaicDashboardPanelId(dashboardId, panelId),
|
|
93
|
+
minSize: 200,
|
|
94
|
+
panel: {
|
|
95
|
+
key: MOSAIC_DASHBOARD_PANEL,
|
|
96
|
+
meta: { dashboardId, panelId },
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function getDashboardPanelTypesByLayoutId(dashboardId, panels) {
|
|
101
|
+
return Object.fromEntries(panels.map((panel) => [
|
|
102
|
+
getMosaicDashboardPanelId(dashboardId, panel.id),
|
|
103
|
+
panel.type,
|
|
104
|
+
]));
|
|
105
|
+
}
|
|
106
|
+
function appendPanelToLayout(layout, panelNode) {
|
|
61
107
|
if (!layout) {
|
|
62
|
-
return
|
|
108
|
+
return panelNode;
|
|
63
109
|
}
|
|
64
110
|
return {
|
|
65
111
|
type: 'split',
|
|
112
|
+
id: `split-${createId()}`,
|
|
66
113
|
direction: 'row',
|
|
67
|
-
children: [layout,
|
|
114
|
+
children: [layout, panelNode],
|
|
68
115
|
};
|
|
69
116
|
}
|
|
70
|
-
function
|
|
117
|
+
function createDashboardGridLayout(dashboardId, panelNode) {
|
|
118
|
+
const children = panelNode ? [panelNode] : [];
|
|
119
|
+
const layouts = createDashboardGridLayoutsForChildren(children);
|
|
120
|
+
return {
|
|
121
|
+
type: 'grid',
|
|
122
|
+
id: getMosaicDashboardGridId(dashboardId),
|
|
123
|
+
children,
|
|
124
|
+
rowHeight: 150,
|
|
125
|
+
margin: [12, 12],
|
|
126
|
+
containerPadding: [0, 0],
|
|
127
|
+
compactType: 'vertical',
|
|
128
|
+
preventCollision: false,
|
|
129
|
+
resizeHandles: ['e', 's', 'w', 'se', 'sw'],
|
|
130
|
+
layouts,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function getLayoutChildId(node) {
|
|
134
|
+
return isLayoutNodeKey(node) ? node : node.id;
|
|
135
|
+
}
|
|
136
|
+
function createDashboardGridItem(panelId, layout, cols = 12, panelType) {
|
|
137
|
+
const effectiveCols = Math.max(1, cols);
|
|
138
|
+
const w = panelType === MOSAIC_DASHBOARD_PROFILER_PANEL_TYPE
|
|
139
|
+
? effectiveCols
|
|
140
|
+
: Math.max(1, Math.ceil(effectiveCols / 2));
|
|
141
|
+
const h = 2;
|
|
142
|
+
const bottom = layout.reduce((max, item) => Math.max(max, item.y + item.h), 0);
|
|
143
|
+
for (let y = 0; y <= bottom; y += 1) {
|
|
144
|
+
for (let x = 0; x <= effectiveCols - w; x += 1) {
|
|
145
|
+
const overlaps = layout.some((item) => x < item.x + item.w &&
|
|
146
|
+
x + w > item.x &&
|
|
147
|
+
y < item.y + item.h &&
|
|
148
|
+
y + h > item.y);
|
|
149
|
+
if (!overlaps) {
|
|
150
|
+
return {
|
|
151
|
+
i: panelId,
|
|
152
|
+
x,
|
|
153
|
+
y,
|
|
154
|
+
w,
|
|
155
|
+
h,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return {
|
|
161
|
+
i: panelId,
|
|
162
|
+
x: 0,
|
|
163
|
+
y: bottom,
|
|
164
|
+
w,
|
|
165
|
+
h,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
function createDashboardGridLayoutsForChildren(children, sourceLayouts, cols, panelTypesByLayoutId = {}) {
|
|
169
|
+
const childIds = new Set(children.map((child) => getLayoutChildId(child)));
|
|
170
|
+
const sourceEntries = new Map(Object.keys(DEFAULT_GRID_COLS).map((breakpoint) => [breakpoint, []]));
|
|
171
|
+
for (const [breakpoint, breakpointLayout] of Object.entries(sourceLayouts ?? {})) {
|
|
172
|
+
sourceEntries.set(breakpoint, breakpointLayout);
|
|
173
|
+
}
|
|
174
|
+
return Object.fromEntries([...sourceEntries.entries()].map(([breakpoint, breakpointLayout]) => {
|
|
175
|
+
const nextLayout = breakpointLayout.filter((item) => childIds.has(item.i));
|
|
176
|
+
const layoutItemIds = new Set(nextLayout.map((item) => item.i));
|
|
177
|
+
for (const child of children) {
|
|
178
|
+
const childId = getLayoutChildId(child);
|
|
179
|
+
if (!layoutItemIds.has(childId)) {
|
|
180
|
+
const item = createDashboardGridItem(childId, nextLayout, getGridColsForBreakpoint(cols, breakpoint), panelTypesByLayoutId[childId]);
|
|
181
|
+
nextLayout.push(item);
|
|
182
|
+
layoutItemIds.add(childId);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return [breakpoint, nextLayout];
|
|
186
|
+
}));
|
|
187
|
+
}
|
|
188
|
+
function isExpectedDashboardPanelNode(node, expectedPanelIds) {
|
|
189
|
+
return expectedPanelIds.has(getLayoutChildId(node));
|
|
190
|
+
}
|
|
191
|
+
function collectDashboardPanelNodes(layout, expectedPanelIds, nodes = [], seen = new Set()) {
|
|
71
192
|
if (!layout)
|
|
72
|
-
return
|
|
73
|
-
if (
|
|
74
|
-
|
|
193
|
+
return nodes;
|
|
194
|
+
if (isLayoutNodeKey(layout) || isLayoutPanelNode(layout)) {
|
|
195
|
+
if (isExpectedDashboardPanelNode(layout, expectedPanelIds)) {
|
|
196
|
+
const id = getLayoutChildId(layout);
|
|
197
|
+
if (!seen.has(id)) {
|
|
198
|
+
nodes.push(layout);
|
|
199
|
+
seen.add(id);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return nodes;
|
|
75
203
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
return null;
|
|
81
|
-
if (nextChildren.length === 1) {
|
|
82
|
-
const onlyChild = nextChildren[0];
|
|
83
|
-
return onlyChild ?? null;
|
|
204
|
+
if (isLayoutSplitNode(layout) || isLayoutGridNode(layout)) {
|
|
205
|
+
for (const child of layout.children) {
|
|
206
|
+
collectDashboardPanelNodes(child, expectedPanelIds, nodes, seen);
|
|
207
|
+
}
|
|
84
208
|
}
|
|
209
|
+
return nodes;
|
|
210
|
+
}
|
|
211
|
+
function normalizeDashboardGridLayout(layout, dashboardId, expectedPanelIds, panelTypesByLayoutId = {}) {
|
|
212
|
+
const collectedPanelIds = collectPanelIds(layout);
|
|
213
|
+
const existingExpectedPanelIds = new Set([...expectedPanelIds].filter((panelId) => collectedPanelIds.has(panelId)));
|
|
214
|
+
const children = collectDashboardPanelNodes(layout, existingExpectedPanelIds);
|
|
215
|
+
const layouts = createDashboardGridLayoutsForChildren(children, isLayoutGridNode(layout) ? layout.layouts : undefined, isLayoutGridNode(layout) ? layout.cols : undefined, panelTypesByLayoutId);
|
|
216
|
+
if (isLayoutGridNode(layout)) {
|
|
217
|
+
return {
|
|
218
|
+
...layout,
|
|
219
|
+
children,
|
|
220
|
+
layouts,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
return {
|
|
224
|
+
...createDashboardGridLayout(dashboardId),
|
|
225
|
+
children,
|
|
226
|
+
layouts,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
function appendPanelToGridLayout(layout, dashboardId, panelNode, panelType, panelTypesByLayoutId = {}) {
|
|
230
|
+
const nextPanelTypesByLayoutId = {
|
|
231
|
+
...panelTypesByLayoutId,
|
|
232
|
+
[panelNode.id]: panelType ?? panelTypesByLayoutId[panelNode.id],
|
|
233
|
+
};
|
|
234
|
+
if (!isLayoutGridNode(layout)) {
|
|
235
|
+
const dashboardPanelPrefix = `dashboard:${dashboardId}:panel:`;
|
|
236
|
+
const expectedPanelIds = new Set([...collectPanelIds(layout)].filter((panelId) => panelId.startsWith(dashboardPanelPrefix)));
|
|
237
|
+
expectedPanelIds.add(panelNode.id);
|
|
238
|
+
const normalizedLayout = normalizeDashboardGridLayout(layout, dashboardId, expectedPanelIds, nextPanelTypesByLayoutId);
|
|
239
|
+
return appendPanelToGridLayout(normalizedLayout, dashboardId, panelNode, panelType, nextPanelTypesByLayoutId);
|
|
240
|
+
}
|
|
241
|
+
const hasChild = layout.children.some((child) => {
|
|
242
|
+
if (isLayoutNodeKey(child))
|
|
243
|
+
return child === panelNode.id;
|
|
244
|
+
return child.id === panelNode.id;
|
|
245
|
+
});
|
|
246
|
+
const children = hasChild ? layout.children : [...layout.children, panelNode];
|
|
247
|
+
const layouts = Object.fromEntries(Object.entries(createDashboardGridLayoutsForChildren(children, layout.layouts, layout.cols, nextPanelTypesByLayoutId) ?? {}).map(([breakpoint, breakpointLayout]) => {
|
|
248
|
+
if (breakpointLayout.some((item) => item.i === panelNode.id)) {
|
|
249
|
+
return [breakpoint, breakpointLayout];
|
|
250
|
+
}
|
|
251
|
+
return [
|
|
252
|
+
breakpoint,
|
|
253
|
+
[
|
|
254
|
+
...breakpointLayout,
|
|
255
|
+
createDashboardGridItem(panelNode.id, breakpointLayout, getGridColsForBreakpoint(layout.cols, breakpoint), nextPanelTypesByLayoutId[panelNode.id]),
|
|
256
|
+
],
|
|
257
|
+
];
|
|
258
|
+
}));
|
|
85
259
|
return {
|
|
86
260
|
...layout,
|
|
87
|
-
children
|
|
261
|
+
children,
|
|
262
|
+
layouts,
|
|
88
263
|
};
|
|
89
264
|
}
|
|
265
|
+
function removePanelFromLayout(layout, panelId) {
|
|
266
|
+
if (!layout)
|
|
267
|
+
return null;
|
|
268
|
+
if (isLayoutNodeKey(layout)) {
|
|
269
|
+
return layout === panelId ? null : layout;
|
|
270
|
+
}
|
|
271
|
+
if (isLayoutPanelNode(layout)) {
|
|
272
|
+
return layout.id === panelId ? null : layout;
|
|
273
|
+
}
|
|
274
|
+
if (isLayoutSplitNode(layout)) {
|
|
275
|
+
const nextChildren = layout.children
|
|
276
|
+
.map((child) => removePanelFromLayout(child, panelId))
|
|
277
|
+
.filter((child) => child !== null);
|
|
278
|
+
if (nextChildren.length === 0)
|
|
279
|
+
return null;
|
|
280
|
+
if (nextChildren.length === 1)
|
|
281
|
+
return nextChildren[0] ?? null;
|
|
282
|
+
return { ...layout, children: nextChildren };
|
|
283
|
+
}
|
|
284
|
+
if (isLayoutGridNode(layout)) {
|
|
285
|
+
const nextChildren = layout.children.filter((child) => {
|
|
286
|
+
if (isLayoutNodeKey(child))
|
|
287
|
+
return child !== panelId;
|
|
288
|
+
return child.id !== panelId;
|
|
289
|
+
});
|
|
290
|
+
const nextLayouts = layout.layouts
|
|
291
|
+
? Object.fromEntries(Object.entries(layout.layouts).map(([breakpoint, breakpointLayout]) => [
|
|
292
|
+
breakpoint,
|
|
293
|
+
breakpointLayout.filter((item) => item.i !== panelId),
|
|
294
|
+
]))
|
|
295
|
+
: layout.layouts;
|
|
296
|
+
if (nextChildren.length === 0)
|
|
297
|
+
return null;
|
|
298
|
+
return { ...layout, children: nextChildren, layouts: nextLayouts };
|
|
299
|
+
}
|
|
300
|
+
return layout;
|
|
301
|
+
}
|
|
90
302
|
function collectPanelIds(layout, panelIds = new Set()) {
|
|
91
303
|
if (!layout)
|
|
92
304
|
return panelIds;
|
|
93
|
-
if (
|
|
305
|
+
if (isLayoutNodeKey(layout)) {
|
|
94
306
|
panelIds.add(layout);
|
|
95
307
|
return panelIds;
|
|
96
308
|
}
|
|
97
|
-
|
|
98
|
-
|
|
309
|
+
if (isLayoutPanelNode(layout)) {
|
|
310
|
+
panelIds.add(layout.id);
|
|
311
|
+
return panelIds;
|
|
312
|
+
}
|
|
313
|
+
if (isLayoutSplitNode(layout)) {
|
|
314
|
+
for (const child of layout.children) {
|
|
315
|
+
collectPanelIds(child, panelIds);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
if (isLayoutGridNode(layout)) {
|
|
319
|
+
for (const child of layout.children) {
|
|
320
|
+
collectPanelIds(child, panelIds);
|
|
321
|
+
}
|
|
99
322
|
}
|
|
100
323
|
return panelIds;
|
|
101
324
|
}
|
|
102
|
-
function
|
|
325
|
+
function ensureLayoutContainsDashboardPanels(layout, dashboardId, panelIds, layoutType = 'dock', panelTypesByLayoutId = {}) {
|
|
103
326
|
let nextLayout = layout;
|
|
104
|
-
|
|
327
|
+
if (layoutType === 'grid') {
|
|
328
|
+
const expectedPanelIds = new Set(panelIds.map((panelId) => getMosaicDashboardPanelId(dashboardId, panelId)));
|
|
329
|
+
nextLayout = normalizeDashboardGridLayout(nextLayout, dashboardId, expectedPanelIds, panelTypesByLayoutId);
|
|
330
|
+
}
|
|
331
|
+
const existing = collectPanelIds(nextLayout);
|
|
105
332
|
for (const panelId of panelIds) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
333
|
+
const layoutPanelId = getMosaicDashboardPanelId(dashboardId, panelId);
|
|
334
|
+
if (!existing.has(layoutPanelId)) {
|
|
335
|
+
const panelNode = createDashboardPanelNode(dashboardId, panelId);
|
|
336
|
+
nextLayout =
|
|
337
|
+
layoutType === 'grid'
|
|
338
|
+
? appendPanelToGridLayout(nextLayout, dashboardId, panelNode, panelTypesByLayoutId[layoutPanelId], panelTypesByLayoutId)
|
|
339
|
+
: appendPanelToLayout(nextLayout, panelNode);
|
|
340
|
+
existing.add(layoutPanelId);
|
|
109
341
|
}
|
|
110
342
|
}
|
|
111
343
|
return nextLayout;
|
|
112
344
|
}
|
|
113
|
-
export function
|
|
114
|
-
return
|
|
345
|
+
export function isVgPlotPanelConfig(panel) {
|
|
346
|
+
return panel.type === MOSAIC_DASHBOARD_VGPLOT_PANEL_TYPE;
|
|
347
|
+
}
|
|
348
|
+
export function getMosaicDashboardPanelId(dashboardId, panelId) {
|
|
349
|
+
return `dashboard:${dashboardId}:panel:${panelId}`;
|
|
115
350
|
}
|
|
116
|
-
export function
|
|
117
|
-
return `dashboard:${dashboardId}:
|
|
351
|
+
export function getMosaicDashboardDockId(dashboardId) {
|
|
352
|
+
return `dashboard:${dashboardId}:dock`;
|
|
353
|
+
}
|
|
354
|
+
export function getMosaicDashboardGridId(dashboardId) {
|
|
355
|
+
return `dashboard:${dashboardId}:grid`;
|
|
118
356
|
}
|
|
119
357
|
export function getMosaicDashboardSelectionName(dashboardId) {
|
|
120
358
|
return `dashboard:${dashboardId}:brush`;
|
|
121
359
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
360
|
+
function destroyDashboardRuntimeChart(chart) {
|
|
361
|
+
if (!chart)
|
|
362
|
+
return;
|
|
363
|
+
destroyRetainedVgPlotChart(chart);
|
|
364
|
+
}
|
|
365
|
+
function evictDashboardSelection(state, dashboardId) {
|
|
366
|
+
state.mosaic.selections[getMosaicDashboardSelectionName(dashboardId)]?.reset();
|
|
367
|
+
}
|
|
368
|
+
function shouldEvictPanelRuntimeForPatch(panel, patch) {
|
|
369
|
+
if (patch.type && patch.type !== panel.type) {
|
|
370
|
+
return true;
|
|
371
|
+
}
|
|
372
|
+
if (panel.type === MOSAIC_DASHBOARD_VGPLOT_PANEL_TYPE) {
|
|
373
|
+
return Boolean(patch.config &&
|
|
374
|
+
Object.prototype.hasOwnProperty.call(patch.config, 'vgplot'));
|
|
375
|
+
}
|
|
376
|
+
return false;
|
|
377
|
+
}
|
|
378
|
+
export function resolveMosaicDashboardPanelSource(dashboard, panel) {
|
|
379
|
+
if (panel.source?.sqlQuery || panel.source?.tableName) {
|
|
380
|
+
return panel.source;
|
|
381
|
+
}
|
|
382
|
+
return dashboard.selectedTable
|
|
383
|
+
? { tableName: dashboard.selectedTable }
|
|
384
|
+
: undefined;
|
|
125
385
|
}
|
|
126
386
|
export function createDefaultMosaicDashboardConfig(props) {
|
|
127
387
|
return MosaicDashboardSliceConfig.parse({
|
|
@@ -133,12 +393,19 @@ export function createMosaicDashboardSlice(props = {}) {
|
|
|
133
393
|
return createSlice((set, get) => ({
|
|
134
394
|
mosaicDashboard: {
|
|
135
395
|
config: createDefaultMosaicDashboardConfig(props.config),
|
|
136
|
-
|
|
396
|
+
runtime: {
|
|
397
|
+
retainedChartsByPanelId: {},
|
|
398
|
+
},
|
|
399
|
+
chartBuilders: props.chartBuilders,
|
|
400
|
+
chartTypes: props.chartTypes,
|
|
401
|
+
addPanelActions: props.addPanelActions ?? [],
|
|
402
|
+
panelRenderers: props.panelRenderers ?? {},
|
|
403
|
+
createDashboard(title, layoutType) {
|
|
137
404
|
const dashboardId = createId();
|
|
138
|
-
get().mosaicDashboard.ensureDashboard(dashboardId, title);
|
|
405
|
+
get().mosaicDashboard.ensureDashboard(dashboardId, title, layoutType);
|
|
139
406
|
return dashboardId;
|
|
140
407
|
},
|
|
141
|
-
ensureDashboard(dashboardId, title) {
|
|
408
|
+
ensureDashboard(dashboardId, title, layoutType) {
|
|
142
409
|
set((state) => produce(state, (draft) => {
|
|
143
410
|
const existing = draft.mosaicDashboard.config.dashboardsById[dashboardId];
|
|
144
411
|
if (existing) {
|
|
@@ -151,14 +418,20 @@ export function createMosaicDashboardSlice(props = {}) {
|
|
|
151
418
|
draft.mosaicDashboard.config.dashboardsById[dashboardId] = {
|
|
152
419
|
id: dashboardId,
|
|
153
420
|
title: title ?? 'Dashboard',
|
|
421
|
+
layoutType: layoutType ?? 'dock',
|
|
154
422
|
selectedTable: undefined,
|
|
155
|
-
|
|
156
|
-
layout:
|
|
423
|
+
panels: [],
|
|
424
|
+
layout: layoutType === 'grid'
|
|
425
|
+
? createDashboardGridLayout(dashboardId)
|
|
426
|
+
: null,
|
|
157
427
|
updatedAt: Date.now(),
|
|
158
428
|
};
|
|
159
429
|
}));
|
|
160
430
|
},
|
|
161
431
|
removeDashboard(dashboardId) {
|
|
432
|
+
get().mosaicDashboard.evictDashboardRuntime(dashboardId, {
|
|
433
|
+
resetSelection: true,
|
|
434
|
+
});
|
|
162
435
|
set((state) => produce(state, (draft) => {
|
|
163
436
|
delete draft.mosaicDashboard.config.dashboardsById[dashboardId];
|
|
164
437
|
}));
|
|
@@ -166,6 +439,11 @@ export function createMosaicDashboardSlice(props = {}) {
|
|
|
166
439
|
getDashboard(dashboardId) {
|
|
167
440
|
return get().mosaicDashboard.config.dashboardsById[dashboardId];
|
|
168
441
|
},
|
|
442
|
+
setConfig(config) {
|
|
443
|
+
set((state) => produce(state, (draft) => {
|
|
444
|
+
draft.mosaicDashboard.config = config;
|
|
445
|
+
}));
|
|
446
|
+
},
|
|
169
447
|
setSelectedTable(dashboardId, tableName) {
|
|
170
448
|
get().mosaicDashboard.ensureDashboard(dashboardId);
|
|
171
449
|
set((state) => produce(state, (draft) => {
|
|
@@ -176,48 +454,155 @@ export function createMosaicDashboardSlice(props = {}) {
|
|
|
176
454
|
dashboard.updatedAt = Date.now();
|
|
177
455
|
}));
|
|
178
456
|
},
|
|
179
|
-
|
|
457
|
+
registerPanelRenderer(type, renderer) {
|
|
458
|
+
set((state) => produce(state, (draft) => {
|
|
459
|
+
draft.mosaicDashboard.panelRenderers[type] = renderer;
|
|
460
|
+
}));
|
|
461
|
+
},
|
|
462
|
+
unregisterPanelRenderer(type) {
|
|
463
|
+
set((state) => produce(state, (draft) => {
|
|
464
|
+
delete draft.mosaicDashboard.panelRenderers[type];
|
|
465
|
+
}));
|
|
466
|
+
},
|
|
467
|
+
addPanel(dashboardId, panel) {
|
|
180
468
|
get().mosaicDashboard.ensureDashboard(dashboardId);
|
|
181
469
|
set((state) => produce(state, (draft) => {
|
|
182
470
|
const dashboard = draft.mosaicDashboard.config.dashboardsById[dashboardId];
|
|
183
471
|
if (!dashboard)
|
|
184
472
|
return;
|
|
185
|
-
dashboard.
|
|
186
|
-
|
|
473
|
+
dashboard.panels.push(panel);
|
|
474
|
+
const panelNode = createDashboardPanelNode(dashboardId, panel.id);
|
|
475
|
+
const panelTypesByLayoutId = getDashboardPanelTypesByLayoutId(dashboardId, dashboard.panels);
|
|
476
|
+
dashboard.layout =
|
|
477
|
+
dashboard.layoutType === 'grid'
|
|
478
|
+
? appendPanelToGridLayout(dashboard.layout, dashboardId, panelNode, panel.type, panelTypesByLayoutId)
|
|
479
|
+
: appendPanelToLayout(dashboard.layout, panelNode);
|
|
187
480
|
dashboard.updatedAt = Date.now();
|
|
188
481
|
}));
|
|
189
|
-
return
|
|
482
|
+
return panel.id;
|
|
190
483
|
},
|
|
191
|
-
|
|
484
|
+
updatePanel(dashboardId, panelId, patch) {
|
|
485
|
+
const existing = get().mosaicDashboard.config.dashboardsById[dashboardId]?.panels.find((candidate) => candidate.id === panelId);
|
|
486
|
+
const shouldEvict = existing
|
|
487
|
+
? shouldEvictPanelRuntimeForPatch(existing, patch)
|
|
488
|
+
: false;
|
|
192
489
|
set((state) => produce(state, (draft) => {
|
|
193
490
|
const dashboard = draft.mosaicDashboard.config.dashboardsById[dashboardId];
|
|
194
491
|
if (!dashboard)
|
|
195
492
|
return;
|
|
196
|
-
const
|
|
197
|
-
if (!
|
|
493
|
+
const panel = dashboard.panels.find((candidate) => candidate.id === panelId);
|
|
494
|
+
if (!panel)
|
|
198
495
|
return;
|
|
199
|
-
Object.assign(
|
|
496
|
+
Object.assign(panel, patch);
|
|
200
497
|
dashboard.updatedAt = Date.now();
|
|
201
498
|
}));
|
|
499
|
+
if (shouldEvict) {
|
|
500
|
+
get().mosaicDashboard.evictPanelRuntime(dashboardId, panelId);
|
|
501
|
+
}
|
|
202
502
|
},
|
|
203
|
-
|
|
503
|
+
removePanel(dashboardId, panelId) {
|
|
504
|
+
get().mosaicDashboard.evictPanelRuntime(dashboardId, panelId);
|
|
204
505
|
set((state) => produce(state, (draft) => {
|
|
205
506
|
const dashboard = draft.mosaicDashboard.config.dashboardsById[dashboardId];
|
|
206
507
|
if (!dashboard)
|
|
207
508
|
return;
|
|
208
|
-
dashboard.
|
|
209
|
-
dashboard.layout = removePanelFromLayout(dashboard.layout, getMosaicDashboardPanelId(dashboardId,
|
|
509
|
+
dashboard.panels = dashboard.panels.filter((panel) => panel.id !== panelId);
|
|
510
|
+
dashboard.layout = removePanelFromLayout(dashboard.layout, getMosaicDashboardPanelId(dashboardId, panelId));
|
|
210
511
|
dashboard.updatedAt = Date.now();
|
|
211
512
|
}));
|
|
212
513
|
},
|
|
514
|
+
getRetainedChart(dashboardId, panelId) {
|
|
515
|
+
return get().mosaicDashboard.runtime.retainedChartsByPanelId[getMosaicDashboardPanelId(dashboardId, panelId)];
|
|
516
|
+
},
|
|
517
|
+
setRetainedChart(dashboardId, panelId, chart) {
|
|
518
|
+
const runtimePanelId = getMosaicDashboardPanelId(dashboardId, panelId);
|
|
519
|
+
const previous = get().mosaicDashboard.runtime.retainedChartsByPanelId[runtimePanelId];
|
|
520
|
+
if (previous && previous !== chart) {
|
|
521
|
+
destroyDashboardRuntimeChart(previous);
|
|
522
|
+
}
|
|
523
|
+
set((state) => ({
|
|
524
|
+
mosaicDashboard: {
|
|
525
|
+
...state.mosaicDashboard,
|
|
526
|
+
runtime: {
|
|
527
|
+
...state.mosaicDashboard.runtime,
|
|
528
|
+
retainedChartsByPanelId: {
|
|
529
|
+
...state.mosaicDashboard.runtime.retainedChartsByPanelId,
|
|
530
|
+
[runtimePanelId]: chart,
|
|
531
|
+
},
|
|
532
|
+
},
|
|
533
|
+
},
|
|
534
|
+
}));
|
|
535
|
+
},
|
|
536
|
+
evictPanelRuntime(dashboardId, panelId) {
|
|
537
|
+
const runtimePanelId = getMosaicDashboardPanelId(dashboardId, panelId);
|
|
538
|
+
const existing = get().mosaicDashboard.runtime.retainedChartsByPanelId[runtimePanelId];
|
|
539
|
+
destroyDashboardRuntimeChart(existing);
|
|
540
|
+
set((state) => {
|
|
541
|
+
const nextRetainedChartsByPanelId = {
|
|
542
|
+
...state.mosaicDashboard.runtime.retainedChartsByPanelId,
|
|
543
|
+
};
|
|
544
|
+
delete nextRetainedChartsByPanelId[runtimePanelId];
|
|
545
|
+
return {
|
|
546
|
+
mosaicDashboard: {
|
|
547
|
+
...state.mosaicDashboard,
|
|
548
|
+
runtime: {
|
|
549
|
+
...state.mosaicDashboard.runtime,
|
|
550
|
+
retainedChartsByPanelId: nextRetainedChartsByPanelId,
|
|
551
|
+
},
|
|
552
|
+
},
|
|
553
|
+
};
|
|
554
|
+
});
|
|
555
|
+
},
|
|
556
|
+
evictDashboardRuntime(dashboardId, options) {
|
|
557
|
+
const runtimePrefix = `dashboard:${dashboardId}:panel:`;
|
|
558
|
+
const existingEntries = Object.entries(get().mosaicDashboard.runtime.retainedChartsByPanelId).filter(([runtimePanelId]) => runtimePanelId.startsWith(runtimePrefix));
|
|
559
|
+
existingEntries.forEach(([, chart]) => {
|
|
560
|
+
destroyDashboardRuntimeChart(chart);
|
|
561
|
+
});
|
|
562
|
+
if (options?.resetSelection) {
|
|
563
|
+
evictDashboardSelection(get(), dashboardId);
|
|
564
|
+
}
|
|
565
|
+
set((state) => {
|
|
566
|
+
const nextRetainedChartsByPanelId = {
|
|
567
|
+
...state.mosaicDashboard.runtime.retainedChartsByPanelId,
|
|
568
|
+
};
|
|
569
|
+
for (const [runtimePanelId] of existingEntries) {
|
|
570
|
+
delete nextRetainedChartsByPanelId[runtimePanelId];
|
|
571
|
+
}
|
|
572
|
+
return {
|
|
573
|
+
mosaicDashboard: {
|
|
574
|
+
...state.mosaicDashboard,
|
|
575
|
+
runtime: {
|
|
576
|
+
...state.mosaicDashboard.runtime,
|
|
577
|
+
retainedChartsByPanelId: nextRetainedChartsByPanelId,
|
|
578
|
+
},
|
|
579
|
+
},
|
|
580
|
+
};
|
|
581
|
+
});
|
|
582
|
+
},
|
|
583
|
+
clearAllDashboardRuntime() {
|
|
584
|
+
Object.values(get().mosaicDashboard.runtime.retainedChartsByPanelId).forEach((chart) => {
|
|
585
|
+
destroyDashboardRuntimeChart(chart);
|
|
586
|
+
});
|
|
587
|
+
set((state) => ({
|
|
588
|
+
mosaicDashboard: {
|
|
589
|
+
...state.mosaicDashboard,
|
|
590
|
+
runtime: {
|
|
591
|
+
...state.mosaicDashboard.runtime,
|
|
592
|
+
retainedChartsByPanelId: {},
|
|
593
|
+
},
|
|
594
|
+
},
|
|
595
|
+
}));
|
|
596
|
+
},
|
|
213
597
|
setLayout(dashboardId, layout) {
|
|
214
598
|
get().mosaicDashboard.ensureDashboard(dashboardId);
|
|
215
599
|
set((state) => produce(state, (draft) => {
|
|
216
600
|
const dashboard = draft.mosaicDashboard.config.dashboardsById[dashboardId];
|
|
217
601
|
if (!dashboard)
|
|
218
602
|
return;
|
|
219
|
-
const
|
|
220
|
-
|
|
603
|
+
const panelIds = dashboard.panels.map((panel) => panel.id);
|
|
604
|
+
const panelTypesByLayoutId = getDashboardPanelTypesByLayoutId(dashboardId, dashboard.panels);
|
|
605
|
+
dashboard.layout = ensureLayoutContainsDashboardPanels(layout, dashboardId, panelIds, dashboard.layoutType, panelTypesByLayoutId);
|
|
221
606
|
dashboard.updatedAt = Date.now();
|
|
222
607
|
}));
|
|
223
608
|
},
|