@marimo-team/frontend 0.25.1-dev17 → 0.25.1-dev18

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 (100) hide show
  1. package/dist/assets/{ConnectedDataExplorerComponent-6WFKCUzO.js → ConnectedDataExplorerComponent-C2uC5lJf.js} +1 -1
  2. package/dist/assets/{ErrorBoundary-AmSQgV_f.js → ErrorBoundary-BVJqkhwk.js} +2 -2
  3. package/dist/assets/{LazyAnyLanguageCodeMirror-D38yVMV5.js → LazyAnyLanguageCodeMirror-BqNgl9tZ.js} +2 -2
  4. package/dist/assets/{RunButton-CmaVvEXE.js → RunButton-adYpTAaW.js} +7 -7
  5. package/dist/assets/{abnfDiagram-VCTEODGH-DbN3lc-G.js → abnfDiagram-VCTEODGH-Daqziwy1.js} +1 -1
  6. package/dist/assets/{add-cell-with-ai-DYEESV1_.js → add-cell-with-ai-CjPxSVh0.js} +10 -10
  7. package/dist/assets/{agent-panel-BBXyOr4f.js → agent-panel-mRH4isVn.js} +4 -4
  8. package/dist/assets/{ai-model-dropdown-DWp8ZCIu.js → ai-model-dropdown-BZNUB6Iv.js} +1 -1
  9. package/dist/assets/{any-language-editor-DxOWP_Dz.js → any-language-editor-DRf07PJG.js} +1 -1
  10. package/dist/assets/{app-config-button-DXferVy2.js → app-config-button-Cc7EMA4I.js} +1 -1
  11. package/dist/assets/{architectureDiagram-5GKGNRK7-CxYo7ny1.js → architectureDiagram-5GKGNRK7-YBlh_63B.js} +1 -1
  12. package/dist/assets/{blockDiagram-I7D4REHJ-XXtnxNOM.js → blockDiagram-I7D4REHJ-Ci6Gslkc.js} +1 -1
  13. package/dist/assets/{cache-panel-CDGgj_k1.js → cache-panel-BBQ7HY25.js} +1 -1
  14. package/dist/assets/{chat-display-B735hdwS.js → chat-display-ChsJwSGb.js} +1 -1
  15. package/dist/assets/{chat-panel-CRLY-8Q_.js → chat-panel-tXybKozg.js} +1 -1
  16. package/dist/assets/{chat-ui-COwKnPlV.js → chat-ui-Dj4a0ZyX.js} +1 -1
  17. package/dist/assets/{chunk-IMKFNOWR-DBsaOYkA.js → chunk-IMKFNOWR-CVUGMMR5.js} +1 -1
  18. package/dist/assets/{chunk-SHT3W25Y-NC5eClb6.js → chunk-SHT3W25Y-V-OZGYmC.js} +1 -1
  19. package/dist/assets/{chunk-SVP7TREG-zq4GRMSe.js → chunk-SVP7TREG-NYpzvObK.js} +1 -1
  20. package/dist/assets/{chunk-TICWLB2K-CtF--EWj.js → chunk-TICWLB2K-DAmEhpdA.js} +1 -1
  21. package/dist/assets/{classDiagram-ZZMXUADV-Ufnn74aN.js → classDiagram-ZZMXUADV-DmHJAfc5.js} +1 -1
  22. package/dist/assets/{classDiagram-v2-VYDZK3BY-Ufnn74aN.js → classDiagram-v2-VYDZK3BY-DmHJAfc5.js} +1 -1
  23. package/dist/assets/{code-visibility-DrRJBvIr.js → code-visibility-DEaFLO3A.js} +1 -1
  24. package/dist/assets/{command-palette-qcsu_Bp2.js → command-palette-CERIrl2Z.js} +1 -1
  25. package/dist/assets/{common-B-ub9i8J.js → common-DBH2dPfd.js} +1 -1
  26. package/dist/assets/{components-DaOSHEng.js → components-Chs3VCBR.js} +1 -1
  27. package/dist/assets/{components-BRVhsaex.js → components-CuWdJDJ8.js} +1 -1
  28. package/dist/assets/{cynefinDiagram-5FMLGOSQ-DEtkQ5VA.js → cynefinDiagram-5FMLGOSQ-DTjbXw-r.js} +1 -1
  29. package/dist/assets/{dagre-Br6SwCX-.js → dagre-4szy_3ND.js} +1 -1
  30. package/dist/assets/{dagre-GXQ25YYZ-CWfhwi40.js → dagre-GXQ25YYZ-BLLPL51D.js} +1 -1
  31. package/dist/assets/{data-grid-overlay-editor-BQ4XUYyf.js → data-grid-overlay-editor-CD6nx7Jc.js} +1 -1
  32. package/dist/assets/{dependency-graph-panel-DC7VQLMv.js → dependency-graph-panel-Dsa9_1CE.js} +1 -1
  33. package/dist/assets/{diagram-S7CK7UJ4-DgJkPXj-.js → diagram-S7CK7UJ4-BEOWs3DZ.js} +1 -1
  34. package/dist/assets/{diagram-UQ7AKVKN-BgMVSftv.js → diagram-UQ7AKVKN-DhcB9YNh.js} +1 -1
  35. package/dist/assets/{diagram-VX7I27RA-DPObfkHw.js → diagram-VX7I27RA-BZS6D99M.js} +1 -1
  36. package/dist/assets/{diagram-Z3DM3KII-BYHzWlR5.js → diagram-Z3DM3KII-Df9yG0Dr.js} +1 -1
  37. package/dist/assets/{documentation-panel-BauooX2S.js → documentation-panel-cgPFYBCG.js} +1 -1
  38. package/dist/assets/{ebnfDiagram-PWID7BFC-CoxVieSX.js → ebnfDiagram-PWID7BFC-D44ZGUpd.js} +1 -1
  39. package/dist/assets/{edit-page-DPhd7_gi.js → edit-page-5BoxMdRg.js} +8 -8
  40. package/dist/assets/{erDiagram-RLTQ6QDP-CryK8kTO.js → erDiagram-RLTQ6QDP-wMbCu1k0.js} +1 -1
  41. package/dist/assets/{error-panel-Chbt4Stb.js → error-panel-BQkG8Owp.js} +1 -1
  42. package/dist/assets/{feedback-button-DSa5c3Pq.js → feedback-button-L9wRkYQK.js} +1 -1
  43. package/dist/assets/{file-explorer-panel-BRzhiu8T.js → file-explorer-panel-BqbyZB-C.js} +1 -1
  44. package/dist/assets/{file-name-input-im0iaWXy.js → file-name-input-BIU5kyHZ.js} +1 -1
  45. package/dist/assets/{flowDiagram-HODETNUW-W7clPIx_.js → flowDiagram-HODETNUW-DXu8WHYs.js} +1 -1
  46. package/dist/assets/{gallery-page-B_5zGznh.js → gallery-page-CfV7ZAmL.js} +1 -1
  47. package/dist/assets/{glide-data-editor-CTXzjUkg.js → glide-data-editor-0wu6GiLW.js} +4 -4
  48. package/dist/assets/{graphlib-5TBKpf9f.js → graphlib-CTJqVmKw.js} +1 -1
  49. package/dist/assets/has-CGywqNo7.js +1 -0
  50. package/dist/assets/{home-page-gnNxFA7J.js → home-page-BpvVdseG.js} +1 -1
  51. package/dist/assets/{index-BGA2MQ61.js → index-D0aUt523.js} +31 -31
  52. package/dist/assets/{infoDiagram-27XIBGKW-COO_rLcz.js → infoDiagram-27XIBGKW-Cdc1u3v9.js} +1 -1
  53. package/dist/assets/{ishikawaDiagram-5VMMS53U-KrNEKYYj.js → ishikawaDiagram-5VMMS53U-CBLHwkrk.js} +1 -1
  54. package/dist/assets/{kanban-definition-UXKFOSKX-mL1vOpaC.js → kanban-definition-UXKFOSKX-B9VLtQSr.js} +1 -1
  55. package/dist/assets/{logs-panel-BKMIsY8h.js → logs-panel-bEm9k3zD.js} +1 -1
  56. package/dist/assets/{mermaid-D9cuWIJ3.js → mermaid-3TiKkcPE.js} +4 -4
  57. package/dist/assets/{mindmap-definition-YA3MSWOX-0UfzA6jE.js → mindmap-definition-YA3MSWOX-wGOfhH41.js} +1 -1
  58. package/dist/assets/{number-overlay-editor-D7NjYfe7.js → number-overlay-editor-K9e5ZWrL.js} +1 -1
  59. package/dist/assets/{outline-panel-QSMLTTpe.js → outline-panel-CffssgnN.js} +1 -1
  60. package/dist/assets/{packages-panel-DpmTy1Zj.js → packages-panel-CKmdUILr.js} +1 -1
  61. package/dist/assets/{panels-Bso8csB-.js → panels-14vO4F3h.js} +6 -6
  62. package/dist/assets/{pegDiagram-XKGWAZYB-C_Mn8HQY.js → pegDiagram-XKGWAZYB-BCEdVP7M.js} +1 -1
  63. package/dist/assets/{pieDiagram-E7YTZNPT-BCjUjlVJ.js → pieDiagram-E7YTZNPT-C8l_dDam.js} +1 -1
  64. package/dist/assets/{process-output-CEKLHiTm.js → process-output-ZDYA_DfN.js} +1 -1
  65. package/dist/assets/{railroadDiagram-O6MQD6OU-B1XuNasU.js → railroadDiagram-O6MQD6OU-t5SV0Qh9.js} +1 -1
  66. package/dist/assets/{requirementDiagram-BXWQKSXE-XekNJuFR.js → requirementDiagram-BXWQKSXE-CQaLae__.js} +1 -1
  67. package/dist/assets/{reveal-component-BYO2ErQd.js → reveal-component-Ce4laJYz.js} +1 -1
  68. package/dist/assets/{run-page-B8V4EsPe.js → run-page-BFPh-t5N.js} +1 -1
  69. package/dist/assets/{scratchpad-panel-BVRfI5pY.js → scratchpad-panel--eaSPPbI.js} +1 -1
  70. package/dist/assets/{secrets-panel-C8RCq9AF.js → secrets-panel-D5VC4iGd.js} +1 -1
  71. package/dist/assets/{sequenceDiagram-WJ2MYXX4-kkt3zDHa.js → sequenceDiagram-WJ2MYXX4-BdUEvoNa.js} +1 -1
  72. package/dist/assets/session-panel-C4xjKL7P.js +1 -0
  73. package/dist/assets/{snippets-panel-C-ljIDQt.js → snippets-panel-D5IV2SYF.js} +1 -1
  74. package/dist/assets/{stateDiagram-D77RDMKH-Bph_mhCF.js → stateDiagram-D77RDMKH-BxQBCmyb.js} +1 -1
  75. package/dist/assets/{stateDiagram-v2-MP3YSRHH-DSDmMkGt.js → stateDiagram-v2-MP3YSRHH-ldBZz7Qk.js} +1 -1
  76. package/dist/assets/{swimlanes-42K2YHIH-DOgT6SSZ.js → swimlanes-42K2YHIH-DyeulHZ_.js} +1 -1
  77. package/dist/assets/{swimlanesDiagram-VR7AAH4N-B0jZFEqF.js → swimlanesDiagram-VR7AAH4N-DtS183IV.js} +1 -1
  78. package/dist/assets/{swiper-component-D2sgxyxf.js → swiper-component-IXbGG3F9.js} +1 -1
  79. package/dist/assets/{terminal-B6gr5FPU.js → terminal-B0l9hsf7.js} +1 -1
  80. package/dist/assets/{timeline-definition-24CTP7MA-D6roMSAh.js → timeline-definition-24CTP7MA-Do_68DsI.js} +1 -1
  81. package/dist/assets/tooltip-PLkI_UfK.js +61 -0
  82. package/dist/assets/{tracing-BI61lCpo.js → tracing-CKx0JpOw.js} +1 -1
  83. package/dist/assets/{tracing-panel-BMqSLs2l.js → tracing-panel-CSkFln9f.js} +2 -2
  84. package/dist/assets/{useCellActionButton-DOqFLFDe.js → useCellActionButton-YroFjW8i.js} +1 -1
  85. package/dist/assets/{vega-component-CWmtMc1h.js → vega-component-B_nXcaF8.js} +1 -1
  86. package/dist/assets/{vega-embed-container-BDH_VhfS.js → vega-embed-container-Bwqt153O.js} +1 -1
  87. package/dist/assets/{vennDiagram-4TSXK5OY-AYIHuyE9.js → vennDiagram-4TSXK5OY-DkrPIenW.js} +1 -1
  88. package/dist/assets/{wardleyDiagram-VM6X3IG4-CogDfA2Q.js → wardleyDiagram-VM6X3IG4-Bx7dpVo2.js} +1 -1
  89. package/dist/assets/{xychartDiagram-S5SC5T6Z-D6Lub9hS.js → xychartDiagram-S5SC5T6Z-BDpyRtk7.js} +1 -1
  90. package/dist/index.html +4 -4
  91. package/package.json +1 -1
  92. package/src/components/data-table/charts/__tests__/chart-panel.test.tsx +286 -0
  93. package/src/components/data-table/charts/charts.tsx +26 -13
  94. package/src/plugins/impl/vega/__tests__/utils.test.ts +16 -1
  95. package/src/plugins/impl/vega/__tests__/vega.test.ts +37 -0
  96. package/src/plugins/impl/vega/loader.ts +23 -1
  97. package/src/plugins/impl/vega/utils.ts +5 -4
  98. package/dist/assets/has-QplVKfjH.js +0 -1
  99. package/dist/assets/session-panel-Ctbe5R3e.js +0 -1
  100. package/dist/assets/tooltip-B1vGi-z4.js +0 -61
