@prismiq/react 0.1.1 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/{CustomSQLEditor-CYlOtecq.d.ts → ChatBubble-3mFpV7yX.d.ts} +42 -3
  2. package/dist/{CustomSQLEditor-d84v_Cgp.d.cts → ChatBubble-CMkEupzn.d.cts} +42 -3
  3. package/dist/{DashboardDialog-DBNTVVSp.d.ts → DashboardDialog-DMmZ3bnf.d.cts} +5 -3
  4. package/dist/{DashboardDialog-CZD8I-6z.d.cts → DashboardDialog-RlcPkdMt.d.ts} +5 -3
  5. package/dist/charts/index.d.cts +2 -2
  6. package/dist/charts/index.d.ts +2 -2
  7. package/dist/{chunk-3LDRRDJ6.js → chunk-F6QYNQEW.js} +194 -28
  8. package/dist/chunk-F6QYNQEW.js.map +1 -0
  9. package/dist/{chunk-WWTT2OJ5.js → chunk-HKZFEXT6.js} +27 -9
  10. package/dist/chunk-HKZFEXT6.js.map +1 -0
  11. package/dist/{chunk-VQDFS6VS.cjs → chunk-N6I3QOHG.cjs} +376 -210
  12. package/dist/chunk-N6I3QOHG.cjs.map +1 -0
  13. package/dist/{chunk-URJH4H6G.cjs → chunk-NXXKG4GN.cjs} +520 -6
  14. package/dist/chunk-NXXKG4GN.cjs.map +1 -0
  15. package/dist/{chunk-ET7GCREP.js → chunk-VEFYFB5H.js} +517 -7
  16. package/dist/chunk-VEFYFB5H.js.map +1 -0
  17. package/dist/{chunk-MDXGGZSW.cjs → chunk-ZYVN6XAZ.cjs} +35 -37
  18. package/dist/chunk-ZYVN6XAZ.cjs.map +1 -0
  19. package/dist/components/index.cjs +62 -54
  20. package/dist/components/index.d.cts +2 -2
  21. package/dist/components/index.d.ts +2 -2
  22. package/dist/components/index.js +1 -1
  23. package/dist/dashboard/index.cjs +34 -34
  24. package/dist/dashboard/index.d.cts +7 -5
  25. package/dist/dashboard/index.d.ts +7 -5
  26. package/dist/dashboard/index.js +2 -2
  27. package/dist/export/index.cjs +7 -7
  28. package/dist/export/index.d.cts +6 -4
  29. package/dist/export/index.d.ts +6 -4
  30. package/dist/export/index.js +1 -1
  31. package/dist/{index-CvKj3SWO.d.cts → index-BA2VUhgN.d.cts} +1 -1
  32. package/dist/{index-DXGLs1yY.d.ts → index-BPo89ZAj.d.ts} +1 -1
  33. package/dist/index.cjs +119 -103
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.d.cts +77 -7
  36. package/dist/index.d.ts +77 -7
  37. package/dist/index.js +5 -5
  38. package/dist/index.js.map +1 -1
  39. package/dist/{types-j0kPJ9Hz.d.cts → types-BaI6sSAG.d.cts} +62 -1
  40. package/dist/{types-j0kPJ9Hz.d.ts → types-BaI6sSAG.d.ts} +62 -1
  41. package/dist/utils/index.d.cts +1 -1
  42. package/dist/utils/index.d.ts +1 -1
  43. package/package.json +2 -6
  44. package/dist/chunk-3LDRRDJ6.js.map +0 -1
  45. package/dist/chunk-ET7GCREP.js.map +0 -1
  46. package/dist/chunk-MDXGGZSW.cjs.map +0 -1
  47. package/dist/chunk-URJH4H6G.cjs.map +0 -1
  48. package/dist/chunk-VQDFS6VS.cjs.map +0 -1
  49. package/dist/chunk-WWTT2OJ5.js.map +0 -1
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var chunk73TPDGXB_cjs = require('./chunk-73TPDGXB.cjs');
4
- var chunkURJH4H6G_cjs = require('./chunk-URJH4H6G.cjs');
4
+ var chunkNXXKG4GN_cjs = require('./chunk-NXXKG4GN.cjs');
5
5
  var chunkLMTG3LRC_cjs = require('./chunk-LMTG3LRC.cjs');
6
6
  var chunkKXB2IZI2_cjs = require('./chunk-KXB2IZI2.cjs');
7
7
  var react = require('react');
@@ -151,8 +151,8 @@ function DashboardProvider({
151
151
  lazyLoading = DEFAULT_LAZY_LOADING,
152
152
  children
153
153
  }) {
154
- const { client } = chunkURJH4H6G_cjs.useAnalytics();
155
- const crossFilterContext = chunkURJH4H6G_cjs.useCrossFilterOptional();
154
+ const { client } = chunkNXXKG4GN_cjs.useAnalytics();
155
+ const crossFilterContext = chunkNXXKG4GN_cjs.useCrossFilterOptional();
156
156
  const lazyLoadingEnabled = lazyLoading.enabled ?? true;
157
157
  const lazyLoadingEnabledRef = react.useRef(lazyLoadingEnabled);
158
158
  lazyLoadingEnabledRef.current = lazyLoadingEnabled;
@@ -182,7 +182,8 @@ function DashboardProvider({
182
182
  if (!lazyLoadingEnabledRef.current) {
183
183
  const initialLoadingState = {};
184
184
  data.widgets.forEach((widget) => {
185
- if (widget.query) {
185
+ const isSqlMode = widget.config?.data_source_mode === "sql" && widget.config?.raw_sql;
186
+ if (widget.query || isSqlMode) {
186
187
  initialLoadingState[widget.id] = true;
187
188
  }
188
189
  });
@@ -191,7 +192,8 @@ function DashboardProvider({
191
192
  }, []);
192
193
  const executeWidgetQuery = react.useCallback(
193
194
  async (widget, currentDashboard, currentFilters, currentCrossFilters, bypassCache = false, signal) => {
194
- if (!widget.query) {
195
+ const isSqlMode = widget.config?.data_source_mode === "sql" && widget.config?.raw_sql;
196
+ if (!widget.query && !isSqlMode) {
195
197
  return;
196
198
  }
197
199
  setWidgetLoading((prev) => ({ ...prev, [widget.id]: true }));
@@ -204,13 +206,18 @@ function DashboardProvider({
204
206
  return next;
205
207
  });
206
208
  try {
207
- let query = applyFiltersToQuery(
208
- widget.query,
209
- currentDashboard,
210
- currentFilters
211
- );
212
- query = applyCrossFiltersToQuery(query, currentCrossFilters, widget.id);
213
- const result = await client.executeQuery(query, bypassCache, signal);
209
+ let result;
210
+ if (isSqlMode) {
211
+ result = await client.executeSQL(widget.config.raw_sql);
212
+ } else {
213
+ let query = applyFiltersToQuery(
214
+ widget.query,
215
+ currentDashboard,
216
+ currentFilters
217
+ );
218
+ query = applyCrossFiltersToQuery(query, currentCrossFilters, widget.id);
219
+ result = await client.executeQuery(query, bypassCache, signal);
220
+ }
214
221
  if (signal?.aborted) return;
215
222
  setWidgetResults((prev) => ({ ...prev, [widget.id]: result }));
216
223
  const refreshTime = result.cached_at ?? Date.now() / 1e3;
@@ -239,7 +246,9 @@ function DashboardProvider({
239
246
  );
240
247
  const executeWidgetsInBatches = react.useCallback(
241
248
  async (widgets, currentDashboard, currentFilters, currentCrossFilters, bypassCache = false, currentBatchSize = batchSize, signal) => {
242
- const widgetsWithQueries = widgets.filter((w) => w.query !== null);
249
+ const widgetsWithQueries = widgets.filter(
250
+ (w) => w.query !== null || w.config?.data_source_mode === "sql" && w.config?.raw_sql
251
+ );
243
252
  for (let i = 0; i < widgetsWithQueries.length; i += currentBatchSize) {
244
253
  if (signal?.aborted) return;
245
254
  const batch = widgetsWithQueries.slice(i, i + currentBatchSize);
@@ -438,7 +447,7 @@ function DashboardProvider({
438
447
  react.useEffect(() => {
439
448
  if (!lazyLoadingEnabled || !dashboard || isLoading) return;
440
449
  const widgetsToLoad = dashboard.widgets.filter(
441
- (w) => visibleWidgets.has(w.id) && w.query !== null && !widgetResults[w.id] && !widgetLoading[w.id]
450
+ (w) => visibleWidgets.has(w.id) && (w.query !== null || w.config?.data_source_mode === "sql" && w.config?.raw_sql) && !widgetResults[w.id] && !widgetLoading[w.id]
442
451
  );
443
452
  if (widgetsToLoad.length > 0) {
444
453
  const signal = abortControllerRef.current?.signal;
@@ -472,7 +481,7 @@ function DashboardProvider({
472
481
  if (prevFilterValuesRef.current === filterValuesKey) return;
473
482
  prevFilterValuesRef.current = filterValuesKey;
474
483
  const widgetsToRefresh = dashboard.widgets.filter(
475
- (w) => everVisibleWidgets.has(w.id) && w.query !== null && widgetResults[w.id]
484
+ (w) => everVisibleWidgets.has(w.id) && (w.query !== null || w.config?.data_source_mode === "sql" && w.config?.raw_sql) && widgetResults[w.id]
476
485
  // Only re-execute if previously loaded
477
486
  );
478
487
  if (widgetsToRefresh.length > 0) {
@@ -1054,7 +1063,7 @@ function EditableDashboardLayout({
1054
1063
  className = ""
1055
1064
  }) {
1056
1065
  const { theme } = chunkLMTG3LRC_cjs.useTheme();
1057
- const { queueUpdate, status, error } = chunkURJH4H6G_cjs.useDebouncedLayoutSave({
1066
+ const { queueUpdate, status, error } = chunkNXXKG4GN_cjs.useDebouncedLayoutSave({
1058
1067
  dashboardId,
1059
1068
  debounceMs,
1060
1069
  savedDurationMs,
@@ -1102,7 +1111,7 @@ function EditableDashboardLayout({
1102
1111
  style: containerStyles2,
1103
1112
  "data-testid": "dashboard-container",
1104
1113
  children: [
1105
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: statusBarStyles, children: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.AutoSaveIndicator, { status, error }) }),
1114
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: statusBarStyles, children: /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.AutoSaveIndicator, { status, error }) }),
1106
1115
  /* @__PURE__ */ jsxRuntime.jsx(
1107
1116
  DashboardLayout,
1108
1117
  {
@@ -1190,7 +1199,7 @@ function WidgetHeader({
1190
1199
  "aria-label": isRefreshing ? "Refreshing..." : "Refresh widget",
1191
1200
  title: isRefreshing ? "Refreshing..." : "Refresh widget",
1192
1201
  children: /* @__PURE__ */ jsxRuntime.jsx(
1193
- chunkURJH4H6G_cjs.Icon,
1202
+ chunkNXXKG4GN_cjs.Icon,
1194
1203
  {
1195
1204
  name: "sync",
1196
1205
  size: 16,
@@ -1209,7 +1218,7 @@ function WidgetHeader({
1209
1218
  style: actionButtonStyle,
1210
1219
  className: "prismiq-widget-action-button",
1211
1220
  "aria-label": hyperlink.title ?? "Open link",
1212
- children: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "link", size: 16 })
1221
+ children: /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "link", size: 16 })
1213
1222
  }
1214
1223
  )
1215
1224
  ] }),
@@ -1404,7 +1413,7 @@ function WidgetContent({
1404
1413
  isRefreshing = false
1405
1414
  }) {
1406
1415
  const { theme } = chunkLMTG3LRC_cjs.useTheme();
1407
- const crossFilterContext = chunkURJH4H6G_cjs.useCrossFilterOptional();
1416
+ const crossFilterContext = chunkNXXKG4GN_cjs.useCrossFilterOptional();
1408
1417
  const data = react.useMemo(() => result ? resultToDataPoints(result) : [], [result]);
1409
1418
  const chartTypesWithCrossFilter = ["bar_chart", "pie_chart", "line_chart", "area_chart"];
1410
1419
  const defaultCrossFilterEnabled = chartTypesWithCrossFilter.includes(widget.type);
@@ -1646,7 +1655,7 @@ function WidgetContent({
1646
1655
  position: "relative"
1647
1656
  };
1648
1657
  const tableContent = /* @__PURE__ */ jsxRuntime.jsx(
1649
- chunkURJH4H6G_cjs.ResultsTable,
1658
+ chunkNXXKG4GN_cjs.ResultsTable,
1650
1659
  {
1651
1660
  result: tableResult,
1652
1661
  pageSize: widget.config.page_size ?? 10,
@@ -1785,7 +1794,7 @@ function WidgetContainer({
1785
1794
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: contentStyles, children }),
1786
1795
  editable && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: overlayStyles, children: [
1787
1796
  onDuplicate && /* @__PURE__ */ jsxRuntime.jsx(
1788
- chunkURJH4H6G_cjs.Button,
1797
+ chunkNXXKG4GN_cjs.Button,
1789
1798
  {
1790
1799
  size: "sm",
1791
1800
  variant: "secondary",
@@ -1795,11 +1804,11 @@ function WidgetContainer({
1795
1804
  },
1796
1805
  title: "Duplicate",
1797
1806
  "data-testid": "duplicate-widget-button",
1798
- children: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "copy", size: 14 })
1807
+ children: /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "copy", size: 14 })
1799
1808
  }
1800
1809
  ),
1801
1810
  onEdit && /* @__PURE__ */ jsxRuntime.jsx(
1802
- chunkURJH4H6G_cjs.Button,
1811
+ chunkNXXKG4GN_cjs.Button,
1803
1812
  {
1804
1813
  size: "sm",
1805
1814
  variant: "secondary",
@@ -1809,11 +1818,11 @@ function WidgetContainer({
1809
1818
  },
1810
1819
  title: "Edit",
1811
1820
  "data-testid": "edit-widget-button",
1812
- children: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "edit", size: 14 })
1821
+ children: /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "edit", size: 14 })
1813
1822
  }
1814
1823
  ),
1815
1824
  onDelete && /* @__PURE__ */ jsxRuntime.jsx(
1816
- chunkURJH4H6G_cjs.Button,
1825
+ chunkNXXKG4GN_cjs.Button,
1817
1826
  {
1818
1827
  size: "sm",
1819
1828
  variant: "danger",
@@ -1823,7 +1832,7 @@ function WidgetContainer({
1823
1832
  },
1824
1833
  title: "Delete",
1825
1834
  "data-testid": "delete-widget-button",
1826
- children: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "trash", size: 14 })
1835
+ children: /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "trash", size: 14 })
1827
1836
  }
1828
1837
  )
1829
1838
  ] }),
@@ -2001,7 +2010,7 @@ function DateRangeFilter({
2001
2010
  ] });
2002
2011
  }
2003
2012
  function useDynamicFilterOptions(filter, limit = 100) {
2004
- const { client } = chunkURJH4H6G_cjs.useAnalytics();
2013
+ const { client } = chunkNXXKG4GN_cjs.useAnalytics();
2005
2014
  const [isLoading, setIsLoading] = react.useState(false);
2006
2015
  const [options, setOptions] = react.useState([]);
2007
2016
  const [error, setError] = react.useState(null);
@@ -2298,7 +2307,7 @@ function MultiSelectFilter({
2298
2307
  disabled: isLoading,
2299
2308
  children: [
2300
2309
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: displayText }),
2301
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: isOpen ? "chevron-up" : "chevron-down", size: 14 })
2310
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: isOpen ? "chevron-up" : "chevron-down", size: 14 })
2302
2311
  ]
2303
2312
  }
2304
2313
  ),
@@ -2347,7 +2356,7 @@ function MultiSelectFilter({
2347
2356
  backgroundColor: isAllSelected ? theme.colors.primary : theme.colors.background,
2348
2357
  borderColor: isAllSelected ? theme.colors.primary : theme.colors.border
2349
2358
  },
2350
- children: isAllSelected && /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "check", size: 12, style: { color: "#fff" } })
2359
+ children: isAllSelected && /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "check", size: 12, style: { color: "#fff" } })
2351
2360
  }
2352
2361
  ),
2353
2362
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "All" })
@@ -2373,7 +2382,7 @@ function MultiSelectFilter({
2373
2382
  backgroundColor: isSelected ? theme.colors.primary : theme.colors.background,
2374
2383
  borderColor: isSelected ? theme.colors.primary : theme.colors.border
2375
2384
  },
2376
- children: isSelected && /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "check", size: 12, style: { color: "#fff" } })
2385
+ children: isSelected && /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "check", size: 12, style: { color: "#fff" } })
2377
2386
  }
