@prismiq/react 0.1.0 → 0.1.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 (57) hide show
  1. package/dist/{CustomSQLEditor-BXB4rf1q.d.cts → CustomSQLEditor-CYlOtecq.d.ts} +10 -3
  2. package/dist/{CustomSQLEditor-DYeId0Gp.d.ts → CustomSQLEditor-d84v_Cgp.d.cts} +10 -3
  3. package/dist/{DashboardDialog-LHmrtNQU.d.cts → DashboardDialog-CZD8I-6z.d.cts} +4 -4
  4. package/dist/{DashboardDialog-B3vYC5Gs.d.ts → DashboardDialog-DBNTVVSp.d.ts} +4 -4
  5. package/dist/{accessibility-2yy5yqRR.d.cts → accessibility-Bu2mNtaB.d.cts} +1 -1
  6. package/dist/{accessibility-2yy5yqRR.d.ts → accessibility-Bu2mNtaB.d.ts} +1 -1
  7. package/dist/charts/index.cjs +27 -27
  8. package/dist/charts/index.d.cts +2 -2
  9. package/dist/charts/index.d.ts +2 -2
  10. package/dist/charts/index.js +2 -2
  11. package/dist/{chunk-MOAEEF5P.js → chunk-3LDRRDJ6.js} +185 -91
  12. package/dist/chunk-3LDRRDJ6.js.map +1 -0
  13. package/dist/{chunk-NK7HKX2J.cjs → chunk-73TPDGXB.cjs} +7 -7
  14. package/dist/{chunk-NK7HKX2J.cjs.map → chunk-73TPDGXB.cjs.map} +1 -1
  15. package/dist/{chunk-UPYINBZU.js → chunk-ET7GCREP.js} +502 -46
  16. package/dist/chunk-ET7GCREP.js.map +1 -0
  17. package/dist/{chunk-2H5WTH4K.js → chunk-FQ23KG6G.js} +3 -3
  18. package/dist/{chunk-2H5WTH4K.js.map → chunk-FQ23KG6G.js.map} +1 -1
  19. package/dist/{chunk-4AVL6GQK.cjs → chunk-KXB2IZI2.cjs} +36 -9
  20. package/dist/chunk-KXB2IZI2.cjs.map +1 -0
  21. package/dist/{chunk-EX74SI67.js → chunk-LBE6GIBC.js} +36 -9
  22. package/dist/chunk-LBE6GIBC.js.map +1 -0
  23. package/dist/{chunk-NY6TZLST.cjs → chunk-URJH4H6G.cjs} +505 -49
  24. package/dist/chunk-URJH4H6G.cjs.map +1 -0
  25. package/dist/{chunk-FEABEF3J.cjs → chunk-VQDFS6VS.cjs} +374 -280
  26. package/dist/chunk-VQDFS6VS.cjs.map +1 -0
  27. package/dist/components/index.cjs +55 -55
  28. package/dist/components/index.d.cts +2 -2
  29. package/dist/components/index.d.ts +2 -2
  30. package/dist/components/index.js +2 -2
  31. package/dist/dashboard/index.cjs +36 -36
  32. package/dist/dashboard/index.d.cts +3 -3
  33. package/dist/dashboard/index.d.ts +3 -3
  34. package/dist/dashboard/index.js +4 -4
  35. package/dist/export/index.d.cts +1 -1
  36. package/dist/export/index.d.ts +1 -1
  37. package/dist/{index-C-Qcuu4Y.d.cts → index-CvKj3SWO.d.cts} +2 -2
  38. package/dist/{index-rPc7ijt8.d.ts → index-DXGLs1yY.d.ts} +2 -2
  39. package/dist/index.cjs +127 -127
  40. package/dist/index.cjs.map +1 -1
  41. package/dist/index.d.cts +30 -9
  42. package/dist/index.d.ts +30 -9
  43. package/dist/index.js +6 -6
  44. package/dist/index.js.map +1 -1
  45. package/dist/{types-WrCbOeAV.d.cts → types-j0kPJ9Hz.d.cts} +16 -1
  46. package/dist/{types-WrCbOeAV.d.ts → types-j0kPJ9Hz.d.ts} +16 -1
  47. package/dist/utils/index.cjs +15 -15
  48. package/dist/utils/index.d.cts +5 -21
  49. package/dist/utils/index.d.ts +5 -21
  50. package/dist/utils/index.js +1 -1
  51. package/package.json +2 -2
  52. package/dist/chunk-4AVL6GQK.cjs.map +0 -1
  53. package/dist/chunk-EX74SI67.js.map +0 -1
  54. package/dist/chunk-FEABEF3J.cjs.map +0 -1
  55. package/dist/chunk-MOAEEF5P.js.map +0 -1
  56. package/dist/chunk-NY6TZLST.cjs.map +0 -1
  57. package/dist/chunk-UPYINBZU.js.map +0 -1
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
- var chunkNK7HKX2J_cjs = require('./chunk-NK7HKX2J.cjs');
4
- var chunkNY6TZLST_cjs = require('./chunk-NY6TZLST.cjs');
3
+ var chunk73TPDGXB_cjs = require('./chunk-73TPDGXB.cjs');
4
+ var chunkURJH4H6G_cjs = require('./chunk-URJH4H6G.cjs');
5
5
  var chunkLMTG3LRC_cjs = require('./chunk-LMTG3LRC.cjs');
6
- var chunk4AVL6GQK_cjs = require('./chunk-4AVL6GQK.cjs');
6
+ var chunkKXB2IZI2_cjs = require('./chunk-KXB2IZI2.cjs');
7
7
  var react = require('react');
8
8
  var jsxRuntime = require('react/jsx-runtime');
9
9
  var legacy = require('react-grid-layout/legacy');
