@sqlrooms/mosaic 0.29.0-rc.0 → 0.29.0-rc.2

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.
Files changed (202) hide show
  1. package/README.md +41 -2
  2. package/dist/MosaicChart.d.ts +20 -0
  3. package/dist/MosaicChart.d.ts.map +1 -0
  4. package/dist/MosaicChart.js +25 -0
  5. package/dist/MosaicChart.js.map +1 -0
  6. package/dist/MosaicChartBuilder.d.ts +32 -0
  7. package/dist/MosaicChartBuilder.d.ts.map +1 -0
  8. package/dist/MosaicChartBuilder.js +35 -0
  9. package/dist/MosaicChartBuilder.js.map +1 -0
  10. package/dist/MosaicColorLegend.d.ts +18 -0
  11. package/dist/MosaicColorLegend.d.ts.map +1 -0
  12. package/dist/MosaicColorLegend.js +117 -0
  13. package/dist/MosaicColorLegend.js.map +1 -0
  14. package/dist/MosaicSlice.d.ts +16 -13
  15. package/dist/MosaicSlice.d.ts.map +1 -1
  16. package/dist/MosaicSlice.js +67 -32
  17. package/dist/MosaicSlice.js.map +1 -1
  18. package/dist/VgPlotChart.d.ts +8 -0
  19. package/dist/VgPlotChart.d.ts.map +1 -1
  20. package/dist/VgPlotChart.js +26 -6
  21. package/dist/VgPlotChart.js.map +1 -1
  22. package/dist/chart-builders/ChartBuilderContent.d.ts +26 -0
  23. package/dist/chart-builders/ChartBuilderContent.d.ts.map +1 -0
  24. package/dist/chart-builders/ChartBuilderContent.js +59 -0
  25. package/dist/chart-builders/ChartBuilderContent.js.map +1 -0
  26. package/dist/chart-builders/ChartBuilderContext.d.ts +11 -0
  27. package/dist/chart-builders/ChartBuilderContext.d.ts.map +1 -0
  28. package/dist/chart-builders/ChartBuilderContext.js +10 -0
  29. package/dist/chart-builders/ChartBuilderContext.js.map +1 -0
  30. package/dist/chart-builders/ChartBuilderDialog.d.ts +23 -0
  31. package/dist/chart-builders/ChartBuilderDialog.d.ts.map +1 -0
  32. package/dist/chart-builders/ChartBuilderDialog.js +15 -0
  33. package/dist/chart-builders/ChartBuilderDialog.js.map +1 -0
  34. package/dist/chart-builders/FieldSelectorInput.d.ts +13 -0
  35. package/dist/chart-builders/FieldSelectorInput.d.ts.map +1 -0
  36. package/dist/chart-builders/FieldSelectorInput.js +19 -0
  37. package/dist/chart-builders/FieldSelectorInput.js.map +1 -0
  38. package/dist/chart-builders/builders.d.ts +7 -0
  39. package/dist/chart-builders/builders.d.ts.map +1 -0
  40. package/dist/chart-builders/builders.js +280 -0
  41. package/dist/chart-builders/builders.js.map +1 -0
  42. package/dist/chart-builders/chartSpecTitle.d.ts +7 -0
  43. package/dist/chart-builders/chartSpecTitle.d.ts.map +1 -0
  44. package/dist/chart-builders/chartSpecTitle.js +10 -0
  45. package/dist/chart-builders/chartSpecTitle.js.map +1 -0
  46. package/dist/chart-builders/createMosaicChartTool.d.ts +45 -0
  47. package/dist/chart-builders/createMosaicChartTool.d.ts.map +1 -0
  48. package/dist/chart-builders/createMosaicChartTool.js +109 -0
  49. package/dist/chart-builders/createMosaicChartTool.js.map +1 -0
  50. package/dist/chart-builders/describeChartSpecs.d.ts +7 -0
  51. package/dist/chart-builders/describeChartSpecs.d.ts.map +1 -0
  52. package/dist/chart-builders/describeChartSpecs.js +38 -0
  53. package/dist/chart-builders/describeChartSpecs.js.map +1 -0
  54. package/dist/chart-builders/types.d.ts +40 -0
  55. package/dist/chart-builders/types.d.ts.map +1 -0
  56. package/dist/chart-builders/types.js +2 -0
  57. package/dist/chart-builders/types.js.map +1 -0
  58. package/dist/dashboard/MosaicDashboard.d.ts +20 -0
  59. package/dist/dashboard/MosaicDashboard.d.ts.map +1 -0
  60. package/dist/dashboard/MosaicDashboard.js +68 -0
  61. package/dist/dashboard/MosaicDashboard.js.map +1 -0
  62. package/dist/dashboard/MosaicDashboardChartPanel.d.ts +3 -0
  63. package/dist/dashboard/MosaicDashboardChartPanel.d.ts.map +1 -0
  64. package/dist/dashboard/MosaicDashboardChartPanel.js +49 -0
  65. package/dist/dashboard/MosaicDashboardChartPanel.js.map +1 -0
  66. package/dist/dashboard/MosaicDashboardCharts.d.ts +3 -0
  67. package/dist/dashboard/MosaicDashboardCharts.d.ts.map +1 -0
  68. package/dist/dashboard/MosaicDashboardCharts.js +45 -0
  69. package/dist/dashboard/MosaicDashboardCharts.js.map +1 -0
  70. package/dist/dashboard/MosaicDashboardContext.d.ts +11 -0
  71. package/dist/dashboard/MosaicDashboardContext.d.ts.map +1 -0
  72. package/dist/dashboard/MosaicDashboardContext.js +10 -0
  73. package/dist/dashboard/MosaicDashboardContext.js.map +1 -0
  74. package/dist/dashboard/MosaicDashboardProfiler.d.ts +3 -0
  75. package/dist/dashboard/MosaicDashboardProfiler.d.ts.map +1 -0
  76. package/dist/dashboard/MosaicDashboardProfiler.js +21 -0
  77. package/dist/dashboard/MosaicDashboardProfiler.js.map +1 -0
  78. package/dist/dashboard/MosaicDashboardSlice.d.ts +68 -0
  79. package/dist/dashboard/MosaicDashboardSlice.d.ts.map +1 -0
  80. package/dist/dashboard/MosaicDashboardSlice.js +230 -0
  81. package/dist/dashboard/MosaicDashboardSlice.js.map +1 -0
  82. package/dist/dashboard/MosaicDashboardToolbar.d.ts +3 -0
  83. package/dist/dashboard/MosaicDashboardToolbar.d.ts.map +1 -0
  84. package/dist/dashboard/MosaicDashboardToolbar.js +19 -0
  85. package/dist/dashboard/MosaicDashboardToolbar.js.map +1 -0
  86. package/dist/dashboard/VgPlotSpecPopoverEditor.d.ts +8 -0
  87. package/dist/dashboard/VgPlotSpecPopoverEditor.d.ts.map +1 -0
  88. package/dist/dashboard/VgPlotSpecPopoverEditor.js +40 -0
  89. package/dist/dashboard/VgPlotSpecPopoverEditor.js.map +1 -0
  90. package/dist/editor/MosaicChartContainer.d.ts +51 -0
  91. package/dist/editor/MosaicChartContainer.d.ts.map +1 -0
  92. package/dist/editor/MosaicChartContainer.js +39 -0
  93. package/dist/editor/MosaicChartContainer.js.map +1 -0
  94. package/dist/editor/MosaicChartDisplay.d.ts +18 -0
  95. package/dist/editor/MosaicChartDisplay.d.ts.map +1 -0
  96. package/dist/editor/MosaicChartDisplay.js +21 -0
  97. package/dist/editor/MosaicChartDisplay.js.map +1 -0
  98. package/dist/editor/MosaicChartEditorActions.d.ts +20 -0
  99. package/dist/editor/MosaicChartEditorActions.d.ts.map +1 -0
  100. package/dist/editor/MosaicChartEditorActions.js +18 -0
  101. package/dist/editor/MosaicChartEditorActions.js.map +1 -0
  102. package/dist/editor/MosaicCodeMirrorEditor.d.ts +15 -0
  103. package/dist/editor/MosaicCodeMirrorEditor.d.ts.map +1 -0
  104. package/dist/editor/MosaicCodeMirrorEditor.js +26 -0
  105. package/dist/editor/MosaicCodeMirrorEditor.js.map +1 -0
  106. package/dist/editor/MosaicEditorContext.d.ts +8 -0
  107. package/dist/editor/MosaicEditorContext.d.ts.map +1 -0
  108. package/dist/editor/MosaicEditorContext.js +14 -0
  109. package/dist/editor/MosaicEditorContext.js.map +1 -0
  110. package/dist/editor/MosaicSpecEditorPanel.d.ts +20 -0
  111. package/dist/editor/MosaicSpecEditorPanel.d.ts.map +1 -0
  112. package/dist/editor/MosaicSpecEditorPanel.js +25 -0
  113. package/dist/editor/MosaicSpecEditorPanel.js.map +1 -0
  114. package/dist/editor/mosaicSchema.d.ts +20 -0
  115. package/dist/editor/mosaicSchema.d.ts.map +1 -0
  116. package/dist/editor/mosaicSchema.js +57 -0
  117. package/dist/editor/mosaicSchema.js.map +1 -0
  118. package/dist/editor/types.d.ts +72 -0
  119. package/dist/editor/types.d.ts.map +1 -0
  120. package/dist/editor/types.js +2 -0
  121. package/dist/editor/types.js.map +1 -0
  122. package/dist/editor/useMosaicChartEditor.d.ts +9 -0
  123. package/dist/editor/useMosaicChartEditor.d.ts.map +1 -0
  124. package/dist/editor/useMosaicChartEditor.js +199 -0
  125. package/dist/editor/useMosaicChartEditor.js.map +1 -0
  126. package/dist/index.d.ts +27 -2
  127. package/dist/index.d.ts.map +1 -1
  128. package/dist/index.js +18 -1
  129. package/dist/index.js.map +1 -1
  130. package/dist/profiler/MosaicProfiler.d.ts +32 -0
  131. package/dist/profiler/MosaicProfiler.d.ts.map +1 -0
  132. package/dist/profiler/MosaicProfiler.js +57 -0
  133. package/dist/profiler/MosaicProfiler.js.map +1 -0
  134. package/dist/profiler/MosaicProfilerHeader.d.ts +7 -0
  135. package/dist/profiler/MosaicProfilerHeader.d.ts.map +1 -0
  136. package/dist/profiler/MosaicProfilerHeader.js +196 -0
  137. package/dist/profiler/MosaicProfilerHeader.js.map +1 -0
  138. package/dist/profiler/MosaicProfilerRows.d.ts +9 -0
  139. package/dist/profiler/MosaicProfilerRows.d.ts.map +1 -0
  140. package/dist/profiler/MosaicProfilerRows.js +65 -0
  141. package/dist/profiler/MosaicProfilerRows.js.map +1 -0
  142. package/dist/profiler/MosaicProfilerStatusBar.d.ts +9 -0
  143. package/dist/profiler/MosaicProfilerStatusBar.d.ts.map +1 -0
  144. package/dist/profiler/MosaicProfilerStatusBar.js +28 -0
  145. package/dist/profiler/MosaicProfilerStatusBar.js.map +1 -0
  146. package/dist/profiler/ProfilerCategoryClient.d.ts +50 -0
  147. package/dist/profiler/ProfilerCategoryClient.d.ts.map +1 -0
  148. package/dist/profiler/ProfilerCategoryClient.js +121 -0
  149. package/dist/profiler/ProfilerCategoryClient.js.map +1 -0
  150. package/dist/profiler/ProfilerCountClient.d.ts +28 -0
  151. package/dist/profiler/ProfilerCountClient.d.ts.map +1 -0
  152. package/dist/profiler/ProfilerCountClient.js +51 -0
  153. package/dist/profiler/ProfilerCountClient.js.map +1 -0
  154. package/dist/profiler/ProfilerHistogramClient.d.ts +69 -0
  155. package/dist/profiler/ProfilerHistogramClient.d.ts.map +1 -0
  156. package/dist/profiler/ProfilerHistogramClient.js +179 -0
  157. package/dist/profiler/ProfilerHistogramClient.js.map +1 -0
  158. package/dist/profiler/ProfilerPageClient.d.ts +37 -0
  159. package/dist/profiler/ProfilerPageClient.d.ts.map +1 -0
  160. package/dist/profiler/ProfilerPageClient.js +65 -0
  161. package/dist/profiler/ProfilerPageClient.js.map +1 -0
  162. package/dist/profiler/ProfilerUnsupportedSummaryClient.d.ts +24 -0
  163. package/dist/profiler/ProfilerUnsupportedSummaryClient.d.ts.map +1 -0
  164. package/dist/profiler/ProfilerUnsupportedSummaryClient.js +51 -0
  165. package/dist/profiler/ProfilerUnsupportedSummaryClient.js.map +1 -0
  166. package/dist/profiler/createProfilerStore.d.ts +45 -0
  167. package/dist/profiler/createProfilerStore.d.ts.map +1 -0
  168. package/dist/profiler/createProfilerStore.js +120 -0
  169. package/dist/profiler/createProfilerStore.js.map +1 -0
  170. package/dist/profiler/layout.d.ts +7 -0
  171. package/dist/profiler/layout.d.ts.map +1 -0
  172. package/dist/profiler/layout.js +13 -0
  173. package/dist/profiler/layout.js.map +1 -0
  174. package/dist/profiler/profilerController.d.ts +64 -0
  175. package/dist/profiler/profilerController.d.ts.map +1 -0
  176. package/dist/profiler/profilerController.js +123 -0
  177. package/dist/profiler/profilerController.js.map +1 -0
  178. package/dist/profiler/types.d.ts +86 -0
  179. package/dist/profiler/types.d.ts.map +1 -0
  180. package/dist/profiler/types.js +2 -0
  181. package/dist/profiler/types.js.map +1 -0
  182. package/dist/profiler/useMosaicProfiler.d.ts +7 -0
  183. package/dist/profiler/useMosaicProfiler.d.ts.map +1 -0
  184. package/dist/profiler/useMosaicProfiler.js +339 -0
  185. package/dist/profiler/useMosaicProfiler.js.map +1 -0
  186. package/dist/profiler/utils.d.ts +61 -0
  187. package/dist/profiler/utils.d.ts.map +1 -0
  188. package/dist/profiler/utils.js +347 -0
  189. package/dist/profiler/utils.js.map +1 -0
  190. package/dist/tableInterop.d.ts +30 -0
  191. package/dist/tableInterop.d.ts.map +1 -0
  192. package/dist/tableInterop.js +85 -0
  193. package/dist/tableInterop.js.map +1 -0
  194. package/dist/use-mosaic.d.ts +11 -0
  195. package/dist/use-mosaic.d.ts.map +1 -0
  196. package/dist/use-mosaic.js +42 -0
  197. package/dist/use-mosaic.js.map +1 -0
  198. package/dist/useMosaicClient.d.ts +5 -4
  199. package/dist/useMosaicClient.d.ts.map +1 -1
  200. package/dist/useMosaicClient.js +13 -3
  201. package/dist/useMosaicClient.js.map +1 -1
  202. package/package.json +24 -6