2378
2387
  ),
2379
2388
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: option.label })
@@ -2468,7 +2477,7 @@ function TextFilter({
2468
2477
  justifyContent: "center"
2469
2478
  };
2470
2479
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: containerStyle, children: [
2471
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "search", size: 14, style: iconStyle }),
2480
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "search", size: 14, style: iconStyle }),
2472
2481
  /* @__PURE__ */ jsxRuntime.jsx(
2473
2482
  "input",
2474
2483
  {
@@ -2487,7 +2496,7 @@ function TextFilter({
2487
2496
  onClick: handleClear,
2488
2497
  style: clearButtonStyle,
2489
2498
  "aria-label": "Clear filter",
2490
- children: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "x", size: 14 })
2499
+ children: /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "x", size: 14 })
2491
2500
  }
2492
2501
  )
2493
2502
  ] });
@@ -2541,7 +2550,7 @@ function FilterBar({
2541
2550
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: filter.label }),
2542
2551
  renderFilter(filter, values, onChange)
2543
2552
  ] }, filter.id)),
2544
- onReset && /* @__PURE__ */ jsxRuntime.jsx("div", { style: actionsStyle, children: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Button, { variant: "ghost", size: "sm", onClick: handleReset, children: "Reset" }) })
2553
+ onReset && /* @__PURE__ */ jsxRuntime.jsx("div", { style: actionsStyle, children: /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Button, { variant: "ghost", size: "sm", onClick: handleReset, children: "Reset" }) })
2545
2554
  ] });
2546
2555
  }
2547
2556
  function renderFilter(filter, values, onChange) {
@@ -2615,7 +2624,7 @@ function DashboardContent({
2615
2624
  refreshWidget
2616
2625
  } = useDashboard();
2617
2626
  const { filters, values, setValue, resetAll } = useDashboardFilters();
2618
- const crossFilterContext = chunkURJH4H6G_cjs.useCrossFilterOptional();
2627
+ const crossFilterContext = chunkNXXKG4GN_cjs.useCrossFilterOptional();
2619
2628
  const renderWidget = react.useCallback(
2620
2629
  (widget) => /* @__PURE__ */ jsxRuntime.jsx(
2621
2630
  LazyWidget,
@@ -2758,7 +2767,7 @@ function DashboardContent({
2758
2767
  ] }, filter.sourceWidgetId)),
2759
2768
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: 1 } }),
2760
2769
  /* @__PURE__ */ jsxRuntime.jsx(
2761
- chunkURJH4H6G_cjs.Button,
2770
+ chunkNXXKG4GN_cjs.Button,
2762
2771
  {
2763
2772
  variant: "ghost",
2764
2773
  size: "sm",
@@ -2787,7 +2796,7 @@ function Dashboard({
2787
2796
  lazyLoading,
2788
2797
  className = ""
2789
2798
  }) {
2790
- return /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.CrossFilterProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(
2799
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.CrossFilterProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(
2791
2800
  DashboardProvider,
2792
2801
  {
2793
2802
  dashboardId: id,
@@ -2895,37 +2904,37 @@ function EditorToolbar({
2895
2904
  ) : /* @__PURE__ */ jsxRuntime.jsx("h2", { style: titleStyle, children: dashboardName || "New Dashboard" }),
2896
2905
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: actionsStyle, children: [
2897
2906
  /* @__PURE__ */ jsxRuntime.jsxs(
2898
- chunkURJH4H6G_cjs.Button,
2907
+ chunkNXXKG4GN_cjs.Button,
2899
2908
  {
2900
2909
  variant: "secondary",
2901
2910
  size: "sm",
2902
2911
  onClick: onAddWidget,
2903
2912
  children: [
2904
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "plus", size: 16 }),
2913
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "plus", size: 16 }),
2905
2914
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { marginLeft: theme.spacing.xs }, children: "Add Widget" })
2906
2915
  ]
2907
2916
  }
2908
2917
  ),
2909
2918
  onEditFilters && /* @__PURE__ */ jsxRuntime.jsxs(
2910
- chunkURJH4H6G_cjs.Button,
2919
+ chunkNXXKG4GN_cjs.Button,
2911
2920
  {
2912
2921
  variant: "ghost",
2913
2922
  size: "sm",
2914
2923
  onClick: onEditFilters,
2915
2924
  children: [
2916
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "filter", size: 16 }),
2925
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "filter", size: 16 }),
2917
2926
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { marginLeft: theme.spacing.xs }, children: "Filters" })
2918
2927
  ]
2919
2928
  }
2920
2929
  ),
2921
2930
  onSettings && /* @__PURE__ */ jsxRuntime.jsxs(
2922
- chunkURJH4H6G_cjs.Button,
2931
+ chunkNXXKG4GN_cjs.Button,
2923
2932
  {
2924
2933
  variant: "ghost",
2925
2934
  size: "sm",
2926
2935
  onClick: onSettings,
2927
2936
  children: [
2928
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "settings", size: 16 }),
2937
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "settings", size: 16 }),
2929
2938
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { marginLeft: theme.spacing.xs }, children: "Settings" })
2930
2939
  ]
2931
2940
  }