package/dist/index.html CHANGED
@@ -66,7 +66,7 @@
66
66
  <marimo-server-token data-token="{{ server_token }}" hidden></marimo-server-token>
67
67
  <!-- /TODO -->
68
68
  <title>{{ title }}</title>
69
- <script type="module" crossorigin src="./assets/index-BGA2MQ61.js"></script>
69
+ <script type="module" crossorigin src="./assets/index-D0aUt523.js"></script>
70
70
  <link rel="modulepreload" crossorigin href="./assets/rolldown-runtime-B0Z9INg1.js">
71
71
  <link rel="modulepreload" crossorigin href="./assets/react-CUdNIagt.js">
72
72
  <link rel="modulepreload" crossorigin href="./assets/compiler-runtime-BQ9S8nyo.js">
@@ -144,11 +144,11 @@
144
144
  <link rel="modulepreload" crossorigin href="./assets/copy-RyCOE8jo.js">
145
145
  <link rel="modulepreload" crossorigin href="./assets/copy-BhJktFeI.js">
146
146
  <link rel="modulepreload" crossorigin href="./assets/copy-icon-DFhUGBjO.js">
147
- <link rel="modulepreload" crossorigin href="./assets/ErrorBoundary-AmSQgV_f.js">
147
+ <link rel="modulepreload" crossorigin href="./assets/ErrorBoundary-BVJqkhwk.js">
148
148
  <link rel="modulepreload" crossorigin href="./assets/config-B4VJJibu.js">
149
149
  <link rel="modulepreload" crossorigin href="./assets/chevron-right-DOPs2jx8.js">
150
150
  <link rel="modulepreload" crossorigin href="./assets/dropdown-menu-VuyoeQOD.js">
151
- <link rel="modulepreload" crossorigin href="./assets/LazyAnyLanguageCodeMirror-D38yVMV5.js">
151
+ <link rel="modulepreload" crossorigin href="./assets/LazyAnyLanguageCodeMirror-BqNgl9tZ.js">
152
152
  <link rel="modulepreload" crossorigin href="./assets/hat-glasses-DVgK5i5l.js">
153
153
  <link rel="modulepreload" crossorigin href="./assets/package-BeYhVWvM.js">
154
154
  <link rel="modulepreload" crossorigin href="./assets/errors-D9vyuMar.js">
@@ -156,7 +156,7 @@
156
156
  <link rel="modulepreload" crossorigin href="./assets/precisionRound-Bq_nmf5u.js">
157
157
  <link rel="modulepreload" crossorigin href="./assets/defaultLocale-D5bOh7g6.js">
158
158
  <link rel="modulepreload" crossorigin href="./assets/vega-loader.browser-CLRkNgm7.js">
159
- <link rel="modulepreload" crossorigin href="./assets/tooltip-B1vGi-z4.js">
159
+ <link rel="modulepreload" crossorigin href="./assets/tooltip-PLkI_UfK.js">
160
160
  <link rel="modulepreload" crossorigin href="./assets/micromark-factory-space-D9Dr-k4J.js">
161
161
  <link rel="modulepreload" crossorigin href="./assets/chunk-YOKDWASO-CaoEAGJk.js">
162
162
  <link rel="stylesheet" crossorigin href="./assets/cells-0PFKL3SH.css">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/frontend",