@@ -0,0 +1,20 @@
1
+ import { PropsWithChildren, ReactElement } from 'react';
2
+ import { MosaicDashboardCharts } from './MosaicDashboardCharts';
3
+ import { MosaicDashboardProfiler } from './MosaicDashboardProfiler';
4
+ import { MosaicDashboardToolbar } from './MosaicDashboardToolbar';
5
+ export type MosaicDashboardRootProps = PropsWithChildren<{
6
+ dashboardId: string;
7
+ }>;
8
+ export declare function MosaicDashboardRoot({ children, dashboardId, }: MosaicDashboardRootProps): import("react/jsx-runtime").JSX.Element;
9
+ export type MosaicDashboardProps = {
10
+ dashboardId: string;
11
+ };
12
+ type MosaicDashboardCompoundComponent = ((props: MosaicDashboardProps) => ReactElement) & {
13
+ Root: typeof MosaicDashboardRoot;
14
+ Toolbar: typeof MosaicDashboardToolbar;
15
+ Profiler: typeof MosaicDashboardProfiler;
16
+ Charts: typeof MosaicDashboardCharts;
17
+ };
18
+ export declare const MosaicDashboard: MosaicDashboardCompoundComponent;
19
+ export {};
20
+ //# sourceMappingURL=MosaicDashboard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MosaicDashboard.d.ts","sourceRoot":"","sources":["../../src/dashboard/MosaicDashboard.tsx"],"names":[],"mappings":"AACA,OAAc,EACZ,iBAAiB,EACjB,YAAY,EAKb,MAAM,OAAO,CAAC;AAKf,OAAO,EAAC,qBAAqB,EAAC,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAC,uBAAuB,EAAC,MAAM,2BAA2B,CAAC;AAKlE,OAAO,EAAC,sBAAsB,EAAC,MAAM,0BAA0B,CAAC;AAEhE,MAAM,MAAM,wBAAwB,GAAG,iBAAiB,CAAC;IACvD,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC,CAAC;AAEH,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,WAAW,GACZ,EAAE,wBAAwB,2CAmG1B;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAkBF,KAAK,gCAAgC,GAAG,CAAC,CACvC,KAAK,EAAE,oBAAoB,KACxB,YAAY,CAAC,GAAG;IACnB,IAAI,EAAE,OAAO,mBAAmB,CAAC;IACjC,OAAO,EAAE,OAAO,sBAAsB,CAAC;IACvC,QAAQ,EAAE,OAAO,uBAAuB,CAAC;IACzC,MAAM,EAAE,OAAO,qBAAqB,CAAC;CACtC,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,gCAQ7B,CAAC"}
@@ -0,0 +1,68 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { createId } from '@paralleldrive/cuid2';
3
+ import { useCallback, useEffect, useMemo, useState, } from 'react';
4
+ import { MosaicChartBuilder } from '../MosaicChartBuilder';
5
+ import { MosaicDashboardContext } from './MosaicDashboardContext';
6
+ import { MosaicDashboardCharts } from './MosaicDashboardCharts';
7
+ import { MosaicDashboardProfiler } from './MosaicDashboardProfiler';
8
+ import { useStoreWithMosaicDashboard, } from './MosaicDashboardSlice';
9
+ import { MosaicDashboardToolbar } from './MosaicDashboardToolbar';
10
+ export function MosaicDashboardRoot({ children, dashboardId, }) {
11
+ const ensureDashboard = useStoreWithMosaicDashboard((state) => state.mosaicDashboard.ensureDashboard);
12
+ const addChart = useStoreWithMosaicDashboard((state) => state.mosaicDashboard.addChart);
13
+ const setSelectedTable = useStoreWithMosaicDashboard((state) => state.mosaicDashboard.setSelectedTable);
14
+ const dashboard = useStoreWithMosaicDashboard((state) => state.mosaicDashboard.config.dashboardsById[dashboardId]);
15
+ const tables = useStoreWithMosaicDashboard((state) => state.db.tables);
16
+ const [builderOpen, setBuilderOpen] = useState(false);
17
+ const tablesWithColumns = useMemo(() => tables.filter((table) => table.columns && table.columns.length > 0), [tables]);
18
+ const selectedTableInfo = useMemo(() => tablesWithColumns.find((table) => table.tableName === dashboard?.selectedTable), [dashboard?.selectedTable, tablesWithColumns]);
19
+ const builderColumns = useMemo(() => selectedTableInfo?.columns?.map((column) => ({
20
+ name: column.name,
21
+ type: column.type,
22
+ })) ?? [], [selectedTableInfo]);
23
+ useEffect(() => {
24
+ ensureDashboard(dashboardId);
25
+ }, [dashboardId, ensureDashboard]);
26
+ useEffect(() => {
27
+ const firstTable = tablesWithColumns[0];
28
+ if (!firstTable)
29
+ return;
30
+ const tableStillExists = tablesWithColumns.some((table) => table.tableName === dashboard?.selectedTable);
31
+ if (!dashboard?.selectedTable || !tableStillExists) {
32
+ setSelectedTable(dashboardId, firstTable.tableName);
33
+ }
34
+ }, [
35
+ dashboard?.selectedTable,
36
+ dashboardId,
37
+ setSelectedTable,
38
+ tablesWithColumns,
39
+ ]);
40
+ const handleCreateChart = useCallback((spec, title) => {
41
+ const newChart = {
42
+ id: createId(),
43
+ title,
44
+ vgplot: JSON.parse(JSON.stringify(spec)),
45
+ };
46
+ addChart(dashboardId, newChart);
47
+ setBuilderOpen(false);
48
+ }, [addChart, dashboardId]);
49
+ const contextValue = useMemo(() => ({
50
+ dashboardId,
51
+ builderOpen,
52
+ canCreateChart: Boolean(dashboard?.selectedTable),
53
+ openBuilder: () => setBuilderOpen(true),
54
+ closeBuilder: () => setBuilderOpen(false),
55
+ setBuilderOpen,
56
+ }), [builderOpen, dashboard?.selectedTable, dashboardId]);
57
+ return (_jsxs(MosaicDashboardContext.Provider, { value: contextValue, children: [children, dashboard?.selectedTable ? (_jsx(MosaicChartBuilder, { open: builderOpen, onOpenChange: setBuilderOpen, tableName: dashboard.selectedTable, columns: builderColumns, onCreateChart: handleCreateChart, children: _jsx(MosaicChartBuilder.Dialog, {}) })) : null] }));
58
+ }
59
+ function MosaicDashboardComponent({ dashboardId, }) {
60
+ return (_jsx(MosaicDashboardRoot, { dashboardId: dashboardId, children: _jsxs("div", { className: "flex h-full flex-col", children: [_jsx(MosaicDashboardToolbar, {}), _jsxs("div", { className: "flex min-h-0 flex-1 flex-col overflow-hidden", children: [_jsx(MosaicDashboardProfiler, {}), _jsx(MosaicDashboardCharts, {})] })] }) }));
61
+ }
62
+ export const MosaicDashboard = Object.assign(MosaicDashboardComponent, {
63
+ Root: MosaicDashboardRoot,
64
+ Toolbar: MosaicDashboardToolbar,
65
+ Profiler: MosaicDashboardProfiler,
66
+ Charts: MosaicDashboardCharts,
67
+ });
68
+ //# sourceMappingURL=MosaicDashboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MosaicDashboard.js","sourceRoot":"","sources":["../../src/dashboard/MosaicDashboard.tsx"],"names":[],"mappings":"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","sourcesContent":["import {createId} from '@paralleldrive/cuid2';\nimport React, {\n PropsWithChildren,\n ReactElement,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport type {ChartBuilderColumn} from '../chart-builders/types';\nimport {MosaicChartBuilder} from '../MosaicChartBuilder';\nimport type {Spec} from '@uwdata/mosaic-spec';\nimport {MosaicDashboardContext} from './MosaicDashboardContext';\nimport {MosaicDashboardCharts} from './MosaicDashboardCharts';\nimport {MosaicDashboardProfiler} from './MosaicDashboardProfiler';\nimport {\n type MosaicDashboardChartConfig,\n useStoreWithMosaicDashboard,\n} from './MosaicDashboardSlice';\nimport {MosaicDashboardToolbar} from './MosaicDashboardToolbar';\n\nexport type MosaicDashboardRootProps = PropsWithChildren<{\n dashboardId: string;\n}>;\n\nexport function MosaicDashboardRoot({\n children,\n dashboardId,\n}: MosaicDashboardRootProps) {\n const ensureDashboard = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.ensureDashboard,\n );\n const addChart = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.addChart,\n );\n const setSelectedTable = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.setSelectedTable,\n );\n const dashboard = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.config.dashboardsById[dashboardId],\n );\n const tables = useStoreWithMosaicDashboard((state) => state.db.tables);\n const [builderOpen, setBuilderOpen] = useState(false);\n\n const tablesWithColumns = useMemo(\n () => tables.filter((table) => table.columns && table.columns.length > 0),\n [tables],\n );\n\n const selectedTableInfo = useMemo(\n () =>\n tablesWithColumns.find(\n (table) => table.tableName === dashboard?.selectedTable,\n ),\n [dashboard?.selectedTable, tablesWithColumns],\n );\n\n const builderColumns: ChartBuilderColumn[] = useMemo(\n () =>\n selectedTableInfo?.columns?.map((column) => ({\n name: column.name,\n type: column.type,\n })) ?? [],\n [selectedTableInfo],\n );\n\n useEffect(() => {\n ensureDashboard(dashboardId);\n }, [dashboardId, ensureDashboard]);\n\n useEffect(() => {\n const firstTable = tablesWithColumns[0];\n if (!firstTable) return;\n const tableStillExists = tablesWithColumns.some(\n (table) => table.tableName === dashboard?.selectedTable,\n );\n if (!dashboard?.selectedTable || !tableStillExists) {\n setSelectedTable(dashboardId, firstTable.tableName);\n }\n }, [\n dashboard?.selectedTable,\n dashboardId,\n setSelectedTable,\n tablesWithColumns,\n ]);\n\n const handleCreateChart = useCallback(\n (spec: Spec, title: string) => {\n const newChart: MosaicDashboardChartConfig = {\n id: createId(),\n title,\n vgplot: JSON.parse(JSON.stringify(spec)) as Record<string, unknown>,\n };\n addChart(dashboardId, newChart);\n setBuilderOpen(false);\n },\n [addChart, dashboardId],\n );\n\n const contextValue = useMemo(\n () => ({\n dashboardId,\n builderOpen,\n canCreateChart: Boolean(dashboard?.selectedTable),\n openBuilder: () => setBuilderOpen(true),\n closeBuilder: () => setBuilderOpen(false),\n setBuilderOpen,\n }),\n [builderOpen, dashboard?.selectedTable, dashboardId],\n );\n\n return (\n <MosaicDashboardContext.Provider value={contextValue}>\n {children}\n {dashboard?.selectedTable ? (\n <MosaicChartBuilder\n open={builderOpen}\n onOpenChange={setBuilderOpen}\n tableName={dashboard.selectedTable}\n columns={builderColumns}\n onCreateChart={handleCreateChart}\n >\n <MosaicChartBuilder.Dialog />\n </MosaicChartBuilder>\n ) : null}\n </MosaicDashboardContext.Provider>\n );\n}\n\nexport type MosaicDashboardProps = {\n dashboardId: string;\n};\n\nfunction MosaicDashboardComponent({\n dashboardId,\n}: MosaicDashboardProps): ReactElement {\n return (\n <MosaicDashboardRoot dashboardId={dashboardId}>\n <div className=\"flex h-full flex-col\">\n <MosaicDashboardToolbar />\n <div className=\"flex min-h-0 flex-1 flex-col overflow-hidden\">\n <MosaicDashboardProfiler />\n <MosaicDashboardCharts />\n </div>\n </div>\n </MosaicDashboardRoot>\n );\n}\n\ntype MosaicDashboardCompoundComponent = ((\n props: MosaicDashboardProps,\n) => ReactElement) & {\n Root: typeof MosaicDashboardRoot;\n Toolbar: typeof MosaicDashboardToolbar;\n Profiler: typeof MosaicDashboardProfiler;\n Charts: typeof MosaicDashboardCharts;\n};\n\nexport const MosaicDashboard: MosaicDashboardCompoundComponent = Object.assign(\n MosaicDashboardComponent,\n {\n Root: MosaicDashboardRoot,\n Toolbar: MosaicDashboardToolbar,\n Profiler: MosaicDashboardProfiler,\n Charts: MosaicDashboardCharts,\n },\n);\n"]}
@@ -0,0 +1,3 @@
1
+ import type { RoomPanelComponent } from '@sqlrooms/layout';
2
+ export declare const MosaicDashboardChartPanel: RoomPanelComponent;
3
+ //# sourceMappingURL=MosaicDashboardChartPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MosaicDashboardChartPanel.d.ts","sourceRoot":"","sources":["../../src/dashboard/MosaicDashboardChartPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,kBAAkB,CAAC;AAyBzD,eAAO,MAAM,yBAAyB,EAAE,kBAmGvC,CAAC"}
@@ -0,0 +1,49 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, SpinnerPane } from '@sqlrooms/ui';
3
+ import { Trash2Icon } from 'lucide-react';
4
+ import { useCallback, useMemo } from 'react';
5
+ import { VgPlotChart } from '../VgPlotChart';
6
+ import { useMosaicDashboardContext } from './MosaicDashboardContext';
7
+ import { getMosaicDashboardSelectionName, parseMosaicDashboardChartId, useStoreWithMosaicDashboard, } from './MosaicDashboardSlice';
8
+ import { VgPlotSpecPopoverEditor } from './VgPlotSpecPopoverEditor';
9
+ function toRenderableMosaicSpec(parsedValue) {
10
+ const mosaicSpec = { ...parsedValue };
11
+ if ('$schema' in mosaicSpec) {
12
+ delete mosaicSpec.$schema;
13
+ }
14
+ return mosaicSpec;
15
+ }
16
+ export const MosaicDashboardChartPanel = ({ panelInfo }) => {
17
+ const { dashboardId } = useMosaicDashboardContext();
18
+ const chartId = parseMosaicDashboardChartId(dashboardId, panelInfo.panelId);
19
+ const dashboard = useStoreWithMosaicDashboard((state) => state.mosaicDashboard.config.dashboardsById[dashboardId]);
20
+ const connection = useStoreWithMosaicDashboard((state) => state.mosaic.connection);
21
+ const updateChart = useStoreWithMosaicDashboard((state) => state.mosaicDashboard.updateChart);
22
+ const removeChart = useStoreWithMosaicDashboard((state) => state.mosaicDashboard.removeChart);
23
+ const getSelection = useStoreWithMosaicDashboard((state) => state.mosaic.getSelection);
24
+ const chart = useMemo(() => chartId
25
+ ? dashboard?.charts.find((candidate) => candidate.id === chartId)
26
+ : undefined, [chartId, dashboard?.charts]);
27
+ const spec = chart?.vgplot
28
+ ? toRenderableMosaicSpec(chart.vgplot)
29
+ : null;
30
+ const brushSelection = useMemo(() => getSelection(getMosaicDashboardSelectionName(dashboardId), 'crossfilter'), [dashboardId, getSelection]);
31
+ const params = useMemo(() => new Map([['brush', brushSelection]]), [brushSelection]);
32
+ const handleSpecApply = useCallback((newVgplot) => {
33
+ if (!chartId)
34
+ return;
35
+ updateChart(dashboardId, chartId, { vgplot: newVgplot });
36
+ }, [chartId, dashboardId, updateChart]);
37
+ const handleRemove = useCallback(() => {
38
+ if (!chartId)
39
+ return;
40
+ removeChart(dashboardId, chartId);
41
+ }, [chartId, dashboardId, removeChart]);
42
+ if (!chart) {
43
+ return (_jsx("div", { className: "text-muted-foreground flex h-full items-center justify-center text-sm", children: "Chart not found" }));
44
+ }
45
+ return (_jsxs("div", { className: "flex h-full flex-col", children: [_jsxs("div", { className: "flex items-center justify-between border-b px-2 py-1", children: [_jsx("span", { className: "truncate text-xs font-medium", children: chart.title }), _jsxs("div", { className: "flex items-center gap-0.5", children: [_jsx(VgPlotSpecPopoverEditor, { value: chart.vgplot, onApply: handleSpecApply }), _jsx(Button, { variant: "ghost", size: "icon", className: "h-6 w-6", title: "Remove chart", onClick: handleRemove, children: _jsx(Trash2Icon, { className: "h-3.5 w-3.5" }) })] })] }), _jsx("div", { className: "min-h-0 flex-1 overflow-auto p-2", children: connection.status === 'loading' ? (_jsx(SpinnerPane, { className: "h-full w-full" })) : connection.status === 'ready' && spec ? (_jsx("div", { className: "bg-background text-foreground inline-block min-w-full rounded-md p-2", children: _jsx(VgPlotChart, { spec: spec, params: params }) })) : (_jsx("div", { className: "text-muted-foreground text-sm", children: connection.status === 'error'
46
+ ? 'Mosaic connection failed'
47
+ : 'No valid chart spec' })) })] }));
48
+ };
49
+ //# sourceMappingURL=MosaicDashboardChartPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MosaicDashboardChartPanel.js","sourceRoot":"","sources":["../../src/dashboard/MosaicDashboardChartPanel.tsx"],"names":[],"mappings":"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","sourcesContent":["import type {RoomPanelComponent} from '@sqlrooms/layout';\nimport {Button, SpinnerPane} from '@sqlrooms/ui';\nimport type {Selection} from '@uwdata/mosaic-core';\nimport type {Spec} from '@uwdata/mosaic-spec';\nimport {Trash2Icon} from 'lucide-react';\nimport {useCallback, useMemo} from 'react';\nimport {VgPlotChart} from '../VgPlotChart';\nimport {useMosaicDashboardContext} from './MosaicDashboardContext';\nimport {\n getMosaicDashboardSelectionName,\n parseMosaicDashboardChartId,\n useStoreWithMosaicDashboard,\n} from './MosaicDashboardSlice';\nimport {VgPlotSpecPopoverEditor} from './VgPlotSpecPopoverEditor';\n\nfunction toRenderableMosaicSpec(\n parsedValue: Record<string, unknown>,\n): Record<string, unknown> {\n const mosaicSpec = {...parsedValue};\n if ('$schema' in mosaicSpec) {\n delete mosaicSpec.$schema;\n }\n return mosaicSpec;\n}\n\nexport const MosaicDashboardChartPanel: RoomPanelComponent = ({panelInfo}) => {\n const {dashboardId} = useMosaicDashboardContext();\n const chartId = parseMosaicDashboardChartId(dashboardId, panelInfo.panelId);\n\n const dashboard = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.config.dashboardsById[dashboardId],\n );\n const connection = useStoreWithMosaicDashboard(\n (state) => state.mosaic.connection,\n );\n const updateChart = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.updateChart,\n );\n const removeChart = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.removeChart,\n );\n const getSelection = useStoreWithMosaicDashboard(\n (state) => state.mosaic.getSelection,\n );\n\n const chart = useMemo(\n () =>\n chartId\n ? dashboard?.charts.find((candidate) => candidate.id === chartId)\n : undefined,\n [chartId, dashboard?.charts],\n );\n\n const spec = chart?.vgplot\n ? (toRenderableMosaicSpec(chart.vgplot) as unknown as Spec)\n : null;\n const brushSelection = useMemo(\n () =>\n getSelection(getMosaicDashboardSelectionName(dashboardId), 'crossfilter'),\n [dashboardId, getSelection],\n );\n const params = useMemo(\n () => new Map<string, Selection>([['brush', brushSelection]]),\n [brushSelection],\n );\n\n const handleSpecApply = useCallback(\n (newVgplot: Record<string, unknown>) => {\n if (!chartId) return;\n updateChart(dashboardId, chartId, {vgplot: newVgplot});\n },\n [chartId, dashboardId, updateChart],\n );\n\n const handleRemove = useCallback(() => {\n if (!chartId) return;\n removeChart(dashboardId, chartId);\n }, [chartId, dashboardId, removeChart]);\n\n if (!chart) {\n return (\n <div className=\"text-muted-foreground flex h-full items-center justify-center text-sm\">\n Chart not found\n </div>\n );\n }\n\n return (\n <div className=\"flex h-full flex-col\">\n <div className=\"flex items-center justify-between border-b px-2 py-1\">\n <span className=\"truncate text-xs font-medium\">{chart.title}</span>\n <div className=\"flex items-center gap-0.5\">\n <VgPlotSpecPopoverEditor\n value={chart.vgplot}\n onApply={handleSpecApply}\n />\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-6 w-6\"\n title=\"Remove chart\"\n onClick={handleRemove}\n >\n <Trash2Icon className=\"h-3.5 w-3.5\" />\n </Button>\n </div>\n </div>\n <div className=\"min-h-0 flex-1 overflow-auto p-2\">\n {connection.status === 'loading' ? (\n <SpinnerPane className=\"h-full w-full\" />\n ) : connection.status === 'ready' && spec ? (\n <div className=\"bg-background text-foreground inline-block min-w-full rounded-md p-2\">\n <VgPlotChart spec={spec} params={params} />\n </div>\n ) : (\n <div className=\"text-muted-foreground text-sm\">\n {connection.status === 'error'\n ? 'Mosaic connection failed'\n : 'No valid chart spec'}\n </div>\n )}\n </div>\n </div>\n );\n};\n"]}
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ export declare const MosaicDashboardCharts: React.FC;
3
+ //# sourceMappingURL=MosaicDashboardCharts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MosaicDashboardCharts.d.ts","sourceRoot":"","sources":["../../src/dashboard/MosaicDashboardCharts.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAwC,MAAM,OAAO,CAAC;AAU7D,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAiFzC,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { isLayoutMosaicNode, LayoutRenderer, } from '@sqlrooms/layout';
3
+ import { Button } from '@sqlrooms/ui';
4
+ import { useCallback, useEffect, useMemo } from 'react';
5
+ import { Plus } from 'lucide-react';
6
+ import { useMosaicDashboardContext } from './MosaicDashboardContext';
7
+ import { getMosaicDashboardMosaicId, getMosaicDashboardPanelId, useStoreWithMosaicDashboard, } from './MosaicDashboardSlice';
8
+ import { MosaicDashboardChartPanel } from './MosaicDashboardChartPanel';
9
+ export const MosaicDashboardCharts = () => {
10
+ const { dashboardId, canCreateChart, openBuilder } = useMosaicDashboardContext();
11
+ const dashboard = useStoreWithMosaicDashboard((state) => state.mosaicDashboard.config.dashboardsById[dashboardId]);
12
+ const registerPanel = useStoreWithMosaicDashboard((state) => state.layout.registerPanel);
13
+ const unregisterPanel = useStoreWithMosaicDashboard((state) => state.layout.unregisterPanel);
14
+ const setLayout = useStoreWithMosaicDashboard((state) => state.mosaicDashboard.setLayout);
15
+ const charts = useMemo(() => dashboard?.charts ?? [], [dashboard?.charts]);
16
+ useEffect(() => {
17
+ const registeredIds = [];
18
+ for (const chart of charts) {
19
+ const panelId = getMosaicDashboardPanelId(dashboardId, chart.id);
20
+ registerPanel(panelId, {
21
+ title: chart.title,
22
+ component: MosaicDashboardChartPanel,
23
+ });
24
+ registeredIds.push(panelId);
25
+ }
26
+ return () => {
27
+ for (const id of registeredIds) {
28
+ unregisterPanel(id);
29
+ }
30
+ };
31
+ }, [charts, dashboardId, registerPanel, unregisterPanel]);
32
+ const mosaicNode = useMemo(() => ({
33
+ type: 'mosaic',
34
+ id: getMosaicDashboardMosaicId(dashboardId),
35
+ layout: dashboard?.layout ?? null,
36
+ }), [dashboard?.layout, dashboardId]);
37
+ const handleLayoutChange = useCallback((nextLayout) => {
38
+ setLayout(dashboardId, nextLayout && isLayoutMosaicNode(nextLayout) ? nextLayout.layout : null);
39
+ }, [dashboardId, setLayout]);
40
+ if (charts.length === 0) {
41
+ return (_jsxs("div", { className: "text-muted-foreground flex h-64 flex-col items-center justify-center gap-2 text-sm", children: [_jsx("p", { children: "No charts yet. Add one to get started." }), _jsxs(Button, { size: "sm", variant: "outline", onClick: openBuilder, disabled: !canCreateChart, children: [_jsx(Plus, { className: "mr-1 h-4 w-4" }), "Add Chart"] })] }));
42
+ }
43
+ return (_jsx("div", { className: "min-h-0 flex-1", children: _jsx(LayoutRenderer, { rootLayout: mosaicNode, onLayoutChange: handleLayoutChange }) }));
44
+ };
45
+ //# sourceMappingURL=MosaicDashboardCharts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MosaicDashboardCharts.js","sourceRoot":"","sources":["../../src/dashboard/MosaicDashboardCharts.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n isLayoutMosaicNode,\n LayoutMosaicNode,\n LayoutNode,\n LayoutRenderer,\n} from '@sqlrooms/layout';\nimport {Button} from '@sqlrooms/ui';\nimport React, {useCallback, useEffect, useMemo} from 'react';\nimport {Plus} from 'lucide-react';\nimport {useMosaicDashboardContext} from './MosaicDashboardContext';\nimport {\n getMosaicDashboardMosaicId,\n getMosaicDashboardPanelId,\n useStoreWithMosaicDashboard,\n} from './MosaicDashboardSlice';\nimport {MosaicDashboardChartPanel} from './MosaicDashboardChartPanel';\n\nexport const MosaicDashboardCharts: React.FC = () => {\n const {dashboardId, canCreateChart, openBuilder} =\n useMosaicDashboardContext();\n const dashboard = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.config.dashboardsById[dashboardId],\n );\n const registerPanel = useStoreWithMosaicDashboard(\n (state) => state.layout.registerPanel,\n );\n const unregisterPanel = useStoreWithMosaicDashboard(\n (state) => state.layout.unregisterPanel,\n );\n const setLayout = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.setLayout,\n );\n\n const charts = useMemo(() => dashboard?.charts ?? [], [dashboard?.charts]);\n\n useEffect(() => {\n const registeredIds: string[] = [];\n\n for (const chart of charts) {\n const panelId = getMosaicDashboardPanelId(dashboardId, chart.id);\n registerPanel(panelId, {\n title: chart.title,\n component: MosaicDashboardChartPanel,\n });\n registeredIds.push(panelId);\n }\n\n return () => {\n for (const id of registeredIds) {\n unregisterPanel(id);\n }\n };\n }, [charts, dashboardId, registerPanel, unregisterPanel]);\n\n const mosaicNode: LayoutMosaicNode = useMemo(\n () => ({\n type: 'mosaic',\n id: getMosaicDashboardMosaicId(dashboardId),\n layout: dashboard?.layout ?? null,\n }),\n [dashboard?.layout, dashboardId],\n );\n\n const handleLayoutChange = useCallback(\n (nextLayout: LayoutNode | null) => {\n setLayout(\n dashboardId,\n nextLayout && isLayoutMosaicNode(nextLayout) ? nextLayout.layout : null,\n );\n },\n [dashboardId, setLayout],\n );\n\n if (charts.length === 0) {\n return (\n <div className=\"text-muted-foreground flex h-64 flex-col items-center justify-center gap-2 text-sm\">\n <p>No charts yet. Add one to get started.</p>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={openBuilder}\n disabled={!canCreateChart}\n >\n <Plus className=\"mr-1 h-4 w-4\" />\n Add Chart\n </Button>\n </div>\n );\n }\n\n return (\n <div className=\"min-h-0 flex-1\">\n <LayoutRenderer\n rootLayout={mosaicNode}\n onLayoutChange={handleLayoutChange}\n />\n </div>\n );\n};\n"]}
@@ -0,0 +1,11 @@
1
+ export type MosaicDashboardContextValue = {
2
+ dashboardId: string;
3
+ builderOpen: boolean;
4
+ canCreateChart: boolean;
5
+ openBuilder: () => void;
6
+ closeBuilder: () => void;
7
+ setBuilderOpen: (open: boolean) => void;
8
+ };
9
+ export declare const MosaicDashboardContext: import("react").Context<MosaicDashboardContextValue | null>;
10
+ export declare function useMosaicDashboardContext(): MosaicDashboardContextValue;
11
+ //# sourceMappingURL=MosaicDashboardContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MosaicDashboardContext.d.ts","sourceRoot":"","sources":["../../src/dashboard/MosaicDashboardContext.tsx"],"names":[],"mappings":"AAEA,MAAM,MAAM,2BAA2B,GAAG;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,EAAE,OAAO,CAAC;IACxB,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,cAAc,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACzC,CAAC;AAEF,eAAO,MAAM,sBAAsB,6DACsB,CAAC;AAE1D,wBAAgB,yBAAyB,IAAI,2BAA2B,CAQvE"}
@@ -0,0 +1,10 @@
1
+ import { createContext, useContext } from 'react';
2
+ export const MosaicDashboardContext = createContext(null);
3
+ export function useMosaicDashboardContext() {
4
+ const ctx = useContext(MosaicDashboardContext);
5
+ if (!ctx) {
6
+ throw new Error('MosaicDashboard compound components must be rendered inside <MosaicDashboard> or <MosaicDashboard.Root>.');
7
+ }
8
+ return ctx;
9
+ }
10
+ //# sourceMappingURL=MosaicDashboardContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MosaicDashboardContext.js","sourceRoot":"","sources":["../../src/dashboard/MosaicDashboardContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAE,UAAU,EAAC,MAAM,OAAO,CAAC;AAWhD,MAAM,CAAC,MAAM,sBAAsB,GACjC,aAAa,CAAqC,IAAI,CAAC,CAAC;AAE1D,MAAM,UAAU,yBAAyB;IACvC,MAAM,GAAG,GAAG,UAAU,CAAC,sBAAsB,CAAC,CAAC;IAC/C,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CACb,0GAA0G,CAC3G,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["import {createContext, useContext} from 'react';\n\nexport type MosaicDashboardContextValue = {\n dashboardId: string;\n builderOpen: boolean;\n canCreateChart: boolean;\n openBuilder: () => void;\n closeBuilder: () => void;\n setBuilderOpen: (open: boolean) => void;\n};\n\nexport const MosaicDashboardContext =\n createContext<MosaicDashboardContextValue | null>(null);\n\nexport function useMosaicDashboardContext(): MosaicDashboardContextValue {\n const ctx = useContext(MosaicDashboardContext);\n if (!ctx) {\n throw new Error(\n 'MosaicDashboard compound components must be rendered inside <MosaicDashboard> or <MosaicDashboard.Root>.',\n );\n }\n return ctx;\n}\n"]}
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ export declare const MosaicDashboardProfiler: React.FC;
3
+ //# sourceMappingURL=MosaicDashboardProfiler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MosaicDashboardProfiler.d.ts","sourceRoot":"","sources":["../../src/dashboard/MosaicDashboardProfiler.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAQ1B,eAAO,MAAM,uBAAuB,EAAE,KAAK,CAAC,EAuC3C,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { SpinnerPane } from '@sqlrooms/ui';
3
+ import { MosaicProfiler } from '../profiler/MosaicProfiler';
4
+ import { useMosaicDashboardContext } from './MosaicDashboardContext';
5
+ import { getMosaicDashboardSelectionName, useStoreWithMosaicDashboard, } from './MosaicDashboardSlice';
6
+ export const MosaicDashboardProfiler = () => {
7
+ const { dashboardId } = useMosaicDashboardContext();
8
+ const selectedTable = useStoreWithMosaicDashboard((state) => state.mosaicDashboard.config.dashboardsById[dashboardId]?.selectedTable);
9
+ const connection = useStoreWithMosaicDashboard((state) => state.mosaic.connection);
10
+ if (!selectedTable) {
11
+ return null;
12
+ }
13
+ if (connection.status === 'loading') {
14
+ return _jsx(SpinnerPane, { className: "h-48 w-full" });
15
+ }
16
+ if (connection.status !== 'ready') {
17
+ return null;
18
+ }
19
+ return (_jsx(MosaicProfiler, { tableName: selectedTable, pageSize: 10, selectionName: getMosaicDashboardSelectionName(dashboardId), children: _jsxs("div", { className: "border-b", children: [_jsx("div", { className: "min-h-0 overflow-auto", children: _jsxs(MosaicProfiler.Table, { children: [_jsx(MosaicProfiler.Header, {}), _jsx(MosaicProfiler.Rows, {})] }) }), _jsx(MosaicProfiler.StatusBar, {})] }) }));
20
+ };
21
+ //# sourceMappingURL=MosaicDashboardProfiler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MosaicDashboardProfiler.js","sourceRoot":"","sources":["../../src/dashboard/MosaicDashboardProfiler.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAC,cAAc,EAAC,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAC,yBAAyB,EAAC,MAAM,0BAA0B,CAAC;AACnE,OAAO,EACL,+BAA+B,EAC/B,2BAA2B,GAC5B,MAAM,wBAAwB,CAAC;AAEhC,MAAM,CAAC,MAAM,uBAAuB,GAAa,GAAG,EAAE;IACpD,MAAM,EAAC,WAAW,EAAC,GAAG,yBAAyB,EAAE,CAAC;IAClD,MAAM,aAAa,GAAG,2BAA2B,CAC/C,CAAC,KAAK,EAAE,EAAE,CACR,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,aAAa,CAC1E,CAAC;IACF,MAAM,UAAU,GAAG,2BAA2B,CAC5C,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CACnC,CAAC;IAEF,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QACpC,OAAO,KAAC,WAAW,IAAC,SAAS,EAAC,aAAa,GAAG,CAAC;IACjD,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CACL,KAAC,cAAc,IACb,SAAS,EAAE,aAAa,EACxB,QAAQ,EAAE,EAAE,EACZ,aAAa,EAAE,+BAA+B,CAAC,WAAW,CAAC,YAE3D,eAAK,SAAS,EAAC,UAAU,aACvB,cAAK,SAAS,EAAC,uBAAuB,YACpC,MAAC,cAAc,CAAC,KAAK,eACnB,KAAC,cAAc,CAAC,MAAM,KAAG,EACzB,KAAC,cAAc,CAAC,IAAI,KAAG,IACF,GACnB,EACN,KAAC,cAAc,CAAC,SAAS,KAAG,IACxB,GACS,CAClB,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import {SpinnerPane} from '@sqlrooms/ui';\nimport React from 'react';\nimport {MosaicProfiler} from '../profiler/MosaicProfiler';\nimport {useMosaicDashboardContext} from './MosaicDashboardContext';\nimport {\n getMosaicDashboardSelectionName,\n useStoreWithMosaicDashboard,\n} from './MosaicDashboardSlice';\n\nexport const MosaicDashboardProfiler: React.FC = () => {\n const {dashboardId} = useMosaicDashboardContext();\n const selectedTable = useStoreWithMosaicDashboard(\n (state) =>\n state.mosaicDashboard.config.dashboardsById[dashboardId]?.selectedTable,\n );\n const connection = useStoreWithMosaicDashboard(\n (state) => state.mosaic.connection,\n );\n\n if (!selectedTable) {\n return null;\n }\n\n if (connection.status === 'loading') {\n return <SpinnerPane className=\"h-48 w-full\" />;\n }\n\n if (connection.status !== 'ready') {\n return null;\n }\n\n return (\n <MosaicProfiler\n tableName={selectedTable}\n pageSize={10}\n selectionName={getMosaicDashboardSelectionName(dashboardId)}\n >\n <div className=\"border-b\">\n <div className=\"min-h-0 overflow-auto\">\n <MosaicProfiler.Table>\n <MosaicProfiler.Header />\n <MosaicProfiler.Rows />\n </MosaicProfiler.Table>\n </div>\n <MosaicProfiler.StatusBar />\n </div>\n </MosaicProfiler>\n );\n};\n"]}
@@ -0,0 +1,68 @@
1
+ import { DbSliceState } from '@sqlrooms/db';
2
+ import { type DuckDbSliceState } from '@sqlrooms/duckdb';
3
+ import type { LayoutMosaicSubNode } from '@sqlrooms/layout-config';
4
+ import { LayoutSliceState } from '@sqlrooms/layout';
5
+ import { BaseRoomStoreState, SliceFunctions } from '@sqlrooms/room-store';
6
+ import { z } from 'zod';
7
+ import { type MosaicSliceState } from '../MosaicSlice';
8
+ export declare const DEFAULT_MOSAIC_DASHBOARD_CHART_VGPLOT: string;
9
+ export declare const DEFAULT_MOSAIC_DASHBOARD_CHART_SPEC: Record<string, unknown>;
10
+ export declare const MosaicDashboardChartConfig: z.ZodObject<{
11
+ id: z.ZodString;
12
+ title: z.ZodDefault<z.ZodString>;
13
+ vgplot: z.ZodDefault<z.ZodObject<{}, z.core.$loose>>;
14
+ }, z.core.$strip>;
15
+ export type MosaicDashboardChartConfig = z.infer<typeof MosaicDashboardChartConfig>;
16
+ export declare const MosaicDashboardEntry: z.ZodObject<{
17
+ id: z.ZodString;
18
+ title: z.ZodDefault<z.ZodString>;
19
+ selectedTable: z.ZodOptional<z.ZodString>;
20
+ charts: z.ZodDefault<z.ZodArray<z.ZodObject<{
21
+ id: z.ZodString;
22
+ title: z.ZodDefault<z.ZodString>;
23
+ vgplot: z.ZodDefault<z.ZodObject<{}, z.core.$loose>>;
24
+ }, z.core.$strip>>>;
25
+ layout: z.ZodDefault<z.ZodNullable<z.ZodType<LayoutMosaicSubNode, unknown, z.core.$ZodTypeInternals<LayoutMosaicSubNode, unknown>>>>;
26
+ updatedAt: z.ZodDefault<z.ZodNumber>;
27
+ }, z.core.$strip>;
28
+ export type MosaicDashboardEntry = z.infer<typeof MosaicDashboardEntry>;
29
+ export declare const MosaicDashboardSliceConfig: z.ZodObject<{
30
+ dashboardsById: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
31
+ id: z.ZodString;
32
+ title: z.ZodDefault<z.ZodString>;
33
+ selectedTable: z.ZodOptional<z.ZodString>;
34
+ charts: z.ZodDefault<z.ZodArray<z.ZodObject<{
35
+ id: z.ZodString;
36
+ title: z.ZodDefault<z.ZodString>;
37
+ vgplot: z.ZodDefault<z.ZodObject<{}, z.core.$loose>>;
38
+ }, z.core.$strip>>>;
39
+ layout: z.ZodDefault<z.ZodNullable<z.ZodType<LayoutMosaicSubNode, unknown, z.core.$ZodTypeInternals<LayoutMosaicSubNode, unknown>>>>;
40
+ updatedAt: z.ZodDefault<z.ZodNumber>;
41
+ }, z.core.$strip>>>;
42
+ }, z.core.$strip>;
43
+ export type MosaicDashboardSliceConfig = z.infer<typeof MosaicDashboardSliceConfig>;
44
+ export type MosaicDashboardSliceState = {
45
+ mosaicDashboard: SliceFunctions & {
46
+ config: MosaicDashboardSliceConfig;
47
+ createDashboard: (title?: string) => string;
48
+ ensureDashboard: (dashboardId: string, title?: string) => void;
49
+ removeDashboard: (dashboardId: string) => void;
50
+ getDashboard: (dashboardId: string) => MosaicDashboardEntry | undefined;
51
+ setSelectedTable: (dashboardId: string, tableName: string) => void;
52
+ addChart: (dashboardId: string, chart: MosaicDashboardChartConfig) => MosaicDashboardChartConfig['id'];
53
+ updateChart: (dashboardId: string, chartId: string, patch: Partial<Pick<MosaicDashboardChartConfig, 'title' | 'vgplot'>>) => void;
54
+ removeChart: (dashboardId: string, chartId: string) => void;
55
+ setLayout: (dashboardId: string, layout: LayoutMosaicSubNode | null) => void;
56
+ };
57
+ };
58
+ export type MosaicDashboardStoreState = BaseRoomStoreState & DbSliceState & DuckDbSliceState & LayoutSliceState & MosaicSliceState & MosaicDashboardSliceState;
59
+ export declare function getMosaicDashboardPanelId(dashboardId: string, chartId: string): string;
60
+ export declare function getMosaicDashboardMosaicId(dashboardId: string): string;
61
+ export declare function getMosaicDashboardSelectionName(dashboardId: string): string;
62
+ export declare function parseMosaicDashboardChartId(dashboardId: string, panelId: string): string | undefined;
63
+ export declare function createDefaultMosaicDashboardConfig(props?: Partial<MosaicDashboardSliceConfig>): MosaicDashboardSliceConfig;
64
+ export declare function createMosaicDashboardSlice(props?: {
65
+ config?: Partial<MosaicDashboardSliceConfig>;
66
+ }): import("zustand").StateCreator<MosaicDashboardSliceState>;
67
+ export declare function useStoreWithMosaicDashboard<T>(selector: (state: MosaicDashboardStoreState) => T): T;
68
+ //# sourceMappingURL=MosaicDashboardSlice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MosaicDashboardSlice.d.ts","sourceRoot":"","sources":["../../src/dashboard/MosaicDashboardSlice.ts"],"names":[],"mappings":"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"}