@@ -151,8 +151,8 @@ function DashboardProvider({
151
151
  lazyLoading = DEFAULT_LAZY_LOADING,
152
152
  children
153
153
  }) {
154
- const { client } = chunkNY6TZLST_cjs.useAnalytics();
155
- const crossFilterContext = chunkNY6TZLST_cjs.useCrossFilterOptional();
154
+ const { client } = chunkURJH4H6G_cjs.useAnalytics();
155
+ const crossFilterContext = chunkURJH4H6G_cjs.useCrossFilterOptional();
156
156
  const lazyLoadingEnabled = lazyLoading.enabled ?? true;
157
157
  const lazyLoadingEnabledRef = react.useRef(lazyLoadingEnabled);
158
158
  lazyLoadingEnabledRef.current = lazyLoadingEnabled;
@@ -171,6 +171,7 @@ function DashboardProvider({
171
171
  const clientRef = react.useRef(client);
172
172
  clientRef.current = client;
173
173
  const loadedDashboardRef = react.useRef(null);
174
+ const abortControllerRef = react.useRef(null);
174
175
  const setDashboardData = react.useCallback((data) => {
175
176
  setDashboard(data);
176
177
  const defaults = data.filters.filter((f) => f.default_value !== void 0).map((f) => ({
@@ -189,7 +190,7 @@ function DashboardProvider({
189
190
  }
190
191
  }, []);
191
192
  const executeWidgetQuery = react.useCallback(
192
- async (widget, currentDashboard, currentFilters, currentCrossFilters, bypassCache = false) => {
193
+ async (widget, currentDashboard, currentFilters, currentCrossFilters, bypassCache = false, signal) => {
193
194
  if (!widget.query) {
194
195
  return;
195
196
  }
@@ -209,16 +210,21 @@ function DashboardProvider({
209
210
  currentFilters
210
211
  );
211
212
  query = applyCrossFiltersToQuery(query, currentCrossFilters, widget.id);
212
- const result = await client.executeQuery(query, bypassCache);
213
+ const result = await client.executeQuery(query, bypassCache, signal);
214
+ if (signal?.aborted) return;
213
215
  setWidgetResults((prev) => ({ ...prev, [widget.id]: result }));
214
216
  const refreshTime = result.cached_at ?? Date.now() / 1e3;
215
217
  setWidgetRefreshTimes((prev) => ({ ...prev, [widget.id]: refreshTime }));
216
218
  } catch (err) {
219
+ if (err instanceof Error && err.name === "AbortError") {
220
+ return;
221
+ }
217
222
  setWidgetErrors((prev) => ({
218
223
  ...prev,
219
224
  [widget.id]: err instanceof Error ? err : new Error("Query failed")
220
225
  }));
221
226
  } finally {
227
+ if (signal?.aborted) return;
222
228
  setWidgetLoading((prev) => ({ ...prev, [widget.id]: false }));
223
229
  if (bypassCache) {
224
230
  setRefreshingWidgets((prev) => {
@@ -232,9 +238,10 @@ function DashboardProvider({
232
238
  [client]
233
239
  );
234
240
  const executeWidgetsInBatches = react.useCallback(
235
- async (widgets, currentDashboard, currentFilters, currentCrossFilters, bypassCache = false, currentBatchSize = batchSize) => {
241
+ async (widgets, currentDashboard, currentFilters, currentCrossFilters, bypassCache = false, currentBatchSize = batchSize, signal) => {
236
242
  const widgetsWithQueries = widgets.filter((w) => w.query !== null);
237
243
  for (let i = 0; i < widgetsWithQueries.length; i += currentBatchSize) {
244
+ if (signal?.aborted) return;
238
245
  const batch = widgetsWithQueries.slice(i, i + currentBatchSize);
239
246
  await Promise.all(
240
247
  batch.map(
@@ -243,7 +250,8 @@ function DashboardProvider({
243
250
  currentDashboard,
244
251
  currentFilters,
245
252
  currentCrossFilters,
246
- bypassCache
253
+ bypassCache,
254
+ signal
247
255
  )
248
256
  )
249
257
  );
@@ -255,16 +263,19 @@ function DashboardProvider({
255
263
  async (currentDashboard, currentFilters, currentCrossFilters) => {
256
264
  const requestId = Math.random().toString(36).substring(2, 11);
257
265
  requestIdRef.current = requestId;
266
+ const signal = abortControllerRef.current?.signal;
258
267
  await executeWidgetsInBatches(
259
268
  currentDashboard.widgets,
260
269
  currentDashboard,
261
270
  currentFilters,
262
271
  currentCrossFilters,
263
- false
272
+ false,
264
273
  // Don't bypass cache on initial load
274
+ batchSize,
275
+ signal
265
276
  );
266
277
  },
267
- [executeWidgetsInBatches]
278
+ [executeWidgetsInBatches, batchSize]
268
279
  );
269
280
  const refreshDashboard = react.useCallback(async () => {
270
281
  if (!dashboard) return;
@@ -430,13 +441,16 @@ function DashboardProvider({
430
441
  (w) => visibleWidgets.has(w.id) && w.query !== null && !widgetResults[w.id] && !widgetLoading[w.id]
431
442
  );
432
443
  if (widgetsToLoad.length > 0) {
444
+ const signal = abortControllerRef.current?.signal;
433
445
  executeWidgetsInBatches(
434
446
  widgetsToLoad,
435
447
  dashboard,
436
448
  filterValues,
437
449
  crossFilters,
438
- false
450
+ false,
439
451
  // Don't bypass cache
452
+ batchSize,
453
+ signal
440
454
  );
441
455
  }
442
456
  }, [
@@ -448,7 +462,8 @@ function DashboardProvider({
448
462
  widgetLoading,
449
463
  filterValues,
450
464
  crossFilters,
451
- executeWidgetsInBatches
465
+ executeWidgetsInBatches,
466
+ batchSize
452
467
  ]);
453
468
  const filterValuesKey = JSON.stringify(filterValues);
454
469
  const prevFilterValuesRef = react.useRef(filterValuesKey);
@@ -461,12 +476,17 @@ function DashboardProvider({
461
476
  // Only re-execute if previously loaded
462
477
  );
463
478
  if (widgetsToRefresh.length > 0) {
479
+ abortControllerRef.current?.abort();
480
+ const controller = new AbortController();
481
+ abortControllerRef.current = controller;
464
482
  executeWidgetsInBatches(
465
483
  widgetsToRefresh,
466
484
  dashboard,
467
485
  filterValues,
468
486
  crossFilters,
469
- false
487
+ false,
488
+ batchSize,
489
+ controller.signal
470
490
  );
471
491
  }
472
492
  }, [
@@ -478,8 +498,16 @@ function DashboardProvider({
478
498
  widgetResults,
479
499
  filterValues,
480
500
  crossFilters,
481
- executeWidgetsInBatches
501
+ executeWidgetsInBatches,
502
+ batchSize
482
503
  ]);
504
+ react.useEffect(() => {
505
+ const controller = new AbortController();
506
+ abortControllerRef.current = controller;
507
+ return () => {
508
+ controller.abort();
509
+ };
510
+ }, [dashboardId]);
483
511
  const contextValue = react.useMemo(
484
512
  () => ({
485
513
  dashboard,
@@ -1026,7 +1054,7 @@ function EditableDashboardLayout({
1026
1054
  className = ""
1027
1055
  }) {
1028
1056
  const { theme } = chunkLMTG3LRC_cjs.useTheme();
1029
- const { queueUpdate, status, error } = chunkNY6TZLST_cjs.useDebouncedLayoutSave({
1057
+ const { queueUpdate, status, error } = chunkURJH4H6G_cjs.useDebouncedLayoutSave({
1030
1058
  dashboardId,
1031
1059
  debounceMs,
1032
1060
  savedDurationMs,
@@ -1074,7 +1102,7 @@ function EditableDashboardLayout({
1074
1102
  style: containerStyles2,
1075
1103
  "data-testid": "dashboard-container",
1076
1104
  children: [
1077
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: statusBarStyles, children: /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.AutoSaveIndicator, { status, error }) }),
1105
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: statusBarStyles, children: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.AutoSaveIndicator, { status, error }) }),
1078
1106
  /* @__PURE__ */ jsxRuntime.jsx(
1079
1107
  DashboardLayout,
1080
1108
  {
@@ -1151,7 +1179,7 @@ function WidgetHeader({
1151
1179
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerStyle, className: "prismiq-widget-header", children: [
1152
1180
  /* @__PURE__ */ jsxRuntime.jsx("h3", { style: titleStyle, children: title }),
1153
1181
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: actionsStyle, children: [
1154
- lastRefreshed !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { style: timestampStyle, title: `Last refreshed: ${new Date(lastRefreshed * 1e3).toLocaleString()}`, children: chunk4AVL6GQK_cjs.formatRelativeTime(lastRefreshed) }),
1182
+ lastRefreshed !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { style: timestampStyle, title: `Last refreshed: ${new Date(lastRefreshed * 1e3).toLocaleString()}`, children: chunkKXB2IZI2_cjs.formatRelativeTime(lastRefreshed) }),
1155
1183
  onRefresh && /* @__PURE__ */ jsxRuntime.jsx(
1156
1184
  "button",
1157
1185
  {
@@ -1162,7 +1190,7 @@ function WidgetHeader({
1162
1190
  "aria-label": isRefreshing ? "Refreshing..." : "Refresh widget",
1163
1191
  title: isRefreshing ? "Refreshing..." : "Refresh widget",
1164
1192
  children: /* @__PURE__ */ jsxRuntime.jsx(
1165
- chunkNY6TZLST_cjs.Icon,
1193
+ chunkURJH4H6G_cjs.Icon,
1166
1194
  {
1167
1195
  name: "sync",
1168
1196
  size: 16,
@@ -1181,7 +1209,7 @@ function WidgetHeader({
1181
1209
  style: actionButtonStyle,
1182
1210
  className: "prismiq-widget-action-button",
1183
1211
  "aria-label": hyperlink.title ?? "Open link",
1184
- children: /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "link", size: 16 })
1212
+ children: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "link", size: 16 })
1185
1213
  }
1186
1214
  )
1187
1215
  ] }),
@@ -1249,7 +1277,7 @@ function TextContent({ config }) {
1249
1277
  "div",
1250
1278
  {
1251
1279
  style: contentStyle,
1252
- dangerouslySetInnerHTML: { __html: chunk4AVL6GQK_cjs.parseMarkdownSafe(config.content, codeStyle) }
1280
+ dangerouslySetInnerHTML: { __html: chunkKXB2IZI2_cjs.parseMarkdownSafe(config.content, codeStyle) }
1253
1281
  }
1254
1282
  );
1255
1283
  }
@@ -1376,7 +1404,7 @@ function WidgetContent({
1376
1404
  isRefreshing = false
1377
1405
  }) {
1378
1406
  const { theme } = chunkLMTG3LRC_cjs.useTheme();
1379
- const crossFilterContext = chunkNY6TZLST_cjs.useCrossFilterOptional();
1407
+ const crossFilterContext = chunkURJH4H6G_cjs.useCrossFilterOptional();
1380
1408
  const data = react.useMemo(() => result ? resultToDataPoints(result) : [], [result]);
1381
1409
  const chartTypesWithCrossFilter = ["bar_chart", "pie_chart", "line_chart", "area_chart"];
1382
1410
  const defaultCrossFilterEnabled = chartTypesWithCrossFilter.includes(widget.type);
@@ -1415,7 +1443,7 @@ function WidgetContent({
1415
1443
  );
1416
1444
  const dateFormatters = react.useMemo(() => {
1417
1445
  if (widget.type === "table" && widget.config.dateFormats) {
1418
- return chunk4AVL6GQK_cjs.createDateFormatters(widget.config.dateFormats);
1446
+ return chunkKXB2IZI2_cjs.createDateFormatters(widget.config.dateFormats);
1419
1447
  }
1420
1448
  return void 0;
1421
1449
  }, [widget.type, widget.config.dateFormats]);
@@ -1452,6 +1480,9 @@ function WidgetContent({
1452
1480
  if (widget.type === "text") {
1453
1481
  return /* @__PURE__ */ jsxRuntime.jsx("div", { style: containerStyle, children: /* @__PURE__ */ jsxRuntime.jsx(TextContent, { config: widget.config }) });
1454
1482
  }
1483
+ if (!result && !error && widget.query) {
1484
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: containerStyle, children: /* @__PURE__ */ jsxRuntime.jsx(LoadingState, {}) });
1485
+ }
1455
1486
  if (!result || result.row_count === 0) {
1456
1487
  return /* @__PURE__ */ jsxRuntime.jsx("div", { style: containerStyle, children: /* @__PURE__ */ jsxRuntime.jsx(EmptyState2, {}) });
1457
1488
  }
@@ -1467,7 +1498,7 @@ function WidgetContent({
1467
1498
  const comparisonValue = widget.config.trend_comparison ? result.rows[0]?.[result.columns.indexOf(widget.config.trend_comparison)] : void 0;
1468
1499
  return wrapWithContainer(
1469
1500
  /* @__PURE__ */ jsxRuntime.jsx(
1470
- chunkNK7HKX2J_cjs.MetricCard,
1501
+ chunk73TPDGXB_cjs.MetricCard,
1471
1502
  {
1472
1503
  title: "",
1473
1504
  value: typeof value === "number" ? value : Number(value) || 0,
@@ -1487,7 +1518,7 @@ function WidgetContent({
1487
1518
  case "bar_chart":
1488
1519
  return wrapWithContainer(
1489
1520
  /* @__PURE__ */ jsxRuntime.jsx(
1490
- chunkNK7HKX2J_cjs.BarChart,
1521
+ chunk73TPDGXB_cjs.BarChart,
1491
1522
  {
1492
1523
  data,
1493
1524
  xAxis,
@@ -1513,7 +1544,7 @@ function WidgetContent({
1513
1544
  case "line_chart":
1514
1545
  return wrapWithContainer(
1515
1546
  /* @__PURE__ */ jsxRuntime.jsx(
1516
- chunkNK7HKX2J_cjs.LineChart,
1547
+ chunk73TPDGXB_cjs.LineChart,
1517
1548
  {
1518
1549
  data,
1519
1550
  xAxis,
@@ -1535,7 +1566,7 @@ function WidgetContent({
1535
1566
  case "area_chart":
1536
1567
  return wrapWithContainer(
1537
1568
  /* @__PURE__ */ jsxRuntime.jsx(
1538
- chunkNK7HKX2J_cjs.AreaChart,
1569
+ chunk73TPDGXB_cjs.AreaChart,
1539
1570
  {
1540
1571
  data,
1541
1572
  xAxis,
@@ -1554,7 +1585,7 @@ function WidgetContent({
1554
1585
  case "pie_chart":
1555
1586
  return wrapWithContainer(
1556
1587
  /* @__PURE__ */ jsxRuntime.jsx(
1557
- chunkNK7HKX2J_cjs.PieChart,
1588
+ chunk73TPDGXB_cjs.PieChart,
1558
1589
  {
1559
1590
  data,
1560
1591
  labelColumn: xAxis,
@@ -1573,7 +1604,7 @@ function WidgetContent({
1573
1604
  case "scatter_chart":
1574
1605
  return wrapWithContainer(
1575
1606
  /* @__PURE__ */ jsxRuntime.jsx(
1576
- chunkNK7HKX2J_cjs.ScatterChart,
1607
+ chunk73TPDGXB_cjs.ScatterChart,
1577
1608
  {
1578
1609
  data,
1579
1610
  xAxis,
@@ -1588,10 +1619,22 @@ function WidgetContent({
1588
1619
  const dimensionColumns = result.columns.filter(
1589
1620
  (col) => col !== widget.config.pivot_column && col !== widget.config.value_column
1590
1621
  );
1591
- tableResult = chunk4AVL6GQK_cjs.pivotQueryResult(result, {
1622
+ let pivotColumnFormat;
1623
+ if (widget.config.dateFormats?.[widget.config.pivot_column]) {
1624
+ pivotColumnFormat = widget.config.dateFormats[widget.config.pivot_column];
1625
+ } else if (widget.query) {
1626
+ const pivotCol = widget.query.columns.find(
1627
+ (c) => c.alias === widget.config.pivot_column || c.column === widget.config.pivot_column
1628
+ );
1629
+ if (pivotCol?.date_format) {
1630
+ pivotColumnFormat = pivotCol.date_format;
1631
+ }
1632
+ }
1633
+ tableResult = chunkKXB2IZI2_cjs.pivotQueryResult(result, {
1592
1634
  pivotColumn: widget.config.pivot_column,
1593
1635
  valueColumn: widget.config.value_column,
1594
- dimensionColumns
1636
+ dimensionColumns,
1637
+ pivotColumnFormat
1595
1638
  });
1596
1639
  }
1597
1640
  const tableContainerStyle = {
@@ -1603,7 +1646,7 @@ function WidgetContent({
1603
1646
  position: "relative"
1604
1647
  };
1605
1648
  const tableContent = /* @__PURE__ */ jsxRuntime.jsx(
1606
- chunkNY6TZLST_cjs.ResultsTable,
1649
+ chunkURJH4H6G_cjs.ResultsTable,
1607
1650
  {
1608
1651
  result: tableResult,
1609
1652
  pageSize: widget.config.page_size ?? 10,
@@ -1742,7 +1785,7 @@ function WidgetContainer({
1742
1785
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: contentStyles, children }),
1743
1786
  editable && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: overlayStyles, children: [
1744
1787
  onDuplicate && /* @__PURE__ */ jsxRuntime.jsx(
1745
- chunkNY6TZLST_cjs.Button,
1788
+ chunkURJH4H6G_cjs.Button,
1746
1789
  {
1747
1790
  size: "sm",
1748
1791
  variant: "secondary",
@@ -1752,11 +1795,11 @@ function WidgetContainer({
1752
1795
  },
1753
1796
  title: "Duplicate",
1754
1797
  "data-testid": "duplicate-widget-button",
1755
- children: /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "copy", size: 14 })
1798
+ children: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "copy", size: 14 })
1756
1799
  }
1757
1800
  ),
1758
1801
  onEdit && /* @__PURE__ */ jsxRuntime.jsx(
1759
- chunkNY6TZLST_cjs.Button,
1802
+ chunkURJH4H6G_cjs.Button,
1760
1803
  {
1761
1804
  size: "sm",
1762
1805
  variant: "secondary",
@@ -1766,11 +1809,11 @@ function WidgetContainer({
1766
1809
  },
1767
1810
  title: "Edit",
1768
1811
  "data-testid": "edit-widget-button",
1769
- children: /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "edit", size: 14 })
1812
+ children: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "edit", size: 14 })
1770
1813
  }
1771
1814
  ),
1772
1815
  onDelete && /* @__PURE__ */ jsxRuntime.jsx(
1773
- chunkNY6TZLST_cjs.Button,
1816
+ chunkURJH4H6G_cjs.Button,
1774
1817
  {
1775
1818
  size: "sm",
1776
1819
  variant: "danger",
@@ -1780,7 +1823,7 @@ function WidgetContainer({
1780
1823
  },
1781
1824
  title: "Delete",
1782
1825
  "data-testid": "delete-widget-button",
1783
- children: /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "trash", size: 14 })
1826
+ children: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "trash", size: 14 })
1784
1827
  }
1785
1828
  )
1786
1829
  ] }),
@@ -1958,7 +2001,7 @@ function DateRangeFilter({
1958
2001
  ] });
1959
2002
  }
1960
2003
  function useDynamicFilterOptions(filter, limit = 100) {
1961
- const { client } = chunkNY6TZLST_cjs.useAnalytics();
2004
+ const { client } = chunkURJH4H6G_cjs.useAnalytics();
1962
2005
  const [isLoading, setIsLoading] = react.useState(false);
1963
2006
  const [options, setOptions] = react.useState([]);
1964
2007
  const [error, setError] = react.useState(null);
@@ -2255,7 +2298,7 @@ function MultiSelectFilter({
2255
2298
  disabled: isLoading,
2256
2299
  children: [
2257
2300
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: displayText }),
2258
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: isOpen ? "chevron-up" : "chevron-down", size: 14 })
2301
+ /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: isOpen ? "chevron-up" : "chevron-down", size: 14 })
2259
2302
  ]
2260
2303
  }
2261
2304
  ),
@@ -2304,7 +2347,7 @@ function MultiSelectFilter({
2304
2347
  backgroundColor: isAllSelected ? theme.colors.primary : theme.colors.background,
2305
2348
  borderColor: isAllSelected ? theme.colors.primary : theme.colors.border
2306
2349
  },
2307
- children: isAllSelected && /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "check", size: 12, style: { color: "#fff" } })
2350
+ children: isAllSelected && /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "check", size: 12, style: { color: "#fff" } })
2308
2351
  }
2309
2352
  ),
2310
2353
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "All" })
@@ -2330,7 +2373,7 @@ function MultiSelectFilter({
2330
2373
  backgroundColor: isSelected ? theme.colors.primary : theme.colors.background,
2331
2374
  borderColor: isSelected ? theme.colors.primary : theme.colors.border
2332
2375
  },
2333
- children: isSelected && /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "check", size: 12, style: { color: "#fff" } })
2376
+ children: isSelected && /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "check", size: 12, style: { color: "#fff" } })
2334
2377
  }
2335
2378
  ),
2336
2379
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: option.label })
@@ -2425,7 +2468,7 @@ function TextFilter({
2425
2468
  justifyContent: "center"
2426
2469
  };
2427
2470
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: containerStyle, children: [
2428
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "search", size: 14, style: iconStyle }),
2471
+ /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "search", size: 14, style: iconStyle }),
2429
2472
  /* @__PURE__ */ jsxRuntime.jsx(
2430
2473
  "input",
2431
2474
  {
@@ -2444,7 +2487,7 @@ function TextFilter({
2444
2487
  onClick: handleClear,
2445
2488
  style: clearButtonStyle,
2446
2489
  "aria-label": "Clear filter",
2447
- children: /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "x", size: 14 })
2490
+ children: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "x", size: 14 })
2448
2491
  }
2449
2492
  )
2450
2493
  ] });
@@ -2498,7 +2541,7 @@ function FilterBar({
2498
2541
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: filter.label }),
2499
2542
  renderFilter(filter, values, onChange)
2500
2543
  ] }, filter.id)),
2501
- onReset && /* @__PURE__ */ jsxRuntime.jsx("div", { style: actionsStyle, children: /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Button, { variant: "ghost", size: "sm", onClick: handleReset, children: "Reset" }) })
2544
+ onReset && /* @__PURE__ */ jsxRuntime.jsx("div", { style: actionsStyle, children: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Button, { variant: "ghost", size: "sm", onClick: handleReset, children: "Reset" }) })
2502
2545
  ] });
2503
2546
  }
2504
2547
  function renderFilter(filter, values, onChange) {
@@ -2572,7 +2615,7 @@ function DashboardContent({
2572
2615
  refreshWidget
2573
2616
  } = useDashboard();
2574
2617
  const { filters, values, setValue, resetAll } = useDashboardFilters();
2575
- const crossFilterContext = chunkNY6TZLST_cjs.useCrossFilterOptional();
2618
+ const crossFilterContext = chunkURJH4H6G_cjs.useCrossFilterOptional();
2576
2619
  const renderWidget = react.useCallback(
2577
2620
  (widget) => /* @__PURE__ */ jsxRuntime.jsx(
2578
2621
  LazyWidget,
@@ -2715,7 +2758,7 @@ function DashboardContent({
2715
2758
  ] }, filter.sourceWidgetId)),
2716
2759
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: 1 } }),
2717
2760
  /* @__PURE__ */ jsxRuntime.jsx(
2718
- chunkNY6TZLST_cjs.Button,
2761
+ chunkURJH4H6G_cjs.Button,
2719
2762
  {
2720
2763
  variant: "ghost",
2721
2764
  size: "sm",
@@ -2744,7 +2787,7 @@ function Dashboard({
2744
2787
  lazyLoading,
2745
2788
  className = ""
2746
2789
  }) {
2747
- return /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.CrossFilterProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(
2790
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.CrossFilterProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(
2748
2791
  DashboardProvider,
2749
2792
  {
2750
2793
  dashboardId: id,
@@ -2852,37 +2895,37 @@ function EditorToolbar({
2852
2895
  ) : /* @__PURE__ */ jsxRuntime.jsx("h2", { style: titleStyle, children: dashboardName || "New Dashboard" }),
2853
2896
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: actionsStyle, children: [
2854
2897
  /* @__PURE__ */ jsxRuntime.jsxs(
2855
- chunkNY6TZLST_cjs.Button,
2898
+ chunkURJH4H6G_cjs.Button,
2856
2899
  {
2857
2900
  variant: "secondary",
2858
2901
  size: "sm",
2859
2902
  onClick: onAddWidget,
2860
2903
  children: [
2861
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "plus", size: 16 }),
2904
+ /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "plus", size: 16 }),
2862
2905
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { marginLeft: theme.spacing.xs }, children: "Add Widget" })
2863
2906
  ]
2864
2907
  }
2865
2908
  ),
2866
2909
  onEditFilters && /* @__PURE__ */ jsxRuntime.jsxs(
2867
- chunkNY6TZLST_cjs.Button,
2910
+ chunkURJH4H6G_cjs.Button,
2868
2911
  {
2869
2912
  variant: "ghost",
2870
2913
  size: "sm",
2871
2914
  onClick: onEditFilters,
2872
2915
  children: [
2873
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "filter", size: 16 }),
2916
+ /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "filter", size: 16 }),
2874
2917
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { marginLeft: theme.spacing.xs }, children: "Filters" })
2875
2918
  ]
2876
2919
  }
2877
2920
  ),
2878
2921
  onSettings && /* @__PURE__ */ jsxRuntime.jsxs(
2879
- chunkNY6TZLST_cjs.Button,
2922
+ chunkURJH4H6G_cjs.Button,
2880
2923
  {
2881
2924
  variant: "ghost",
2882
2925
  size: "sm",
2883
2926
  onClick: onSettings,
2884
2927
  children: [
2885
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "settings", size: 16 }),
2928
+ /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "settings", size: 16 }),
2886
2929
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { marginLeft: theme.spacing.xs }, children: "Settings" })
2887
2930
  ]
2888
2931
  }
@@ -2892,7 +2935,7 @@ function EditorToolbar({
2892
2935
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: rightSectionStyle, children: [
2893
2936
  hasChanges && /* @__PURE__ */ jsxRuntime.jsx("span", { style: unsavedStyle, children: "Unsaved changes" }),
2894
2937
  /* @__PURE__ */ jsxRuntime.jsx(
2895
- chunkNY6TZLST_cjs.Button,
2938
+ chunkURJH4H6G_cjs.Button,
2896
2939
  {
2897
2940
  variant: "ghost",
2898
2941
  size: "sm",
@@ -2902,7 +2945,7 @@ function EditorToolbar({
2902
2945
  }
2903
2946
  ),
2904
2947
  /* @__PURE__ */ jsxRuntime.jsx(
2905
- chunkNY6TZLST_cjs.Button,
2948
+ chunkURJH4H6G_cjs.Button,
2906
2949
  {
2907
2950
  variant: "primary",
2908
2951
  size: "sm",
@@ -2997,7 +3040,9 @@ function WidgetTypeSelector({
2997
3040
  borderRadius: theme.radius.sm,
2998
3041
  border: `2px solid ${isSelected ? theme.colors.primary : theme.colors.border}`,
2999
3042
  cursor: "pointer",
3000
- transition: "all 0.15s ease"
3043
+ transition: "all 0.15s ease",
3044
+ minWidth: 0
3045
+ // Allow grid item to shrink below content width
3001
3046
  });
3002
3047
  const iconStyle = (isSelected) => ({
3003
3048
  width: "28px",
@@ -3024,9 +3069,7 @@ function WidgetTypeSelector({
3024
3069
  const descStyle = {
3025
3070
  fontSize: theme.fontSizes.xs,
3026
3071
  color: theme.colors.textMuted,
3027
- whiteSpace: "nowrap",
3028
- overflow: "hidden",
3029
- textOverflow: "ellipsis"
3072
+ whiteSpace: "nowrap"
3030
3073
  };
3031
3074
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `prismiq-widget-type-selector ${className}`, style: containerStyle, children: [
3032
3075
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Widget Type" }),
@@ -3049,7 +3092,7 @@ function WidgetTypeSelector({
3049
3092
  }
3050
3093
  },
3051
3094
  children: [
3052
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: iconStyle(isSelected), children: /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: widgetType.icon, size: 16 }) }),
3095
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: iconStyle(isSelected), children: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: widgetType.icon, size: 16 }) }),
3053
3096
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: textContainerStyle, children: [
3054
3097
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: nameLabelStyle, children: widgetType.label }),
3055
3098
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: descStyle, children: widgetType.description })
@@ -3193,19 +3236,26 @@ function MetricConfig({
3193
3236
  onChange
3194
3237
  }) {
3195
3238
  const { theme } = chunkLMTG3LRC_cjs.useTheme();
3239
+ const { getDisplayName } = chunkURJH4H6G_cjs.useSchema();
3196
3240
  const initialTable = query?.tables[0]?.name ?? "";
3197
3241
  const initialAggregation = query?.columns[0]?.aggregation ?? "count";
3198
- const initialColumn = query?.columns[0]?.column ?? "*";
3242
+ const rawInitialColumn = query?.columns[0]?.column ?? "*";
3243
+ const needsColumnForInitial = AGGREGATIONS.find((a) => a.value === initialAggregation)?.needsColumn ?? false;
3244
+ const initialColumn = rawInitialColumn === "*" && needsColumnForInitial ? "" : rawInitialColumn;
3245
+ const initialFilters = (query?.filters ?? []).map((f) => ({
3246
+ ...f,
3247
+ table_id: "t1"
3248
+ }));
3199
3249
  const [selectedTable, setSelectedTable] = react.useState(initialTable);
3200
3250
  const [aggregation, setAggregation] = react.useState(initialAggregation);
3201
3251
  const [selectedColumn, setSelectedColumn] = react.useState(initialColumn);
3202
- const [filters, setFilters] = react.useState(query?.filters ?? []);
3252
+ const [filters, setFilters] = react.useState(initialFilters);
3203
3253
  const tableOptions = react.useMemo(() => {
3204
3254
  return schema.tables.map((t) => ({
3205
3255
  value: t.name,
3206
- label: t.name
3256
+ label: getDisplayName(t.name)
3207
3257
  }));
3208
- }, [schema.tables]);
3258
+ }, [schema.tables, getDisplayName]);
3209
3259
  const currentTable = react.useMemo(() => {
3210
3260
  return schema.tables.find((t) => t.name === selectedTable);
3211
3261
  }, [schema.tables, selectedTable]);
@@ -3220,8 +3270,12 @@ function MetricConfig({
3220
3270
  const needsColumn = react.useMemo(() => {
3221
3271
  return AGGREGATIONS.find((a) => a.value === aggregation)?.needsColumn ?? false;
3222
3272
  }, [aggregation]);
3273
+ const isValidAggregation = react.useMemo(() => {
3274
+ return AGGREGATIONS.some((a) => a.value === aggregation);
3275
+ }, [aggregation]);
3223
3276
  react.useEffect(() => {
3224
3277
  if (!selectedTable) return;
3278
+ if (!isValidAggregation) return;
3225
3279
  const tableId = "t1";
3226
3280
  const tables = [{ id: tableId, name: selectedTable }];
3227
3281
  const column = needsColumn ? selectedColumn : "*";
@@ -3239,7 +3293,7 @@ function MetricConfig({
3239
3293
  filters: filters.length > 0 ? filters : void 0
3240
3294
  };
3241
3295
  onChange(queryDef);
3242
- }, [selectedTable, aggregation, selectedColumn, needsColumn, filters, onChange]);
3296
+ }, [selectedTable, aggregation, selectedColumn, needsColumn, isValidAggregation, filters, onChange]);
3243
3297
  const handleTableChange = react.useCallback((value) => {
3244
3298
  setSelectedTable(value);
3245
3299
  setSelectedColumn("");
@@ -3268,7 +3322,7 @@ function MetricConfig({
3268
3322
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
3269
3323
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "From Table" }),
3270
3324
  /* @__PURE__ */ jsxRuntime.jsx(
3271
- chunkNY6TZLST_cjs.Select,
3325
+ chunkURJH4H6G_cjs.Select,
3272
3326
  {
3273
3327
  value: selectedTable,
3274
3328
  onChange: handleTableChange,
@@ -3279,7 +3333,7 @@ function MetricConfig({
3279
3333
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
3280
3334
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Metric" }),
3281
3335
  /* @__PURE__ */ jsxRuntime.jsx(
3282
- chunkNY6TZLST_cjs.Select,
3336
+ chunkURJH4H6G_cjs.Select,
3283
3337
  {
3284
3338
  value: aggregation,
3285
3339
  onChange: (value) => setAggregation(value),
@@ -3294,7 +3348,7 @@ function MetricConfig({
3294
3348
  needsColumn && selectedTable && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
3295
3349
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Column" }),
3296
3350
  columnOptions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
3297
- chunkNY6TZLST_cjs.Select,
3351
+ chunkURJH4H6G_cjs.Select,
3298
3352
  {
3299
3353
  value: selectedColumn,
3300
3354
  onChange: setSelectedColumn,
@@ -3305,7 +3359,7 @@ function MetricConfig({
3305
3359
  selectedTable && currentTable && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
3306
3360
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Filters (optional)" }),
3307
3361
  /* @__PURE__ */ jsxRuntime.jsx(
3308
- chunkNY6TZLST_cjs.FilterBuilder,
3362
+ chunkURJH4H6G_cjs.FilterBuilder,
3309
3363
  {
3310
3364
  tables: [{ id: "t1", name: selectedTable }],
3311
3365
  filters,
@@ -3364,17 +3418,23 @@ function ChartConfig({
3364
3418
  onChange
3365
3419
  }) {
3366
3420
  const { theme } = chunkLMTG3LRC_cjs.useTheme();
3421
+ const { getDisplayName } = chunkURJH4H6G_cjs.useSchema();
3367
3422
  const initialTables = query?.tables ?? [];
3368
3423
  const groupByCol = query?.columns.find((c) => c.aggregation === "none");
3369
3424
  const initialGroupBy = groupByCol?.column ?? query?.group_by?.[0]?.column ?? "";
3370
3425
  const initialGroupByTableId = groupByCol?.table_id ?? query?.tables?.[0]?.id ?? "t1";
3371
3426
  const initialDateTrunc = groupByCol?.date_trunc ?? "";
3372
- const initialMeasures = query?.columns.filter((c) => c.aggregation !== "none").map((c) => ({
3373
- // Store as table-qualified ref so parseColumnRef can resolve it correctly
3374
- column: c.table_id ? `${c.table_id}.${c.column}` : c.column,
3375
- aggregation: c.aggregation,
3376
- table_id: c.table_id
3377
- })) ?? [];
3427
+ const initialMeasures = query?.columns.filter((c) => c.aggregation !== "none").map((c) => {
3428
+ const isStarWithNonCount = (c.column === "*" || c.column.endsWith(".*")) && c.aggregation !== "count";
3429
+ const column = isStarWithNonCount ? "" : c.table_id ? `${c.table_id}.${c.column}` : c.column;
3430
+ return {
3431
+ column,
3432
+ aggregation: c.aggregation,
3433
+ table_id: c.table_id,
3434
+ // Preserve original alias to maintain compatibility with widget config
3435
+ alias: c.alias
3436
+ };
3437
+ }) ?? [];
3378
3438
  const initialJoins = query?.joins ?? [];
3379
3439
  const [tables, setTables] = react.useState(initialTables);
3380
3440
  const [joins, setJoins] = react.useState(initialJoins);
@@ -3395,9 +3455,9 @@ function ChartConfig({
3395
3455
  const tableOptions = react.useMemo(() => {
3396
3456
  return schema.tables.map((t) => ({
3397
3457
  value: t.name,
3398
- label: t.name
3458
+ label: getDisplayName(t.name)
3399
3459
  }));
3400
- }, [schema.tables]);
3460
+ }, [schema.tables, getDisplayName]);
3401
3461
  const currentTable = react.useMemo(() => {
3402
3462
  return schema.tables.find((t) => t.name === selectedTable);
3403
3463
  }, [schema.tables, selectedTable]);
@@ -3467,7 +3527,7 @@ function ChartConfig({
3467
3527
  const parsedMeasures = [];
3468
3528
  const invalidColumns = [];
3469
3529
  validMeasures.forEach((m, i) => {
3470
- const measureAlias = validMeasures.length > 1 ? `value_${i + 1}` : "value";
3530
+ const measureAlias = m.alias ?? (validMeasures.length > 1 ? `value_${i + 1}` : "value");
3471
3531
  if (m.aggregation === "count" && (!m.column || m.column.endsWith(".*") || m.column === "*")) {
3472
3532
  parsedMeasures.push({
3473
3533
  table_id: m.table_id ?? tables[0]?.id ?? "t1",
@@ -3477,7 +3537,7 @@ function ChartConfig({
3477
3537
  });
3478
3538
  return;
3479
3539
  }
3480
- const parsed = chunk4AVL6GQK_cjs.parseColumnRef(m.column, tables[0]?.id ?? "t1");
3540
+ const parsed = chunkKXB2IZI2_cjs.parseColumnRef(m.column, tables[0]?.id ?? "t1");
3481
3541
  if (!parsed) {
3482
3542
  invalidColumns.push(m.column);
3483
3543
  return;
@@ -3531,6 +3591,9 @@ function ChartConfig({
3531
3591
  setJoins(
3532
3592
  (prev) => prev.filter((j) => tableIds.has(j.from_table_id) && tableIds.has(j.to_table_id))
3533
3593
  );
3594
+ setFilters(
3595
+ (prev) => prev.filter((f) => tableIds.has(f.table_id))
3596
+ );
3534
3597
  if (!tableIds.has(groupByTableId)) {
3535
3598
  setGroupByColumn("");
3536
3599
  setGroupByTableId(newTables[0]?.id ?? "t1");
@@ -3542,7 +3605,7 @@ function ChartConfig({
3542
3605
  setDateTrunc("");
3543
3606
  return;
3544
3607
  }
3545
- const parsed = chunk4AVL6GQK_cjs.parseColumnRef(value, groupByTableId);
3608
+ const parsed = chunkKXB2IZI2_cjs.parseColumnRef(value, groupByTableId);
3546
3609
  if (parsed) {
3547
3610
  setGroupByTableId(parsed.tableId);
3548
3611
  setGroupByColumn(parsed.column);
@@ -3601,7 +3664,7 @@ function ChartConfig({
3601
3664
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
3602
3665
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "From Table" }),
3603
3666
  /* @__PURE__ */ jsxRuntime.jsx(
3604
- chunkNY6TZLST_cjs.Select,
3667
+ chunkURJH4H6G_cjs.Select,
3605
3668
  {
3606
3669
  value: selectedTable,
3607
3670
  onChange: handleTableChange,
@@ -3609,9 +3672,9 @@ function ChartConfig({
3609
3672
  }
3610
3673
  )
3611
3674
  ] }),
3612
- selectedTable && /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.CollapsibleSection, { title: "Join Tables", defaultOpen: tables.length > 1, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: theme.spacing.md }, children: [
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: [
3613
3676
  /* @__PURE__ */ jsxRuntime.jsx(
3614
- chunkNY6TZLST_cjs.TableSelector,
3677
+ chunkURJH4H6G_cjs.TableSelector,
3615
3678
  {
3616
3679
  schema,
3617
3680
  tables,
@@ -3623,7 +3686,7 @@ function ChartConfig({
3623
3686
  tables.length >= 2 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
3624
3687
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Join Conditions" }),
3625
3688
  /* @__PURE__ */ jsxRuntime.jsx(
3626
- chunkNY6TZLST_cjs.JoinBuilder,
3689
+ chunkURJH4H6G_cjs.JoinBuilder,
3627
3690
  {
3628
3691
  schema,
3629
3692
  tables,
@@ -3637,7 +3700,7 @@ function ChartConfig({
3637
3700
  selectedTable && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
3638
3701
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Group By (X-Axis)" }),
3639
3702
  groupByOptions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
3640
- chunkNY6TZLST_cjs.Select,
3703
+ chunkURJH4H6G_cjs.Select,
3641
3704
  {
3642
3705
  value: groupByValue,
3643
3706
  onChange: handleGroupByChange,
@@ -3649,7 +3712,7 @@ function ChartConfig({
3649
3712
  selectedTable && groupByColumn && isGroupByDate && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
3650
3713
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Date Granularity" }),
3651
3714
  /* @__PURE__ */ jsxRuntime.jsx(
3652
- chunkNY6TZLST_cjs.Select,
3715
+ chunkURJH4H6G_cjs.Select,
3653
3716
  {
3654
3717
  value: dateTrunc,
3655
3718
  onChange: (value) => setDateTrunc(value),
@@ -3658,8 +3721,8 @@ function ChartConfig({
3658
3721
  ),
3659
3722
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: helpTextStyle, children: "Truncate dates to this interval" })
3660
3723
  ] }),
3661
- selectedTable && isGroupByDate && /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.CollapsibleSection, { title: "Time Series Options", defaultOpen: timeSeries !== void 0, children: /* @__PURE__ */ jsxRuntime.jsx(
3662
- chunkNY6TZLST_cjs.TimeSeriesConfig,
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,
3663
3726
  {
3664
3727
  schema,
3665
3728
  tables,
@@ -3672,7 +3735,7 @@ function ChartConfig({
3672
3735
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Measures (Y-Axis)" }),
3673
3736
  measures.map((measure, index) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: measureRowStyle, children: [
3674
3737
  /* @__PURE__ */ jsxRuntime.jsx(
3675
- chunkNY6TZLST_cjs.Select,
3738
+ chunkURJH4H6G_cjs.Select,
3676
3739
  {
3677
3740
  value: measure.aggregation,
3678
3741
  onChange: (value) => updateMeasure(index, { aggregation: value }),
@@ -3683,7 +3746,7 @@ function ChartConfig({
3683
3746
  measure.aggregation !== "count" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3684
3747
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: theme.colors.textMuted }, children: "of" }),
3685
3748
  measureColumnOptions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
3686
- chunkNY6TZLST_cjs.Select,
3749
+ chunkURJH4H6G_cjs.Select,
3687
3750
  {
3688
3751
  value: measure.column,
3689
3752
  onChange: (value) => updateMeasure(index, { column: value }),
@@ -3692,17 +3755,17 @@ function ChartConfig({
3692
3755
  }
3693
3756
  ) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...helpTextStyle, flex: 1 }, children: "No numeric columns" })
3694
3757
  ] }),
3695
- measures.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Button, { variant: "ghost", size: "sm", onClick: () => removeMeasure(index), children: /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "x", size: 14 }) })
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 }) })
3696
3759
  ] }, measureIdsRef.current[index])),
3697
3760
  /* @__PURE__ */ jsxRuntime.jsxs(
3698
- chunkNY6TZLST_cjs.Button,
3761
+ chunkURJH4H6G_cjs.Button,
3699
3762
  {
3700
3763
  variant: "ghost",
3701
3764
  size: "sm",
3702
3765
  onClick: addMeasure,
3703
3766
  style: { alignSelf: "flex-start" },
3704
3767
  children: [
3705
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "plus", size: 14 }),
3768
+ /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "plus", size: 14 }),
3706
3769
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { marginLeft: theme.spacing.xs }, children: "Add measure" })
3707
3770
  ]
3708
3771
  }
@@ -3712,7 +3775,7 @@ function ChartConfig({
3712
3775
  selectedTable && currentTable && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
3713
3776
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Filters (optional)" }),
3714
3777
  /* @__PURE__ */ jsxRuntime.jsx(
3715
- chunkNY6TZLST_cjs.FilterBuilder,
3778
+ chunkURJH4H6G_cjs.FilterBuilder,
3716
3779
  {
3717
3780
  tables,
3718
3781
  filters,
@@ -3722,12 +3785,12 @@ function ChartConfig({
3722
3785
  )
3723
3786
  ] }),
3724
3787
  selectedTable && /* @__PURE__ */ jsxRuntime.jsx(
3725
- chunkNY6TZLST_cjs.CollapsibleSection,
3788
+ chunkURJH4H6G_cjs.CollapsibleSection,
3726
3789
  {
3727
3790
  title: "Calculated Fields",
3728
3791
  defaultOpen: calculatedFields.length > 0,
3729
3792
  children: /* @__PURE__ */ jsxRuntime.jsx(
3730
- chunkNY6TZLST_cjs.CalculatedFieldBuilder,
3793
+ chunkURJH4H6G_cjs.CalculatedFieldBuilder,
3731
3794
  {
3732
3795
  fields: calculatedFields,
3733
3796
  onChange: setCalculatedFields,
@@ -3785,25 +3848,31 @@ function PieConfig({
3785
3848
  onChange
3786
3849
  }) {
3787
3850
  const { theme } = chunkLMTG3LRC_cjs.useTheme();
3851
+ const { getDisplayName } = chunkURJH4H6G_cjs.useSchema();
3788
3852
  const initialTable = query?.tables[0]?.name ?? "";
3789
3853
  const labelCol = query?.columns.find((c) => c.aggregation === "none");
3790
3854
  const initialLabel = labelCol?.column ?? "";
3791
3855
  const initialDateTrunc = labelCol?.date_trunc ?? "";
3792
3856
  const measureCol = query?.columns.find((c) => c.aggregation !== "none");
3793
- const initialValueColumn = measureCol?.column ?? "";
3857
+ const rawInitialValueColumn = measureCol?.column ?? "";
3794
3858
  const initialAggregation = measureCol?.aggregation ?? "sum";
3859
+ const initialValueColumn = rawInitialValueColumn === "*" && initialAggregation !== "count" ? "" : rawInitialValueColumn;
3860
+ const initialFilters = (query?.filters ?? []).map((f) => ({
3861
+ ...f,
3862
+ table_id: "t1"
3863
+ }));
3795
3864
  const [selectedTable, setSelectedTable] = react.useState(initialTable);
3796
3865
  const [labelColumn, setLabelColumn] = react.useState(initialLabel);
3797
3866
  const [dateTrunc, setDateTrunc] = react.useState(initialDateTrunc);
3798
3867
  const [valueColumn, setValueColumn] = react.useState(initialValueColumn);
3799
3868
  const [aggregation, setAggregation] = react.useState(initialAggregation);
3800
- const [filters, setFilters] = react.useState(query?.filters ?? []);
3869
+ const [filters, setFilters] = react.useState(initialFilters);
3801
3870
  const tableOptions = react.useMemo(() => {
3802
3871
  return schema.tables.map((t) => ({
3803
3872
  value: t.name,
3804
- label: t.name
3873
+ label: getDisplayName(t.name)
3805
3874
  }));
3806
- }, [schema.tables]);
3875
+ }, [schema.tables, getDisplayName]);
3807
3876
  const currentTable = react.useMemo(() => {
3808
3877
  return schema.tables.find((t) => t.name === selectedTable);
3809
3878
  }, [schema.tables, selectedTable]);
@@ -3828,8 +3897,12 @@ function PieConfig({
3828
3897
  label: `${c.name} (${c.data_type})`
3829
3898
  }));
3830
3899
  }, [currentTable]);
3900
+ const isValidAggregation = react.useMemo(() => {
3901
+ return AGGREGATIONS3.some((a) => a.value === aggregation);
3902
+ }, [aggregation]);
3831
3903
  react.useEffect(() => {
3832
3904
  if (!selectedTable || !labelColumn) return;
3905
+ if (!isValidAggregation) return;
3833
3906
  const needsValueColumn = aggregation !== "count";
3834
3907
  if (needsValueColumn && !valueColumn) return;
3835
3908
  const tableId = "t1";
@@ -3859,7 +3932,7 @@ function PieConfig({
3859
3932
  order_by: [{ table_id: tableId, column: labelColumn, direction: "ASC" }]
3860
3933
  };
3861
3934
  onChange(queryDef);
3862
- }, [selectedTable, labelColumn, dateTrunc, valueColumn, aggregation, filters, onChange]);
3935
+ }, [selectedTable, labelColumn, dateTrunc, valueColumn, aggregation, isValidAggregation, filters, onChange]);
3863
3936
  const handleTableChange = react.useCallback((value) => {
3864
3937
  setSelectedTable(value);
3865
3938
  setLabelColumn("");
@@ -3901,7 +3974,7 @@ function PieConfig({
3901
3974
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
3902
3975
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "From Table" }),
3903
3976
  /* @__PURE__ */ jsxRuntime.jsx(
3904
- chunkNY6TZLST_cjs.Select,
3977
+ chunkURJH4H6G_cjs.Select,
3905
3978
  {
3906
3979
  value: selectedTable,
3907
3980
  onChange: handleTableChange,
@@ -3912,7 +3985,7 @@ function PieConfig({
3912
3985
  selectedTable && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
3913
3986
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Slices (Labels)" }),
3914
3987
  labelOptions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
3915
- chunkNY6TZLST_cjs.Select,
3988
+ chunkURJH4H6G_cjs.Select,
3916
3989
  {
3917
3990
  value: labelColumn,
3918
3991
  onChange: handleLabelChange,
@@ -3924,7 +3997,7 @@ function PieConfig({
3924
3997
  selectedTable && labelColumn && isLabelDate && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
3925
3998
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Date Granularity" }),
3926
3999
  /* @__PURE__ */ jsxRuntime.jsx(
3927
- chunkNY6TZLST_cjs.Select,
4000
+ chunkURJH4H6G_cjs.Select,
3928
4001
  {
3929
4002
  value: dateTrunc,
3930
4003
  onChange: (value) => setDateTrunc(value),
@@ -3937,7 +4010,7 @@ function PieConfig({
3937
4010
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Size (Value)" }),
3938
4011
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: rowStyle, children: [
3939
4012
  /* @__PURE__ */ jsxRuntime.jsx(
3940
- chunkNY6TZLST_cjs.Select,
4013
+ chunkURJH4H6G_cjs.Select,
3941
4014
  {
3942
4015
  value: aggregation,
3943
4016
  onChange: (value) => setAggregation(value),
@@ -3948,7 +4021,7 @@ function PieConfig({
3948
4021
  aggregation !== "count" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3949
4022
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: theme.colors.textMuted }, children: "of" }),
3950
4023
  valueColumnOptions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
3951
- chunkNY6TZLST_cjs.Select,
4024
+ chunkURJH4H6G_cjs.Select,
3952
4025
  {
3953
4026
  value: valueColumn,
3954
4027
  onChange: setValueColumn,
@@ -3963,7 +4036,7 @@ function PieConfig({
3963
4036
  selectedTable && currentTable && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
3964
4037
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Filters (optional)" }),
3965
4038
  /* @__PURE__ */ jsxRuntime.jsx(
3966
- chunkNY6TZLST_cjs.FilterBuilder,
4039
+ chunkURJH4H6G_cjs.FilterBuilder,
3967
4040
  {
3968
4041
  tables: [{ id: "t1", name: selectedTable }],
3969
4042
  filters,
@@ -3980,18 +4053,23 @@ function TableConfig({
3980
4053
  onChange
3981
4054
  }) {
3982
4055
  const { theme } = chunkLMTG3LRC_cjs.useTheme();
4056
+ const { getDisplayName } = chunkURJH4H6G_cjs.useSchema();
3983
4057
  const initialTable = query?.tables[0]?.name ?? "";
3984
4058
  const initialColumns = query?.columns.map((c) => c.column) ?? [];
4059
+ const initialFilters = (query?.filters ?? []).map((f) => ({
4060
+ ...f,
4061
+ table_id: "t1"
4062
+ }));
3985
4063
  const [selectedTable, setSelectedTable] = react.useState(initialTable);
3986
4064
  const [selectedColumns, setSelectedColumns] = react.useState(initialColumns);
3987
- const [filters, setFilters] = react.useState(query?.filters ?? []);
4065
+ const [filters, setFilters] = react.useState(initialFilters);
3988
4066
  const [limit, setLimit] = react.useState(query?.limit ?? 100);
3989
4067
  const tableOptions = react.useMemo(() => {
3990
4068
  return schema.tables.map((t) => ({
3991
4069
  value: t.name,
3992
- label: t.name
4070
+ label: getDisplayName(t.name)
3993
4071
  }));
3994
- }, [schema.tables]);
4072
+ }, [schema.tables, getDisplayName]);
3995
4073
  const currentTable = react.useMemo(() => {
3996
4074
  return schema.tables.find((t) => t.name === selectedTable);
3997
4075
  }, [schema.tables, selectedTable]);
@@ -4081,7 +4159,7 @@ function TableConfig({
4081
4159
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4082
4160
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "From Table" }),
4083
4161
  /* @__PURE__ */ jsxRuntime.jsx(
4084
- chunkNY6TZLST_cjs.Select,
4162
+ chunkURJH4H6G_cjs.Select,
4085
4163
  {
4086
4164
  value: selectedTable,
4087
4165
  onChange: handleTableChange,
@@ -4098,7 +4176,7 @@ function TableConfig({
4098
4176
  ] })
4099
4177
  ] }),
4100
4178
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: columnsContainerStyle, children: currentTable.columns.map((col) => /* @__PURE__ */ jsxRuntime.jsx(
4101
- chunkNY6TZLST_cjs.Checkbox,
4179
+ chunkURJH4H6G_cjs.Checkbox,
4102
4180
  {
4103
4181
  label: `${col.name} (${col.data_type})`,
4104
4182
  checked: selectedColumns.includes(col.name),
@@ -4111,7 +4189,7 @@ function TableConfig({
4111
4189
  selectedTable && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4112
4190
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Maximum Rows" }),
4113
4191
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: rowStyle, children: /* @__PURE__ */ jsxRuntime.jsx(
4114
- chunkNY6TZLST_cjs.Select,
4192
+ chunkURJH4H6G_cjs.Select,
4115
4193
  {
4116
4194
  value: String(limit),
4117
4195
  onChange: (value) => setLimit(parseInt(value, 10)),
@@ -4130,7 +4208,7 @@ function TableConfig({
4130
4208
  selectedTable && currentTable && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4131
4209
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Filters (optional)" }),
4132
4210
  /* @__PURE__ */ jsxRuntime.jsx(
4133
- chunkNY6TZLST_cjs.FilterBuilder,
4211
+ chunkURJH4H6G_cjs.FilterBuilder,
4134
4212
  {
4135
4213
  tables: [{ id: "t1", name: selectedTable }],
4136
4214
  filters,
@@ -4214,11 +4292,11 @@ function HyperlinkSection({
4214
4292
  target
4215
4293
  });
4216
4294
  };
4217
- return /* @__PURE__ */ jsxRuntime.jsxs(chunkNY6TZLST_cjs.CollapsibleSection, { title: "Hyperlink", defaultOpen, children: [
4295
+ return /* @__PURE__ */ jsxRuntime.jsxs(chunkURJH4H6G_cjs.CollapsibleSection, { title: "Hyperlink", defaultOpen, children: [
4218
4296
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4219
4297
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "URL" }),
4220
4298
  /* @__PURE__ */ jsxRuntime.jsx(
4221
- chunkNY6TZLST_cjs.Input,
4299
+ chunkURJH4H6G_cjs.Input,
4222
4300
  {
4223
4301
  value: hyperlink?.url || "",
4224
4302
  onChange: (e) => handleUrlChange(e.target.value),
@@ -4231,7 +4309,7 @@ function HyperlinkSection({
4231
4309
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4232
4310
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Tooltip Text" }),
4233
4311
  /* @__PURE__ */ jsxRuntime.jsx(
4234
- chunkNY6TZLST_cjs.Input,
4312
+ chunkURJH4H6G_cjs.Input,
4235
4313
  {
4236
4314
  value: hyperlink?.title || "",
4237
4315
  onChange: (e) => handleTitleChange(e.target.value),
@@ -4242,7 +4320,7 @@ function HyperlinkSection({
4242
4320
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4243
4321
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Open In" }),
4244
4322
  /* @__PURE__ */ jsxRuntime.jsx(
4245
- chunkNY6TZLST_cjs.Select,
4323
+ chunkURJH4H6G_cjs.Select,
4246
4324
  {
4247
4325
  value: hyperlink?.target || "_blank",
4248
4326
  onChange: handleTargetChange,
@@ -4318,14 +4396,14 @@ function ReferenceLinesSection({
4318
4396
  onChange(lines.filter((_, i) => i !== index));
4319
4397
  };
4320
4398
  return /* @__PURE__ */ jsxRuntime.jsxs(
4321
- chunkNY6TZLST_cjs.CollapsibleSection,
4399
+ chunkURJH4H6G_cjs.CollapsibleSection,
4322
4400
  {
4323
4401
  title: "Reference Lines",
4324
4402
  defaultOpen: defaultOpen || lines.length > 0,
4325
4403
  children: [
4326
4404
  lines.map((line, index) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: lineRowStyle, children: [
4327
4405
  /* @__PURE__ */ jsxRuntime.jsx(
4328
- chunkNY6TZLST_cjs.Input,
4406
+ chunkURJH4H6G_cjs.Input,
4329
4407
  {
4330
4408
  type: "number",
4331
4409
  value: String(line.value),
@@ -4335,7 +4413,7 @@ function ReferenceLinesSection({
4335
4413
  }
4336
4414
  ),
4337
4415
  /* @__PURE__ */ jsxRuntime.jsx(
4338
- chunkNY6TZLST_cjs.Input,
4416
+ chunkURJH4H6G_cjs.Input,
4339
4417
  {
4340
4418
  value: line.label ?? "",
4341
4419
  onChange: (e) => updateLine(index, { label: e.target.value || void 0 }),
@@ -4354,7 +4432,7 @@ function ReferenceLinesSection({
4354
4432
  }
4355
4433
  ),
4356
4434
  /* @__PURE__ */ jsxRuntime.jsx(
4357
- chunkNY6TZLST_cjs.Select,
4435
+ chunkURJH4H6G_cjs.Select,
4358
4436
  {
4359
4437
  value: line.lineStyle ?? "dashed",
4360
4438
  onChange: (value) => updateLine(index, {
@@ -4364,10 +4442,10 @@ function ReferenceLinesSection({
4364
4442
  style: { width: "90px" }
4365
4443
  }
4366
4444
  ),
4367
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Button, { variant: "ghost", size: "sm", onClick: () => removeLine(index), children: /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "x", size: 14 }) })
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 }) })
4368
4446
  ] }, lineIdsRef.current[index])),
4369
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: addButtonStyle, children: /* @__PURE__ */ jsxRuntime.jsxs(chunkNY6TZLST_cjs.Button, { variant: "ghost", size: "sm", onClick: addLine, children: [
4370
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "plus", size: 14 }),
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 }),
4371
4449
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { marginLeft: theme.spacing.xs }, children: "Add reference line" })
4372
4450
  ] }) })
4373
4451
  ]
@@ -4451,7 +4529,7 @@ function TextFormattingSection({
4451
4529
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerStyle, children: [
4452
4530
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Content" }),
4453
4531
  config.markdown && /* @__PURE__ */ jsxRuntime.jsx(
4454
- chunkNY6TZLST_cjs.Checkbox,
4532
+ chunkURJH4H6G_cjs.Checkbox,
4455
4533
  {
4456
4534
  label: "Preview",
4457
4535
  checked: showPreview,
@@ -4465,7 +4543,7 @@ function TextFormattingSection({
4465
4543
  "div",
4466
4544
  {
4467
4545
  dangerouslySetInnerHTML: {
4468
- __html: chunk4AVL6GQK_cjs.parseMarkdownSafe(config.content ?? "")
4546
+ __html: chunkKXB2IZI2_cjs.parseMarkdownSafe(config.content ?? "")
4469
4547
  }
4470
4548
  }
4471
4549
  )
@@ -4481,7 +4559,7 @@ function TextFormattingSection({
4481
4559
  )
4482
4560
  ] }),
4483
4561
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: fieldStyle, children: /* @__PURE__ */ jsxRuntime.jsx(
4484
- chunkNY6TZLST_cjs.Checkbox,
4562
+ chunkURJH4H6G_cjs.Checkbox,
4485
4563
  {
4486
4564
  label: "Enable Markdown",
4487
4565
  checked: config.markdown ?? false,
@@ -4492,7 +4570,7 @@ function TextFormattingSection({
4492
4570
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: halfFieldStyle, children: [
4493
4571
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Alignment" }),
4494
4572
  /* @__PURE__ */ jsxRuntime.jsx(
4495
- chunkNY6TZLST_cjs.Select,
4573
+ chunkURJH4H6G_cjs.Select,
4496
4574
  {
4497
4575
  value: config.alignment ?? "Left",
4498
4576
  onChange: (value) => onChange("alignment", value),
@@ -4503,7 +4581,7 @@ function TextFormattingSection({
4503
4581
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: halfFieldStyle, children: [
4504
4582
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Font Size" }),
4505
4583
  /* @__PURE__ */ jsxRuntime.jsx(
4506
- chunkNY6TZLST_cjs.Select,
4584
+ chunkURJH4H6G_cjs.Select,
4507
4585
  {
4508
4586
  value: config.fontSize ?? "Normal",
4509
4587
  onChange: (value) => onChange("fontSize", value),
@@ -4620,13 +4698,13 @@ function PivotConfigSection({
4620
4698
  ).map((col) => col.column);
4621
4699
  }, [query, config.pivot_column, config.value_column]);
4622
4700
  return /* @__PURE__ */ jsxRuntime.jsxs(
4623
- chunkNY6TZLST_cjs.CollapsibleSection,
4701
+ chunkURJH4H6G_cjs.CollapsibleSection,
4624
4702
  {
4625
4703
  title: "Pivot Table",
4626
4704
  defaultOpen: defaultOpen || isPivotEnabled,
4627
4705
  children: [
4628
4706
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: fieldStyle, children: /* @__PURE__ */ jsxRuntime.jsx(
4629
- chunkNY6TZLST_cjs.Checkbox,
4707
+ chunkURJH4H6G_cjs.Checkbox,
4630
4708
  {
4631
4709
  label: "Enable Pivot Mode",
4632
4710
  checked: isPivotEnabled,
@@ -4637,7 +4715,7 @@ function PivotConfigSection({
4637
4715
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4638
4716
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Pivot Column" }),
4639
4717
  /* @__PURE__ */ jsxRuntime.jsx(
4640
- chunkNY6TZLST_cjs.Select,
4718
+ chunkURJH4H6G_cjs.Select,
4641
4719
  {
4642
4720
  value: config.pivot_column ?? "",
4643
4721
  onChange: (value) => onChange("pivot_column", value || void 0),
@@ -4652,7 +4730,7 @@ function PivotConfigSection({
4652
4730
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4653
4731
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Value Column" }),
4654
4732
  /* @__PURE__ */ jsxRuntime.jsx(
4655
- chunkNY6TZLST_cjs.Select,
4733
+ chunkURJH4H6G_cjs.Select,
4656
4734
  {
4657
4735
  value: config.value_column ?? "",
4658
4736
  onChange: (value) => onChange("value_column", value || void 0),
@@ -4715,7 +4793,7 @@ function LayoutConstraintsSection({
4715
4793
  };
4716
4794
  const hasConstraints = position.minW !== void 0 || position.maxW !== void 0 || position.minH !== void 0 || position.maxH !== void 0;
4717
4795
  return /* @__PURE__ */ jsxRuntime.jsx(
4718
- chunkNY6TZLST_cjs.CollapsibleSection,
4796
+ chunkURJH4H6G_cjs.CollapsibleSection,
4719
4797
  {
4720
4798
  title: "Size Constraints",
4721
4799
  defaultOpen: defaultOpen || hasConstraints,
@@ -4723,7 +4801,7 @@ function LayoutConstraintsSection({
4723
4801
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4724
4802
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Min Width" }),
4725
4803
  /* @__PURE__ */ jsxRuntime.jsx(
4726
- chunkNY6TZLST_cjs.Input,
4804
+ chunkURJH4H6G_cjs.Input,
4727
4805
  {
4728
4806
  type: "number",
4729
4807
  value: position.minW !== void 0 ? String(position.minW) : "",
@@ -4737,7 +4815,7 @@ function LayoutConstraintsSection({
4737
4815
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4738
4816
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Max Width" }),
4739
4817
  /* @__PURE__ */ jsxRuntime.jsx(
4740
- chunkNY6TZLST_cjs.Input,
4818
+ chunkURJH4H6G_cjs.Input,
4741
4819
  {
4742
4820
  type: "number",
4743
4821
  value: position.maxW !== void 0 ? String(position.maxW) : "",
@@ -4751,7 +4829,7 @@ function LayoutConstraintsSection({
4751
4829
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4752
4830
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Min Height" }),
4753
4831
  /* @__PURE__ */ jsxRuntime.jsx(
4754
- chunkNY6TZLST_cjs.Input,
4832
+ chunkURJH4H6G_cjs.Input,
4755
4833
  {
4756
4834
  type: "number",
4757
4835
  value: position.minH !== void 0 ? String(position.minH) : "",
@@ -4764,7 +4842,7 @@ function LayoutConstraintsSection({
4764
4842
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4765
4843
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Max Height" }),
4766
4844
  /* @__PURE__ */ jsxRuntime.jsx(
4767
- chunkNY6TZLST_cjs.Input,
4845
+ chunkURJH4H6G_cjs.Input,
4768
4846
  {
4769
4847
  type: "number",
4770
4848
  value: position.maxH !== void 0 ? String(position.maxH) : "",
@@ -4832,14 +4910,14 @@ function CrossFilterSection({
4832
4910
  });
4833
4911
  };
4834
4912
  return /* @__PURE__ */ jsxRuntime.jsxs(
4835
- chunkNY6TZLST_cjs.CollapsibleSection,
4913
+ chunkURJH4H6G_cjs.CollapsibleSection,
4836
4914
  {
4837
4915
  title: "Cross-Filtering",
4838
4916
  defaultOpen: defaultOpen || crossFilterEnabled,
4839
4917
  children: [
4840
4918
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4841
4919
  /* @__PURE__ */ jsxRuntime.jsx(
4842
- chunkNY6TZLST_cjs.Checkbox,
4920
+ chunkURJH4H6G_cjs.Checkbox,
4843
4921
  {
4844
4922
  label: "Enable as filter source",
4845
4923
  checked: crossFilterEnabled,
@@ -4851,7 +4929,7 @@ function CrossFilterSection({
4851
4929
  crossFilterEnabled && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4852
4930
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Filter Column" }),
4853
4931
  /* @__PURE__ */ jsxRuntime.jsx(
4854
- chunkNY6TZLST_cjs.Select,
4932
+ chunkURJH4H6G_cjs.Select,
4855
4933
  {
4856
4934
  value: config.cross_filter?.column ?? config.x_axis ?? "",
4857
4935
  onChange: handleColumnChange,
@@ -4950,11 +5028,11 @@ function ValueFormattingSection({
4950
5028
  marginBottom: theme.spacing.xs
4951
5029
  };
4952
5030
  const isCurrency = config.valueFormat === "currency" || config.format === "currency";
4953
- return /* @__PURE__ */ jsxRuntime.jsxs(chunkNY6TZLST_cjs.CollapsibleSection, { title: "Value Formatting", defaultOpen, children: [
5031
+ return /* @__PURE__ */ jsxRuntime.jsxs(chunkURJH4H6G_cjs.CollapsibleSection, { title: "Value Formatting", defaultOpen, children: [
4954
5032
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4955
5033
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Format" }),
4956
5034
  /* @__PURE__ */ jsxRuntime.jsx(
4957
- chunkNY6TZLST_cjs.Select,
5035
+ chunkURJH4H6G_cjs.Select,
4958
5036
  {
4959
5037
  value: config.valueFormat || config.format || "number",
4960
5038
  onChange: (value) => {
@@ -4969,7 +5047,7 @@ function ValueFormattingSection({
4969
5047
  isCurrency && showCurrency && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4970
5048
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Currency Symbol" }),
4971
5049
  /* @__PURE__ */ jsxRuntime.jsx(
4972
- chunkNY6TZLST_cjs.Input,
5050
+ chunkURJH4H6G_cjs.Input,
4973
5051
  {
4974
5052
  value: config.currencySymbol ?? "$",
4975
5053
  onChange: (e) => onChange("currencySymbol", e.target.value),
@@ -4981,7 +5059,7 @@ function ValueFormattingSection({
4981
5059
  showCompact && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4982
5060
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Compact Notation" }),
4983
5061
  /* @__PURE__ */ jsxRuntime.jsx(
4984
- chunkNY6TZLST_cjs.Select,
5062
+ chunkURJH4H6G_cjs.Select,
4985
5063
  {
4986
5064
  value: config.compactNotation || "",
4987
5065
  onChange: (value) => onChange("compactNotation", value ? value : null),
@@ -4992,7 +5070,7 @@ function ValueFormattingSection({
4992
5070
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
4993
5071
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Decimal Places" }),
4994
5072
  /* @__PURE__ */ jsxRuntime.jsx(
4995
- chunkNY6TZLST_cjs.Select,
5073
+ chunkURJH4H6G_cjs.Select,
4996
5074
  {
4997
5075
  value: String(config.decimalDigits ?? 2),
4998
5076
  onChange: (value) => onChange("decimalDigits", parseInt(value, 10)),
@@ -5033,9 +5111,9 @@ function DisplayConfigSection({
5033
5111
  "pie_chart",
5034
5112
  "scatter_chart"
5035
5113
  ].includes(widgetType);
5036
- return /* @__PURE__ */ jsxRuntime.jsxs(chunkNY6TZLST_cjs.CollapsibleSection, { title: "Display Options", defaultOpen, children: [
5114
+ return /* @__PURE__ */ jsxRuntime.jsxs(chunkURJH4H6G_cjs.CollapsibleSection, { title: "Display Options", defaultOpen, children: [
5037
5115
  showColorPalette && /* @__PURE__ */ jsxRuntime.jsx("div", { style: fieldStyle, children: /* @__PURE__ */ jsxRuntime.jsx(
5038
- chunkNY6TZLST_cjs.ColorPaletteSelector,
5116
+ chunkURJH4H6G_cjs.ColorPaletteSelector,
5039
5117
  {
5040
5118
  value: config.colors,
5041
5119
  onChange: (colors) => onChange("colors", colors)
@@ -5044,7 +5122,7 @@ function DisplayConfigSection({
5044
5122
  showOrientation && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
5045
5123
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Orientation" }),
5046
5124
  /* @__PURE__ */ jsxRuntime.jsx(
5047
- chunkNY6TZLST_cjs.Select,
5125
+ chunkURJH4H6G_cjs.Select,
5048
5126
  {
5049
5127
  value: config.orientation || "vertical",
5050
5128
  onChange: (value) => onChange("orientation", value),
@@ -5057,7 +5135,7 @@ function DisplayConfigSection({
5057
5135
  ] }),
5058
5136
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: rowStyle, children: [
5059
5137
  /* @__PURE__ */ jsxRuntime.jsx(
5060
- chunkNY6TZLST_cjs.Checkbox,
5138
+ chunkURJH4H6G_cjs.Checkbox,
5061
5139
  {
5062
5140
  label: "Show Legend",
5063
5141
  checked: config.show_legend ?? true,
@@ -5065,7 +5143,7 @@ function DisplayConfigSection({
5065
5143
  }
5066
5144
  ),
5067
5145
  /* @__PURE__ */ jsxRuntime.jsx(
5068
- chunkNY6TZLST_cjs.Checkbox,
5146
+ chunkURJH4H6G_cjs.Checkbox,
5069
5147
  {
5070
5148
  label: "Data Labels",
5071
5149
  checked: config.show_data_labels ?? false,
@@ -5073,7 +5151,7 @@ function DisplayConfigSection({
5073
5151
  }
5074
5152
  ),
5075
5153
  showStacked && /* @__PURE__ */ jsxRuntime.jsx(
5076
- chunkNY6TZLST_cjs.Checkbox,
5154
+ chunkURJH4H6G_cjs.Checkbox,
5077
5155
  {
5078
5156
  label: "Stacked",
5079
5157
  checked: config.stacked ?? false,
@@ -5158,10 +5236,10 @@ function DateFormattingSection({
5158
5236
  fontSize: theme.fontSizes.sm,
5159
5237
  color: theme.colors.textMuted
5160
5238
  };
5161
- return /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.CollapsibleSection, { title: "Date Formatting", defaultOpen, children: dateColumns.map((col) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
5239
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.CollapsibleSection, { title: "Date Formatting", defaultOpen, children: dateColumns.map((col) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
5162
5240
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: columnNameStyle, children: col.alias }) }),
5163
5241
  /* @__PURE__ */ jsxRuntime.jsx(
5164
- chunkNY6TZLST_cjs.Select,
5242
+ chunkURJH4H6G_cjs.Select,
5165
5243
  {
5166
5244
  value: config.dateFormats?.[col.name] || "",
5167
5245
  onChange: (value) => handleFormatChange(col.name, value),
@@ -5219,10 +5297,10 @@ function TrendConfigSection({
5219
5297
  color: theme.colors.textMuted,
5220
5298
  marginTop: theme.spacing.xs
5221
5299
  };
5222
- return /* @__PURE__ */ jsxRuntime.jsxs(chunkNY6TZLST_cjs.CollapsibleSection, { title: "Trend Comparison", defaultOpen, children: [
5300
+ return /* @__PURE__ */ jsxRuntime.jsxs(chunkURJH4H6G_cjs.CollapsibleSection, { title: "Trend Comparison", defaultOpen, children: [
5223
5301
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
5224
5302
  /* @__PURE__ */ jsxRuntime.jsx(
5225
- chunkNY6TZLST_cjs.Checkbox,
5303
+ chunkURJH4H6G_cjs.Checkbox,
5226
5304
  {
5227
5305
  label: "Show Trend Indicator",
5228
5306
  checked: config.showTrend ?? false,
@@ -5235,7 +5313,7 @@ function TrendConfigSection({
5235
5313
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
5236
5314
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Comparison Period" }),
5237
5315
  /* @__PURE__ */ jsxRuntime.jsx(
5238
- chunkNY6TZLST_cjs.Select,
5316
+ chunkURJH4H6G_cjs.Select,
5239
5317
  {
5240
5318
  value: config.trendPeriod || "previous_period",
5241
5319
  onChange: (value) => onChange("trendPeriod", value),
@@ -5246,7 +5324,7 @@ function TrendConfigSection({
5246
5324
  dateColumnOptions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
5247
5325
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Date Column" }),
5248
5326
  /* @__PURE__ */ jsxRuntime.jsx(
5249
- chunkNY6TZLST_cjs.Select,
5327
+ chunkURJH4H6G_cjs.Select,
5250
5328
  {
5251
5329
  value: config.trendDateColumn || "",
5252
5330
  onChange: (value) => onChange("trendDateColumn", value || void 0),
@@ -5292,7 +5370,7 @@ function WidgetEditorPage({
5292
5370
  onCancel
5293
5371
  }) {
5294
5372
  const { theme } = chunkLMTG3LRC_cjs.useTheme();
5295
- const { client } = chunkNY6TZLST_cjs.useAnalytics();
5373
+ const { client } = chunkURJH4H6G_cjs.useAnalytics();
5296
5374
  const isNew = widget === null;
5297
5375
  const [type, setType] = react.useState(widget?.type ?? "bar_chart");
5298
5376
  const [title, setTitle] = react.useState(widget?.title ?? "New Widget");
@@ -5305,7 +5383,7 @@ function WidgetEditorPage({
5305
5383
  widget?.position ?? { x: 0, y: 0, w: 6, h: 4, minW: 2, minH: 2 }
5306
5384
  );
5307
5385
  const [dataSourceMode, setDataSourceMode] = react.useState(
5308
- isNew ? "guided" : widget?.dataSourceMode ?? "guided"
5386
+ isNew ? "guided" : widget?.config?.data_source_mode ?? "guided"
5309
5387
  );
5310
5388
  const [previewResult, setPreviewResult] = react.useState(null);
5311
5389
  const [previewLoading, setPreviewLoading] = react.useState(false);
@@ -5352,6 +5430,26 @@ function WidgetEditorPage({
5352
5430
  setPreviewError(null);
5353
5431
  }
5354
5432
  }, [query, refreshPreview]);
5433
+ const queryHasAdvancedFeatures = react.useCallback((q) => {
5434
+ if (!q) return false;
5435
+ if (q.tables && q.tables.length > 1 && q.joins && q.joins.length > 0) return true;
5436
+ if (q.calculated_fields && q.calculated_fields.length > 0) return true;
5437
+ if (q.group_by && q.group_by.length > 0) return true;
5438
+ if (q.order_by && q.order_by.length > 0) return true;
5439
+ if (q.limit != null) return true;
5440
+ if (q.offset != null) return true;
5441
+ if (q.time_series) return true;
5442
+ return false;
5443
+ }, []);
5444
+ const handleModeSwitch = react.useCallback((newMode) => {
5445
+ if (newMode === "guided" && (dataSourceMode === "advanced" || dataSourceMode === "saved") && queryHasAdvancedFeatures(query)) {
5446
+ const confirmed = window.confirm(
5447
+ "This query uses advanced features (e.g. joins, calculated fields, grouping, sorting, pagination, time series) that Guided mode may not fully represent. The query will be preserved but some settings may not be editable in Guided mode.\n\nSwitch to Guided mode?"
5448
+ );
5449
+ if (!confirmed) return;
5450
+ }
5451
+ setDataSourceMode(newMode);
5452
+ }, [dataSourceMode, query, queryHasAdvancedFeatures]);
5355
5453
  const handleSavedQuerySelect = react.useCallback((savedQuery) => {
5356
5454
  setQuery(savedQuery.query);
5357
5455
  }, []);
@@ -5368,11 +5466,10 @@ function WidgetEditorPage({
5368
5466
  id: widget?.id ?? generateId(),
5369
5467
  type,
5370
5468
  title,
5371
- config,
5469
+ config: { ...config, data_source_mode: dataSourceMode },
5372
5470
  query,
5373
5471
  position,
5374
- hyperlink,
5375
- dataSourceMode
5472
+ hyperlink
5376
5473
  };
5377
5474
  onSave(savedWidget);
5378
5475
  }, [widget, type, title, config, query, position, hyperlink, dataSourceMode, onSave]);
@@ -5398,7 +5495,8 @@ function WidgetEditorPage({
5398
5495
  justifyContent: "space-between",
5399
5496
  padding: `${theme.spacing.md} ${theme.spacing.lg}`,
5400
5497
  borderBottom: `1px solid ${theme.colors.border}`,
5401
- backgroundColor: theme.colors.surface
5498
+ backgroundColor: theme.colors.surface,
5499
+ flexShrink: 0
5402
5500
  };
5403
5501
  const headerLeftStyle = {
5404
5502
  display: "flex",
@@ -5429,38 +5527,28 @@ function WidgetEditorPage({
5429
5527
  };
5430
5528
  const bodyStyle = {
5431
5529
  flex: 1,
5432
- display: "flex",
5433
- minHeight: 0
5530
+ overflow: "auto",
5531
+ display: "grid",
5532
+ gridTemplateColumns: "360px 1fr"
5434
5533
  };
5435
5534
  const leftPanelStyle = {
5436
- width: "320px",
5437
- flexShrink: 0,
5438
5535
  borderRight: `1px solid ${theme.colors.border}`,
5439
- overflow: "auto",
5440
5536
  padding: theme.spacing.md,
5537
+ paddingBottom: theme.spacing.xl,
5441
5538
  display: "flex",
5442
5539
  flexDirection: "column",
5443
5540
  gap: theme.spacing.lg
5444
5541
  };
5445
5542
  const mainPanelStyle = {
5446
- flex: 1,
5447
- display: "flex",
5448
- flexDirection: "column",
5449
- minHeight: 0
5543
+ minWidth: 0
5450
5544
  };
5451
5545
  const previewPanelStyle = {
5452
- height: "300px",
5453
- flexShrink: 0,
5454
- padding: theme.spacing.md,
5455
- borderBottom: `1px solid ${theme.colors.border}`
5456
- };
5457
- const dataSourcePanelStyle = {
5458
- flex: "1 1 auto",
5459
- display: "flex",
5460
- flexDirection: "column",
5461
- minHeight: 0,
5546
+ height: "440px",
5547
+ padding: theme.spacing.lg,
5548
+ borderBottom: `1px solid ${theme.colors.border}`,
5462
5549
  overflow: "hidden"
5463
5550
  };
5551
+ const dataSourcePanelStyle = {};
5464
5552
  const dataSourceHeaderStyle = {
5465
5553
  display: "flex",
5466
5554
  alignItems: "center",
@@ -5480,15 +5568,12 @@ function WidgetEditorPage({
5480
5568
  transition: "all 0.15s ease"
5481
5569
  });
5482
5570
  const dataSourceContentStyle = {
5483
- flex: "1 1 auto",
5484
- overflow: "auto",
5485
5571
  padding: theme.spacing.md,
5486
- paddingBottom: "100px",
5487
- // Extra space to ensure filter buttons are visible
5488
- minHeight: "250px"
5572
+ paddingBottom: "200px"
5573
+ // Extra padding to create scroll room for filters
5489
5574
  };
5490
5575
  const sectionStyle = {
5491
- marginBottom: theme.spacing.md
5576
+ // Note: Parent has flex gap for spacing between sections
5492
5577
  };
5493
5578
  const sectionTitleStyle = {
5494
5579
  fontSize: theme.fontSizes.xs,
@@ -5537,7 +5622,7 @@ function WidgetEditorPage({
5537
5622
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
5538
5623
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "X-Axis Column" }),
5539
5624
  /* @__PURE__ */ jsxRuntime.jsx(
5540
- chunkNY6TZLST_cjs.Select,
5625
+ chunkURJH4H6G_cjs.Select,
5541
5626
  {
5542
5627
  value: config.x_axis || "",
5543
5628
  onChange: (value) => updateConfig("x_axis", value || void 0),
@@ -5598,7 +5683,7 @@ function WidgetEditorPage({
5598
5683
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
5599
5684
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "X-Axis Column" }),
5600
5685
  /* @__PURE__ */ jsxRuntime.jsx(
5601
- chunkNY6TZLST_cjs.Select,
5686
+ chunkURJH4H6G_cjs.Select,
5602
5687
  {
5603
5688
  value: config.x_axis || "",
5604
5689
  onChange: (value) => updateConfig("x_axis", value || void 0),
@@ -5679,7 +5764,7 @@ function WidgetEditorPage({
5679
5764
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
5680
5765
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "X-Axis Column" }),
5681
5766
  /* @__PURE__ */ jsxRuntime.jsx(
5682
- chunkNY6TZLST_cjs.Select,
5767
+ chunkURJH4H6G_cjs.Select,
5683
5768
  {
5684
5769
  value: config.x_axis || "",
5685
5770
  onChange: (value) => updateConfig("x_axis", value || void 0),
@@ -5690,7 +5775,7 @@ function WidgetEditorPage({
5690
5775
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
5691
5776
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Y-Axis Column" }),
5692
5777
  /* @__PURE__ */ jsxRuntime.jsx(
5693
- chunkNY6TZLST_cjs.Select,
5778
+ chunkURJH4H6G_cjs.Select,
5694
5779
  {
5695
5780
  value: config.y_axis?.[0] || "",
5696
5781
  onChange: (value) => updateConfig("y_axis", value ? [value] : void 0),
@@ -5723,7 +5808,7 @@ function WidgetEditorPage({
5723
5808
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
5724
5809
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Page Size" }),
5725
5810
  /* @__PURE__ */ jsxRuntime.jsx(
5726
- chunkNY6TZLST_cjs.Select,
5811
+ chunkURJH4H6G_cjs.Select,
5727
5812
  {
5728
5813
  value: String(config.page_size || 10),
5729
5814
  onChange: (value) => updateConfig("page_size", parseInt(value, 10)),
@@ -5737,7 +5822,7 @@ function WidgetEditorPage({
5737
5822
  )
5738
5823
  ] }),
5739
5824
  /* @__PURE__ */ jsxRuntime.jsx(
5740
- chunkNY6TZLST_cjs.Checkbox,
5825
+ chunkURJH4H6G_cjs.Checkbox,
5741
5826
  {
5742
5827
  label: "Sortable Columns",
5743
5828
  checked: config.sortable ?? true,
@@ -5795,10 +5880,10 @@ function WidgetEditorPage({
5795
5880
  },
5796
5881
  children: [
5797
5882
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: theme.spacing.sm }, children: [
5798
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "table", size: 16 }),
5883
+ /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "table", size: 16 }),
5799
5884
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 500, color: theme.colors.text }, children: "Query configured" })
5800
5885
  ] }),
5801
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Button, { variant: "ghost", size: "sm", onClick: handleClearQuery, children: /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "x", size: 16 }) })
5886
+ /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Button, { variant: "ghost", size: "sm", onClick: handleClearQuery, children: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "x", size: 16 }) })
5802
5887
  ]
5803
5888
  }
5804
5889
  ),
@@ -5817,14 +5902,14 @@ function WidgetEditorPage({
5817
5902
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerStyle, children: [
5818
5903
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerLeftStyle, children: [
5819
5904
  /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", style: backButtonStyle, onClick: onCancel, children: [
5820
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "chevron-left", size: 16 }),
5905
+ /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "chevron-left", size: 16 }),
5821
5906
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Back" })
5822
5907
  ] }),
5823
5908
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: headerTitleStyle, children: isNew ? "Add Widget" : "Edit Widget" })
5824
5909
  ] }),
5825
5910
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerActionsStyle, children: [
5826
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Button, { variant: "ghost", onClick: onCancel, children: "Cancel" }),
5827
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Button, { variant: "primary", onClick: handleSave, children: isNew ? "Add Widget" : "Save Changes" })
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" })
5828
5913
  ] })
5829
5914
  ] }),
5830
5915
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: bodyStyle, children: [
@@ -5835,7 +5920,7 @@ function WidgetEditorPage({
5835
5920
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
5836
5921
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Title" }),
5837
5922
  /* @__PURE__ */ jsxRuntime.jsx(
5838
- chunkNY6TZLST_cjs.Input,
5923
+ chunkURJH4H6G_cjs.Input,
5839
5924
  {
5840
5925
  value: title,
5841
5926
  onChange: (e) => setTitle(e.target.value),
@@ -5882,30 +5967,39 @@ function WidgetEditorPage({
5882
5967
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: dataSourceHeaderStyle, children: [
5883
5968
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: theme.fontSizes.sm, fontWeight: 500, marginRight: "auto" }, children: "Data Source" }),
5884
5969
  /* @__PURE__ */ jsxRuntime.jsx(
5885
- "button",
5886
- {
5887
- type: "button",
5888
- style: tabStyle(dataSourceMode === "guided"),
5889
- onClick: () => setDataSourceMode("guided"),
5890
- children: "Guided"
5891
- }
5892
- ),
5893
- /* @__PURE__ */ jsxRuntime.jsx(
5894
- "button",
5970
+ chunkURJH4H6G_cjs.Tooltip,
5895
5971
  {
5896
- type: "button",
5897
- style: tabStyle(dataSourceMode === "advanced"),
5898
- onClick: () => setDataSourceMode("advanced"),
5899
- children: "Advanced"
5972
+ content: "Quick setup: pick columns from dropdowns to build your chart",
5973
+ position: "bottom",
5974
+ style: { whiteSpace: "normal" },
5975
+ children: /* @__PURE__ */ jsxRuntime.jsx(
5976
+ "button",
5977
+ {
5978
+ type: "button",
5979
+ "data-testid": "data-source-mode-guided",
5980
+ style: tabStyle(dataSourceMode === "guided"),
5981
+ onClick: () => handleModeSwitch("guided"),
5982
+ children: "Guided"
5983
+ }
5984
+ )
5900
5985
  }
5901
5986
  ),
5902
5987
  /* @__PURE__ */ jsxRuntime.jsx(
5903
- "button",
5988
+ chunkURJH4H6G_cjs.Tooltip,
5904
5989
  {
5905
- type: "button",
5906
- style: tabStyle(dataSourceMode === "saved"),
5907
- onClick: () => setDataSourceMode("saved"),
5908
- children: "Saved Query"
5990
+ content: "Full control: combine tables, add filters, and create custom calculations",
5991
+ position: "bottom",
5992
+ style: { whiteSpace: "normal" },
5993
+ children: /* @__PURE__ */ jsxRuntime.jsx(
5994
+ "button",
5995
+ {
5996
+ type: "button",
5997
+ "data-testid": "data-source-mode-advanced",
5998
+ style: tabStyle(dataSourceMode === "advanced"),
5999
+ onClick: () => handleModeSwitch("advanced"),
6000
+ children: "Advanced"
6001
+ }
6002
+ )
5909
6003
  }
5910
6004
  )
5911
6005
  ] }),
@@ -5921,7 +6015,7 @@ function WidgetEditorPage({
5921
6015
  }
5922
6016
  ),
5923
6017
  dataSourceMode === "advanced" && /* @__PURE__ */ jsxRuntime.jsx(
5924
- chunkNY6TZLST_cjs.QueryBuilder,
6018
+ chunkURJH4H6G_cjs.QueryBuilder,
5925
6019
  {
5926
6020
  initialQuery: query ?? void 0,
5927
6021
  onQueryChange: handleQueryChange,
@@ -5932,7 +6026,7 @@ function WidgetEditorPage({
5932
6026
  }
5933
6027
  ),
5934
6028
  dataSourceMode === "saved" && /* @__PURE__ */ jsxRuntime.jsx(
5935
- chunkNY6TZLST_cjs.SavedQueryPicker,
6029
+ chunkURJH4H6G_cjs.SavedQueryPicker,
5936
6030
  {
5937
6031
  currentQuery: query,
5938
6032
  onSelect: handleSavedQuerySelect,
@@ -5982,8 +6076,8 @@ function DashboardEditor({
5982
6076
  className = ""
5983
6077
  }) {
5984
6078
  const { theme } = chunkLMTG3LRC_cjs.useTheme();
5985
- const { client } = chunkNY6TZLST_cjs.useAnalytics();
5986
- const { schema } = chunkNY6TZLST_cjs.useSchema();
6079
+ const { client } = chunkURJH4H6G_cjs.useAnalytics();
6080
+ const { schema } = chunkURJH4H6G_cjs.useSchema();
5987
6081
  const [currentDashboardId, setCurrentDashboardId] = react.useState(dashboardId);
5988
6082
  react.useEffect(() => {
5989
6083
  setCurrentDashboardId(dashboardId);
@@ -6610,7 +6704,7 @@ function WidgetPalette({
6610
6704
  Object.assign(e.currentTarget.style, itemStyle);
6611
6705
  },
6612
6706
  children: [
6613
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: iconContainerStyle, children: /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: widgetType.icon, size: 24 }) }),
6707
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: iconContainerStyle, children: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: widgetType.icon, size: 24 }) }),
6614
6708
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: labelStyle, children: widgetType.label }),
6615
6709
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: descriptionStyle, children: widgetType.description })
6616
6710
  ]
@@ -6762,7 +6856,7 @@ function WidgetEditor({
6762
6856
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
6763
6857
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Format" }),
6764
6858
  /* @__PURE__ */ jsxRuntime.jsx(
6765
- chunkNY6TZLST_cjs.Select,
6859
+ chunkURJH4H6G_cjs.Select,
6766
6860
  {
6767
6861
  value: config.format || "number",
6768
6862
  onChange: (value) => updateConfig("format", value),
@@ -6778,7 +6872,7 @@ function WidgetEditor({
6778
6872
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
6779
6873
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Trend Comparison Field" }),
6780
6874
  /* @__PURE__ */ jsxRuntime.jsx(
6781
- chunkNY6TZLST_cjs.Select,
6875
+ chunkURJH4H6G_cjs.Select,
6782
6876
  {
6783
6877
  value: config.trend_comparison || "",
6784
6878
  onChange: (value) => updateConfig("trend_comparison", value || void 0),
@@ -6795,7 +6889,7 @@ function WidgetEditor({
6795
6889
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
6796
6890
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "X-Axis Column" }),
6797
6891
  /* @__PURE__ */ jsxRuntime.jsx(
6798
- chunkNY6TZLST_cjs.Select,
6892
+ chunkURJH4H6G_cjs.Select,
6799
6893
  {
6800
6894
  value: config.x_axis || "",
6801
6895
  onChange: (value) => updateConfig("x_axis", value),
@@ -6806,7 +6900,7 @@ function WidgetEditor({
6806
6900
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
6807
6901
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Orientation" }),
6808
6902
  /* @__PURE__ */ jsxRuntime.jsx(
6809
- chunkNY6TZLST_cjs.Select,
6903
+ chunkURJH4H6G_cjs.Select,
6810
6904
  {
6811
6905
  value: config.orientation || "vertical",
6812
6906
  onChange: (value) => updateConfig("orientation", value),
@@ -6819,7 +6913,7 @@ function WidgetEditor({
6819
6913
  ] }),
6820
6914
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: rowStyle, children: [
6821
6915
  /* @__PURE__ */ jsxRuntime.jsx(
6822
- chunkNY6TZLST_cjs.Checkbox,
6916
+ chunkURJH4H6G_cjs.Checkbox,
6823
6917
  {
6824
6918
  label: "Show Legend",
6825
6919
  checked: config.show_legend ?? true,
@@ -6827,7 +6921,7 @@ function WidgetEditor({
6827
6921
  }
6828
6922
  ),
6829
6923
  /* @__PURE__ */ jsxRuntime.jsx(
6830
- chunkNY6TZLST_cjs.Checkbox,
6924
+ chunkURJH4H6G_cjs.Checkbox,
6831
6925
  {
6832
6926
  label: "Stacked",
6833
6927
  checked: config.stacked ?? false,
@@ -6835,7 +6929,7 @@ function WidgetEditor({
6835
6929
  }
6836
6930
  ),
6837
6931
  /* @__PURE__ */ jsxRuntime.jsx(
6838
- chunkNY6TZLST_cjs.Checkbox,
6932
+ chunkURJH4H6G_cjs.Checkbox,
6839
6933
  {
6840
6934
  label: "Show Data Labels",
6841
6935
  checked: config.show_data_labels ?? false,
@@ -6850,7 +6944,7 @@ function WidgetEditor({
6850
6944
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
6851
6945
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "X-Axis Column" }),
6852
6946
  /* @__PURE__ */ jsxRuntime.jsx(
6853
- chunkNY6TZLST_cjs.Select,
6947
+ chunkURJH4H6G_cjs.Select,
6854
6948
  {
6855
6949
  value: config.x_axis || "",
6856
6950
  onChange: (value) => updateConfig("x_axis", value),
@@ -6860,7 +6954,7 @@ function WidgetEditor({
6860
6954
  ] }),
6861
6955
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: rowStyle, children: [
6862
6956
  /* @__PURE__ */ jsxRuntime.jsx(
6863
- chunkNY6TZLST_cjs.Checkbox,
6957
+ chunkURJH4H6G_cjs.Checkbox,
6864
6958
  {
6865
6959
  label: "Show Legend",
6866
6960
  checked: config.show_legend ?? true,
@@ -6868,7 +6962,7 @@ function WidgetEditor({
6868
6962
  }
6869
6963
  ),
6870
6964
  /* @__PURE__ */ jsxRuntime.jsx(
6871
- chunkNY6TZLST_cjs.Checkbox,
6965
+ chunkURJH4H6G_cjs.Checkbox,
6872
6966
  {
6873
6967
  label: "Show Data Labels",
6874
6968
  checked: config.show_data_labels ?? false,
@@ -6880,7 +6974,7 @@ function WidgetEditor({
6880
6974
  case "pie_chart":
6881
6975
  return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: rowStyle, children: [
6882
6976
  /* @__PURE__ */ jsxRuntime.jsx(
6883
- chunkNY6TZLST_cjs.Checkbox,
6977
+ chunkURJH4H6G_cjs.Checkbox,
6884
6978
  {
6885
6979
  label: "Show Legend",
6886
6980
  checked: config.show_legend ?? true,
@@ -6888,7 +6982,7 @@ function WidgetEditor({
6888
6982
  }
6889
6983
  ),
6890
6984
  /* @__PURE__ */ jsxRuntime.jsx(
6891
- chunkNY6TZLST_cjs.Checkbox,
6985
+ chunkURJH4H6G_cjs.Checkbox,
6892
6986
  {
6893
6987
  label: "Show Data Labels",
6894
6988
  checked: config.show_data_labels ?? true,
@@ -6901,7 +6995,7 @@ function WidgetEditor({
6901
6995
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
6902
6996
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Page Size" }),
6903
6997
  /* @__PURE__ */ jsxRuntime.jsx(
6904
- chunkNY6TZLST_cjs.Select,
6998
+ chunkURJH4H6G_cjs.Select,
6905
6999
  {
6906
7000
  value: String(config.page_size || 10),
6907
7001
  onChange: (value) => updateConfig("page_size", parseInt(value, 10)),
@@ -6916,7 +7010,7 @@ function WidgetEditor({
6916
7010
  )
6917
7011
  ] }),
6918
7012
  /* @__PURE__ */ jsxRuntime.jsx(
6919
- chunkNY6TZLST_cjs.Checkbox,
7013
+ chunkURJH4H6G_cjs.Checkbox,
6920
7014
  {
6921
7015
  label: "Sortable Columns",
6922
7016
  checked: config.sortable ?? true,
@@ -6949,7 +7043,7 @@ function WidgetEditor({
6949
7043
  )
6950
7044
  ] }),
6951
7045
  /* @__PURE__ */ jsxRuntime.jsx(
6952
- chunkNY6TZLST_cjs.Checkbox,
7046
+ chunkURJH4H6G_cjs.Checkbox,
6953
7047
  {
6954
7048
  label: "Enable Markdown",
6955
7049
  checked: config.markdown ?? true,
@@ -6964,7 +7058,7 @@ function WidgetEditor({
6964
7058
  return /* @__PURE__ */ jsxRuntime.jsx("div", { style: overlayStyle, onClick: onCancel, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: modalStyle, onClick: (e) => e.stopPropagation(), children: [
6965
7059
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerStyle, children: [
6966
7060
  /* @__PURE__ */ jsxRuntime.jsx("h2", { style: titleStyle, children: "Edit Widget" }),
6967
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Button, { variant: "ghost", size: "sm", onClick: onCancel, children: /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "x", size: 20 }) })
7061
+ /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Button, { variant: "ghost", size: "sm", onClick: onCancel, children: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "x", size: 20 }) })
6968
7062
  ] }),
6969
7063
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: bodyStyle, children: [
6970
7064
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: sectionStyle, children: [
@@ -6972,7 +7066,7 @@ function WidgetEditor({
6972
7066
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
6973
7067
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Title" }),
6974
7068
  /* @__PURE__ */ jsxRuntime.jsx(
6975
- chunkNY6TZLST_cjs.Input,
7069
+ chunkURJH4H6G_cjs.Input,
6976
7070
  {
6977
7071
  value: title,
6978
7072
  onChange: (e) => setTitle(e.target.value),
@@ -7008,10 +7102,10 @@ function WidgetEditor({
7008
7102
  },
7009
7103
  children: [
7010
7104
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: theme.spacing.sm }, children: [
7011
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "table", size: 16 }),
7105
+ /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "table", size: 16 }),
7012
7106
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 500, color: theme.colors.text }, children: queryName || "Custom Query" })
7013
7107
  ] }),
7014
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Button, { variant: "ghost", size: "sm", onClick: handleClearQuery, children: /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "x", size: 16 }) })
7108
+ /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Button, { variant: "ghost", size: "sm", onClick: handleClearQuery, children: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "x", size: 16 }) })
7015
7109
  ]
7016
7110
  }
7017
7111
  ),
@@ -7039,11 +7133,11 @@ function WidgetEditor({
7039
7133
  },
7040
7134
  children: [
7041
7135
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { textAlign: "center", color: theme.colors.textMuted }, children: [
7042
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "table", size: 24, style: { marginBottom: theme.spacing.xs } }),
7136
+ /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "table", size: 24, style: { marginBottom: theme.spacing.xs } }),
7043
7137
  /* @__PURE__ */ jsxRuntime.jsx("div", { children: "Select a saved query to power this widget" })
7044
7138
  ] }),
7045
7139
  /* @__PURE__ */ jsxRuntime.jsx(
7046
- chunkNY6TZLST_cjs.SavedQueryPicker,
7140
+ chunkURJH4H6G_cjs.SavedQueryPicker,
7047
7141
  {
7048
7142
  currentQuery: null,
7049
7143
  onSelect: handleSelectSavedQuery,
@@ -7056,8 +7150,8 @@ function WidgetEditor({
7056
7150
  ] })
7057
7151
  ] }),
7058
7152
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: footerStyle, children: [
7059
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Button, { variant: "ghost", onClick: onCancel, children: "Cancel" }),
7060
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Button, { variant: "primary", onClick: handleSave, children: "Save Widget" })
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" })
7061
7155
  ] })
7062
7156
  ] }) });
7063
7157
  }
@@ -7202,31 +7296,31 @@ var DashboardCard = react.forwardRef(
7202
7296
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerStyles, children: [
7203
7297
  /* @__PURE__ */ jsxRuntime.jsx("h3", { style: titleStyles, children: dashboard.name }),
7204
7298
  actions ? actions : /* @__PURE__ */ jsxRuntime.jsxs(
7205
- chunkNY6TZLST_cjs.Dropdown,
7299
+ chunkURJH4H6G_cjs.Dropdown,
7206
7300
  {
7207
7301
  trigger: /* @__PURE__ */ jsxRuntime.jsx(
7208
- chunkNY6TZLST_cjs.Button,
7302
+ chunkURJH4H6G_cjs.Button,
7209
7303
  {
7210
7304
  variant: "ghost",
7211
7305
  size: "sm",
7212
7306
  onClick: (e) => e.stopPropagation(),
7213
7307
  disabled: actionsDisabled,
7214
7308
  "aria-label": "Dashboard actions",
7215
- children: /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "more-vertical", size: 16 })
7309
+ children: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "more-vertical", size: 16 })
7216
7310
  }
7217
7311
  ),
7218
7312
  children: [
7219
- /* @__PURE__ */ jsxRuntime.jsxs(chunkNY6TZLST_cjs.DropdownItem, { onClick: () => handleMenuAction("edit"), children: [
7220
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "edit", size: 14 }),
7313
+ /* @__PURE__ */ jsxRuntime.jsxs(chunkURJH4H6G_cjs.DropdownItem, { onClick: () => handleMenuAction("edit"), children: [
7314
+ /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "edit", size: 14 }),
7221
7315
  "Edit"
7222
7316
  ] }),
7223
- /* @__PURE__ */ jsxRuntime.jsxs(chunkNY6TZLST_cjs.DropdownItem, { onClick: () => handleMenuAction("duplicate"), children: [
7224
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "copy", size: 14 }),
7317
+ /* @__PURE__ */ jsxRuntime.jsxs(chunkURJH4H6G_cjs.DropdownItem, { onClick: () => handleMenuAction("duplicate"), children: [
7318
+ /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "copy", size: 14 }),
7225
7319
  "Duplicate"
7226
7320
  ] }),
7227
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.DropdownSeparator, {}),
7228
- /* @__PURE__ */ jsxRuntime.jsxs(chunkNY6TZLST_cjs.DropdownItem, { onClick: () => handleMenuAction("delete"), children: [
7229
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "trash", size: 14 }),
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 }),
7230
7324
  "Delete"
7231
7325
  ] })
7232
7326
  ]
@@ -7236,13 +7330,13 @@ var DashboardCard = react.forwardRef(
7236
7330
  dashboard.description && /* @__PURE__ */ jsxRuntime.jsx("p", { style: descriptionStyles, children: dashboard.description }),
7237
7331
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: metaStyles, children: [
7238
7332
  /* @__PURE__ */ jsxRuntime.jsxs("span", { style: metaItemStyles, children: [
7239
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "grid", size: 12 }),
7333
+ /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "grid", size: 12 }),
7240
7334
  dashboard.widgets.length,
7241
7335
  " widget",
7242
7336
  dashboard.widgets.length !== 1 ? "s" : ""
7243
7337
  ] }),
7244
7338
  /* @__PURE__ */ jsxRuntime.jsxs("span", { style: metaItemStyles, children: [
7245
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "calendar", size: 12 }),
7339
+ /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "calendar", size: 12 }),
7246
7340
  formatDate(dashboard.updated_at)
7247
7341
  ] }),
7248
7342
  dashboard.is_public ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: publicBadgeStyles, children: "Public" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: privateBadgeStyles, children: "Private" })
@@ -7300,32 +7394,32 @@ var DashboardList = react.forwardRef(
7300
7394
  if (isLoading) {
7301
7395
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, style: { ...containerStyles, ...style }, ...props, children: [
7302
7396
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerStyles2, children: [
7303
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Skeleton, { width: 200, height: 32 }),
7304
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Skeleton, { width: 150, height: 40 })
7397
+ /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Skeleton, { width: 200, height: 32 }),
7398
+ /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Skeleton, { width: 150, height: 40 })
7305
7399
  ] }),
7306
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: getGridStyles(columns), children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Skeleton, { height: 150, style: { borderRadius: "var(--prismiq-radius-lg)" } }, i)) })
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)) })
7307
7401
  ] });
7308
7402
  }
7309
7403
  if (error) {
7310
7404
  return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, style: { ...containerStyles, ...style }, ...props, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: errorStyles, children: [
7311
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "alert-circle", size: 48 }),
7405
+ /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "alert-circle", size: 48 }),
7312
7406
  /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
7313
7407
  "Failed to load dashboards: ",
7314
7408
  error.message
7315
7409
  ] }),
7316
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Button, { variant: "secondary", onClick: () => window.location.reload(), children: "Retry" })
7410
+ /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Button, { variant: "secondary", onClick: () => window.location.reload(), children: "Retry" })
7317
7411
  ] }) });
7318
7412
  }
7319
7413
  if (!dashboards || dashboards.length === 0) {
7320
7414
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, style: { ...containerStyles, ...style }, ...props, children: [
7321
7415
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerStyles2, children: [
7322
7416
  /* @__PURE__ */ jsxRuntime.jsx("h2", { style: titleStyles2, children: "Dashboards" }),
7323
- onCreate && /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Button, { onClick: onCreate, leftIcon: /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "plus", size: 16 }), children: "Create Dashboard" })
7417
+ onCreate && /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Button, { onClick: onCreate, leftIcon: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "plus", size: 16 }), children: "Create Dashboard" })
7324
7418
  ] }),
7325
7419
  emptyState || /* @__PURE__ */ jsxRuntime.jsx(
7326
- chunkNY6TZLST_cjs.EmptyState,
7420
+ chunkURJH4H6G_cjs.EmptyState,
7327
7421
  {
7328
- icon: /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "layout", size: 64 }),
7422
+ icon: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "layout", size: 64 }),
7329
7423
  title: "No dashboards yet",
7330
7424
  description: "Create your first dashboard to start visualizing your data.",
7331
7425
  action: onCreate ? { label: "Create Dashboard", onClick: onCreate } : void 0
@@ -7340,7 +7434,7 @@ var DashboardList = react.forwardRef(
7340
7434
  dashboards.length,
7341
7435
  ")"
7342
7436
  ] }),
7343
- onCreate && /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Button, { onClick: onCreate, leftIcon: /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Icon, { name: "plus", size: 16 }), children: "Create Dashboard" })
7437
+ onCreate && /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Button, { onClick: onCreate, leftIcon: /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Icon, { name: "plus", size: 16 }), children: "Create Dashboard" })
7344
7438
  ] }),
7345
7439
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: getGridStyles(columns), children: dashboards.map((dashboard) => {
7346
7440
  const cardProps = {
@@ -7440,7 +7534,7 @@ var DashboardDialog = react.forwardRef(
7440
7534
  );
7441
7535
  const displayError = validationError || error;
7442
7536
  return /* @__PURE__ */ jsxRuntime.jsx(
7443
- chunkNY6TZLST_cjs.Dialog,
7537
+ chunkURJH4H6G_cjs.Dialog,
7444
7538
  {
7445
7539
  open,
7446
7540
  onClose,
@@ -7452,7 +7546,7 @@ var DashboardDialog = react.forwardRef(
7452
7546
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyles, children: [
7453
7547
  /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "dashboard-name", style: labelStyles, children: "Name" }),
7454
7548
  /* @__PURE__ */ jsxRuntime.jsx(
7455
- chunkNY6TZLST_cjs.Input,
7549
+ chunkURJH4H6G_cjs.Input,
7456
7550
  {
7457
7551
  id: "dashboard-name",
7458
7552
  value: formState.name,
@@ -7466,7 +7560,7 @@ var DashboardDialog = react.forwardRef(
7466
7560
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyles, children: [
7467
7561
  /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "dashboard-description", style: labelStyles, children: "Description (optional)" }),
7468
7562
  /* @__PURE__ */ jsxRuntime.jsx(
7469
- chunkNY6TZLST_cjs.Input,
7563
+ chunkURJH4H6G_cjs.Input,
7470
7564
  {
7471
7565
  id: "dashboard-description",
7472
7566
  value: formState.description,
@@ -7478,7 +7572,7 @@ var DashboardDialog = react.forwardRef(
7478
7572
  ] }),
7479
7573
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: checkboxContainerStyles, children: [
7480
7574
  /* @__PURE__ */ jsxRuntime.jsx(
7481
- chunkNY6TZLST_cjs.Checkbox,
7575
+ chunkURJH4H6G_cjs.Checkbox,
7482
7576
  {
7483
7577
  id: "dashboard-public",
7484
7578
  checked: formState.isPublic,
@@ -7488,9 +7582,9 @@ var DashboardDialog = react.forwardRef(
7488
7582
  ),
7489
7583
  /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "dashboard-public", style: checkboxLabelStyles, children: "Make this dashboard public" })
7490
7584
  ] }),
7491
- /* @__PURE__ */ jsxRuntime.jsxs(chunkNY6TZLST_cjs.DialogFooter, { children: [
7585
+ /* @__PURE__ */ jsxRuntime.jsxs(chunkURJH4H6G_cjs.DialogFooter, { children: [
7492
7586
  /* @__PURE__ */ jsxRuntime.jsx(
7493
- chunkNY6TZLST_cjs.Button,
7587
+ chunkURJH4H6G_cjs.Button,
7494
7588
  {
7495
7589
  type: "button",
7496
7590
  variant: "secondary",
@@ -7499,7 +7593,7 @@ var DashboardDialog = react.forwardRef(
7499
7593
  children: "Cancel"
7500
7594
  }
7501
7595
  ),
7502
- /* @__PURE__ */ jsxRuntime.jsx(chunkNY6TZLST_cjs.Button, { type: "submit", loading: isLoading, children: isEditMode ? "Save Changes" : "Create Dashboard" })
7596
+ /* @__PURE__ */ jsxRuntime.jsx(chunkURJH4H6G_cjs.Button, { type: "submit", loading: isLoading, children: isEditMode ? "Save Changes" : "Create Dashboard" })
7503
7597
  ] })
7504
7598
  ] })
7505
7599
  }
@@ -7539,5 +7633,5 @@ exports.useDashboardFilters = useDashboardFilters;
7539
7633
  exports.useFullscreen = useFullscreen;
7540
7634
  exports.useWidget = useWidget;
7541
7635
  exports.useWidgetVisibility = useWidgetVisibility;
7542
- //# sourceMappingURL=chunk-FEABEF3J.cjs.map
7543
- //# sourceMappingURL=chunk-FEABEF3J.cjs.map
7636
+ //# sourceMappingURL=chunk-VQDFS6VS.cjs.map
7637
+ //# sourceMappingURL=chunk-VQDFS6VS.cjs.map