@@ -2935,7 +2944,7 @@ function EditorToolbar({
2935
2944
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: rightSectionStyle, children: [
2936
2945
  hasChanges && /* @__PURE__ */ jsxRuntime.jsx("span", { style: unsavedStyle, children: "Unsaved changes" }),
2937
2946
  /* @__PURE__ */ jsxRuntime.jsx(
2938
- chunkURJH4H6G_cjs.Button,
2947
+ chunkNXXKG4GN_cjs.Button,
2939
2948
  {
2940
2949
  variant: "ghost",
2941
2950
  size: "sm",
@@ -2945,7 +2954,7 @@ function EditorToolbar({
2945
2954
  }
2946
2955
  ),
2947
2956
  /* @__PURE__ */ jsxRuntime.jsx(
2948
- chunkURJH4H6G_cjs.Button,
2957
+ chunkNXXKG4GN_cjs.Button,
2949
2958
  {
2950
2959
  variant: "primary",
2951
2960
  size: "sm",
@@ -3092,7 +3101,7 @@ function WidgetTypeSelector({
3092
3101
  }
3093
3102
  },
3094
3103
  children: [
3095
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: iconStyle(isSelected), children: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: widgetType.icon, size: 16 }) }),
3104
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: iconStyle(isSelected), children: /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: widgetType.icon, size: 16 }) }),
3096
3105
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: textContainerStyle, children: [
3097
3106
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: nameLabelStyle, children: widgetType.label }),
3098
3107
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: descStyle, children: widgetType.description })
@@ -3119,6 +3128,7 @@ function WidgetPreview({
3119
3128
  title,
3120
3129
  config,
3121
3130
  query,
3131
+ rawSql,
3122
3132
  result,
3123
3133
  isLoading = false,
3124
3134
  error,
@@ -3173,13 +3183,14 @@ function WidgetPreview({
3173
3183
  };
3174
3184
  const previewWidget = createPreviewWidget(type, title, config, query);
3175
3185
  const needsQuery = type !== "text";
3176
- const showEmptyState = needsQuery && !query && !isLoading;
3177
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `prismiq-widget-preview ${className}`, style: containerStyle, children: [
3186
+ const hasDataSource = !!query || !!rawSql;
3187
+ const showEmptyState = needsQuery && !hasDataSource && !isLoading;
3188
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `prismiq-widget-preview ${className}`, style: containerStyle, "data-testid": "widget-preview", children: [
3178
3189
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerStyle, children: [
3179
3190
  /* @__PURE__ */ jsxRuntime.jsx("h3", { style: titleStyle, children: title || "Widget Preview" }),
3180
3191
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: labelStyle, children: "Preview" })
3181
3192
  ] }),
3182
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: contentStyle, children: showEmptyState ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: emptyStateStyle, children: [
3193
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: contentStyle, children: showEmptyState ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: emptyStateStyle, "data-testid": "widget-preview-empty", children: [
3183
3194
  /* @__PURE__ */ jsxRuntime.jsx(
3184
3195
  "div",
3185
3196
  {
@@ -3236,7 +3247,7 @@ function MetricConfig({
3236
3247
  onChange
3237
3248
  }) {
3238
3249
  const { theme } = chunkLMTG3LRC_cjs.useTheme();
3239
- const { getDisplayName } = chunkURJH4H6G_cjs.useSchema();
3250
+ const { getDisplayName } = chunkNXXKG4GN_cjs.useSchema();
3240
3251
  const initialTable = query?.tables[0]?.name ?? "";
3241
3252
  const initialAggregation = query?.columns[0]?.aggregation ?? "count";
3242
3253
  const rawInitialColumn = query?.columns[0]?.column ?? "*";
@@ -3322,7 +3333,7 @@ function MetricConfig({
3322
3333
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
3323
3334
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "From Table" }),
3324
3335
  /* @__PURE__ */ jsxRuntime.jsx(
3325
- chunkURJH4H6G_cjs.Select,
3336
+ chunkNXXKG4GN_cjs.Select,
3326
3337
  {
3327
3338
  value: selectedTable,
3328
3339
  onChange: handleTableChange,
@@ -3333,7 +3344,7 @@ function MetricConfig({
3333
3344
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
3334
3345
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Metric" }),
3335
3346
  /* @__PURE__ */ jsxRuntime.jsx(
3336
- chunkURJH4H6G_cjs.Select,
3347
+ chunkNXXKG4GN_cjs.Select,
3337
3348
  {
3338
3349
  value: aggregation,
3339
3350
  onChange: (value) => setAggregation(value),
@@ -3348,7 +3359,7 @@ function MetricConfig({
3348
3359
  needsColumn && selectedTable && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
3349
3360
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Column" }),
3350
3361
  columnOptions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
3351
- chunkURJH4H6G_cjs.Select,
3362
+ chunkNXXKG4GN_cjs.Select,
3352
3363
  {
3353
3364
  value: selectedColumn,
3354
3365
  onChange: setSelectedColumn,
@@ -3359,7 +3370,7 @@ function MetricConfig({
3359
3370
  selectedTable && currentTable && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
3360
3371
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Filters (optional)" }),
3361
3372
  /* @__PURE__ */ jsxRuntime.jsx(
3362
- chunkURJH4H6G_cjs.FilterBuilder,
3373
+ chunkNXXKG4GN_cjs.FilterBuilder,
3363
3374
  {
3364
3375
  tables: [{ id: "t1", name: selectedTable }],
3365
3376
  filters,
@@ -3418,7 +3429,7 @@ function ChartConfig({
3418
3429
  onChange
3419
3430
  }) {
3420
3431
  const { theme } = chunkLMTG3LRC_cjs.useTheme();
3421
- const { getDisplayName } = chunkURJH4H6G_cjs.useSchema();
3432
+ const { getDisplayName } = chunkNXXKG4GN_cjs.useSchema();
3422
3433
  const initialTables = query?.tables ?? [];
3423
3434
  const groupByCol = query?.columns.find((c) => c.aggregation === "none");
3424
3435
  const initialGroupBy = groupByCol?.column ?? query?.group_by?.[0]?.column ?? "";
@@ -3664,7 +3675,7 @@ function ChartConfig({
3664
3675
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
3665
3676
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "From Table" }),
3666
3677
  /* @__PURE__ */ jsxRuntime.jsx(
3667
- chunkURJH4H6G_cjs.Select,
3678
+ chunkNXXKG4GN_cjs.Select,
3668
3679
  {
3669
3680
  value: selectedTable,
3670
3681
  onChange: handleTableChange,
@@ -3672,9 +3683,9 @@ function ChartConfig({
3672
3683
  }
3673
3684
  )
3674
3685
  ] }),
3675
- selectedTable && /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.CollapsibleSection, { title: "Join Tables", defaultOpen: tables.length > 1, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: theme.spacing.md }, children: [
3686
+ selectedTable && /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.CollapsibleSection, { title: "Join Tables", defaultOpen: tables.length > 1, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: theme.spacing.md }, children: [
3676
3687
  /* @__PURE__ */ jsxRuntime.jsx(
3677
- chunkURJH4H6G_cjs.TableSelector,
3688
+ chunkNXXKG4GN_cjs.TableSelector,
3678
3689
  {
3679
3690
  schema,
3680
3691
  tables,
@@ -3686,7 +3697,7 @@ function ChartConfig({
3686
3697
  tables.length >= 2 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
3687
3698
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Join Conditions" }),
3688
3699
  /* @__PURE__ */ jsxRuntime.jsx(
3689
- chunkURJH4H6G_cjs.JoinBuilder,
3700
+ chunkNXXKG4GN_cjs.JoinBuilder,
3690
3701
  {
3691
3702
  schema,
3692
3703
  tables,
@@ -3700,7 +3711,7 @@ function ChartConfig({
3700
3711
  selectedTable && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
3701
3712
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Group By (X-Axis)" }),
3702
3713
  groupByOptions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
3703
- chunkURJH4H6G_cjs.Select,
3714
+ chunkNXXKG4GN_cjs.Select,
3704
3715
  {
3705
3716
  value: groupByValue,
3706
3717
  onChange: handleGroupByChange,
@@ -3712,7 +3723,7 @@ function ChartConfig({
3712
3723
  selectedTable && groupByColumn && isGroupByDate && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
3713
3724
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Date Granularity" }),
3714
3725
  /* @__PURE__ */ jsxRuntime.jsx(
3715
- chunkURJH4H6G_cjs.Select,
3726
+ chunkNXXKG4GN_cjs.Select,
3716
3727
  {
3717
3728
  value: dateTrunc,
3718
3729
  onChange: (value) => setDateTrunc(value),
@@ -3721,8 +3732,8 @@ function ChartConfig({
3721
3732
  ),
3722
3733
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: helpTextStyle, children: "Truncate dates to this interval" })
3723
3734
  ] }),
3724
- selectedTable && isGroupByDate && /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.CollapsibleSection, { title: "Time Series Options", defaultOpen: timeSeries !== void 0, children: /* @__PURE__ */ jsxRuntime.jsx(
3725
- chunkURJH4H6G_cjs.TimeSeriesConfig,
3735
+ selectedTable && isGroupByDate && /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.CollapsibleSection, { title: "Time Series Options", defaultOpen: timeSeries !== void 0, children: /* @__PURE__ */ jsxRuntime.jsx(
3736
+ chunkNXXKG4GN_cjs.TimeSeriesConfig,
3726
3737
  {
3727
3738
  schema,
3728
3739
  tables,
@@ -3735,7 +3746,7 @@ function ChartConfig({
3735
3746
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Measures (Y-Axis)" }),
3736
3747
  measures.map((measure, index) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: measureRowStyle, children: [
3737
3748
  /* @__PURE__ */ jsxRuntime.jsx(
3738
- chunkURJH4H6G_cjs.Select,
3749
+ chunkNXXKG4GN_cjs.Select,
3739
3750
  {
3740
3751
  value: measure.aggregation,
3741
3752
  onChange: (value) => updateMeasure(index, { aggregation: value }),
@@ -3746,7 +3757,7 @@ function ChartConfig({
3746
3757
  measure.aggregation !== "count" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3747
3758
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: theme.colors.textMuted }, children: "of" }),
3748
3759
  measureColumnOptions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
3749
- chunkURJH4H6G_cjs.Select,
3760
+ chunkNXXKG4GN_cjs.Select,
3750
3761
  {
3751
3762
  value: measure.column,
3752
3763
  onChange: (value) => updateMeasure(index, { column: value }),
@@ -3755,17 +3766,17 @@ function ChartConfig({
3755
3766
  }
3756
3767
  ) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...helpTextStyle, flex: 1 }, children: "No numeric columns" })
3757
3768
  ] }),
3758
- measures.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Button, { variant: "ghost", size: "sm", onClick: () => removeMeasure(index), children: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "x", size: 14 }) })
3769
+ measures.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Button, { variant: "ghost", size: "sm", onClick: () => removeMeasure(index), children: /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "x", size: 14 }) })
3759
3770
  ] }, measureIdsRef.current[index])),
3760
3771
  /* @__PURE__ */ jsxRuntime.jsxs(
3761
- chunkURJH4H6G_cjs.Button,
3772
+ chunkNXXKG4GN_cjs.Button,
3762
3773
  {
3763
3774
  variant: "ghost",
3764
3775
  size: "sm",
3765
3776
  onClick: addMeasure,
3766
3777
  style: { alignSelf: "flex-start" },
3767
3778
  children: [
3768
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "plus", size: 14 }),
3779
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "plus", size: 14 }),
3769
3780
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { marginLeft: theme.spacing.xs }, children: "Add measure" })
3770
3781
  ]
3771
3782
  }
@@ -3775,7 +3786,7 @@ function ChartConfig({
3775
3786
  selectedTable && currentTable && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
3776
3787
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Filters (optional)" }),
3777
3788
  /* @__PURE__ */ jsxRuntime.jsx(
3778
- chunkURJH4H6G_cjs.FilterBuilder,
3789
+ chunkNXXKG4GN_cjs.FilterBuilder,
3779
3790
  {
3780
3791
  tables,
3781
3792
  filters,
@@ -3785,12 +3796,12 @@ function ChartConfig({
3785
3796
  )
3786
3797
  ] }),
3787
3798
  selectedTable && /* @__PURE__ */ jsxRuntime.jsx(
3788
- chunkURJH4H6G_cjs.CollapsibleSection,
3799
+ chunkNXXKG4GN_cjs.CollapsibleSection,
3789
3800
  {
3790
3801
  title: "Calculated Fields",
3791
3802
  defaultOpen: calculatedFields.length > 0,
3792
3803
  children: /* @__PURE__ */ jsxRuntime.jsx(
3793
- chunkURJH4H6G_cjs.CalculatedFieldBuilder,
3804
+ chunkNXXKG4GN_cjs.CalculatedFieldBuilder,
3794
3805
  {
3795
3806
  fields: calculatedFields,
3796
3807
  onChange: setCalculatedFields,
@@ -3848,7 +3859,7 @@ function PieConfig({
3848
3859
  onChange
3849
3860
  }) {
3850
3861
  const { theme } = chunkLMTG3LRC_cjs.useTheme();
3851
- const { getDisplayName } = chunkURJH4H6G_cjs.useSchema();
3862
+ const { getDisplayName } = chunkNXXKG4GN_cjs.useSchema();
3852
3863
  const initialTable = query?.tables[0]?.name ?? "";
3853
3864
  const labelCol = query?.columns.find((c) => c.aggregation === "none");
3854
3865
  const initialLabel = labelCol?.column ?? "";
@@ -3974,7 +3985,7 @@ function PieConfig({
3974
3985
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
3975
3986
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "From Table" }),
3976
3987
  /* @__PURE__ */ jsxRuntime.jsx(
3977
- chunkURJH4H6G_cjs.Select,
3988
+ chunkNXXKG4GN_cjs.Select,
3978
3989
  {
3979
3990
  value: selectedTable,
3980
3991
  onChange: handleTableChange,
@@ -3985,7 +3996,7 @@ function PieConfig({
3985
3996
  selectedTable && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
3986
3997
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Slices (Labels)" }),
3987
3998
  labelOptions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
3988
- chunkURJH4H6G_cjs.Select,
3999
+ chunkNXXKG4GN_cjs.Select,
3989
4000
  {
3990
4001
  value: labelColumn,
3991
4002
  onChange: handleLabelChange,
@@ -3997,7 +4008,7 @@ function PieConfig({
3997
4008
  selectedTable && labelColumn && isLabelDate && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
3998
4009
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Date Granularity" }),
3999
4010
  /* @__PURE__ */ jsxRuntime.jsx(
4000
- chunkURJH4H6G_cjs.Select,
4011
+ chunkNXXKG4GN_cjs.Select,
4001
4012
  {
4002
4013
  value: dateTrunc,
4003
4014
  onChange: (value) => setDateTrunc(value),
@@ -4010,7 +4021,7 @@ function PieConfig({
4010
4021
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Size (Value)" }),
4011
4022
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: rowStyle, children: [
4012
4023
  /* @__PURE__ */ jsxRuntime.jsx(
4013
- chunkURJH4H6G_cjs.Select,
4024
+ chunkNXXKG4GN_cjs.Select,
4014
4025
  {
4015
4026
  value: aggregation,
4016
4027
  onChange: (value) => setAggregation(value),
@@ -4021,7 +4032,7 @@ function PieConfig({
4021
4032
  aggregation !== "count" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4022
4033
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: theme.colors.textMuted }, children: "of" }),
4023
4034
  valueColumnOptions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
4024
- chunkURJH4H6G_cjs.Select,
4035
+ chunkNXXKG4GN_cjs.Select,
4025
4036
  {
4026
4037
  value: valueColumn,
4027
4038
  onChange: setValueColumn,
@@ -4036,7 +4047,7 @@ function PieConfig({
4036
4047
  selectedTable && currentTable && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4037
4048
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Filters (optional)" }),
4038
4049
  /* @__PURE__ */ jsxRuntime.jsx(
4039
- chunkURJH4H6G_cjs.FilterBuilder,
4050
+ chunkNXXKG4GN_cjs.FilterBuilder,
4040
4051
  {
4041
4052
  tables: [{ id: "t1", name: selectedTable }],
4042
4053
  filters,
@@ -4053,7 +4064,7 @@ function TableConfig({
4053
4064
  onChange
4054
4065
  }) {
4055
4066
  const { theme } = chunkLMTG3LRC_cjs.useTheme();
4056
- const { getDisplayName } = chunkURJH4H6G_cjs.useSchema();
4067
+ const { getDisplayName } = chunkNXXKG4GN_cjs.useSchema();
4057
4068
  const initialTable = query?.tables[0]?.name ?? "";
4058
4069
  const initialColumns = query?.columns.map((c) => c.column) ?? [];
4059
4070
  const initialFilters = (query?.filters ?? []).map((f) => ({
@@ -4159,7 +4170,7 @@ function TableConfig({
4159
4170
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4160
4171
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "From Table" }),
4161
4172
  /* @__PURE__ */ jsxRuntime.jsx(
4162
- chunkURJH4H6G_cjs.Select,
4173
+ chunkNXXKG4GN_cjs.Select,
4163
4174
  {
4164
4175
  value: selectedTable,
4165
4176
  onChange: handleTableChange,
@@ -4176,7 +4187,7 @@ function TableConfig({
4176
4187
  ] })
4177
4188
  ] }),
4178
4189
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: columnsContainerStyle, children: currentTable.columns.map((col) => /* @__PURE__ */ jsxRuntime.jsx(
4179
- chunkURJH4H6G_cjs.Checkbox,
4190
+ chunkNXXKG4GN_cjs.Checkbox,
4180
4191
  {
4181
4192
  label: `${col.name} (${col.data_type})`,
4182
4193
  checked: selectedColumns.includes(col.name),
@@ -4189,7 +4200,7 @@ function TableConfig({
4189
4200
  selectedTable && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4190
4201
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Maximum Rows" }),
4191
4202
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: rowStyle, children: /* @__PURE__ */ jsxRuntime.jsx(
4192
- chunkURJH4H6G_cjs.Select,
4203
+ chunkNXXKG4GN_cjs.Select,
4193
4204
  {
4194
4205
  value: String(limit),
4195
4206
  onChange: (value) => setLimit(parseInt(value, 10)),
@@ -4208,7 +4219,7 @@ function TableConfig({
4208
4219
  selectedTable && currentTable && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4209
4220
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Filters (optional)" }),
4210
4221
  /* @__PURE__ */ jsxRuntime.jsx(
4211
- chunkURJH4H6G_cjs.FilterBuilder,
4222
+ chunkNXXKG4GN_cjs.FilterBuilder,
4212
4223
  {
4213
4224
  tables: [{ id: "t1", name: selectedTable }],
4214
4225
  filters,
@@ -4292,11 +4303,11 @@ function HyperlinkSection({
4292
4303
  target
4293
4304
  });
4294
4305
  };
4295
- return /* @__PURE__ */ jsxRuntime.jsxs(chunkURJH4H6G_cjs.CollapsibleSection, { title: "Hyperlink", defaultOpen, children: [
4306
+ return /* @__PURE__ */ jsxRuntime.jsxs(chunkNXXKG4GN_cjs.CollapsibleSection, { title: "Hyperlink", defaultOpen, children: [
4296
4307
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4297
4308
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "URL" }),
4298
4309
  /* @__PURE__ */ jsxRuntime.jsx(
4299
- chunkURJH4H6G_cjs.Input,
4310
+ chunkNXXKG4GN_cjs.Input,
4300
4311
  {
4301
4312
  value: hyperlink?.url || "",
4302
4313
  onChange: (e) => handleUrlChange(e.target.value),
@@ -4309,7 +4320,7 @@ function HyperlinkSection({
4309
4320
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4310
4321
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Tooltip Text" }),
4311
4322
  /* @__PURE__ */ jsxRuntime.jsx(
4312
- chunkURJH4H6G_cjs.Input,
4323
+ chunkNXXKG4GN_cjs.Input,
4313
4324
  {
4314
4325
  value: hyperlink?.title || "",
4315
4326
  onChange: (e) => handleTitleChange(e.target.value),
@@ -4320,7 +4331,7 @@ function HyperlinkSection({
4320
4331
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4321
4332
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Open In" }),
4322
4333
  /* @__PURE__ */ jsxRuntime.jsx(
4323
- chunkURJH4H6G_cjs.Select,
4334
+ chunkNXXKG4GN_cjs.Select,
4324
4335
  {
4325
4336
  value: hyperlink?.target || "_blank",
4326
4337
  onChange: handleTargetChange,
@@ -4396,14 +4407,14 @@ function ReferenceLinesSection({
4396
4407
  onChange(lines.filter((_, i) => i !== index));
4397
4408
  };
4398
4409
  return /* @__PURE__ */ jsxRuntime.jsxs(
4399
- chunkURJH4H6G_cjs.CollapsibleSection,
4410
+ chunkNXXKG4GN_cjs.CollapsibleSection,
4400
4411
  {
4401
4412
  title: "Reference Lines",
4402
4413
  defaultOpen: defaultOpen || lines.length > 0,
4403
4414
  children: [
4404
4415
  lines.map((line, index) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: lineRowStyle, children: [
4405
4416
  /* @__PURE__ */ jsxRuntime.jsx(
4406
- chunkURJH4H6G_cjs.Input,
4417
+ chunkNXXKG4GN_cjs.Input,
4407
4418
  {
4408
4419
  type: "number",
4409
4420
  value: String(line.value),
@@ -4413,7 +4424,7 @@ function ReferenceLinesSection({
4413
4424
  }
4414
4425
  ),
4415
4426
  /* @__PURE__ */ jsxRuntime.jsx(
4416
- chunkURJH4H6G_cjs.Input,
4427
+ chunkNXXKG4GN_cjs.Input,
4417
4428
  {
4418
4429
  value: line.label ?? "",
4419
4430
  onChange: (e) => updateLine(index, { label: e.target.value || void 0 }),
@@ -4432,7 +4443,7 @@ function ReferenceLinesSection({
4432
4443
  }
4433
4444
  ),
4434
4445
  /* @__PURE__ */ jsxRuntime.jsx(
4435
- chunkURJH4H6G_cjs.Select,
4446
+ chunkNXXKG4GN_cjs.Select,
4436
4447
  {
4437
4448
  value: line.lineStyle ?? "dashed",
4438
4449
  onChange: (value) => updateLine(index, {
@@ -4442,10 +4453,10 @@ function ReferenceLinesSection({
4442
4453
  style: { width: "90px" }
4443
4454
  }
4444
4455
  ),
4445
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Button, { variant: "ghost", size: "sm", onClick: () => removeLine(index), children: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "x", size: 14 }) })
4456
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Button, { variant: "ghost", size: "sm", onClick: () => removeLine(index), children: /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "x", size: 14 }) })
4446
4457
  ] }, lineIdsRef.current[index])),
4447
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: addButtonStyle, children: /* @__PURE__ */ jsxRuntime.jsxs(chunkURJH4H6G_cjs.Button, { variant: "ghost", size: "sm", onClick: addLine, children: [
4448
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "plus", size: 14 }),
4458
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: addButtonStyle, children: /* @__PURE__ */ jsxRuntime.jsxs(chunkNXXKG4GN_cjs.Button, { variant: "ghost", size: "sm", onClick: addLine, children: [
4459
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "plus", size: 14 }),
4449
4460
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { marginLeft: theme.spacing.xs }, children: "Add reference line" })
4450
4461
  ] }) })
4451
4462
  ]
@@ -4529,7 +4540,7 @@ function TextFormattingSection({
4529
4540
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerStyle, children: [
4530
4541
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Content" }),
4531
4542
  config.markdown && /* @__PURE__ */ jsxRuntime.jsx(
4532
- chunkURJH4H6G_cjs.Checkbox,
4543
+ chunkNXXKG4GN_cjs.Checkbox,
4533
4544
  {
4534
4545
  label: "Preview",
4535
4546
  checked: showPreview,
@@ -4559,7 +4570,7 @@ function TextFormattingSection({
4559
4570
  )
4560
4571
  ] }),
4561
4572
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: fieldStyle, children: /* @__PURE__ */ jsxRuntime.jsx(
4562
- chunkURJH4H6G_cjs.Checkbox,
4573
+ chunkNXXKG4GN_cjs.Checkbox,
4563
4574
  {
4564
4575
  label: "Enable Markdown",
4565
4576
  checked: config.markdown ?? false,
@@ -4570,7 +4581,7 @@ function TextFormattingSection({
4570
4581
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: halfFieldStyle, children: [
4571
4582
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Alignment" }),
4572
4583
  /* @__PURE__ */ jsxRuntime.jsx(
4573
- chunkURJH4H6G_cjs.Select,
4584
+ chunkNXXKG4GN_cjs.Select,
4574
4585
  {
4575
4586
  value: config.alignment ?? "Left",
4576
4587
  onChange: (value) => onChange("alignment", value),
@@ -4581,7 +4592,7 @@ function TextFormattingSection({
4581
4592
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: halfFieldStyle, children: [
4582
4593
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Font Size" }),
4583
4594
  /* @__PURE__ */ jsxRuntime.jsx(
4584
- chunkURJH4H6G_cjs.Select,
4595
+ chunkNXXKG4GN_cjs.Select,
4585
4596
  {
4586
4597
  value: config.fontSize ?? "Normal",
4587
4598
  onChange: (value) => onChange("fontSize", value),
@@ -4698,13 +4709,13 @@ function PivotConfigSection({
4698
4709
  ).map((col) => col.column);
4699
4710
  }, [query, config.pivot_column, config.value_column]);
4700
4711
  return /* @__PURE__ */ jsxRuntime.jsxs(
4701
- chunkURJH4H6G_cjs.CollapsibleSection,
4712
+ chunkNXXKG4GN_cjs.CollapsibleSection,
4702
4713
  {
4703
4714
  title: "Pivot Table",
4704
4715
  defaultOpen: defaultOpen || isPivotEnabled,
4705
4716
  children: [
4706
4717
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: fieldStyle, children: /* @__PURE__ */ jsxRuntime.jsx(
4707
- chunkURJH4H6G_cjs.Checkbox,
4718
+ chunkNXXKG4GN_cjs.Checkbox,
4708
4719
  {
4709
4720
  label: "Enable Pivot Mode",
4710
4721
  checked: isPivotEnabled,
@@ -4715,7 +4726,7 @@ function PivotConfigSection({
4715
4726
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4716
4727
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Pivot Column" }),
4717
4728
  /* @__PURE__ */ jsxRuntime.jsx(
4718
- chunkURJH4H6G_cjs.Select,
4729
+ chunkNXXKG4GN_cjs.Select,
4719
4730
  {
4720
4731
  value: config.pivot_column ?? "",
4721
4732
  onChange: (value) => onChange("pivot_column", value || void 0),
@@ -4730,7 +4741,7 @@ function PivotConfigSection({
4730
4741
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4731
4742
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Value Column" }),
4732
4743
  /* @__PURE__ */ jsxRuntime.jsx(
4733
- chunkURJH4H6G_cjs.Select,
4744
+ chunkNXXKG4GN_cjs.Select,
4734
4745
  {
4735
4746
  value: config.value_column ?? "",
4736
4747
  onChange: (value) => onChange("value_column", value || void 0),
@@ -4793,7 +4804,7 @@ function LayoutConstraintsSection({
4793
4804
  };
4794
4805
  const hasConstraints = position.minW !== void 0 || position.maxW !== void 0 || position.minH !== void 0 || position.maxH !== void 0;
4795
4806
  return /* @__PURE__ */ jsxRuntime.jsx(
4796
- chunkURJH4H6G_cjs.CollapsibleSection,
4807
+ chunkNXXKG4GN_cjs.CollapsibleSection,
4797
4808
  {
4798
4809
  title: "Size Constraints",
4799
4810
  defaultOpen: defaultOpen || hasConstraints,
@@ -4801,7 +4812,7 @@ function LayoutConstraintsSection({
4801
4812
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4802
4813
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Min Width" }),
4803
4814
  /* @__PURE__ */ jsxRuntime.jsx(
4804
- chunkURJH4H6G_cjs.Input,
4815
+ chunkNXXKG4GN_cjs.Input,
4805
4816
  {
4806
4817
  type: "number",
4807
4818
  value: position.minW !== void 0 ? String(position.minW) : "",
@@ -4815,7 +4826,7 @@ function LayoutConstraintsSection({
4815
4826
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4816
4827
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Max Width" }),
4817
4828
  /* @__PURE__ */ jsxRuntime.jsx(
4818
- chunkURJH4H6G_cjs.Input,
4829
+ chunkNXXKG4GN_cjs.Input,
4819
4830
  {
4820
4831
  type: "number",
4821
4832
  value: position.maxW !== void 0 ? String(position.maxW) : "",
@@ -4829,7 +4840,7 @@ function LayoutConstraintsSection({
4829
4840
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4830
4841
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Min Height" }),
4831
4842
  /* @__PURE__ */ jsxRuntime.jsx(
4832
- chunkURJH4H6G_cjs.Input,
4843
+ chunkNXXKG4GN_cjs.Input,
4833
4844
  {
4834
4845
  type: "number",
4835
4846
  value: position.minH !== void 0 ? String(position.minH) : "",
@@ -4842,7 +4853,7 @@ function LayoutConstraintsSection({
4842
4853
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4843
4854
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Max Height" }),
4844
4855
  /* @__PURE__ */ jsxRuntime.jsx(
4845
- chunkURJH4H6G_cjs.Input,
4856
+ chunkNXXKG4GN_cjs.Input,
4846
4857
  {
4847
4858
  type: "number",
4848
4859
  value: position.maxH !== void 0 ? String(position.maxH) : "",
@@ -4910,14 +4921,14 @@ function CrossFilterSection({
4910
4921
  });
4911
4922
  };
4912
4923
  return /* @__PURE__ */ jsxRuntime.jsxs(
4913
- chunkURJH4H6G_cjs.CollapsibleSection,
4924
+ chunkNXXKG4GN_cjs.CollapsibleSection,
4914
4925
  {
4915
4926
  title: "Cross-Filtering",
4916
4927
  defaultOpen: defaultOpen || crossFilterEnabled,
4917
4928
  children: [
4918
4929
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4919
4930
  /* @__PURE__ */ jsxRuntime.jsx(
4920
- chunkURJH4H6G_cjs.Checkbox,
4931
+ chunkNXXKG4GN_cjs.Checkbox,
4921
4932
  {
4922
4933
  label: "Enable as filter source",
4923
4934
  checked: crossFilterEnabled,
@@ -4929,7 +4940,7 @@ function CrossFilterSection({
4929
4940
  crossFilterEnabled && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4930
4941
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Filter Column" }),
4931
4942
  /* @__PURE__ */ jsxRuntime.jsx(
4932
- chunkURJH4H6G_cjs.Select,
4943
+ chunkNXXKG4GN_cjs.Select,
4933
4944
  {
4934
4945
  value: config.cross_filter?.column ?? config.x_axis ?? "",
4935
4946
  onChange: handleColumnChange,
@@ -5028,11 +5039,11 @@ function ValueFormattingSection({
5028
5039
  marginBottom: theme.spacing.xs
5029
5040
  };
5030
5041
  const isCurrency = config.valueFormat === "currency" || config.format === "currency";
5031
- return /* @__PURE__ */ jsxRuntime.jsxs(chunkURJH4H6G_cjs.CollapsibleSection, { title: "Value Formatting", defaultOpen, children: [
5042
+ return /* @__PURE__ */ jsxRuntime.jsxs(chunkNXXKG4GN_cjs.CollapsibleSection, { title: "Value Formatting", defaultOpen, children: [
5032
5043
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
5033
5044
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Format" }),
5034
5045
  /* @__PURE__ */ jsxRuntime.jsx(
5035
- chunkURJH4H6G_cjs.Select,
5046
+ chunkNXXKG4GN_cjs.Select,
5036
5047
  {
5037
5048
  value: config.valueFormat || config.format || "number",
5038
5049
  onChange: (value) => {
@@ -5047,7 +5058,7 @@ function ValueFormattingSection({
5047
5058
  isCurrency && showCurrency && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
5048
5059
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Currency Symbol" }),
5049
5060
  /* @__PURE__ */ jsxRuntime.jsx(
5050
- chunkURJH4H6G_cjs.Input,
5061
+ chunkNXXKG4GN_cjs.Input,
5051
5062
  {
5052
5063
  value: config.currencySymbol ?? "$",
5053
5064
  onChange: (e) => onChange("currencySymbol", e.target.value),
@@ -5059,7 +5070,7 @@ function ValueFormattingSection({
5059
5070
  showCompact && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
5060
5071
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Compact Notation" }),
5061
5072
  /* @__PURE__ */ jsxRuntime.jsx(
5062
- chunkURJH4H6G_cjs.Select,
5073
+ chunkNXXKG4GN_cjs.Select,
5063
5074
  {
5064
5075
  value: config.compactNotation || "",
5065
5076
  onChange: (value) => onChange("compactNotation", value ? value : null),
@@ -5070,7 +5081,7 @@ function ValueFormattingSection({
5070
5081
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
5071
5082
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Decimal Places" }),
5072
5083
  /* @__PURE__ */ jsxRuntime.jsx(
5073
- chunkURJH4H6G_cjs.Select,
5084
+ chunkNXXKG4GN_cjs.Select,
5074
5085
  {
5075
5086
  value: String(config.decimalDigits ?? 2),
5076
5087
  onChange: (value) => onChange("decimalDigits", parseInt(value, 10)),
@@ -5111,9 +5122,9 @@ function DisplayConfigSection({
5111
5122
  "pie_chart",
5112
5123
  "scatter_chart"
5113
5124
  ].includes(widgetType);
5114
- return /* @__PURE__ */ jsxRuntime.jsxs(chunkURJH4H6G_cjs.CollapsibleSection, { title: "Display Options", defaultOpen, children: [
5125
+ return /* @__PURE__ */ jsxRuntime.jsxs(chunkNXXKG4GN_cjs.CollapsibleSection, { title: "Display Options", defaultOpen, children: [
5115
5126
  showColorPalette && /* @__PURE__ */ jsxRuntime.jsx("div", { style: fieldStyle, children: /* @__PURE__ */ jsxRuntime.jsx(
5116
- chunkURJH4H6G_cjs.ColorPaletteSelector,
5127
+ chunkNXXKG4GN_cjs.ColorPaletteSelector,
5117
5128
  {
5118
5129
  value: config.colors,
5119
5130
  onChange: (colors) => onChange("colors", colors)
@@ -5122,7 +5133,7 @@ function DisplayConfigSection({
5122
5133
  showOrientation && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
5123
5134
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Orientation" }),
5124
5135
  /* @__PURE__ */ jsxRuntime.jsx(
5125
- chunkURJH4H6G_cjs.Select,
5136
+ chunkNXXKG4GN_cjs.Select,
5126
5137
  {
5127
5138
  value: config.orientation || "vertical",
5128
5139
  onChange: (value) => onChange("orientation", value),
@@ -5135,7 +5146,7 @@ function DisplayConfigSection({
5135
5146
  ] }),
5136
5147
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: rowStyle, children: [
5137
5148
  /* @__PURE__ */ jsxRuntime.jsx(
5138
- chunkURJH4H6G_cjs.Checkbox,
5149
+ chunkNXXKG4GN_cjs.Checkbox,
5139
5150
  {
5140
5151
  label: "Show Legend",
5141
5152
  checked: config.show_legend ?? true,
@@ -5143,7 +5154,7 @@ function DisplayConfigSection({
5143
5154
  }
5144
5155
  ),
5145
5156
  /* @__PURE__ */ jsxRuntime.jsx(
5146
- chunkURJH4H6G_cjs.Checkbox,
5157
+ chunkNXXKG4GN_cjs.Checkbox,
5147
5158
  {
5148
5159
  label: "Data Labels",
5149
5160
  checked: config.show_data_labels ?? false,
@@ -5151,7 +5162,7 @@ function DisplayConfigSection({
5151
5162
  }
5152
5163
  ),
5153
5164
  showStacked && /* @__PURE__ */ jsxRuntime.jsx(
5154
- chunkURJH4H6G_cjs.Checkbox,
5165
+ chunkNXXKG4GN_cjs.Checkbox,
5155
5166
  {
5156
5167
  label: "Stacked",
5157
5168
  checked: config.stacked ?? false,
@@ -5236,10 +5247,10 @@ function DateFormattingSection({
5236
5247
  fontSize: theme.fontSizes.sm,
5237
5248
  color: theme.colors.textMuted
5238
5249
  };
5239
- return /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.CollapsibleSection, { title: "Date Formatting", defaultOpen, children: dateColumns.map((col) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
5250
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.CollapsibleSection, { title: "Date Formatting", defaultOpen, children: dateColumns.map((col) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
5240
5251
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: columnNameStyle, children: col.alias }) }),
5241
5252
  /* @__PURE__ */ jsxRuntime.jsx(
5242
- chunkURJH4H6G_cjs.Select,
5253
+ chunkNXXKG4GN_cjs.Select,
5243
5254
  {
5244
5255
  value: config.dateFormats?.[col.name] || "",
5245
5256
  onChange: (value) => handleFormatChange(col.name, value),
@@ -5297,10 +5308,10 @@ function TrendConfigSection({
5297
5308
  color: theme.colors.textMuted,
5298
5309
  marginTop: theme.spacing.xs
5299
5310
  };
5300
- return /* @__PURE__ */ jsxRuntime.jsxs(chunkURJH4H6G_cjs.CollapsibleSection, { title: "Trend Comparison", defaultOpen, children: [
5311
+ return /* @__PURE__ */ jsxRuntime.jsxs(chunkNXXKG4GN_cjs.CollapsibleSection, { title: "Trend Comparison", defaultOpen, children: [
5301
5312
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
5302
5313
  /* @__PURE__ */ jsxRuntime.jsx(
5303
- chunkURJH4H6G_cjs.Checkbox,
5314
+ chunkNXXKG4GN_cjs.Checkbox,
5304
5315
  {
5305
5316
  label: "Show Trend Indicator",
5306
5317
  checked: config.showTrend ?? false,
@@ -5313,7 +5324,7 @@ function TrendConfigSection({
5313
5324
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
5314
5325
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Comparison Period" }),
5315
5326
  /* @__PURE__ */ jsxRuntime.jsx(
5316
- chunkURJH4H6G_cjs.Select,
5327
+ chunkNXXKG4GN_cjs.Select,
5317
5328
  {
5318
5329
  value: config.trendPeriod || "previous_period",
5319
5330
  onChange: (value) => onChange("trendPeriod", value),
@@ -5324,7 +5335,7 @@ function TrendConfigSection({
5324
5335
  dateColumnOptions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
5325
5336
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Date Column" }),
5326
5337
  /* @__PURE__ */ jsxRuntime.jsx(
5327
- chunkURJH4H6G_cjs.Select,
5338
+ chunkNXXKG4GN_cjs.Select,
5328
5339
  {
5329
5340
  value: config.trendDateColumn || "",
5330
5341
  onChange: (value) => onChange("trendDateColumn", value || void 0),
@@ -5370,7 +5381,8 @@ function WidgetEditorPage({
5370
5381
  onCancel
5371
5382
  }) {
5372
5383
  const { theme } = chunkLMTG3LRC_cjs.useTheme();
5373
- const { client } = chunkURJH4H6G_cjs.useAnalytics();
5384
+ const { client } = chunkNXXKG4GN_cjs.useAnalytics();
5385
+ const { enabled: llmEnabled, isLoading: llmStatusLoading } = chunkNXXKG4GN_cjs.useLLMStatus();
5374
5386
  const isNew = widget === null;
5375
5387
  const [type, setType] = react.useState(widget?.type ?? "bar_chart");
5376
5388
  const [title, setTitle] = react.useState(widget?.title ?? "New Widget");
@@ -5382,6 +5394,8 @@ function WidgetEditorPage({
5382
5394
  const [position, setPosition] = react.useState(
5383
5395
  widget?.position ?? { x: 0, y: 0, w: 6, h: 4, minW: 2, minH: 2 }
5384
5396
  );
5397
+ const [rawSql, setRawSql] = react.useState(widget?.config?.raw_sql ?? "");
5398
+ const [schemaOpen, setSchemaOpen] = react.useState(true);
5385
5399
  const [dataSourceMode, setDataSourceMode] = react.useState(
5386
5400
  isNew ? "guided" : widget?.config?.data_source_mode ?? "guided"
5387
5401
  );
@@ -5406,6 +5420,24 @@ function WidgetEditorPage({
5406
5420
  []
5407
5421
  );
5408
5422
  const refreshPreview = react.useCallback(async () => {
5423
+ if (dataSourceMode === "sql") {
5424
+ if (!rawSql.trim() || !client) {
5425
+ setPreviewResult(null);
5426
+ return;
5427
+ }
5428
+ setPreviewLoading(true);
5429
+ setPreviewError(null);
5430
+ try {
5431
+ const result = await client.executeSQL(rawSql);
5432
+ setPreviewResult(result);
5433
+ } catch (err) {
5434
+ setPreviewError(err instanceof Error ? err : new Error("SQL execution failed"));
5435
+ setPreviewResult(null);
5436
+ } finally {
5437
+ setPreviewLoading(false);
5438
+ }
5439
+ return;
5440
+ }
5409
5441
  if (!query || !client) {
5410
5442
  setPreviewResult(null);
5411
5443
  return;
@@ -5421,15 +5453,18 @@ function WidgetEditorPage({
5421
5453
  } finally {
5422
5454
  setPreviewLoading(false);
5423
5455
  }
5424
- }, [query, client]);
5456
+ }, [query, rawSql, dataSourceMode, client]);
5425
5457
  react.useEffect(() => {
5458
+ if (dataSourceMode === "sql") {
5459
+ return;
5460
+ }
5426
5461
  if (query) {
5427
5462
  void refreshPreview();
5428
5463
  } else {
5429
5464
  setPreviewResult(null);
5430
5465
  setPreviewError(null);
5431
5466
  }
5432
- }, [query, refreshPreview]);
5467
+ }, [query, dataSourceMode, refreshPreview]);
5433
5468
  const queryHasAdvancedFeatures = react.useCallback((q) => {
5434
5469
  if (!q) return false;
5435
5470
  if (q.tables && q.tables.length > 1 && q.joins && q.joins.length > 0) return true;
@@ -5461,18 +5496,25 @@ function WidgetEditorPage({
5461
5496
  setPreviewResult(null);
5462
5497
  setPreviewError(null);
5463
5498
  }, []);
5499
+ const handleApplySql = react.useCallback((sql) => {
5500
+ setRawSql(sql);
5501
+ }, []);
5464
5502
  const handleSave = react.useCallback(() => {
5503
+ const savedConfig = { ...config, data_source_mode: dataSourceMode };
5504
+ if (dataSourceMode === "sql") {
5505
+ savedConfig.raw_sql = rawSql.trim() || void 0;
5506
+ }
5465
5507
  const savedWidget = {
5466
5508
  id: widget?.id ?? generateId(),
5467
5509
  type,
5468
5510
  title,
5469
- config: { ...config, data_source_mode: dataSourceMode },
5470
- query,
5511
+ config: savedConfig,
5512
+ query: dataSourceMode === "sql" ? null : query,
5471
5513
  position,
5472
5514
  hyperlink
5473
5515
  };
5474
5516
  onSave(savedWidget);
5475
- }, [widget, type, title, config, query, position, hyperlink, dataSourceMode, onSave]);
5517
+ }, [widget, type, title, config, query, rawSql, position, hyperlink, dataSourceMode, onSave]);
5476
5518
  const columnSelectOptions = react.useMemo(() => {
5477
5519
  if (!schema) return [];
5478
5520
  return schema.tables.flatMap(
@@ -5482,6 +5524,13 @@ function WidgetEditorPage({
5482
5524
  }))
5483
5525
  );
5484
5526
  }, [schema]);
5527
+ const widgetContext = react.useMemo(() => ({
5528
+ widget_type: type,
5529
+ x_axis: config.x_axis,
5530
+ y_axis: config.y_axis,
5531
+ series_column: config.series_column,
5532
+ last_error: previewError?.message
5533
+ }), [type, config.x_axis, config.y_axis, config.series_column, previewError]);
5485
5534
  const containerStyle = {
5486
5535
  display: "flex",
5487
5536
  flexDirection: "column",
@@ -5622,7 +5671,7 @@ function WidgetEditorPage({
5622
5671
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
5623
5672
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "X-Axis Column" }),
5624
5673
  /* @__PURE__ */ jsxRuntime.jsx(
5625
- chunkURJH4H6G_cjs.Select,
5674
+ chunkNXXKG4GN_cjs.Select,
5626
5675
  {
5627
5676
  value: config.x_axis || "",
5628
5677
  onChange: (value) => updateConfig("x_axis", value || void 0),
@@ -5683,7 +5732,7 @@ function WidgetEditorPage({
5683
5732
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
5684
5733
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "X-Axis Column" }),
5685
5734
  /* @__PURE__ */ jsxRuntime.jsx(
5686
- chunkURJH4H6G_cjs.Select,
5735
+ chunkNXXKG4GN_cjs.Select,
5687
5736
  {
5688
5737
  value: config.x_axis || "",
5689
5738
  onChange: (value) => updateConfig("x_axis", value || void 0),
@@ -5764,7 +5813,7 @@ function WidgetEditorPage({
5764
5813
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
5765
5814
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "X-Axis Column" }),
5766
5815
  /* @__PURE__ */ jsxRuntime.jsx(
5767
- chunkURJH4H6G_cjs.Select,
5816
+ chunkNXXKG4GN_cjs.Select,
5768
5817
  {
5769
5818
  value: config.x_axis || "",
5770
5819
  onChange: (value) => updateConfig("x_axis", value || void 0),
@@ -5775,7 +5824,7 @@ function WidgetEditorPage({
5775
5824
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
5776
5825
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Y-Axis Column" }),
5777
5826
  /* @__PURE__ */ jsxRuntime.jsx(
5778
- chunkURJH4H6G_cjs.Select,
5827
+ chunkNXXKG4GN_cjs.Select,
5779
5828
  {
5780
5829
  value: config.y_axis?.[0] || "",
5781
5830
  onChange: (value) => updateConfig("y_axis", value ? [value] : void 0),
@@ -5808,7 +5857,7 @@ function WidgetEditorPage({
5808
5857
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
5809
5858
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Page Size" }),
5810
5859
  /* @__PURE__ */ jsxRuntime.jsx(
5811
- chunkURJH4H6G_cjs.Select,
5860
+ chunkNXXKG4GN_cjs.Select,
5812
5861
  {
5813
5862
  value: String(config.page_size || 10),
5814
5863
  onChange: (value) => updateConfig("page_size", parseInt(value, 10)),
@@ -5822,7 +5871,7 @@ function WidgetEditorPage({
5822
5871
  )
5823
5872
  ] }),
5824
5873
  /* @__PURE__ */ jsxRuntime.jsx(
5825
- chunkURJH4H6G_cjs.Checkbox,
5874
+ chunkNXXKG4GN_cjs.Checkbox,
5826
5875
  {
5827
5876
  label: "Sortable Columns",
5828
5877
  checked: config.sortable ?? true,
@@ -5880,10 +5929,10 @@ function WidgetEditorPage({
5880
5929
  },
5881
5930
  children: [
5882
5931
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: theme.spacing.sm }, children: [
5883
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "table", size: 16 }),
5932
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "table", size: 16 }),
5884
5933
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 500, color: theme.colors.text }, children: "Query configured" })
5885
5934
  ] }),
5886
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Button, { variant: "ghost", size: "sm", onClick: handleClearQuery, children: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "x", size: 16 }) })
5935
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Button, { variant: "ghost", size: "sm", onClick: handleClearQuery, children: /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "x", size: 16 }) })
5887
5936
  ]
5888
5937
  }
5889
5938
  ),
@@ -5902,14 +5951,14 @@ function WidgetEditorPage({
5902
5951
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerStyle, children: [
5903
5952
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerLeftStyle, children: [
5904
5953
  /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", style: backButtonStyle, onClick: onCancel, children: [
5905
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "chevron-left", size: 16 }),
5954
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "chevron-left", size: 16 }),
5906
5955
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Back" })
5907
5956
  ] }),
5908
5957
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: headerTitleStyle, children: isNew ? "Add Widget" : "Edit Widget" })
5909
5958
  ] }),
5910
5959
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerActionsStyle, children: [
5911
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Button, { variant: "ghost", onClick: onCancel, children: "Cancel" }),
5912
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Button, { variant: "primary", onClick: handleSave, children: isNew ? "Add Widget" : "Save Changes" })
5960
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Button, { variant: "ghost", onClick: onCancel, children: "Cancel" }),
5961
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Button, { variant: "primary", onClick: handleSave, children: isNew ? "Add Widget" : "Save Changes" })
5913
5962
  ] })
5914
5963
  ] }),
5915
5964
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: bodyStyle, children: [
@@ -5920,7 +5969,7 @@ function WidgetEditorPage({
5920
5969
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
5921
5970
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Title" }),
5922
5971
  /* @__PURE__ */ jsxRuntime.jsx(
5923
- chunkURJH4H6G_cjs.Input,
5972
+ chunkNXXKG4GN_cjs.Input,
5924
5973
  {
5925
5974
  value: title,
5926
5975
  onChange: (e) => setTitle(e.target.value),
@@ -5958,6 +6007,7 @@ function WidgetEditorPage({
5958
6007
  title,
5959
6008
  config,
5960
6009
  query,
6010
+ rawSql: dataSourceMode === "sql" ? rawSql : void 0,
5961
6011
  result: previewResult,
5962
6012
  isLoading: previewLoading,
5963
6013
  error: previewError
@@ -5967,7 +6017,7 @@ function WidgetEditorPage({
5967
6017
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: dataSourceHeaderStyle, children: [
5968
6018
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: theme.fontSizes.sm, fontWeight: 500, marginRight: "auto" }, children: "Data Source" }),
5969
6019
  /* @__PURE__ */ jsxRuntime.jsx(
5970
- chunkURJH4H6G_cjs.Tooltip,
6020
+ chunkNXXKG4GN_cjs.Tooltip,
5971
6021
  {
5972
6022
  content: "Quick setup: pick columns from dropdowns to build your chart",
5973
6023
  position: "bottom",
@@ -5985,7 +6035,7 @@ function WidgetEditorPage({
5985
6035
  }
5986
6036
  ),
5987
6037
  /* @__PURE__ */ jsxRuntime.jsx(
5988
- chunkURJH4H6G_cjs.Tooltip,
6038
+ chunkNXXKG4GN_cjs.Tooltip,
5989
6039
  {
5990
6040
  content: "Full control: combine tables, add filters, and create custom calculations",
5991
6041
  position: "bottom",
@@ -6001,6 +6051,24 @@ function WidgetEditorPage({
6001
6051
  }
6002
6052
  )
6003
6053
  }
6054
+ ),
6055
+ /* @__PURE__ */ jsxRuntime.jsx(
6056
+ chunkNXXKG4GN_cjs.Tooltip,
6057
+ {
6058
+ content: "Write raw SQL queries directly, with optional AI assistance",
6059
+ position: "bottom",
6060
+ style: { whiteSpace: "normal" },
6061
+ children: /* @__PURE__ */ jsxRuntime.jsx(
6062
+ "button",
6063
+ {
6064
+ type: "button",
6065
+ "data-testid": "data-source-mode-sql",
6066
+ style: tabStyle(dataSourceMode === "sql"),
6067
+ onClick: () => handleModeSwitch("sql"),
6068
+ children: "SQL"
6069
+ }
6070
+ )
6071
+ }
6004
6072
  )
6005
6073
  ] }),
6006
6074
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: dataSourceContentStyle, children: [
@@ -6015,7 +6083,7 @@ function WidgetEditorPage({
6015
6083
  }
6016
6084
  ),
6017
6085
  dataSourceMode === "advanced" && /* @__PURE__ */ jsxRuntime.jsx(
6018
- chunkURJH4H6G_cjs.QueryBuilder,
6086
+ chunkNXXKG4GN_cjs.QueryBuilder,
6019
6087
  {
6020
6088
  initialQuery: query ?? void 0,
6021
6089
  onQueryChange: handleQueryChange,
@@ -6026,13 +6094,107 @@ function WidgetEditorPage({
6026
6094
  }
6027
6095
  ),
6028
6096
  dataSourceMode === "saved" && /* @__PURE__ */ jsxRuntime.jsx(
6029
- chunkURJH4H6G_cjs.SavedQueryPicker,
6097
+ chunkNXXKG4GN_cjs.SavedQueryPicker,
6030
6098
  {
6031
6099
  currentQuery: query,
6032
6100
  onSelect: handleSavedQuerySelect,
6033
6101
  showSave: false
6034
6102
  }
6035
- )
6103
+ ),
6104
+ dataSourceMode === "sql" && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: 0, height: "100%", minHeight: "400px" }, children: [
6105
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "data-testid": "schema-panel", style: {
6106
+ width: schemaOpen ? "220px" : "36px",
6107
+ flexShrink: 0,
6108
+ transition: "width 0.2s ease",
6109
+ borderRight: `1px solid ${theme.colors.border}`,
6110
+ display: "flex",
6111
+ flexDirection: "column",
6112
+ overflow: "hidden"
6113
+ }, children: schemaOpen ? /* @__PURE__ */ jsxRuntime.jsx(
6114
+ chunkNXXKG4GN_cjs.SchemaExplorer,
6115
+ {
6116
+ searchable: true,
6117
+ collapsible: true,
6118
+ onColumnSelect: (table, col) => {
6119
+ const ref = `"${table.name}"."${col.name}"`;
6120
+ setRawSql((prev) => prev ? `${prev} ${ref}` : ref);
6121
+ },
6122
+ headerAction: /* @__PURE__ */ jsxRuntime.jsx(
6123
+ "button",
6124
+ {
6125
+ type: "button",
6126
+ onClick: () => setSchemaOpen(false),
6127
+ title: "Collapse schema panel",
6128
+ "data-testid": "schema-toggle-open",
6129
+ style: {
6130
+ display: "flex",
6131
+ alignItems: "center",
6132
+ justifyContent: "center",
6133
+ width: "22px",
6134
+ height: "22px",
6135
+ backgroundColor: "transparent",
6136
+ border: `1px solid ${theme.colors.border}`,
6137
+ borderRadius: theme.radius.sm,
6138
+ cursor: "pointer",
6139
+ color: theme.colors.textMuted,
6140
+ flexShrink: 0
6141
+ },
6142
+ children: /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "chevron-left", size: 12 })
6143
+ }
6144
+ ),
6145
+ style: { flex: 1, border: "none", borderRadius: 0 }
6146
+ }
6147
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(
6148
+ "button",
6149
+ {
6150
+ type: "button",
6151
+ onClick: () => setSchemaOpen(true),
6152
+ title: "Show schema browser",
6153
+ "data-testid": "schema-toggle-collapsed",
6154
+ style: {
6155
+ display: "flex",
6156
+ flexDirection: "column",
6157
+ alignItems: "center",
6158
+ gap: "6px",
6159
+ paddingTop: theme.spacing.sm,
6160
+ width: "100%",
6161
+ height: "100%",
6162
+ backgroundColor: theme.colors.surface,
6163
+ border: "none",
6164
+ cursor: "pointer",
6165
+ color: theme.colors.textMuted,
6166
+ fontFamily: theme.fonts.sans
6167
+ },
6168
+ children: [
6169
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "table", size: 16 }),
6170
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: {
6171
+ writingMode: "vertical-rl",
6172
+ fontSize: "11px",
6173
+ fontWeight: 500,
6174
+ letterSpacing: "0.04em"
6175
+ }, children: "Schema" })
6176
+ ]
6177
+ }
6178
+ ) }),
6179
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: 1, minWidth: 0 }, "data-testid": "sql-editor", children: /* @__PURE__ */ jsxRuntime.jsx(
6180
+ chunkNXXKG4GN_cjs.CustomSQLEditor,
6181
+ {
6182
+ initialSql: rawSql,
6183
+ onSqlChange: setRawSql,
6184
+ onExecute: () => void refreshPreview(),
6185
+ showResults: false,
6186
+ placeholder: "Write your SQL query here..."
6187
+ }
6188
+ ) }),
6189
+ !llmStatusLoading && llmEnabled && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: "340px", flexShrink: 0 }, "data-testid": "chat-panel", children: /* @__PURE__ */ jsxRuntime.jsx(
6190
+ chunkNXXKG4GN_cjs.ChatPanel,
6191
+ {
6192
+ currentSql: rawSql || null,
6193
+ onApplySql: handleApplySql,
6194
+ widgetContext
6195
+ }
6196
+ ) })
6197
+ ] })
6036
6198
  ] })
6037
6199
  ] })
6038
6200
  ] })
@@ -6076,8 +6238,8 @@ function DashboardEditor({
6076
6238
  className = ""
6077
6239
  }) {
6078
6240
  const { theme } = chunkLMTG3LRC_cjs.useTheme();
6079
- const { client } = chunkURJH4H6G_cjs.useAnalytics();
6080
- const { schema } = chunkURJH4H6G_cjs.useSchema();
6241
+ const { client } = chunkNXXKG4GN_cjs.useAnalytics();
6242
+ const { schema } = chunkNXXKG4GN_cjs.useSchema();
6081
6243
  const [currentDashboardId, setCurrentDashboardId] = react.useState(dashboardId);
6082
6244
  react.useEffect(() => {
6083
6245
  setCurrentDashboardId(dashboardId);
@@ -6114,7 +6276,9 @@ function DashboardEditor({
6114
6276
  clientRef.current = client;
6115
6277
  const loadedDashboardRef = react.useRef(null);
6116
6278
  const executeWidgetQueries = react.useCallback(async (widgets, currentClient) => {
6117
- const widgetsWithQueries = widgets.filter((w) => w.query);
6279
+ const widgetsWithQueries = widgets.filter(
6280
+ (w) => w.query || w.config?.data_source_mode === "sql" && w.config?.raw_sql
6281
+ );
6118
6282
  if (widgetsWithQueries.length === 0) return;
6119
6283
  for (let i = 0; i < widgetsWithQueries.length; i += batchSize) {
6120
6284
  const batch = widgetsWithQueries.slice(i, i + batchSize);
@@ -6128,7 +6292,8 @@ function DashboardEditor({
6128
6292
  await Promise.all(
6129
6293
  batch.map(async (widget) => {
6130
6294
  try {
6131
- const result = await currentClient.executeQuery(widget.query);
6295
+ const isSqlMode = widget.config?.data_source_mode === "sql" && widget.config?.raw_sql;
6296
+ const result = isSqlMode ? await currentClient.executeSQL(widget.config.raw_sql) : await currentClient.executeQuery(widget.query);
6132
6297
  setWidgetResults((prev) => ({ ...prev, [widget.id]: result }));
6133
6298
  setWidgetRefreshTimes((prev) => ({ ...prev, [widget.id]: Math.floor(Date.now() / 1e3) }));
6134
6299
  } catch (err) {
@@ -6205,11 +6370,12 @@ function DashboardEditor({
6205
6370
  const refreshWidget = react.useCallback(
6206
6371
  async (widgetId, widgetOverride) => {
6207
6372
  const widget = widgetOverride ?? dashboard.widgets.find((w) => w.id === widgetId);
6208
- if (!widget?.query || !client) return;
6373
+ const isSqlMode = widget?.config?.data_source_mode === "sql" && widget?.config?.raw_sql;
6374
+ if (!widget?.query && !isSqlMode || !client) return;
6209
6375
  setWidgetLoading((prev) => ({ ...prev, [widgetId]: true }));
6210
6376
  setRefreshingWidgets((prev) => new Set(prev).add(widgetId));
6211
6377
  try {
6212
- const result = await client.executeQuery(widget.query, true);
6378
+ const result = isSqlMode ? await client.executeSQL(widget.config.raw_sql) : await client.executeQuery(widget.query, true);
6213
6379
  setWidgetResults((prev) => ({ ...prev, [widgetId]: result }));
6214
6380
  setWidgetRefreshTimes((prev) => ({ ...prev, [widgetId]: Math.floor(Date.now() / 1e3) }));
6215
6381
  setWidgetErrors((prev) => {
@@ -6704,7 +6870,7 @@ function WidgetPalette({
6704
6870
  Object.assign(e.currentTarget.style, itemStyle);
6705
6871
  },
6706
6872
  children: [
6707
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: iconContainerStyle, children: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: widgetType.icon, size: 24 }) }),
6873
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: iconContainerStyle, children: /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: widgetType.icon, size: 24 }) }),
6708
6874
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: labelStyle, children: widgetType.label }),
6709
6875
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: descriptionStyle, children: widgetType.description })
6710
6876
  ]
@@ -6856,7 +7022,7 @@ function WidgetEditor({
6856
7022
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
6857
7023
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Format" }),
6858
7024
  /* @__PURE__ */ jsxRuntime.jsx(
6859
- chunkURJH4H6G_cjs.Select,
7025
+ chunkNXXKG4GN_cjs.Select,
6860
7026
  {
6861
7027
  value: config.format || "number",
6862
7028
  onChange: (value) => updateConfig("format", value),
@@ -6872,7 +7038,7 @@ function WidgetEditor({
6872
7038
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
6873
7039
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Trend Comparison Field" }),
6874
7040
  /* @__PURE__ */ jsxRuntime.jsx(
6875
- chunkURJH4H6G_cjs.Select,
7041
+ chunkNXXKG4GN_cjs.Select,
6876
7042
  {
6877
7043
  value: config.trend_comparison || "",
6878
7044
  onChange: (value) => updateConfig("trend_comparison", value || void 0),
@@ -6889,7 +7055,7 @@ function WidgetEditor({
6889
7055
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
6890
7056
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "X-Axis Column" }),
6891
7057
  /* @__PURE__ */ jsxRuntime.jsx(
6892
- chunkURJH4H6G_cjs.Select,
7058
+ chunkNXXKG4GN_cjs.Select,
6893
7059
  {
6894
7060
  value: config.x_axis || "",
6895
7061
  onChange: (value) => updateConfig("x_axis", value),
@@ -6900,7 +7066,7 @@ function WidgetEditor({
6900
7066
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
6901
7067
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Orientation" }),
6902
7068
  /* @__PURE__ */ jsxRuntime.jsx(
6903
- chunkURJH4H6G_cjs.Select,
7069
+ chunkNXXKG4GN_cjs.Select,
6904
7070
  {
6905
7071
  value: config.orientation || "vertical",
6906
7072
  onChange: (value) => updateConfig("orientation", value),
@@ -6913,7 +7079,7 @@ function WidgetEditor({
6913
7079
  ] }),
6914
7080
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: rowStyle, children: [
6915
7081
  /* @__PURE__ */ jsxRuntime.jsx(
6916
- chunkURJH4H6G_cjs.Checkbox,
7082
+ chunkNXXKG4GN_cjs.Checkbox,
6917
7083
  {
6918
7084
  label: "Show Legend",
6919
7085
  checked: config.show_legend ?? true,
@@ -6921,7 +7087,7 @@ function WidgetEditor({
6921
7087
  }
6922
7088
  ),
6923
7089
  /* @__PURE__ */ jsxRuntime.jsx(
6924
- chunkURJH4H6G_cjs.Checkbox,
7090
+ chunkNXXKG4GN_cjs.Checkbox,
6925
7091
  {
6926
7092
  label: "Stacked",
6927
7093
  checked: config.stacked ?? false,
@@ -6929,7 +7095,7 @@ function WidgetEditor({
6929
7095
  }
6930
7096
  ),
6931
7097
  /* @__PURE__ */ jsxRuntime.jsx(
6932
- chunkURJH4H6G_cjs.Checkbox,
7098
+ chunkNXXKG4GN_cjs.Checkbox,
6933
7099
  {
6934
7100
  label: "Show Data Labels",
6935
7101
  checked: config.show_data_labels ?? false,
@@ -6944,7 +7110,7 @@ function WidgetEditor({
6944
7110
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
6945
7111
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "X-Axis Column" }),
6946
7112
  /* @__PURE__ */ jsxRuntime.jsx(
6947
- chunkURJH4H6G_cjs.Select,
7113
+ chunkNXXKG4GN_cjs.Select,
6948
7114
  {
6949
7115
  value: config.x_axis || "",
6950
7116
  onChange: (value) => updateConfig("x_axis", value),
@@ -6954,7 +7120,7 @@ function WidgetEditor({
6954
7120
  ] }),
6955
7121
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: rowStyle, children: [
6956
7122
  /* @__PURE__ */ jsxRuntime.jsx(
6957
- chunkURJH4H6G_cjs.Checkbox,
7123
+ chunkNXXKG4GN_cjs.Checkbox,
6958
7124
  {
6959
7125
  label: "Show Legend",
6960
7126
  checked: config.show_legend ?? true,
@@ -6962,7 +7128,7 @@ function WidgetEditor({
6962
7128
  }
6963
7129
  ),
6964
7130
  /* @__PURE__ */ jsxRuntime.jsx(
6965
- chunkURJH4H6G_cjs.Checkbox,
7131
+ chunkNXXKG4GN_cjs.Checkbox,
6966
7132
  {
6967
7133
  label: "Show Data Labels",
6968
7134
  checked: config.show_data_labels ?? false,
@@ -6974,7 +7140,7 @@ function WidgetEditor({
6974
7140
  case "pie_chart":
6975
7141
  return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: rowStyle, children: [
6976
7142
  /* @__PURE__ */ jsxRuntime.jsx(
6977
- chunkURJH4H6G_cjs.Checkbox,
7143
+ chunkNXXKG4GN_cjs.Checkbox,
6978
7144
  {
6979
7145
  label: "Show Legend",
6980
7146
  checked: config.show_legend ?? true,
@@ -6982,7 +7148,7 @@ function WidgetEditor({
6982
7148
  }
6983
7149
  ),
6984
7150
  /* @__PURE__ */ jsxRuntime.jsx(
6985
- chunkURJH4H6G_cjs.Checkbox,
7151
+ chunkNXXKG4GN_cjs.Checkbox,
6986
7152
  {
6987
7153
  label: "Show Data Labels",
6988
7154
  checked: config.show_data_labels ?? true,
@@ -6995,7 +7161,7 @@ function WidgetEditor({
6995
7161
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
6996
7162
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Page Size" }),
6997
7163
  /* @__PURE__ */ jsxRuntime.jsx(
6998
- chunkURJH4H6G_cjs.Select,
7164
+ chunkNXXKG4GN_cjs.Select,
6999
7165
  {
7000
7166
  value: String(config.page_size || 10),
7001
7167
  onChange: (value) => updateConfig("page_size", parseInt(value, 10)),
@@ -7010,7 +7176,7 @@ function WidgetEditor({
7010
7176
  )
7011
7177
  ] }),
7012
7178
  /* @__PURE__ */ jsxRuntime.jsx(
7013
- chunkURJH4H6G_cjs.Checkbox,
7179
+ chunkNXXKG4GN_cjs.Checkbox,
7014
7180
  {
7015
7181
  label: "Sortable Columns",
7016
7182
  checked: config.sortable ?? true,
@@ -7043,7 +7209,7 @@ function WidgetEditor({
7043
7209
  )
7044
7210
  ] }),
7045
7211
  /* @__PURE__ */ jsxRuntime.jsx(
7046
- chunkURJH4H6G_cjs.Checkbox,
7212
+ chunkNXXKG4GN_cjs.Checkbox,
7047
7213
  {
7048
7214
  label: "Enable Markdown",
7049
7215
  checked: config.markdown ?? true,
@@ -7058,7 +7224,7 @@ function WidgetEditor({
7058
7224
  return /* @__PURE__ */ jsxRuntime.jsx("div", { style: overlayStyle, onClick: onCancel, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: modalStyle, onClick: (e) => e.stopPropagation(), children: [
7059
7225
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerStyle, children: [
7060
7226
  /* @__PURE__ */ jsxRuntime.jsx("h2", { style: titleStyle, children: "Edit Widget" }),
7061
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Button, { variant: "ghost", size: "sm", onClick: onCancel, children: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "x", size: 20 }) })
7227
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Button, { variant: "ghost", size: "sm", onClick: onCancel, children: /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "x", size: 20 }) })
7062
7228
  ] }),
7063
7229
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: bodyStyle, children: [
7064
7230
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: sectionStyle, children: [
@@ -7066,7 +7232,7 @@ function WidgetEditor({
7066
7232
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
7067
7233
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Title" }),
7068
7234
  /* @__PURE__ */ jsxRuntime.jsx(
7069
- chunkURJH4H6G_cjs.Input,
7235
+ chunkNXXKG4GN_cjs.Input,
7070
7236
  {
7071
7237
  value: title,
7072
7238
  onChange: (e) => setTitle(e.target.value),
@@ -7102,10 +7268,10 @@ function WidgetEditor({
7102
7268
  },
7103
7269
  children: [
7104
7270
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: theme.spacing.sm }, children: [
7105
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "table", size: 16 }),
7271
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "table", size: 16 }),
7106
7272
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 500, color: theme.colors.text }, children: queryName || "Custom Query" })
7107
7273
  ] }),
7108
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Button, { variant: "ghost", size: "sm", onClick: handleClearQuery, children: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "x", size: 16 }) })
7274
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Button, { variant: "ghost", size: "sm", onClick: handleClearQuery, children: /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "x", size: 16 }) })
7109
7275
  ]
7110
7276
  }
7111
7277
  ),
@@ -7133,11 +7299,11 @@ function WidgetEditor({
7133
7299
  },
7134
7300
  children: [
7135
7301
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { textAlign: "center", color: theme.colors.textMuted }, children: [
7136
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "table", size: 24, style: { marginBottom: theme.spacing.xs } }),
7302
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "table", size: 24, style: { marginBottom: theme.spacing.xs } }),
7137
7303
  /* @__PURE__ */ jsxRuntime.jsx("div", { children: "Select a saved query to power this widget" })
7138
7304
  ] }),
7139
7305
  /* @__PURE__ */ jsxRuntime.jsx(
7140
- chunkURJH4H6G_cjs.SavedQueryPicker,
7306
+ chunkNXXKG4GN_cjs.SavedQueryPicker,
7141
7307
  {
7142
7308
  currentQuery: null,
7143
7309
  onSelect: handleSelectSavedQuery,
@@ -7150,8 +7316,8 @@ function WidgetEditor({
7150
7316
  ] })
7151
7317
  ] }),
7152
7318
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: footerStyle, children: [
7153
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Button, { variant: "ghost", onClick: onCancel, children: "Cancel" }),
7154
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Button, { variant: "primary", onClick: handleSave, children: "Save Widget" })
7319
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Button, { variant: "ghost", onClick: onCancel, children: "Cancel" }),
7320
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Button, { variant: "primary", onClick: handleSave, children: "Save Widget" })
7155
7321
  ] })
7156
7322
  ] }) });
7157
7323
  }
@@ -7296,31 +7462,31 @@ var DashboardCard = react.forwardRef(
7296
7462
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerStyles, children: [
7297
7463
  /* @__PURE__ */ jsxRuntime.jsx("h3", { style: titleStyles, children: dashboard.name }),
7298
7464
  actions ? actions : /* @__PURE__ */ jsxRuntime.jsxs(
7299
- chunkURJH4H6G_cjs.Dropdown,
7465
+ chunkNXXKG4GN_cjs.Dropdown,
7300
7466
  {
7301
7467
  trigger: /* @__PURE__ */ jsxRuntime.jsx(
7302
- chunkURJH4H6G_cjs.Button,
7468
+ chunkNXXKG4GN_cjs.Button,
7303
7469
  {
7304
7470
  variant: "ghost",
7305
7471
  size: "sm",
7306
7472
  onClick: (e) => e.stopPropagation(),
7307
7473
  disabled: actionsDisabled,
7308
7474
  "aria-label": "Dashboard actions",
7309
- children: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "more-vertical", size: 16 })
7475
+ children: /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "more-vertical", size: 16 })
7310
7476
  }
7311
7477
  ),
7312
7478
  children: [
7313
- /* @__PURE__ */ jsxRuntime.jsxs(chunkURJH4H6G_cjs.DropdownItem, { onClick: () => handleMenuAction("edit"), children: [
7314
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "edit", size: 14 }),
7479
+ /* @__PURE__ */ jsxRuntime.jsxs(chunkNXXKG4GN_cjs.DropdownItem, { onClick: () => handleMenuAction("edit"), children: [
7480
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "edit", size: 14 }),
7315
7481
  "Edit"
7316
7482
  ] }),
7317
- /* @__PURE__ */ jsxRuntime.jsxs(chunkURJH4H6G_cjs.DropdownItem, { onClick: () => handleMenuAction("duplicate"), children: [
7318
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "copy", size: 14 }),
7483
+ /* @__PURE__ */ jsxRuntime.jsxs(chunkNXXKG4GN_cjs.DropdownItem, { onClick: () => handleMenuAction("duplicate"), children: [
7484
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "copy", size: 14 }),
7319
7485
  "Duplicate"
7320
7486
  ] }),
7321
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.DropdownSeparator, {}),
7322
- /* @__PURE__ */ jsxRuntime.jsxs(chunkURJH4H6G_cjs.DropdownItem, { onClick: () => handleMenuAction("delete"), children: [
7323
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "trash", size: 14 }),
7487
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.DropdownSeparator, {}),
7488
+ /* @__PURE__ */ jsxRuntime.jsxs(chunkNXXKG4GN_cjs.DropdownItem, { onClick: () => handleMenuAction("delete"), children: [
7489
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "trash", size: 14 }),
7324
7490
  "Delete"
7325
7491
  ] })
7326
7492
  ]
@@ -7330,13 +7496,13 @@ var DashboardCard = react.forwardRef(
7330
7496
  dashboard.description && /* @__PURE__ */ jsxRuntime.jsx("p", { style: descriptionStyles, children: dashboard.description }),
7331
7497
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: metaStyles, children: [
7332
7498
  /* @__PURE__ */ jsxRuntime.jsxs("span", { style: metaItemStyles, children: [
7333
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "grid", size: 12 }),
7499
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "grid", size: 12 }),
7334
7500
  dashboard.widgets.length,
7335
7501
  " widget",
7336
7502
  dashboard.widgets.length !== 1 ? "s" : ""
7337
7503
  ] }),
7338
7504
  /* @__PURE__ */ jsxRuntime.jsxs("span", { style: metaItemStyles, children: [
7339
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "calendar", size: 12 }),
7505
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "calendar", size: 12 }),
7340
7506
  formatDate(dashboard.updated_at)
7341
7507
  ] }),
7342
7508
  dashboard.is_public ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: publicBadgeStyles, children: "Public" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: privateBadgeStyles, children: "Private" })
@@ -7394,32 +7560,32 @@ var DashboardList = react.forwardRef(
7394
7560
  if (isLoading) {
7395
7561
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, style: { ...containerStyles, ...style }, ...props, children: [
7396
7562
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerStyles2, children: [
7397
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Skeleton, { width: 200, height: 32 }),
7398
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Skeleton, { width: 150, height: 40 })
7563
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Skeleton, { width: 200, height: 32 }),
7564
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Skeleton, { width: 150, height: 40 })
7399
7565
  ] }),
7400
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: getGridStyles(columns), children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Skeleton, { height: 150, style: { borderRadius: "var(--prismiq-radius-lg)" } }, i)) })
7566
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: getGridStyles(columns), children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Skeleton, { height: 150, style: { borderRadius: "var(--prismiq-radius-lg)" } }, i)) })
7401
7567
  ] });
7402
7568
  }
7403
7569
  if (error) {
7404
7570
  return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, style: { ...containerStyles, ...style }, ...props, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: errorStyles, children: [
7405
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "alert-circle", size: 48 }),
7571
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "alert-circle", size: 48 }),
7406
7572
  /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
7407
7573
  "Failed to load dashboards: ",
7408
7574
  error.message
7409
7575
  ] }),
7410
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Button, { variant: "secondary", onClick: () => window.location.reload(), children: "Retry" })
7576
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Button, { variant: "secondary", onClick: () => window.location.reload(), children: "Retry" })
7411
7577
  ] }) });
7412
7578
  }
7413
7579
  if (!dashboards || dashboards.length === 0) {
7414
7580
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, style: { ...containerStyles, ...style }, ...props, children: [
7415
7581
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerStyles2, children: [
7416
7582
  /* @__PURE__ */ jsxRuntime.jsx("h2", { style: titleStyles2, children: "Dashboards" }),
7417
- onCreate && /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Button, { onClick: onCreate, leftIcon: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "plus", size: 16 }), children: "Create Dashboard" })
7583
+ onCreate && /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Button, { onClick: onCreate, leftIcon: /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "plus", size: 16 }), children: "Create Dashboard" })
7418
7584
  ] }),
7419
7585
  emptyState || /* @__PURE__ */ jsxRuntime.jsx(
7420
- chunkURJH4H6G_cjs.EmptyState,
7586
+ chunkNXXKG4GN_cjs.EmptyState,
7421
7587
  {
7422
- icon: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "layout", size: 64 }),
7588
+ icon: /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "layout", size: 64 }),
7423
7589
  title: "No dashboards yet",
7424
7590
  description: "Create your first dashboard to start visualizing your data.",
7425
7591
  action: onCreate ? { label: "Create Dashboard", onClick: onCreate } : void 0
@@ -7434,7 +7600,7 @@ var DashboardList = react.forwardRef(
7434
7600
  dashboards.length,
7435
7601
  ")"
7436
7602
  ] }),
7437
- onCreate && /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Button, { onClick: onCreate, leftIcon: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "plus", size: 16 }), children: "Create Dashboard" })
7603
+ onCreate && /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Button, { onClick: onCreate, leftIcon: /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Icon, { name: "plus", size: 16 }), children: "Create Dashboard" })
7438
7604
  ] }),
7439
7605
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: getGridStyles(columns), children: dashboards.map((dashboard) => {
7440
7606
  const cardProps = {
@@ -7534,7 +7700,7 @@ var DashboardDialog = react.forwardRef(
7534
7700
  );
7535
7701
  const displayError = validationError || error;
7536
7702
  return /* @__PURE__ */ jsxRuntime.jsx(
7537
- chunkURJH4H6G_cjs.Dialog,
7703
+ chunkNXXKG4GN_cjs.Dialog,
7538
7704
  {
7539
7705
  open,
7540
7706
  onClose,
@@ -7546,7 +7712,7 @@ var DashboardDialog = react.forwardRef(
7546
7712
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyles, children: [
7547
7713
  /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "dashboard-name", style: labelStyles, children: "Name" }),
7548
7714
  /* @__PURE__ */ jsxRuntime.jsx(
7549
- chunkURJH4H6G_cjs.Input,
7715
+ chunkNXXKG4GN_cjs.Input,
7550
7716
  {
7551
7717
  id: "dashboard-name",
7552
7718
  value: formState.name,
@@ -7560,7 +7726,7 @@ var DashboardDialog = react.forwardRef(
7560
7726
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyles, children: [
7561
7727
  /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "dashboard-description", style: labelStyles, children: "Description (optional)" }),
7562
7728
  /* @__PURE__ */ jsxRuntime.jsx(
7563
- chunkURJH4H6G_cjs.Input,
7729
+ chunkNXXKG4GN_cjs.Input,
7564
7730
  {
7565
7731
  id: "dashboard-description",
7566
7732
  value: formState.description,
@@ -7572,7 +7738,7 @@ var DashboardDialog = react.forwardRef(
7572
7738
  ] }),
7573
7739
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: checkboxContainerStyles, children: [
7574
7740
  /* @__PURE__ */ jsxRuntime.jsx(
7575
- chunkURJH4H6G_cjs.Checkbox,
7741
+ chunkNXXKG4GN_cjs.Checkbox,
7576
7742
  {
7577
7743
  id: "dashboard-public",
7578
7744
  checked: formState.isPublic,
@@ -7582,9 +7748,9 @@ var DashboardDialog = react.forwardRef(
7582
7748
  ),
7583
7749
  /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "dashboard-public", style: checkboxLabelStyles, children: "Make this dashboard public" })
7584
7750
  ] }),
7585
- /* @__PURE__ */ jsxRuntime.jsxs(chunkURJH4H6G_cjs.DialogFooter, { children: [
7751
+ /* @__PURE__ */ jsxRuntime.jsxs(chunkNXXKG4GN_cjs.DialogFooter, { children: [
7586
7752
  /* @__PURE__ */ jsxRuntime.jsx(
7587
- chunkURJH4H6G_cjs.Button,
7753
+ chunkNXXKG4GN_cjs.Button,
7588
7754
  {
7589
7755
  type: "button",
7590
7756
  variant: "secondary",
@@ -7593,7 +7759,7 @@ var DashboardDialog = react.forwardRef(
7593
7759
  children: "Cancel"
7594
7760
  }
7595
7761
  ),
7596
- /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Button, { type: "submit", loading: isLoading, children: isEditMode ? "Save Changes" : "Create Dashboard" })
7762
+ /* @__PURE__ */ jsxRuntime.jsx(chunkNXXKG4GN_cjs.Button, { type: "submit", loading: isLoading, children: isEditMode ? "Save Changes" : "Create Dashboard" })
7597
7763
  ] })
7598
7764
  ] })
7599
7765
  }
@@ -7633,5 +7799,5 @@ exports.useDashboardFilters = useDashboardFilters;
7633
7799
  exports.useFullscreen = useFullscreen;
7634
7800
  exports.useWidget = useWidget;
7635
7801
  exports.useWidgetVisibility = useWidgetVisibility;
7636
- //# sourceMappingURL=chunk-VQDFS6VS.cjs.map
7637
- //# sourceMappingURL=chunk-VQDFS6VS.cjs.map
7802
+ //# sourceMappingURL=chunk-N6I3QOHG.cjs.map
7803
+ //# sourceMappingURL=chunk-N6I3QOHG.cjs.map