3
- "version": "0.25.1-dev17",
3
+ "version": "0.25.1-dev18",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -0,0 +1,286 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import { fireEvent, render, waitFor } from "@testing-library/react";
4
+ import { createStore, Provider } from "jotai";
5
+ import { Tooltip } from "radix-ui";
6
+ import type { ComponentProps } from "react";
7
+ import { beforeAll, describe, expect, it, vi } from "vitest";
8
+ import { SetupMocks } from "@/__mocks__/common";
9
+ import { cellId } from "@/__tests__/branded";
10
+ import { LazyVegaEmbed } from "@/components/charts/lazy";
11
+ import { vegaLoader } from "@/plugins/impl/vega/loader";
12
+ import { ChartPanel, TablePanel, type TablePanelProps } from "../charts";
13
+ import { getChartTabName, tabsStorageAtom } from "../storage";
14
+ import { ChartType, NONE_VALUE } from "../types";
15
+
16
+ vi.mock("@/components/charts/lazy", () => ({
17
+ LazyVegaEmbed: vi.fn(() => null),
18
+ }));
19
+
20
+ beforeAll(() => {
21
+ SetupMocks.resizeObserver();
22
+ });
23
+
24
+ describe("ChartPanel", () => {
25
+ it.each([undefined, null, []] as const)(
26
+ "infers the full CSV through TablePanel without backend metadata (%s)",
27
+ async (fieldTypes) => {
28
+ vi.spyOn(vegaLoader, "load").mockResolvedValue(
29
+ "value,index\n,0\n2.5,1\n",
30
+ );
31
+ const store = createStore();
32
+ const id = cellId("csv-inference");
33
+ const tabName = getChartTabName(0, ChartType.BAR);
34
+ store.set(
35
+ tabsStorageAtom,
36
+ new Map([
37
+ [
38
+ id,
39
+ [
40
+ {
41
+ tabName,
42
+ chartType: ChartType.BAR,
43
+ config: {
44
+ general: {
45
+ xColumn: { field: "value", type: "number" },
46
+ yColumn: {
47
+ field: "index",
48
+ type: "integer",
49
+ aggregate: NONE_VALUE,
50
+ },
51
+ },
52
+ },
53
+ },
54
+ ],
55
+ ],
56
+ ]),
57
+ );
58
+ const sample = [{ value: null }];
59
+ const SampleTable = (_props: { data: typeof sample }) => null;
60
+ const props: TablePanelProps = {
61
+ cellId: id,
62
+ data: sample,
63
+ dataTable: <SampleTable data={sample} />,
64
+ totalRows: 2,
65
+ columns: 1,
66
+ displayHeader: true,
67
+ fieldTypes: fieldTypes == null ? fieldTypes : [...fieldTypes],
68
+ rowHeaders: [["index", ["integer", "int64"]]],
69
+ getDataUrl: vi
70
+ .fn()
71
+ .mockResolvedValue({ data_url: "chart.csv", format: "csv" }),
72
+ };
73
+ const { getByRole } = render(
74
+ <Provider store={store}>
75
+ <Tooltip.Provider>
76
+ <TablePanel {...props} />
77
+ </Tooltip.Provider>
78
+ </Provider>,
79
+ );
80
+ fireEvent.click(getByRole("tab", { name: tabName }));
81
+ await waitFor(() => {
82
+ expect(vi.mocked(LazyVegaEmbed).mock.lastCall?.[0].spec).toEqual(
83
+ expect.objectContaining({
84
+ data: {
85
+ values: [
86
+ { value: null, index: 0 },
87
+ { value: 2.5, index: 1 },
88
+ ],
89
+ },
90
+ }),
91
+ );
92
+ });
93
+ },
94
+ );
95
+
96
+ it("reloads CSV only when column types change, not their array identity", async () => {
97
+ vi.spyOn(vegaLoader, "load").mockResolvedValue("value\n001\n");
98
+ const getDataUrl = vi.fn().mockResolvedValue({
99
+ data_url: "chart.csv",
100
+ format: "csv",
101
+ });
102
+ const props: ComponentProps<typeof ChartPanel> = {
103
+ tableData: [{ value: "001" }],
104
+ chartConfig: {
105
+ general: {
106
+ xColumn: { field: "value", type: "string" },
107
+ yColumn: { field: "value", type: "integer", aggregate: NONE_VALUE },
108
+ },
109
+ },
110
+ chartType: ChartType.BAR,
111
+ saveChart: vi.fn(),
112
+ saveChartType: vi.fn(),
113
+ getDataUrl,
114
+ isLargeDataset: false,
115
+ };
116
+ const panel = (
117
+ fieldTypes: ComponentProps<typeof ChartPanel>["fieldTypes"],
118
+ ) => (
119
+ <Tooltip.Provider>
120
+ <ChartPanel {...props} fieldTypes={fieldTypes} />
121
+ </Tooltip.Provider>
122
+ );
123
+ const expectValues = async (value: string | number) => {
124
+ await waitFor(() => {
125
+ expect(vi.mocked(LazyVegaEmbed).mock.lastCall?.[0].spec).toEqual(
126
+ expect.objectContaining({ data: { values: [{ value }] } }),
127
+ );
128
+ });
129
+ };
130
+
131
+ const { rerender } = render(panel([["value", ["string", "object"]]]));
132
+ await expectValues("001");
133
+ expect(getDataUrl).toHaveBeenCalledTimes(1);
134
+
135
+ rerender(panel([["value", ["string", "object"]]]));
136
+ await expectValues("001");
137
+ expect(getDataUrl).toHaveBeenCalledTimes(1);
138
+
139
+ rerender(panel([["value", ["integer", "int64"]]]));
140
+ await expectValues(1);
141
+ expect(getDataUrl).toHaveBeenCalledTimes(2);
142
+ });
143
+
144
+ it("uses column types to parse numeric CSV values without coercing text", async () => {
145
+ vi.spyOn(vegaLoader, "load").mockResolvedValue(
146
+ "a.b,n,label,day,timestamp,active,duration\ninf,1,inf,2024-01-01,2024-01-01T12:00:00Z,True,1 days\n-inf,2,001,2024-01-02,2024-01-02T12:00:00Z,False,2 days\n2.5,3,2024-01-03,2024-01-03,2024-01-03T12:00:00Z,True,3 days\n,4,,,,,\n",
147
+ );
148
+
149
+ render(
150
+ <Tooltip.Provider>
151
+ <ChartPanel
152
+ tableData={[{ "a.b": 1, n: 1 }]}
153
+ chartConfig={{
154
+ general: {
155
+ xColumn: { field: "a.b", type: "number" },
156
+ yColumn: { field: "n", type: "integer", aggregate: NONE_VALUE },
157
+ },
158
+ }}
159
+ chartType={ChartType.BAR}
160
+ saveChart={vi.fn()}
161
+ saveChartType={vi.fn()}
162
+ getDataUrl={vi.fn().mockResolvedValue({
163
+ data_url: "chart.csv",
164
+ format: "csv",
165
+ })}
166
+ fieldTypes={[
167
+ ["a.b", ["number", "float64"]],
168
+ ["n", ["integer", "int64"]],
169
+ ["label", ["string", "object"]],
170
+ ["day", ["date", "date"]],
171
+ ["timestamp", ["datetime", "datetime64[ns]"]],
172
+ ["active", ["boolean", "bool"]],
173
+ ["duration", ["unknown", "timedelta64[ns]"]],
174
+ ]}
175
+ isLargeDataset={false}
176
+ />
177
+ </Tooltip.Provider>,
178
+ );
179
+
180
+ await waitFor(() => {
181
+ expect(vi.mocked(LazyVegaEmbed).mock.lastCall?.[0].spec).toEqual(
182
+ expect.objectContaining({
183
+ data: {
184
+ values: [
185
+ {
186
+ "a.b": Infinity,
187
+ n: 1,
188
+ label: "inf",
189
+ day: new Date("2024-01-01"),
190
+ timestamp: new Date("2024-01-01T12:00:00Z"),
191
+ active: true,
192
+ duration: "1 days",
193
+ },
194
+ {
195
+ "a.b": -Infinity,
196
+ n: 2,
197
+ label: "001",
198
+ day: new Date("2024-01-02"),
199
+ timestamp: new Date("2024-01-02T12:00:00Z"),
200
+ active: false,
201
+ duration: "2 days",
202
+ },
203
+ {
204
+ "a.b": 2.5,
205
+ n: 3,
206
+ label: "2024-01-03",
207
+ day: new Date("2024-01-03"),
208
+ timestamp: new Date("2024-01-03T12:00:00Z"),
209
+ active: true,
210
+ duration: "3 days",
211
+ },
212
+ {
213
+ "a.b": null,
214
+ n: 4,
215
+ label: null,
216
+ day: "",
217
+ timestamp: "",
218
+ active: null,
219
+ duration: "",
220
+ },
221
+ ],
222
+ },
223
+ }),
224
+ );
225
+ });
226
+ });
227
+
228
+ it.each([true, false])(
229
+ "keeps dotted CSV columns aligned with the chart encodings (schema: %s)",
230
+ async (hasSchema) => {
231
+ vi.spyOn(vegaLoader, "load").mockResolvedValue("a.b,n\n1,1\n2,2\n3,3\n");
232
+
233
+ render(
234
+ <Tooltip.Provider>
235
+ <ChartPanel
236
+ tableData={[{ "a.b": 1, n: 1 }]}
237
+ chartConfig={{
238
+ general: {
239
+ xColumn: { field: "a.b", type: "number" },
240
+ yColumn: {
241
+ field: "n",
242
+ type: "number",
243
+ aggregate: NONE_VALUE,
244
+ },
245
+ },
246
+ }}
247
+ chartType={ChartType.BAR}
248
+ saveChart={vi.fn()}
249
+ saveChartType={vi.fn()}
250
+ getDataUrl={vi.fn().mockResolvedValue({
251
+ data_url: "chart.csv",
252
+ format: "csv",
253
+ })}
254
+ fieldTypes={
255
+ hasSchema
256
+ ? [
257
+ ["a.b", ["number", "float64"]],
258
+ ["n", ["integer", "int64"]],
259
+ ]
260
+ : undefined
261
+ }
262
+ isLargeDataset={false}
263
+ />
264
+ </Tooltip.Provider>,
265
+ );
266
+
267
+ await waitFor(() => {
268
+ expect(vi.mocked(LazyVegaEmbed).mock.lastCall?.[0].spec).toEqual(
269
+ expect.objectContaining({
270
+ data: {
271
+ values: [
272
+ { "a.b": 1, n: 1 },
273
+ { "a.b": 2, n: 2 },
274
+ { "a.b": 3, n: 3 },
275
+ ],
276
+ },
277
+ encoding: expect.objectContaining({
278
+ x: expect.objectContaining({ field: "a\\.b" }),
279
+ y: expect.objectContaining({ field: "n" }),
280
+ }),
281
+ }),
282
+ );
283
+ });
284
+ },
285
+ );
286
+ });
@@ -23,9 +23,11 @@ import { Form } from "@/components/ui/form";
23
23
  import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
24
24
  import type { CellId } from "@/core/cells/ids";
25
25
  import { useAsyncData } from "@/hooks/useAsyncData";
26
+ import { useDeepCompareMemoize } from "@/hooks/useDeepCompareMemoize";
26
27
  import { useDebouncedCallback } from "@/hooks/useDebounce";
27
28
  import type { GetDataUrl } from "@/plugins/impl/DataTablePlugin";
28
29
  import { vegaLoadData } from "@/plugins/impl/vega/loader";
30
+ import { getVegaFieldTypes } from "@/plugins/impl/vega/utils";
29
31
  import { useTheme } from "@/theme/useTheme";
30
32
  import { uniqueBy } from "@/utils/arrays";
31
33
  import { inferFieldTypes } from "../columns";
@@ -284,6 +286,7 @@ export const TablePanel: React.FC<TablePanelProps> = ({
284
286
  saveChart={saveChart}
285
287
  saveChartType={saveChartType}
286
288
  getDataUrl={getDataUrl}
289
+ hasSchema={Boolean(fieldTypes?.length)}
287
290
  fieldTypes={mergeIndexFields(
288
291
  fieldTypes ?? inferFieldTypes(dataTable.props.data),
289
292
  rowHeaders,
@@ -307,6 +310,7 @@ export const ChartPanel: React.FC<{
307
310
  saveChartType: (chartType: ChartType) => void;
308
311
  getDataUrl?: GetDataUrl;
309
312
  fieldTypes?: FieldTypesWithExternalType | null;
313
+ hasSchema?: boolean;
310
314
  isLargeDataset: boolean;
311
315
  }> = ({
312
316
  tableData,
@@ -316,6 +320,7 @@ export const ChartPanel: React.FC<{
316
320
  saveChartType,
317
321
  getDataUrl,
318
322
  fieldTypes,
323
+ hasSchema = Boolean(fieldTypes?.length),
319
324
  isLargeDataset,
320
325
  }) => {
321
326
  const { theme } = useTheme();
@@ -331,6 +336,8 @@ export const ChartPanel: React.FC<{
331
336
  const [renderLargeCharts, setRenderLargeCharts] = useState(!isLargeDataset);
332
337
 
333
338
  const { ref: chartContainerRef } = useResizeObserver();
339
+ // Sample-inferred types are useful for controls, but not full CSV parsing.
340
+ const csvFieldTypes = useDeepCompareMemoize(hasSchema ? fieldTypes : null);
334
341
 
335
342
  const { data, isPending, error } = useAsyncData(async () => {
336
343
  if (!getDataUrl || tableData.length === 0 || !renderLargeCharts) {
@@ -342,20 +349,26 @@ export const ChartPanel: React.FC<{
342
349
  return response.data_url;
343
350
  }
344
351
 
345
- const chartData = await vegaLoadData(
346
- response.data_url,
347
- response.format === "arrow"
348
- ? { type: "arrow" }
349
- : response.format === "json"
350
- ? { type: "json" }
351
- : { type: "csv", parse: "auto" },
352
- {
353
- replacePeriod: true,
354
- },
355
- );
356
- return chartData;
352
+ let format: Parameters<typeof vegaLoadData>[1];
353
+ if (response.format === "arrow") {
354
+ format = { type: "arrow" };
355
+ } else if (response.format === "json") {
356
+ format = { type: "json" };
357
+ } else {
358
+ format = {
359
+ type: "csv",
360
+ parse: getVegaFieldTypes(
361
+ csvFieldTypes &&
362
+ Object.fromEntries(
363
+ csvFieldTypes.map(([name, [type]]) => [name, type]),
364
+ ),
365
+ { parseDates: true },
366
+ ),
367
+ };
368
+ }
369
+ return vegaLoadData(response.data_url, format);
357
370
  // Re-run when the data table changes
358
- }, [tableData, renderLargeCharts]);
371
+ }, [tableData, renderLargeCharts, csvFieldTypes]);
359
372
 
360
373
  const formValues = form.watch();
361
374
 
@@ -1,7 +1,22 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
3
  import { describe, expect, it } from "vitest";
4
- import { getContainerWidth } from "../utils";
4
+ import { getContainerWidth, getVegaFieldTypes } from "../utils";
5
+
6
+ describe("getVegaFieldTypes", () => {
7
+ it("preserves date strings unless the caller requests date parsing", () => {
8
+ expect(getVegaFieldTypes({ day: "date", timestamp: "datetime" })).toEqual({
9
+ day: "string",
10
+ timestamp: "date",
11
+ });
12
+ expect(
13
+ getVegaFieldTypes(
14
+ { day: "date", timestamp: "datetime" },
15
+ { parseDates: true },
16
+ ),
17
+ ).toEqual({ day: "date", timestamp: "date" });
18
+ });
19
+ });
5
20
 
6
21
  describe("getContainerWidth", () => {
7
22
  it('should return "container" when spec width is "container"', () => {
@@ -13,6 +13,43 @@ const { ZERO_WIDTH_SPACE, replacePeriodsInColumnNames, uniquifyColumnNames } =
13
13
  exportedForTesting;
14
14
 
15
15
  describe("vega loader", () => {
16
+ it("parses infinities only in explicitly numeric CSV fields", async () => {
17
+ vi.spyOn(vegaLoader, "load").mockResolvedValue(
18
+ "value,label,id\ninf,inf,1\n-inf,-inf,2\n+inf,+inf,3\n2.5,002.5,4\n,,5\nNaN,NaN,6\n",
19
+ );
20
+
21
+ const data = await vegaLoadData("chart.csv", {
22
+ type: "csv",
23
+ parse: { value: "number", label: "string", id: "integer" },
24
+ });
25
+
26
+ expect(data).toEqual([
27
+ { value: Infinity, label: "inf", id: 1 },
28
+ { value: -Infinity, label: "-inf", id: 2 },
29
+ { value: Infinity, label: "+inf", id: 3 },
30
+ { value: 2.5, label: "002.5", id: 4 },
31
+ { value: null, label: null, id: 5 },
32
+ { value: Number.NaN, label: "NaN", id: 6 },
33
+ ]);
34
+ });
35
+
36
+ it("preserves the table's large integer and infinity handling", async () => {
37
+ vi.spyOn(vegaLoader, "load").mockResolvedValue(
38
+ "id,value\n9007199254740993,inf\n9007199254740995,-inf\n",
39
+ );
40
+
41
+ const data = await vegaLoadData(
42
+ "table.csv",
43
+ { type: "csv", parse: { id: "integer", value: "number" } },
44
+ { handleBigIntAndNumberLike: true },
45
+ );
46
+
47
+ expect(data).toEqual([
48
+ { id: BigInt("9007199254740993"), value: "inf" },
49
+ { id: BigInt("9007199254740995"), value: "-inf" },
50
+ ]);
51
+ });
52
+
16
53
  it("should parse csv data with dates", async () => {
17
54
  const csvData = `
18
55
  active,username,id
@@ -16,6 +16,26 @@ const previousNumberParser = typeParsers.number;
16
16
  const previousDateParser = typeParsers.date;
17
17
  const previousBooleanParser = typeParsers.boolean;
18
18
 
19
+ const NUMBER_MIDDLEWARE: Middleware = () => {
20
+ const parseNumber = (value: string) => {
21
+ if (value === "inf" || value === "+inf") {
22
+ return Number.POSITIVE_INFINITY;
23
+ }
24
+ if (value === "-inf") {
25
+ return Number.NEGATIVE_INFINITY;
26
+ }
27
+ return previousNumberParser(value);
28
+ };
29
+
30
+ typeParsers.integer = parseNumber;
31
+ typeParsers.number = parseNumber;
32
+
33
+ return () => {
34
+ typeParsers.integer = previousIntegerParser;
35
+ typeParsers.number = previousNumberParser;
36
+ };
37
+ };
38
+
19
39
  const BIG_INT_MIDDLEWARE: Middleware = () => {
20
40
  // Custom parser to:
21
41
  // - handle BigInt
@@ -159,6 +179,8 @@ export async function vegaLoadData<T = object>(
159
179
  const middleware: Middleware[] = [DATE_MIDDLEWARE];
160
180
  if (handleBigIntAndNumberLike) {
161
181
  middleware.push(BIG_INT_MIDDLEWARE);
182
+ } else {
183
+ middleware.push(NUMBER_MIDDLEWARE);
162
184
  }
163
185
 
164
186
  let unsubscribes: Unsubscribe[] = [];
@@ -216,7 +238,7 @@ export async function vegaLoadData<T = object>(
216
238
 
217
239
  // Apply middleware
218
240
  unsubscribes = middleware.map((m) => m());
219
- // Always set parse to auto for csv data, to be able to parse dates and floats
241
+ // CSV defaults to inference when no explicit column types are available.
220
242
  const results = isCsv
221
243
  ? // csv -> json
222
244
  read(csvOrJsonData, {
@@ -45,21 +45,22 @@ function toArray<T>(value: T | T[] | undefined): T[] {
45
45
 
46
46
  export function getVegaFieldTypes(
47
47
  types: Record<string, DataType> | undefined | null,
48
+ { parseDates = false }: { parseDates?: boolean } = {},
48
49
  ): FieldTypes | "auto" {
49
50
  if (!types || Object.keys(types).length === 0) {
50
51
  // If fieldTypes is provided, use it to parse the data
51
52
  // Otherwise, infer the data types
52
53
  return "auto";
53
54
  }
54
- // Convert all 'date' to 'string', because dates don't format back to
55
- // the correct formatting. For example, a date like '2024-01-01' will
56
- // be formatted to '2024-01-01T00:00:00.000Z'.
55
+ // Preserve date-only strings for callers such as the data editor.
56
+ // Parsing creates Date objects that JSON serializes as full timestamps.
57
+ // Charts opt into date parsing for temporal axes.
57
58
  return Objects.mapValues(types, (type): VegaDataType => {
58
59
  if (type === "geometry") {
59
60
  return "string";
60
61
  }
61
62
  if (type === "date") {
62
- return "string";
63
+ return parseDates ? "date" : "string";
63
64
  }
64
65
  if (type === "time") {
65
66
  return "string";
@@ -1 +0,0 @@
1
- import{Ga as e}from"./index-BGA2MQ61.js";var t=Object.prototype.hasOwnProperty;function n(e,n){return e!=null&&t.call(e,n)}function r(t,r){return t!=null&&e(t,r,n)}export{r as t};
@@ -1 +0,0 @@
1
- import{a as e}from"./rolldown-runtime-B0Z9INg1.js";import{c as t,f as n,l as r,u as i}from"./useEvent-Dc9HkKI2.js";import{t as a}from"./react-CUdNIagt.js";import{$r as o,Ai as s,Bi as c,Bt as l,Cn as u,D as d,Gn as f,Ha as p,Hi as m,Ii as h,Ji as g,Ki as _,Kn as v,Li as y,M as b,Mi as x,P as S,Qr as C,Ri as w,Rn as T,Rt as E,Ui as D,Wa as O,Wi as k,Xi as A,Yi as j,Zi as M,_n as ee,c as N,fn as P,gn as F,i as I,jn as L,qi as R,qn as z,ro as te,ti as ne,to as re,yr as ie,yt as B,zi as V}from"./cells-B3WiM6w3.js";import{t as H}from"./compiler-runtime-BQ9S8nyo.js";import{s as ae}from"./config-BxZgoFvi.js";import{O as U}from"./config-DpGPGznL.js";import{t as W}from"./ErrorBoundary-AmSQgV_f.js";import{t as oe}from"./cn-ldLVeaqm.js";import{t as G}from"./jsx-runtime-B74pBk57.js";import{r as se}from"./config-B4VJJibu.js";import{t as ce}from"./tooltip-DR2Z2N4w.js";import{r as le,t as ue}from"./button-BoklZTGL.js";import{t as K}from"./createLucideIcon-rHn2EdoM.js";import{i as q}from"./paths-CzfpItSz.js";import{r as J}from"./useNumberFormatter-C4-_TnkF.js";import{R as de,j as fe}from"./RunButton-CmaVvEXE.js";import{a as pe}from"./input-BDakodZ2.js";import{t as me}from"./copy-icon-DFhUGBjO.js";import{l as he}from"./arrays-BqUx5USx.js";import{i as ge}from"./strings-BHZPE0Mc.js";import{r as _e}from"./requests-yTHMxhVa.js";import{t as ve}from"./context-BFOBKCJB.js";import{n as ye}from"./useAsyncData-DucTwMkf.js";import{$t as be,An as xe,Jt as Se,Mn as Ce,Nn as we,On as Te,Qt as Ee,S as De,Sn as Oe,Xt as ke,Yt as Ae,Zt as je,_ as Me,_n as Ne,bn as Pe,da as Fe,in as Ie,jn as Le,k as Re,kn as ze,nn as Be,nr as Ve,v as He,vn as Ue,xn as We,yn as Ge}from"./index-BGA2MQ61.js";import{t as Ke}from"./empty-state-CzxjZqGW.js";import{n as qe,t as Je}from"./common-B-ub9i8J.js";import{a as Ye,i as Xe,n as Ze,o as Qe,r as $e,s as et,t as tt}from"./components-BRVhsaex.js";var nt=K(`square-equal`,[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}],[`path`,{d:`M7 10h10`,key:`1101jm`}],[`path`,{d:`M7 14h10`,key:`1mhdw3`}]]),Y=H(),X=e(a(),1),Z=G(),rt=1;function it(e){return 1.75+e*rt}function at(e){return 3+e*rt}function ot(e){return 3.25+e*rt}var Q={engineEmpty:.75,engine:.75,database:1,tableLoading:2.75,tableSchemaless:2,columnLocal:1.25,columnPreview:2.5};function $(e){return{paddingLeft:`${e}rem`}}var st=n(e=>{let t=e(w),n=e(ne),r=e(I);return he(t,e=>{if(!e.variable_name)return-1;let t=Object.values(n).find(t=>t.name===e.variable_name);if(!t)return 0;let i=r.inOrderIds.indexOf(t.declaredBy[0]);return i===-1?0:i})}),ct=U(`marimo:datasources:hideEmpty`,!1,C,{getOnInit:!0});function lt(e){let t=!1,n=[];for(let r of e){if(!k(r)||!m(r)){n.push(r);continue}let e=r.child_schemas??[],i=lt(e);if(r.tables.length===0&&i.length===0){t=!0;continue}if(i===e){n.push(r);continue}t=!0,n.push({...r,child_schemas:i})}return t?n:e}function ut(e){let t=!1,n=[];for(let r of e){if(D(r)&&r.schemas.length===0){t=!0;continue}if(r.schemas.length===0){n.push(r);continue}let e=lt(r.schemas);if(e.length===0){t=!0;continue}if(e===r.schemas){n.push(r);continue}t=!0,n.push({...r,schemas:e})}return t?n:e}var dt=()=>{let e=(0,Y.c)(42),[n,a]=X.useState(``),[o,s]=t(ct),c=i(y),l=r(st),d=r(x),f;bb0:{if(!o){f=d;break bb0}let t,n;e[0]===d?(t=e[1],n=e[2]):(t=!1,n=d.map(e=>{let n=ut(e.databases);return n===e.databases?e:(t=!0,{...e,databases:n})}),e[0]=d,e[1]=t,e[2]=n),f=t?n:d}let p=f;if(l.length===0&&p.length===0){let t;return e[3]===Symbol.for(`react.memo_cache_sentinel`)?(t=(0,Z.jsx)(Ke,{title:`No tables found`,description:`Any datasets/dataframes in the global scope will be shown here.`,action:(0,Z.jsx)(Qe,{group:`database`,label:`Add database or catalog`,variant:`outline`,size:`sm`}),icon:(0,Z.jsx)(q,{})}),e[3]=t):t=e[3],t}let m;e[4]===n?m=e[5]:(m=n.trim(),e[4]=n,e[5]=m);let h=!!m,g;e[6]===c?g=e[7]:(g=e=>{c(e.length>0),a(e)},e[6]=c,e[7]=g);let _;e[8]!==n||e[9]!==g?(_=(0,Z.jsx)(F,{placeholder:`Search tables...`,className:`h-6 m-1`,value:n,onValueChange:g,rootClassName:`flex-1 border-r border-b-0`}),e[8]=n,e[9]=g,e[10]=_):_=e[10];let v;e[11]===h?v=e[12]:(v=h&&(0,Z.jsx)(`button`,{type:`button`,className:`float-right border-b px-2 m-0 h-full hover:bg-accent hover:text-accent-foreground`,onClick:()=>a(``),children:(0,Z.jsx)(J,{className:`h-4 w-4`})}),e[11]=h,e[12]=v);let b=!o,S;e[13]!==o||e[14]!==s?(S=()=>s(!o),e[13]=o,e[14]=s,e[15]=S):S=e[15];let C;e[16]!==b||e[17]!==S?(C=(0,Z.jsx)(Ie,{"data-testid":`datasources-hide-empty-button`,isVisible:b,onToggle:S,showTooltip:`Show empty schemas and databases`,hideTooltip:`Hide empty schemas and databases`,size:`sm`,className:`px-2 rounded-none focus-visible:outline-hidden`}),e[16]=b,e[17]=S,e[18]=C):C=e[18];let w;e[19]===Symbol.for(`react.memo_cache_sentinel`)?(w=(0,Z.jsx)(Qe,{group:`database`,label:`Add database or catalog`,compact:!0,variant:`ghost`,size:`sm`,className:`px-2 rounded-none focus-visible:outline-hidden`}),e[19]=w):w=e[19];let T;e[20]!==_||e[21]!==v||e[22]!==C?(T=(0,Z.jsxs)(`div`,{className:`flex items-center w-full border-b`,children:[_,v,C,w]}),e[20]=_,e[21]=v,e[22]=C,e[23]=T):T=e[23];let E;if(e[24]!==p||e[25]!==n){let t;e[27]===n?t=e[28]:(t=e=>(0,Z.jsx)(ft,{connection:e,hasChildren:e.databases.length>0,children:e.databases.map(t=>(0,Z.jsx)(gt,{connection:e,database:t,searchValue:n},t.name))},e.name),e[27]=n,e[28]=t),E=p.map(t),e[24]=p,e[25]=n,e[26]=E}else E=e[26];let D;e[29]!==p.length||e[30]!==l.length?(D=p.length>0&&l.length>0&&(0,Z.jsxs)(Ae,{className:`pr-2`,style:$(Q.engine),children:[(0,Z.jsx)(Re,{className:`h-4 w-4 text-muted-foreground`}),(0,Z.jsx)(`span`,{className:`text-xs`,children:`Python`})]}),e[29]=p.length,e[30]=l.length,e[31]=D):D=e[31];let O;e[32]!==n||e[33]!==l?(O=l.length>0&&(0,Z.jsx)(bt,{tables:l,searchValue:n}),e[32]=n,e[33]=l,e[34]=O):O=e[34];let k;e[35]!==E||e[36]!==D||e[37]!==O?(k=(0,Z.jsxs)(u,{className:`flex flex-col`,children:[E,D,O]}),e[35]=E,e[36]=D,e[37]=O,e[38]=k):k=e[38];let A;return e[39]!==k||e[40]!==T?(A=(0,Z.jsxs)(P,{className:`border-b bg-background rounded-none h-full pb-10 overflow-auto outline-hidden`,shouldFilter:!1,children:[T,k]}),e[39]=k,e[40]=T,e[41]=A):A=e[41],A},ft=e=>{let t=(0,Y.c)(26),{connection:n,children:r,hasChildren:i}=e,a=n.name===M,o=a?`In-Memory`:n.name,{previewDataSourceConnection:c}=_e(),l;t[0]!==n.name||t[1]!==c?(l=async()=>{await c({engine:n.name})},t[0]=n.name,t[1]=c,t[2]=l):l=t[2];let u=l,d;t[3]===Symbol.for(`react.memo_cache_sentinel`)?(d=$(Q.engine),t[3]=d):d=t[3];let f;t[4]===n.dialect?f=t[5]:(f=(0,Z.jsx)(L,{className:`h-4 w-4 text-muted-foreground`,name:n.dialect}),t[4]=n.dialect,t[5]=f);let p;t[6]===n.dialect?p=t[7]:(p=s(n.dialect),t[6]=n.dialect,t[7]=p);let m;t[8]===p?m=t[9]:(m=(0,Z.jsx)(`span`,{className:`text-xs`,children:p}),t[8]=p,t[9]=m);let h=o,g;t[10]===h?g=t[11]:(g=(0,Z.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[`(`,(0,Z.jsx)(et,{variableName:h}),`)`]}),t[10]=h,t[11]=g);let _;t[12]!==u||t[13]!==a?(_=!a&&(0,Z.jsx)(Be,{onClick:u,tooltip:`Refresh connection`,className:`ml-auto h-4 p-0`,iconClassName:`h-3.5 w-3.5`}),t[12]=u,t[13]=a,t[14]=_):_=t[14];let v;t[15]!==f||t[16]!==m||t[17]!==g||t[18]!==_?(v=(0,Z.jsxs)(Ae,{className:`pr-2`,style:d,children:[f,m,g,_]}),t[15]=f,t[16]=m,t[17]=g,t[18]=_,t[19]=v):v=t[19];let y;t[20]!==r||t[21]!==i?(y=i?r:(0,Z.jsx)(ke,{content:`No databases available`,style:$(Q.engineEmpty)}),t[20]=r,t[21]=i,t[22]=y):y=t[22];let b;return t[23]!==y||t[24]!==v?(b=(0,Z.jsxs)(Z.Fragment,{children:[v,y]}),t[23]=y,t[24]=v,t[25]=b):b=t[25],b},pt=X.createContext(null);function mt(){let e=X.useContext(pt);if(e==null)throw Error(`useDataSourceTree must be used within a DataSourceTreeContext.Provider`);return e}function ht(e,{schema:t,schemaPath:n}){return{engine:e.engineName,database:e.databaseName,schema:t,schemaPath:n,defaultSchema:e.defaultSchema,defaultDatabase:e.defaultDatabase,dialect:e.dialect}}var gt=e=>{let t=(0,Y.c)(21),{connection:n,database:r,searchValue:i}=e,a;t[0]!==n.default_database||t[1]!==n.default_schema||t[2]!==n.dialect||t[3]!==n.name||t[4]!==r.name||t[5]!==i?(a={engineName:n.name,databaseName:r.name,dialect:n.dialect,defaultSchema:n.default_schema,defaultDatabase:n.default_database,searchValue:i},t[0]=n.default_database,t[1]=n.default_schema,t[2]=n.dialect,t[3]=n.name,t[4]=r.name,t[5]=i,t[6]=a):a=t[6];let o=a,s=n.name,c=r.schemas,l;t[7]===r?l=t[8]:(l=D(r),t[7]=r,t[8]=l);let u;t[9]===Symbol.for(`react.memo_cache_sentinel`)?(u=[],t[9]=u):u=t[9];let d;t[10]!==r.schemas||t[11]!==l?(d=(0,Z.jsx)(vt,{schemas:c,schemasResolved:l,schemaPath:u,depth:0}),t[10]=r.schemas,t[11]=l,t[12]=d):d=t[12];let f;t[13]!==d||t[14]!==o?(f=(0,Z.jsx)(pt.Provider,{value:o,children:d}),t[13]=d,t[14]=o,t[15]=f):f=t[15];let p;return t[16]!==n.name||t[17]!==r||t[18]!==i||t[19]!==f?(p=(0,Z.jsx)(_t,{engineName:s,database:r,searchValue:i,children:f}),t[16]=n.name,t[17]=r,t[18]=i,t[19]=f,t[20]=p):p=t[20],p},_t=e=>{let t=(0,Y.c)(29),{searchValue:n,engineName:r,database:i,children:a}=e,o;t[0]!==i||t[1]!==n?(o=g(i,n),t[0]=i,t[1]=n,t[2]=o):o=t[2];let s=o,[c,l]=X.useState(s),[u,d]=X.useState(!1),[f,p]=X.useState(n),[m,h]=X.useState(s);(f!==n||m!==s)&&(p(n),h(s),l(s));let _;t[3]===Symbol.for(`react.memo_cache_sentinel`)?(_=$(Q.database),t[3]=_):_=t[3];let v;t[4]!==c||t[5]!==u?(v=()=>{l(!c),d(!u)},t[4]=c,t[5]=u,t[6]=v):v=t[6];let y=`${r}:${i.name}`,b;t[7]===c?b=t[8]:(b=(0,Z.jsx)(be,{isExpanded:c}),t[7]=c,t[8]=b);let x=u&&c?`text-foreground`:`text-muted-foreground`,S;t[9]===x?S=t[10]:(S=oe(`h-4 w-4`,x),t[9]=x,t[10]=S);let C;t[11]===S?C=t[12]:(C=(0,Z.jsx)(q,{className:S}),t[11]=S,t[12]=C);let w=u&&c&&`font-semibold`,T;t[13]===w?T=t[14]:(T=oe(w),t[13]=w,t[14]=T);let E;t[15]===i.name?E=t[16]:(E=i.name===``?(0,Z.jsx)(`i`,{children:`Not connected`}):i.name,t[15]=i.name,t[16]=E);let D;t[17]!==T||t[18]!==E?(D=(0,Z.jsx)(`span`,{className:T,children:E}),t[17]=T,t[18]=E,t[19]=D):D=t[19];let O;t[20]!==D||t[21]!==v||t[22]!==y||t[23]!==b||t[24]!==C?(O=(0,Z.jsxs)(ee,{className:`text-sm flex flex-row gap-1 items-center cursor-pointer rounded-none`,style:_,onSelect:v,value:y,children:[b,C,D]}),t[20]=D,t[21]=v,t[22]=y,t[23]=b,t[24]=C,t[25]=O):O=t[25];let k=c&&a,A;return t[26]!==O||t[27]!==k?(A=(0,Z.jsxs)(Z.Fragment,{children:[O,k]}),t[26]=O,t[27]=k,t[28]=A):A=t[28],A},vt=e=>{let{schemas:t,schemasResolved:n,depth:r}=e,i=mt(),{engineName:a,databaseName:o,searchValue:s}=i,{addSchemaList:c}=h(),l=Me(e.schemaPath),[u,d]=X.useState(!1),{isPending:p,error:m}=ye(async()=>{if(!n&&a){d(!0);try{let e=await f.request({engine:a,database:o,schemaPath:l});c({schemas:e.schemas??[],sqlSchemaContext:{engine:a,database:o,schemaPath:l}})}finally{d(!1)}}},[n,a,o,l]),g=$(it(r));return p||u?(0,Z.jsx)(Ee,{message:`Loading schemas...`,style:g}):m?(0,Z.jsx)(je,{error:m,style:g}):t.length===0?(0,Z.jsx)(ke,{content:`No schemas available`,style:g}):(0,Z.jsx)(Z.Fragment,{children:t.map(e=>_(e.name)?(0,Z.jsx)(bt,{tables:e.tables,tablesResolved:k(e),searchValue:s,sqlTableContext:ht(i,{schema:e.name,schemaPath:l})},e.name):(0,Z.jsx)(yt,{schema:e,schemaPath:[...l,e.name],depth:r},e.name))})},yt=e=>{let t=(0,Y.c)(41),{schema:n,schemaPath:r,depth:i}=e,a=mt(),{databaseName:o,searchValue:s}=a,c;t[0]!==n||t[1]!==s?(c=R(n,s),t[0]=n,t[1]=s,t[2]=c):c=t[2];let l=c,[u,d]=X.useState(l),[f,p]=X.useState(!1),[h,g]=X.useState(s),[_,v]=X.useState(l),y;t[3]===r?y=t[4]:(y=r.join(`.`),t[3]=r,t[4]=y);let b=`${o}:${y}`,x;t[5]===n.child_schemas?x=t[6]:(x=n.child_schemas??[],t[5]=n.child_schemas,t[6]=x);let S=x;(h!==s||_!==l)&&(g(s),v(l),d(l));let C;t[7]===i?C=t[8]:(C=$(it(i)),t[7]=i,t[8]=C);let w;t[9]!==u||t[10]!==f?(w=()=>{d(!u),p(!f)},t[9]=u,t[10]=f,t[11]=w):w=t[11];let T;t[12]===u?T=t[13]:(T=(0,Z.jsx)(be,{isExpanded:u}),t[12]=u,t[13]=T);let E=f&&u&&`text-foreground`,D;t[14]===E?D=t[15]:(D=oe(`h-4 w-4 text-muted-foreground`,E),t[14]=E,t[15]=D);let O;t[16]===D?O=t[17]:(O=(0,Z.jsx)(re,{className:D}),t[16]=D,t[17]=O);let A=f&&u&&`font-semibold`,j;t[18]===A?j=t[19]:(j=oe(A),t[18]=A,t[19]=j);let M;t[20]!==n.name||t[21]!==j?(M=(0,Z.jsx)(`span`,{className:j,children:n.name}),t[20]=n.name,t[21]=j,t[22]=M):M=t[22];let N;t[23]!==M||t[24]!==C||t[25]!==w||t[26]!==T||t[27]!==O||t[28]!==b?(N=(0,Z.jsxs)(ee,{className:`text-sm flex flex-row gap-1 items-center cursor-pointer rounded-none`,style:C,onSelect:w,value:b,children:[T,O,M]}),t[23]=M,t[24]=C,t[25]=w,t[26]=T,t[27]=O,t[28]=b,t[29]=N):N=t[29];let P;t[30]!==S||t[31]!==i||t[32]!==u||t[33]!==n||t[34]!==r||t[35]!==s||t[36]!==a?(P=u&&(0,Z.jsxs)(Z.Fragment,{children:[(S.length>0||!m(n))&&(0,Z.jsx)(vt,{schemas:S,schemasResolved:m(n),schemaPath:r,depth:i+1}),(0,Z.jsx)(bt,{tables:n.tables,tablesResolved:k(n),searchValue:s,tableIndentRem:at(i),columnIndentRem:ot(i),sqlTableContext:ht(a,{schema:n.name,schemaPath:r})})]}),t[30]=S,t[31]=i,t[32]=u,t[33]=n,t[34]=r,t[35]=s,t[36]=a,t[37]=P):P=t[37];let F;return t[38]!==N||t[39]!==P?(F=(0,Z.jsxs)(Z.Fragment,{children:[N,P]}),t[38]=N,t[39]=P,t[40]=F):F=t[40],F},bt=e=>{let t=(0,Y.c)(31),{tables:n,sqlTableContext:r,searchValue:i,tablesResolved:a,tableIndentRem:o,columnIndentRem:s}=e,c=a===void 0||a,{addTableList:l}=h(),[u,d]=X.useState(!1),f;t[0]!==l||t[1]!==r||t[2]!==c?(f=async()=>{if(!c&&r){d(!0);let{engine:e,database:t,schema:n,schemaPath:i}=r,a=await z.request({engine:e,database:t,schema:n,schemaPath:i??[]});if(!a?.tables)throw d(!1),Error(`No tables available`);l({tables:a.tables,sqlTableContext:r}),d(!1)}},t[0]=l,t[1]=r,t[2]=c,t[3]=f):f=t[3];let p;t[4]!==r||t[5]!==c?(p=[c,r],t[4]=r,t[5]=c,t[6]=p):p=t[6];let{isPending:m,error:g}=ye(f,p),_=o??Q.tableLoading,v;t[7]===_?v=t[8]:(v=$(_),t[7]=_,t[8]=v);let y=v;if(m||u){let e;return t[9]===y?e=t[10]:(e=(0,Z.jsx)(Ee,{message:`Loading tables...`,style:y}),t[9]=y,t[10]=e),e}if(g){let e;return t[11]!==g||t[12]!==y?(e=(0,Z.jsx)(je,{error:g,style:y}),t[11]=g,t[12]=y,t[13]=e):e=t[13],e}if(n.length===0){let e;return t[14]===y?e=t[15]:(e=(0,Z.jsx)(ke,{content:`No tables found`,style:y}),t[14]=y,t[15]=e),e}let b;if(t[16]!==s||t[17]!==i||t[18]!==r||t[19]!==o||t[20]!==n){let e;t[22]===i?e=t[23]:(e=e=>!i||e.name.toLowerCase().includes(i.toLowerCase()),t[22]=i,t[23]=e);let a=n.filter(e),c;t[24]!==s||t[25]!==i||t[26]!==r||t[27]!==o?(c=e=>(0,Z.jsx)(xt,{table:e,sqlTableContext:r,isSearching:!!i,tableIndentRem:o,columnIndentRem:s},e.name),t[24]=s,t[25]=i,t[26]=r,t[27]=o,t[28]=c):c=t[28],b=a.map(c),t[16]=s,t[17]=i,t[18]=r,t[19]=o,t[20]=n,t[21]=b}else b=t[21];let x;return t[29]===b?x=t[30]:(x=(0,Z.jsx)(Z.Fragment,{children:b}),t[29]=b,t[30]=x),x},xt=e=>{let t=(0,Y.c)(69),{table:n,sqlTableContext:i,isSearching:a,tableIndentRem:o,columnIndentRem:s}=e,{addTable:c}=h(),[u,f]=X.useState(!1),p=n.columns.length>0,m;t[0]!==c||t[1]!==u||t[2]!==i||t[3]!==n.name||t[4]!==p?(m=async()=>{if(u&&!p&&i){let{engine:e,database:t,schema:r,schemaPath:a}=i,o=await v.request({engine:e,database:t,schema:r,tableName:n.name,schemaPath:a??[]});if(!o?.table)throw Error(`No table details available`);c({table:o.table,sqlTableContext:i})}},t[0]=c,t[1]=u,t[2]=i,t[3]=n.name,t[4]=p,t[5]=m):m=t[5];let g;t[6]!==u||t[7]!==p?(g=[u,p],t[6]=u,t[7]=p,t[8]=g):g=t[8];let{isFetching:_,isPending:y,error:b}=ye(m,g),x=r(ae),S=E(),{createNewCell:C}=d(),w=De(),T;t[9]!==w||t[10]!==x||t[11]!==C||t[12]!==S||t[13]!==i||t[14]!==n?(T=()=>{l({autoInstantiate:x,createNewCell:C,fromCellId:S}),w((()=>{if(n.source_type===`catalog`){let e=i?.database?[i.database,...i.schemaPath??[],n.name].join(`.`):n.name;return`${n.engine}.load_table("${e}")`}if(i)return j({table:n,columnName:`*`,sqlTableContext:i});switch(n.source_type){case`local`:return`mo.ui.table(${n.name})`;case`duckdb`:case`connection`:return j({table:n,columnName:`*`,sqlTableContext:i});default:return ge(n.source_type),``}})())},t[9]=w,t[10]=x,t[11]=C,t[12]=S,t[13]=i,t[14]=n,t[15]=T):T=t[15];let D=T,k;t[16]!==n.num_columns||t[17]!==n.num_rows?(k=()=>{let e=[];return n.num_rows!=null&&e.push(`${n.num_rows} rows`),n.num_columns!=null&&e.push(`${n.num_columns} columns`),e.length===0?null:(0,Z.jsx)(`div`,{className:`flex flex-row gap-2 items-center pl-6 group-hover:hidden`,children:(0,Z.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:e.join(`, `)})})},t[16]=n.num_columns,t[17]=n.num_rows,t[18]=k):k=t[18];let M=k,N;t[19]!==s||t[20]!==b||t[21]!==_||t[22]!==y||t[23]!==i||t[24]!==n?(N=()=>{let e=$(s??Q.tableLoading);if(y||_)return(0,Z.jsx)(Ee,{message:`Loading columns...`,style:e});if(b)return(0,Z.jsx)(je,{error:b,style:e});let t=n.columns;return t.length===0?(0,Z.jsx)(ke,{content:`No columns found`,style:e}):t.map(e=>(0,Z.jsx)(St,{table:n,column:e,sqlTableContext:i,columnIndentRem:s},e.name))},t[19]=s,t[20]=b,t[21]=_,t[22]=y,t[23]=i,t[24]=n,t[25]=N):N=t[25];let P=N,F;t[26]!==u||t[27]!==a||t[28]!==n.source_type||t[29]!==n.type?(F=()=>{if(n.source_type===`local`)return;let e=n.type===`table`?O:te;return(0,Z.jsx)(e,{className:`h-3 w-3`,strokeWidth:u||a?2.5:void 0})},t[26]=u,t[27]=a,t[28]=n.source_type,t[29]=n.type,t[30]=F):F=t[30];let I=F,L;t[31]!==i||t[32]!==n.name?(L=A(i,n.name),t[31]=i,t[32]=n.name,t[33]=L):L=t[33];let R=L,z=o??(i?Q.tableSchemaless:0),ne=(u||a)&&`font-semibold`,re;t[34]===ne?re=t[35]:(re=oe(`rounded-none group h-8 cursor-pointer`,ne),t[34]=ne,t[35]=re);let ie;t[36]===z?ie=t[37]:(ie=$(z),t[36]=z,t[37]=ie);let B;t[38]===u?B=t[39]:(B=()=>f(!u),t[38]=u,t[39]=B);let V;t[40]===I?V=t[41]:(V=I(),t[40]=I,t[41]=V);let H;t[42]===n.name?H=t[43]:(H=(0,Z.jsx)(`span`,{className:`text-sm`,children:n.name}),t[42]=n.name,t[43]=H);let U;t[44]!==V||t[45]!==H?(U=(0,Z.jsxs)(`div`,{className:`flex gap-2 items-center flex-1 pl-1`,children:[V,H]}),t[44]=V,t[45]=H,t[46]=U):U=t[46];let W;t[47]===M?W=t[48]:(W=M(),t[47]=M,t[48]=W);let G;t[49]===D?G=t[50]:(G=le.stopPropagation(()=>D()),t[49]=D,t[50]=G);let se;t[51]===Symbol.for(`react.memo_cache_sentinel`)?(se=(0,Z.jsx)(Fe,{className:`h-3 w-3`}),t[51]=se):se=t[51];let K;t[52]===G?K=t[53]:(K=(0,Z.jsx)(ce,{content:`Add table to notebook`,delayDuration:400,children:(0,Z.jsx)(ue,{className:`group-hover:inline-flex hidden`,variant:`text`,size:`icon`,onClick:G,children:se})}),t[52]=G,t[53]=K);let q;t[54]!==u||t[55]!==ie||t[56]!==B||t[57]!==U||t[58]!==W||t[59]!==K||t[60]!==re||t[61]!==R?(q=(0,Z.jsxs)(ee,{className:re,style:ie,value:R,"aria-selected":u,forceMount:!0,onSelect:B,children:[U,W,K]}),t[54]=u,t[55]=ie,t[56]=B,t[57]=U,t[58]=W,t[59]=K,t[60]=re,t[61]=R,t[62]=q):q=t[62];let J;t[63]!==u||t[64]!==P?(J=u&&P(),t[63]=u,t[64]=P,t[65]=J):J=t[65];let de;return t[66]!==q||t[67]!==J?(de=(0,Z.jsxs)(Z.Fragment,{children:[q,J]}),t[66]=q,t[67]=J,t[68]=de):de=t[68],de},St=e=>{let t=(0,Y.c)(51),{table:n,column:a,sqlTableContext:o,columnIndentRem:s}=e,[l,u]=X.useState(!1),d=r(y),f=i(V);d&&l&&u(!1),f(l?e=>new Set([...e,`${n.name}:${a.name}`]):e=>(e.delete(`${n.name}:${a.name}`),new Set(e)));let p=De(),{columnsPreviews:m}=c(),h;t[0]!==a.name||t[1]!==n.primary_keys?(h=n.primary_keys?.includes(a.name)||!1,t[0]=a.name,t[1]=n.primary_keys,t[2]=h):h=t[2];let g=h,_;t[3]!==a.name||t[4]!==n.indexes?(_=n.indexes?.includes(a.name)||!1,t[3]=a.name,t[4]=n.indexes,t[5]=_):_=t[5];let v=_,b;t[6]===p?b=t[7]:(b=e=>{p(e)},t[6]=p,t[7]=b);let x=b,S=Ct,C=l?`font-semibold`:``,w;t[8]!==a.name||t[9]!==C?(w=(0,Z.jsx)(`span`,{className:C,children:a.name}),t[8]=a.name,t[9]=C,t[10]=w):w=t[10];let T=w,E=`${n.name}.${a.name}`,D=`${n.name}.${a.name}`,O;t[11]===l?O=t[12]:(O=()=>u(!l),t[11]=l,t[12]=O);let k;t[13]!==s||t[14]!==o?(k=s??(o?ot(0):Q.columnLocal),t[13]=s,t[14]=o,t[15]=k):k=t[15];let A;t[16]===k?A=t[17]:(A=$(k),t[16]=k,t[17]=A);let j;t[18]!==a.type||t[19]!==T?(j=(0,Z.jsx)(Se,{columnName:T,dataType:a.type}),t[18]=a.type,t[19]=T,t[20]=j):j=t[20];let M;t[21]===g?M=t[22]:(M=g&&S({tooltipContent:`Primary key`,content:`PK`}),t[21]=g,t[22]=M);let N;t[23]===v?N=t[24]:(N=v&&S({tooltipContent:`Indexed`,content:`IDX`}),t[23]=v,t[24]=N);let P;t[25]!==A||t[26]!==j||t[27]!==M||t[28]!==N?(P=(0,Z.jsxs)(`div`,{className:`flex flex-row gap-2 items-center flex-1`,style:A,children:[j,M,N]}),t[25]=A,t[26]=j,t[27]=M,t[28]=N,t[29]=P):P=t[29];let F;t[30]===a.name?F=t[31]:(F=(0,Z.jsx)(ce,{content:`Copy column name`,delayDuration:400,children:(0,Z.jsx)(ue,{variant:`text`,size:`icon`,className:`group-hover:opacity-100 opacity-0 hover:bg-muted text-muted-foreground hover:text-foreground`,children:(0,Z.jsx)(me,{tooltip:!1,value:a.name,className:`h-3 w-3`})})}),t[30]=a.name,t[31]=F);let I;t[32]===a.external_type?I=t[33]:(I=(0,Z.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:a.external_type}),t[32]=a.external_type,t[33]=I);let L;t[34]!==P||t[35]!==F||t[36]!==I||t[37]!==E||t[38]!==D||t[39]!==O?(L=(0,Z.jsxs)(ee,{className:`rounded-none py-1 group cursor-pointer`,value:D,onSelect:O,children:[P,F,I]},E),t[34]=P,t[35]=F,t[36]=I,t[37]=E,t[38]=D,t[39]=O,t[40]=L):L=t[40];let R;t[41]!==a||t[42]!==m||t[43]!==x||t[44]!==l||t[45]!==o||t[46]!==n?(R=l&&(0,Z.jsx)(`div`,{className:`pr-2 py-2 bg-(--slate-1) shadow-inner border-b`,style:$(Q.columnPreview),children:(0,Z.jsx)(W,{children:(0,Z.jsx)(He,{table:n,column:a,onAddColumnChart:x,preview:m.get(o?`${o.database}.${o.schema}.${n.name}:${a.name}`:`${n.name}:${a.name}`),sqlTableContext:o})})}),t[41]=a,t[42]=m,t[43]=x,t[44]=l,t[45]=o,t[46]=n,t[47]=R):R=t[47];let z;return t[48]!==L||t[49]!==R?(z=(0,Z.jsxs)(Z.Fragment,{children:[L,R]}),t[48]=L,t[49]=R,t[50]=z):z=t[50],z};function Ct(e){let{tooltipContent:t,content:n}=e;return(0,Z.jsx)(ce,{content:t,delayDuration:100,children:(0,Z.jsx)(`span`,{className:`text-xs text-black bg-gray-100 dark:invert rounded px-1`,children:n})})}function wt(e){return e}var Tt={name:`name`,type:`type-value`,defs:`defs-refs`},Et=[wt({id:Tt.name,accessorFn:e=>[e.name,e.declaredBy],enableSorting:!0,sortingFn:`alphanumeric`,header:({column:e})=>(0,Z.jsx)(Te,{header:`Name`,column:e}),cell:({getValue:e})=>{let[t,n]=e();return(0,Z.jsx)(Je,{name:t,declaredBy:n})}}),wt({id:Tt.type,accessorFn:e=>[e.dataType,e.value],enableSorting:!0,sortingFn:`alphanumeric`,header:({column:e})=>(0,Z.jsx)(Te,{header:(0,Z.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,Z.jsx)(`span`,{children:`Type`}),(0,Z.jsx)(`span`,{children:`Value`})]}),column:e}),cell:({getValue:e})=>{let[t,n]=e();return(0,Z.jsxs)(`div`,{className:`max-w-[150px]`,children:[(0,Z.jsx)(`div`,{className:`text-ellipsis overflow-hidden whitespace-nowrap text-muted-foreground font-mono text-xs`,children:t}),(0,Z.jsx)(`div`,{className:`text-ellipsis overflow-hidden whitespace-nowrap`,title:n??``,children:n})]})}}),wt({id:Tt.defs,accessorFn:e=>[e.declaredBy,e.usedBy,e.name,e.declaredByNames,e.usedByNames],enableSorting:!0,sortingFn:`basic`,header:({column:e})=>(0,Z.jsx)(Te,{header:(0,Z.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,Z.jsx)(`span`,{children:`Declared By`}),(0,Z.jsx)(`span`,{children:`Used By`})]}),column:e}),cell:({getValue:e})=>{let[t,n,r]=e(),i=e=>{let t=N(e);t&&ie(t,r)};return(0,Z.jsxs)(`div`,{className:`flex flex-col gap-1 py-1`,children:[(0,Z.jsxs)(`div`,{className:`flex flex-row overflow-auto gap-2 items-center`,children:[(0,Z.jsx)(`span`,{title:`Declared by`,children:(0,Z.jsx)(nt,{className:`w-3.5 h-3.5 text-muted-foreground`})}),t.length===1?(0,Z.jsx)(Ve,{variant:`focus`,cellId:t[0],skipScroll:!0,onClick:()=>i(t[0])}):(0,Z.jsx)(`div`,{className:`text-destructive flex flex-row gap-2`,children:t.slice(0,3).map((e,n)=>(0,Z.jsxs)(`span`,{className:`flex`,children:[(0,Z.jsx)(Ve,{variant:`focus`,cellId:e,skipScroll:!0,className:`whitespace-nowrap text-destructive`,onClick:()=>i(e)},e),n<t.length-1&&`, `]},e))})]}),(0,Z.jsxs)(`div`,{className:`flex flex-row overflow-auto gap-2 items-baseline`,children:[(0,Z.jsx)(`span`,{title:`Used by`,children:(0,Z.jsx)(de,{className:`w-3.5 h-3.5 text-muted-foreground`})}),(0,Z.jsx)(qe,{maxCount:3,cellIds:n,skipScroll:!0,onClick:i})]})]})}})];function Dt({variables:e,sort:t,cellIdToIndex:n}){t||={id:Tt.defs,desc:!1};let r=[];switch(t.id){case Tt.name:r=he(e,e=>e.name);break;case Tt.type:r=he(e,e=>e.dataType);break;case Tt.defs:r=he(e,e=>n.get(e.declaredBy[0]))}return t.desc?r.toReversed():r}var Ot=(0,X.memo)(({className:e,cellIds:t,variables:n})=>{let[r,i]=X.useState([]),[a,o]=X.useState(``),s=S(),{locale:c}=ve(),l=(0,X.useMemo)(()=>{let e=e=>{let n=s[e];return T(n)?`cell-${t.indexOf(e)}`:n??`cell-${t.indexOf(e)}`};return Object.values(n).map(t=>({...t,declaredByNames:t.declaredBy.map(e),usedByNames:t.usedBy.map(e)}))},[n,s,t]),u=(0,X.useMemo)(()=>{let e=new Map;return t.forEach((t,n)=>e.set(t,n)),Dt({variables:l,sort:r[0],cellIdToIndex:e})},[l,r,t]),d=xe({data:u,columns:Et,getCoreRowModel:Le(),onGlobalFilterChange:o,getFilteredRowModel:Ce(),enableFilters:!0,enableGlobalFilter:!0,enableColumnPinning:!1,getColumnCanGlobalFilter(e){return e.columnDef.enableGlobalFilter??!0},globalFilterFn:`auto`,manualSorting:!0,locale:c,onSortingChange:i,getSortedRowModel:we(),state:{sorting:r,globalFilter:a}});return(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(pe,{className:`w-full`,placeholder:`Search`,value:a,onChange:e=>o(e.target.value)}),(0,Z.jsxs)(Ne,{className:oe(`w-full text-sm flex-1 border-separate border-spacing-0`,e),children:[(0,Z.jsx)(We,{children:(0,Z.jsx)(Oe,{className:`whitespace-nowrap text-xs`,children:d.getFlatHeaders().map(e=>(0,Z.jsx)(Pe,{className:`sticky top-0 bg-background border-b`,children:ze(e.column.columnDef.header,e.getContext())},e.id))})}),(0,Z.jsx)(Ue,{children:d.getRowModel().rows.map(e=>(0,Z.jsx)(Oe,{className:`hover:bg-accent`,children:e.getVisibleCells().map(e=>(0,Z.jsx)(Ge,{className:`border-b`,children:ze(e.column.columnDef.cell,e.getContext())},e.id))},e.id))})]})]})});Ot.displayName=`VariableTable`;var kt=()=>{let e=(0,Y.c)(30),n=o(),i=b(),a=r(w),s=r(x),c=B(`database`),[l,u]=t(fe),d=a.length+s.length,f;e[0]!==d||e[1]!==l.hasUserInteracted||e[2]!==l.openSections?(f=!l.hasUserInteracted&&d>0?[...new Set([...l.openSections,`datasources`])]:l.openSections,e[0]=d,e[1]=l.hasUserInteracted,e[2]=l.openSections,e[3]=f):f=e[3];let m=f,h;e[4]===u?h=e[5]:(h=e=>{u({openSections:e,hasUserInteracted:!0})},e[4]=u,e[5]=h);let g=h,_;e[6]===m?_=e[7]:(_=m.includes(`datasources`),e[6]=m,e[7]=_);let v=!_&&d>0,y=c.length>0,S;e[8]===Symbol.for(`react.memo_cache_sentinel`)?(S=(0,Z.jsx)(q,{className:`w-4 h-4`}),e[8]=S):S=e[8];let C;e[9]!==d||e[10]!==v?(C=v&&(0,Z.jsx)(Ye,{children:d}),e[9]=d,e[10]=v,e[11]=C):C=e[11];let T;e[12]!==c.length||e[13]!==y?(T=y&&(0,Z.jsx)(tt,{count:c.length,type:`database`}),e[12]=c.length,e[13]=y,e[14]=T):T=e[14];let E;e[15]!==C||e[16]!==T?(E=(0,Z.jsxs)(Xe,{children:[S,`Data sources`,C,T]}),e[15]=C,e[16]=T,e[17]=E):E=e[17];let D;e[18]===Symbol.for(`react.memo_cache_sentinel`)?(D=(0,Z.jsx)(Ze,{children:(0,Z.jsx)(dt,{})}),e[18]=D):D=e[18];let O;e[19]===E?O=e[20]:(O=(0,Z.jsxs)($e,{value:`datasources`,children:[E,D]}),e[19]=E,e[20]=O);let k;e[21]===Symbol.for(`react.memo_cache_sentinel`)?(k=(0,Z.jsxs)(Xe,{children:[(0,Z.jsx)(p,{className:`w-4 h-4`}),`Variables`]}),e[21]=k):k=e[21];let A;e[22]!==i||e[23]!==n?(A=(0,Z.jsxs)($e,{value:`variables`,lastItem:!0,children:[k,(0,Z.jsx)(Ze,{children:Object.keys(n).length===0?(0,Z.jsx)(`div`,{className:`px-3 py-4 text-sm text-muted-foreground`,children:`No variables defined`}):(0,Z.jsx)(Ot,{cellIds:i.inOrderIds,variables:n})})]}),e[22]=i,e[23]=n,e[24]=A):A=e[24];let j;return e[25]!==g||e[26]!==m||e[27]!==A||e[28]!==O?(j=(0,Z.jsxs)(se,{type:`multiple`,value:m,onValueChange:g,className:`flex flex-col h-full overflow-auto`,children:[O,A]}),e[25]=g,e[26]=m,e[27]=A,e[28]=O,e[29]=j):j=e[29],j};export{kt as default};