@prismiq/react 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{CustomSQLEditor-DYeId0Gp.d.ts → ChatBubble-ARocmvZD.d.cts} +48 -4
- package/dist/{CustomSQLEditor-BXB4rf1q.d.cts → ChatBubble-BN_CjIpk.d.ts} +48 -4
- package/dist/{DashboardDialog-B3vYC5Gs.d.ts → DashboardDialog-UhUGXx2h.d.ts} +6 -4
- package/dist/{DashboardDialog-LHmrtNQU.d.cts → DashboardDialog-Z-HypxmG.d.cts} +6 -4
- package/dist/{accessibility-2yy5yqRR.d.cts → accessibility-Bu2mNtaB.d.cts} +1 -1
- package/dist/{accessibility-2yy5yqRR.d.ts → accessibility-Bu2mNtaB.d.ts} +1 -1
- package/dist/charts/index.cjs +27 -27
- package/dist/charts/index.d.cts +2 -2
- package/dist/charts/index.d.ts +2 -2
- package/dist/charts/index.js +2 -2
- package/dist/{chunk-NK7HKX2J.cjs → chunk-73TPDGXB.cjs} +7 -7
- package/dist/{chunk-NK7HKX2J.cjs.map → chunk-73TPDGXB.cjs.map} +1 -1
- package/dist/{chunk-FEABEF3J.cjs → chunk-FKXCINUF.cjs} +551 -299
- package/dist/chunk-FKXCINUF.cjs.map +1 -0
- package/dist/{chunk-2H5WTH4K.js → chunk-FQ23KG6G.js} +3 -3
- package/dist/{chunk-2H5WTH4K.js.map → chunk-FQ23KG6G.js.map} +1 -1
- package/dist/{chunk-UPYINBZU.js → chunk-GELI7MDZ.js} +982 -51
- package/dist/chunk-GELI7MDZ.js.map +1 -0
- package/dist/{chunk-WWTT2OJ5.js → chunk-HKZFEXT6.js} +27 -9
- package/dist/chunk-HKZFEXT6.js.map +1 -0
- package/dist/{chunk-MOAEEF5P.js → chunk-JBJ5LEAG.js} +362 -110
- package/dist/chunk-JBJ5LEAG.js.map +1 -0
- package/dist/{chunk-4AVL6GQK.cjs → chunk-KXB2IZI2.cjs} +36 -9
- package/dist/chunk-KXB2IZI2.cjs.map +1 -0
- package/dist/{chunk-EX74SI67.js → chunk-LBE6GIBC.js} +36 -9
- package/dist/chunk-LBE6GIBC.js.map +1 -0
- package/dist/{chunk-NY6TZLST.cjs → chunk-PG7QBH3G.cjs} +988 -53
- package/dist/chunk-PG7QBH3G.cjs.map +1 -0
- package/dist/{chunk-MDXGGZSW.cjs → chunk-ZYVN6XAZ.cjs} +35 -37
- package/dist/chunk-ZYVN6XAZ.cjs.map +1 -0
- package/dist/components/index.cjs +63 -55
- package/dist/components/index.d.cts +2 -2
- package/dist/components/index.d.ts +2 -2
- package/dist/components/index.js +2 -2
- package/dist/dashboard/index.cjs +36 -36
- package/dist/dashboard/index.d.cts +7 -5
- package/dist/dashboard/index.d.ts +7 -5
- package/dist/dashboard/index.js +4 -4
- package/dist/export/index.cjs +7 -7
- package/dist/export/index.d.cts +6 -4
- package/dist/export/index.d.ts +6 -4
- package/dist/export/index.js +1 -1
- package/dist/{index-C-Qcuu4Y.d.cts → index-B8DelfpL.d.cts} +2 -2
- package/dist/{index-rPc7ijt8.d.ts → index-RbfYPQD_.d.ts} +2 -2
- package/dist/index.cjs +150 -134
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +97 -9
- package/dist/index.d.ts +97 -9
- package/dist/index.js +7 -7
- package/dist/index.js.map +1 -1
- package/dist/{types-WrCbOeAV.d.cts → types-ccB9Ps3k.d.cts} +59 -1
- package/dist/{types-WrCbOeAV.d.ts → types-ccB9Ps3k.d.ts} +59 -1
- package/dist/utils/index.cjs +15 -15
- package/dist/utils/index.d.cts +5 -21
- package/dist/utils/index.d.ts +5 -21
- package/dist/utils/index.js +1 -1
- package/package.json +3 -7
- package/dist/chunk-4AVL6GQK.cjs.map +0 -1
- package/dist/chunk-EX74SI67.js.map +0 -1
- package/dist/chunk-FEABEF3J.cjs.map +0 -1
- package/dist/chunk-MDXGGZSW.cjs.map +0 -1
- package/dist/chunk-MOAEEF5P.js.map +0 -1
- package/dist/chunk-NY6TZLST.cjs.map +0 -1
- package/dist/chunk-UPYINBZU.js.map +0 -1
- package/dist/chunk-WWTT2OJ5.js.map +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
3
|
+
var chunk73TPDGXB_cjs = require('./chunk-73TPDGXB.cjs');
|
|
4
|
+
var chunkPG7QBH3G_cjs = require('./chunk-PG7QBH3G.cjs');
|
|
5
5
|
var chunkLMTG3LRC_cjs = require('./chunk-LMTG3LRC.cjs');
|
|
6
|
-
var
|
|
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 } =
|
|
155
|
-
const crossFilterContext =
|
|
154
|
+
const { client } = chunkPG7QBH3G_cjs.useAnalytics();
|
|
155
|
+
const crossFilterContext = chunkPG7QBH3G_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) => ({
|
|
@@ -181,7 +182,8 @@ function DashboardProvider({
|
|
|
181
182
|
if (!lazyLoadingEnabledRef.current) {
|
|
182
183
|
const initialLoadingState = {};
|
|
183
184
|
data.widgets.forEach((widget) => {
|
|
184
|
-
|
|
185
|
+
const isSqlMode = widget.config?.data_source_mode === "sql" && widget.config?.raw_sql;
|
|
186
|
+
if (widget.query || isSqlMode) {
|
|
185
187
|
initialLoadingState[widget.id] = true;
|
|
186
188
|
}
|
|
187
189
|
});
|
|
@@ -189,8 +191,9 @@ function DashboardProvider({
|
|
|
189
191
|
}
|
|
190
192
|
}, []);
|
|
191
193
|
const executeWidgetQuery = react.useCallback(
|
|
192
|
-
async (widget, currentDashboard, currentFilters, currentCrossFilters, bypassCache = false) => {
|
|
193
|
-
|
|
194
|
+
async (widget, currentDashboard, currentFilters, currentCrossFilters, bypassCache = false, signal) => {
|
|
195
|
+
const isSqlMode = widget.config?.data_source_mode === "sql" && widget.config?.raw_sql;
|
|
196
|
+
if (!widget.query && !isSqlMode) {
|
|
194
197
|
return;
|
|
195
198
|
}
|
|
196
199
|
setWidgetLoading((prev) => ({ ...prev, [widget.id]: true }));
|
|
@@ -203,22 +206,32 @@ function DashboardProvider({
|
|
|
203
206
|
return next;
|
|
204
207
|
});
|
|
205
208
|
try {
|
|
206
|
-
let
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
209
|
+
let result;
|
|
210
|
+
if (isSqlMode) {
|
|
211
|
+
result = await client.executeSQL(widget.config.raw_sql);
|
|
212
|
+
} else {
|
|
213
|
+
let query = applyFiltersToQuery(
|
|
214
|
+
widget.query,
|
|
215
|
+
currentDashboard,
|
|
216
|
+
currentFilters
|
|
217
|
+
);
|
|
218
|
+
query = applyCrossFiltersToQuery(query, currentCrossFilters, widget.id);
|
|
219
|
+
result = await client.executeQuery(query, bypassCache, signal);
|
|
220
|
+
}
|
|
221
|
+
if (signal?.aborted) return;
|
|
213
222
|
setWidgetResults((prev) => ({ ...prev, [widget.id]: result }));
|
|
214
223
|
const refreshTime = result.cached_at ?? Date.now() / 1e3;
|
|
215
224
|
setWidgetRefreshTimes((prev) => ({ ...prev, [widget.id]: refreshTime }));
|
|
216
225
|
} catch (err) {
|
|
226
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
217
229
|
setWidgetErrors((prev) => ({
|
|
218
230
|
...prev,
|
|
219
231
|
[widget.id]: err instanceof Error ? err : new Error("Query failed")
|
|
220
232
|
}));
|
|
221
233
|
} finally {
|
|
234
|
+
if (signal?.aborted) return;
|
|
222
235
|
setWidgetLoading((prev) => ({ ...prev, [widget.id]: false }));
|
|
223
236
|
if (bypassCache) {
|
|
224
237
|
setRefreshingWidgets((prev) => {
|
|
@@ -232,9 +245,12 @@ function DashboardProvider({
|
|
|
232
245
|
[client]
|
|
233
246
|
);
|
|
234
247
|
const executeWidgetsInBatches = react.useCallback(
|
|
235
|
-
async (widgets, currentDashboard, currentFilters, currentCrossFilters, bypassCache = false, currentBatchSize = batchSize) => {
|
|
236
|
-
const widgetsWithQueries = widgets.filter(
|
|
248
|
+
async (widgets, currentDashboard, currentFilters, currentCrossFilters, bypassCache = false, currentBatchSize = batchSize, signal) => {
|
|
249
|
+
const widgetsWithQueries = widgets.filter(
|
|
250
|
+
(w) => w.query !== null || w.config?.data_source_mode === "sql" && w.config?.raw_sql
|
|
251
|
+
);
|
|
237
252
|
for (let i = 0; i < widgetsWithQueries.length; i += currentBatchSize) {
|
|
253
|
+
if (signal?.aborted) return;
|
|
238
254
|
const batch = widgetsWithQueries.slice(i, i + currentBatchSize);
|
|
239
255
|
await Promise.all(
|
|
240
256
|
batch.map(
|
|
@@ -243,7 +259,8 @@ function DashboardProvider({
|
|
|
243
259
|
currentDashboard,
|
|
244
260
|
currentFilters,
|
|
245
261
|
currentCrossFilters,
|
|
246
|
-
bypassCache
|
|
262
|
+
bypassCache,
|
|
263
|
+
signal
|
|
247
264
|
)
|
|
248
265
|
)
|
|
249
266
|
);
|
|
@@ -255,16 +272,19 @@ function DashboardProvider({
|
|
|
255
272
|
async (currentDashboard, currentFilters, currentCrossFilters) => {
|
|
256
273
|
const requestId = Math.random().toString(36).substring(2, 11);
|
|
257
274
|
requestIdRef.current = requestId;
|
|
275
|
+
const signal = abortControllerRef.current?.signal;
|
|
258
276
|
await executeWidgetsInBatches(
|
|
259
277
|
currentDashboard.widgets,
|
|
260
278
|
currentDashboard,
|
|
261
279
|
currentFilters,
|
|
262
280
|
currentCrossFilters,
|
|
263
|
-
false
|
|
281
|
+
false,
|
|
264
282
|
// Don't bypass cache on initial load
|
|
283
|
+
batchSize,
|
|
284
|
+
signal
|
|
265
285
|
);
|
|
266
286
|
},
|
|
267
|
-
[executeWidgetsInBatches]
|
|
287
|
+
[executeWidgetsInBatches, batchSize]
|
|
268
288
|
);
|
|
269
289
|
const refreshDashboard = react.useCallback(async () => {
|
|
270
290
|
if (!dashboard) return;
|
|
@@ -427,16 +447,19 @@ function DashboardProvider({
|
|
|
427
447
|
react.useEffect(() => {
|
|
428
448
|
if (!lazyLoadingEnabled || !dashboard || isLoading) return;
|
|
429
449
|
const widgetsToLoad = dashboard.widgets.filter(
|
|
430
|
-
(w) => visibleWidgets.has(w.id) && w.query !== null && !widgetResults[w.id] && !widgetLoading[w.id]
|
|
450
|
+
(w) => visibleWidgets.has(w.id) && (w.query !== null || w.config?.data_source_mode === "sql" && w.config?.raw_sql) && !widgetResults[w.id] && !widgetLoading[w.id]
|
|
431
451
|
);
|
|
432
452
|
if (widgetsToLoad.length > 0) {
|
|
453
|
+
const signal = abortControllerRef.current?.signal;
|
|
433
454
|
executeWidgetsInBatches(
|
|
434
455
|
widgetsToLoad,
|
|
435
456
|
dashboard,
|
|
436
457
|
filterValues,
|
|
437
458
|
crossFilters,
|
|
438
|
-
false
|
|
459
|
+
false,
|
|
439
460
|
// Don't bypass cache
|
|
461
|
+
batchSize,
|
|
462
|
+
signal
|
|
440
463
|
);
|
|
441
464
|
}
|
|
442
465
|
}, [
|
|
@@ -448,7 +471,8 @@ function DashboardProvider({
|
|
|
448
471
|
widgetLoading,
|
|
449
472
|
filterValues,
|
|
450
473
|
crossFilters,
|
|
451
|
-
executeWidgetsInBatches
|
|
474
|
+
executeWidgetsInBatches,
|
|
475
|
+
batchSize
|
|
452
476
|
]);
|
|
453
477
|
const filterValuesKey = JSON.stringify(filterValues);
|
|
454
478
|
const prevFilterValuesRef = react.useRef(filterValuesKey);
|
|
@@ -457,16 +481,21 @@ function DashboardProvider({
|
|
|
457
481
|
if (prevFilterValuesRef.current === filterValuesKey) return;
|
|
458
482
|
prevFilterValuesRef.current = filterValuesKey;
|
|
459
483
|
const widgetsToRefresh = dashboard.widgets.filter(
|
|
460
|
-
(w) => everVisibleWidgets.has(w.id) && w.query !== null && widgetResults[w.id]
|
|
484
|
+
(w) => everVisibleWidgets.has(w.id) && (w.query !== null || w.config?.data_source_mode === "sql" && w.config?.raw_sql) && widgetResults[w.id]
|
|
461
485
|
// Only re-execute if previously loaded
|
|
462
486
|
);
|
|
463
487
|
if (widgetsToRefresh.length > 0) {
|
|
488
|
+
abortControllerRef.current?.abort();
|
|
489
|
+
const controller = new AbortController();
|
|
490
|
+
abortControllerRef.current = controller;
|
|
464
491
|
executeWidgetsInBatches(
|
|
465
492
|
widgetsToRefresh,
|
|
466
493
|
dashboard,
|
|
467
494
|
filterValues,
|
|
468
495
|
crossFilters,
|
|
469
|
-
false
|
|
496
|
+
false,
|
|
497
|
+
batchSize,
|
|
498
|
+
controller.signal
|
|
470
499
|
);
|
|
471
500
|
}
|
|
472
501
|
}, [
|
|
@@ -478,8 +507,16 @@ function DashboardProvider({
|
|
|
478
507
|
widgetResults,
|
|
479
508
|
filterValues,
|
|
480
509
|
crossFilters,
|
|
481
|
-
executeWidgetsInBatches
|
|
510
|
+
executeWidgetsInBatches,
|
|
511
|
+
batchSize
|
|
482
512
|
]);
|
|
513
|
+
react.useEffect(() => {
|
|
514
|
+
const controller = new AbortController();
|
|
515
|
+
abortControllerRef.current = controller;
|
|
516
|
+
return () => {
|
|
517
|
+
controller.abort();
|
|
518
|
+
};
|
|
519
|
+
}, [dashboardId]);
|
|
483
520
|
const contextValue = react.useMemo(
|
|
484
521
|
() => ({
|
|
485
522
|
dashboard,
|
|
@@ -1026,7 +1063,7 @@ function EditableDashboardLayout({
|
|
|
1026
1063
|
className = ""
|
|
1027
1064
|
}) {
|
|
1028
1065
|
const { theme } = chunkLMTG3LRC_cjs.useTheme();
|
|
1029
|
-
const { queueUpdate, status, error } =
|
|
1066
|
+
const { queueUpdate, status, error } = chunkPG7QBH3G_cjs.useDebouncedLayoutSave({
|
|
1030
1067
|
dashboardId,
|
|
1031
1068
|
debounceMs,
|
|
1032
1069
|
savedDurationMs,
|
|
@@ -1074,7 +1111,7 @@ function EditableDashboardLayout({
|
|
|
1074
1111
|
style: containerStyles2,
|
|
1075
1112
|
"data-testid": "dashboard-container",
|
|
1076
1113
|
children: [
|
|
1077
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: statusBarStyles, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1114
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: statusBarStyles, children: /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.AutoSaveIndicator, { status, error }) }),
|
|
1078
1115
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1079
1116
|
DashboardLayout,
|
|
1080
1117
|
{
|
|
@@ -1151,7 +1188,7 @@ function WidgetHeader({
|
|
|
1151
1188
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerStyle, className: "prismiq-widget-header", children: [
|
|
1152
1189
|
/* @__PURE__ */ jsxRuntime.jsx("h3", { style: titleStyle, children: title }),
|
|
1153
1190
|
/* @__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:
|
|
1191
|
+
lastRefreshed !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { style: timestampStyle, title: `Last refreshed: ${new Date(lastRefreshed * 1e3).toLocaleString()}`, children: chunkKXB2IZI2_cjs.formatRelativeTime(lastRefreshed) }),
|
|
1155
1192
|
onRefresh && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1156
1193
|
"button",
|
|
1157
1194
|
{
|
|
@@ -1162,7 +1199,7 @@ function WidgetHeader({
|
|
|
1162
1199
|
"aria-label": isRefreshing ? "Refreshing..." : "Refresh widget",
|
|
1163
1200
|
title: isRefreshing ? "Refreshing..." : "Refresh widget",
|
|
1164
1201
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1165
|
-
|
|
1202
|
+
chunkPG7QBH3G_cjs.Icon,
|
|
1166
1203
|
{
|
|
1167
1204
|
name: "sync",
|
|
1168
1205
|
size: 16,
|
|
@@ -1181,7 +1218,7 @@ function WidgetHeader({
|
|
|
1181
1218
|
style: actionButtonStyle,
|
|
1182
1219
|
className: "prismiq-widget-action-button",
|
|
1183
1220
|
"aria-label": hyperlink.title ?? "Open link",
|
|
1184
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1221
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "link", size: 16 })
|
|
1185
1222
|
}
|
|
1186
1223
|
)
|
|
1187
1224
|
] }),
|
|
@@ -1249,7 +1286,7 @@ function TextContent({ config }) {
|
|
|
1249
1286
|
"div",
|
|
1250
1287
|
{
|
|
1251
1288
|
style: contentStyle,
|
|
1252
|
-
dangerouslySetInnerHTML: { __html:
|
|
1289
|
+
dangerouslySetInnerHTML: { __html: chunkKXB2IZI2_cjs.parseMarkdownSafe(config.content, codeStyle) }
|
|
1253
1290
|
}
|
|
1254
1291
|
);
|
|
1255
1292
|
}
|
|
@@ -1376,7 +1413,7 @@ function WidgetContent({
|
|
|
1376
1413
|
isRefreshing = false
|
|
1377
1414
|
}) {
|
|
1378
1415
|
const { theme } = chunkLMTG3LRC_cjs.useTheme();
|
|
1379
|
-
const crossFilterContext =
|
|
1416
|
+
const crossFilterContext = chunkPG7QBH3G_cjs.useCrossFilterOptional();
|
|
1380
1417
|
const data = react.useMemo(() => result ? resultToDataPoints(result) : [], [result]);
|
|
1381
1418
|
const chartTypesWithCrossFilter = ["bar_chart", "pie_chart", "line_chart", "area_chart"];
|
|
1382
1419
|
const defaultCrossFilterEnabled = chartTypesWithCrossFilter.includes(widget.type);
|
|
@@ -1415,7 +1452,7 @@ function WidgetContent({
|
|
|
1415
1452
|
);
|
|
1416
1453
|
const dateFormatters = react.useMemo(() => {
|
|
1417
1454
|
if (widget.type === "table" && widget.config.dateFormats) {
|
|
1418
|
-
return
|
|
1455
|
+
return chunkKXB2IZI2_cjs.createDateFormatters(widget.config.dateFormats);
|
|
1419
1456
|
}
|
|
1420
1457
|
return void 0;
|
|
1421
1458
|
}, [widget.type, widget.config.dateFormats]);
|
|
@@ -1452,6 +1489,9 @@ function WidgetContent({
|
|
|
1452
1489
|
if (widget.type === "text") {
|
|
1453
1490
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: containerStyle, children: /* @__PURE__ */ jsxRuntime.jsx(TextContent, { config: widget.config }) });
|
|
1454
1491
|
}
|
|
1492
|
+
if (!result && !error && widget.query) {
|
|
1493
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: containerStyle, children: /* @__PURE__ */ jsxRuntime.jsx(LoadingState, {}) });
|
|
1494
|
+
}
|
|
1455
1495
|
if (!result || result.row_count === 0) {
|
|
1456
1496
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: containerStyle, children: /* @__PURE__ */ jsxRuntime.jsx(EmptyState2, {}) });
|
|
1457
1497
|
}
|
|
@@ -1467,7 +1507,7 @@ function WidgetContent({
|
|
|
1467
1507
|
const comparisonValue = widget.config.trend_comparison ? result.rows[0]?.[result.columns.indexOf(widget.config.trend_comparison)] : void 0;
|
|
1468
1508
|
return wrapWithContainer(
|
|
1469
1509
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1470
|
-
|
|
1510
|
+
chunk73TPDGXB_cjs.MetricCard,
|
|
1471
1511
|
{
|
|
1472
1512
|
title: "",
|
|
1473
1513
|
value: typeof value === "number" ? value : Number(value) || 0,
|
|
@@ -1487,7 +1527,7 @@ function WidgetContent({
|
|
|
1487
1527
|
case "bar_chart":
|
|
1488
1528
|
return wrapWithContainer(
|
|
1489
1529
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1490
|
-
|
|
1530
|
+
chunk73TPDGXB_cjs.BarChart,
|
|
1491
1531
|
{
|
|
1492
1532
|
data,
|
|
1493
1533
|
xAxis,
|
|
@@ -1513,7 +1553,7 @@ function WidgetContent({
|
|
|
1513
1553
|
case "line_chart":
|
|
1514
1554
|
return wrapWithContainer(
|
|
1515
1555
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1516
|
-
|
|
1556
|
+
chunk73TPDGXB_cjs.LineChart,
|
|
1517
1557
|
{
|
|
1518
1558
|
data,
|
|
1519
1559
|
xAxis,
|
|
@@ -1535,7 +1575,7 @@ function WidgetContent({
|
|
|
1535
1575
|
case "area_chart":
|
|
1536
1576
|
return wrapWithContainer(
|
|
1537
1577
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1538
|
-
|
|
1578
|
+
chunk73TPDGXB_cjs.AreaChart,
|
|
1539
1579
|
{
|
|
1540
1580
|
data,
|
|
1541
1581
|
xAxis,
|
|
@@ -1554,7 +1594,7 @@ function WidgetContent({
|
|
|
1554
1594
|
case "pie_chart":
|
|
1555
1595
|
return wrapWithContainer(
|
|
1556
1596
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1557
|
-
|
|
1597
|
+
chunk73TPDGXB_cjs.PieChart,
|
|
1558
1598
|
{
|
|
1559
1599
|
data,
|
|
1560
1600
|
labelColumn: xAxis,
|
|
@@ -1573,7 +1613,7 @@ function WidgetContent({
|
|
|
1573
1613
|
case "scatter_chart":
|
|
1574
1614
|
return wrapWithContainer(
|
|
1575
1615
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1576
|
-
|
|
1616
|
+
chunk73TPDGXB_cjs.ScatterChart,
|
|
1577
1617
|
{
|
|
1578
1618
|
data,
|
|
1579
1619
|
xAxis,
|
|
@@ -1588,10 +1628,22 @@ function WidgetContent({
|
|
|
1588
1628
|
const dimensionColumns = result.columns.filter(
|
|
1589
1629
|
(col) => col !== widget.config.pivot_column && col !== widget.config.value_column
|
|
1590
1630
|
);
|
|
1591
|
-
|
|
1631
|
+
let pivotColumnFormat;
|
|
1632
|
+
if (widget.config.dateFormats?.[widget.config.pivot_column]) {
|
|
1633
|
+
pivotColumnFormat = widget.config.dateFormats[widget.config.pivot_column];
|
|
1634
|
+
} else if (widget.query) {
|
|
1635
|
+
const pivotCol = widget.query.columns.find(
|
|
1636
|
+
(c) => c.alias === widget.config.pivot_column || c.column === widget.config.pivot_column
|
|
1637
|
+
);
|
|
1638
|
+
if (pivotCol?.date_format) {
|
|
1639
|
+
pivotColumnFormat = pivotCol.date_format;
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
tableResult = chunkKXB2IZI2_cjs.pivotQueryResult(result, {
|
|
1592
1643
|
pivotColumn: widget.config.pivot_column,
|
|
1593
1644
|
valueColumn: widget.config.value_column,
|
|
1594
|
-
dimensionColumns
|
|
1645
|
+
dimensionColumns,
|
|
1646
|
+
pivotColumnFormat
|
|
1595
1647
|
});
|
|
1596
1648
|
}
|
|
1597
1649
|
const tableContainerStyle = {
|
|
@@ -1603,7 +1655,7 @@ function WidgetContent({
|
|
|
1603
1655
|
position: "relative"
|
|
1604
1656
|
};
|
|
1605
1657
|
const tableContent = /* @__PURE__ */ jsxRuntime.jsx(
|
|
1606
|
-
|
|
1658
|
+
chunkPG7QBH3G_cjs.ResultsTable,
|
|
1607
1659
|
{
|
|
1608
1660
|
result: tableResult,
|
|
1609
1661
|
pageSize: widget.config.page_size ?? 10,
|
|
@@ -1742,7 +1794,7 @@ function WidgetContainer({
|
|
|
1742
1794
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: contentStyles, children }),
|
|
1743
1795
|
editable && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: overlayStyles, children: [
|
|
1744
1796
|
onDuplicate && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1745
|
-
|
|
1797
|
+
chunkPG7QBH3G_cjs.Button,
|
|
1746
1798
|
{
|
|
1747
1799
|
size: "sm",
|
|
1748
1800
|
variant: "secondary",
|
|
@@ -1752,11 +1804,11 @@ function WidgetContainer({
|
|
|
1752
1804
|
},
|
|
1753
1805
|
title: "Duplicate",
|
|
1754
1806
|
"data-testid": "duplicate-widget-button",
|
|
1755
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1807
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "copy", size: 14 })
|
|
1756
1808
|
}
|
|
1757
1809
|
),
|
|
1758
1810
|
onEdit && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1759
|
-
|
|
1811
|
+
chunkPG7QBH3G_cjs.Button,
|
|
1760
1812
|
{
|
|
1761
1813
|
size: "sm",
|
|
1762
1814
|
variant: "secondary",
|
|
@@ -1766,11 +1818,11 @@ function WidgetContainer({
|
|
|
1766
1818
|
},
|
|
1767
1819
|
title: "Edit",
|
|
1768
1820
|
"data-testid": "edit-widget-button",
|
|
1769
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1821
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "edit", size: 14 })
|
|
1770
1822
|
}
|
|
1771
1823
|
),
|
|
1772
1824
|
onDelete && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1773
|
-
|
|
1825
|
+
chunkPG7QBH3G_cjs.Button,
|
|
1774
1826
|
{
|
|
1775
1827
|
size: "sm",
|
|
1776
1828
|
variant: "danger",
|
|
@@ -1780,7 +1832,7 @@ function WidgetContainer({
|
|
|
1780
1832
|
},
|
|
1781
1833
|
title: "Delete",
|
|
1782
1834
|
"data-testid": "delete-widget-button",
|
|
1783
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1835
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "trash", size: 14 })
|
|
1784
1836
|
}
|
|
1785
1837
|
)
|
|
1786
1838
|
] }),
|
|
@@ -1958,7 +2010,7 @@ function DateRangeFilter({
|
|
|
1958
2010
|
] });
|
|
1959
2011
|
}
|
|
1960
2012
|
function useDynamicFilterOptions(filter, limit = 100) {
|
|
1961
|
-
const { client } =
|
|
2013
|
+
const { client } = chunkPG7QBH3G_cjs.useAnalytics();
|
|
1962
2014
|
const [isLoading, setIsLoading] = react.useState(false);
|
|
1963
2015
|
const [options, setOptions] = react.useState([]);
|
|
1964
2016
|
const [error, setError] = react.useState(null);
|
|
@@ -2255,7 +2307,7 @@ function MultiSelectFilter({
|
|
|
2255
2307
|
disabled: isLoading,
|
|
2256
2308
|
children: [
|
|
2257
2309
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: displayText }),
|
|
2258
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2310
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: isOpen ? "chevron-up" : "chevron-down", size: 14 })
|
|
2259
2311
|
]
|
|
2260
2312
|
}
|
|
2261
2313
|
),
|
|
@@ -2304,7 +2356,7 @@ function MultiSelectFilter({
|
|
|
2304
2356
|
backgroundColor: isAllSelected ? theme.colors.primary : theme.colors.background,
|
|
2305
2357
|
borderColor: isAllSelected ? theme.colors.primary : theme.colors.border
|
|
2306
2358
|
},
|
|
2307
|
-
children: isAllSelected && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2359
|
+
children: isAllSelected && /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "check", size: 12, style: { color: "#fff" } })
|
|
2308
2360
|
}
|
|
2309
2361
|
),
|
|
2310
2362
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "All" })
|
|
@@ -2330,7 +2382,7 @@ function MultiSelectFilter({
|
|
|
2330
2382
|
backgroundColor: isSelected ? theme.colors.primary : theme.colors.background,
|
|
2331
2383
|
borderColor: isSelected ? theme.colors.primary : theme.colors.border
|
|
2332
2384
|
},
|
|
2333
|
-
children: isSelected && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2385
|
+
children: isSelected && /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "check", size: 12, style: { color: "#fff" } })
|
|
2334
2386
|
}
|
|
2335
2387
|
),
|
|
2336
2388
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: option.label })
|
|
@@ -2425,7 +2477,7 @@ function TextFilter({
|
|
|
2425
2477
|
justifyContent: "center"
|
|
2426
2478
|
};
|
|
2427
2479
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: containerStyle, children: [
|
|
2428
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2480
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "search", size: 14, style: iconStyle }),
|
|
2429
2481
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2430
2482
|
"input",
|
|
2431
2483
|
{
|
|
@@ -2444,7 +2496,7 @@ function TextFilter({
|
|
|
2444
2496
|
onClick: handleClear,
|
|
2445
2497
|
style: clearButtonStyle,
|
|
2446
2498
|
"aria-label": "Clear filter",
|
|
2447
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2499
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "x", size: 14 })
|
|
2448
2500
|
}
|
|
2449
2501
|
)
|
|
2450
2502
|
] });
|
|
@@ -2498,7 +2550,7 @@ function FilterBar({
|
|
|
2498
2550
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: filter.label }),
|
|
2499
2551
|
renderFilter(filter, values, onChange)
|
|
2500
2552
|
] }, filter.id)),
|
|
2501
|
-
onReset && /* @__PURE__ */ jsxRuntime.jsx("div", { style: actionsStyle, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2553
|
+
onReset && /* @__PURE__ */ jsxRuntime.jsx("div", { style: actionsStyle, children: /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Button, { variant: "ghost", size: "sm", onClick: handleReset, children: "Reset" }) })
|
|
2502
2554
|
] });
|
|
2503
2555
|
}
|
|
2504
2556
|
function renderFilter(filter, values, onChange) {
|
|
@@ -2572,7 +2624,7 @@ function DashboardContent({
|
|
|
2572
2624
|
refreshWidget
|
|
2573
2625
|
} = useDashboard();
|
|
2574
2626
|
const { filters, values, setValue, resetAll } = useDashboardFilters();
|
|
2575
|
-
const crossFilterContext =
|
|
2627
|
+
const crossFilterContext = chunkPG7QBH3G_cjs.useCrossFilterOptional();
|
|
2576
2628
|
const renderWidget = react.useCallback(
|
|
2577
2629
|
(widget) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2578
2630
|
LazyWidget,
|
|
@@ -2715,7 +2767,7 @@ function DashboardContent({
|
|
|
2715
2767
|
] }, filter.sourceWidgetId)),
|
|
2716
2768
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: 1 } }),
|
|
2717
2769
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2718
|
-
|
|
2770
|
+
chunkPG7QBH3G_cjs.Button,
|
|
2719
2771
|
{
|
|
2720
2772
|
variant: "ghost",
|
|
2721
2773
|
size: "sm",
|
|
@@ -2744,7 +2796,7 @@ function Dashboard({
|
|
|
2744
2796
|
lazyLoading,
|
|
2745
2797
|
className = ""
|
|
2746
2798
|
}) {
|
|
2747
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2799
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.CrossFilterProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2748
2800
|
DashboardProvider,
|
|
2749
2801
|
{
|
|
2750
2802
|
dashboardId: id,
|
|
@@ -2852,37 +2904,37 @@ function EditorToolbar({
|
|
|
2852
2904
|
) : /* @__PURE__ */ jsxRuntime.jsx("h2", { style: titleStyle, children: dashboardName || "New Dashboard" }),
|
|
2853
2905
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: actionsStyle, children: [
|
|
2854
2906
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2855
|
-
|
|
2907
|
+
chunkPG7QBH3G_cjs.Button,
|
|
2856
2908
|
{
|
|
2857
2909
|
variant: "secondary",
|
|
2858
2910
|
size: "sm",
|
|
2859
2911
|
onClick: onAddWidget,
|
|
2860
2912
|
children: [
|
|
2861
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2913
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "plus", size: 16 }),
|
|
2862
2914
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { marginLeft: theme.spacing.xs }, children: "Add Widget" })
|
|
2863
2915
|
]
|
|
2864
2916
|
}
|
|
2865
2917
|
),
|
|
2866
2918
|
onEditFilters && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2867
|
-
|
|
2919
|
+
chunkPG7QBH3G_cjs.Button,
|
|
2868
2920
|
{
|
|
2869
2921
|
variant: "ghost",
|
|
2870
2922
|
size: "sm",
|
|
2871
2923
|
onClick: onEditFilters,
|
|
2872
2924
|
children: [
|
|
2873
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2925
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "filter", size: 16 }),
|
|
2874
2926
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { marginLeft: theme.spacing.xs }, children: "Filters" })
|
|
2875
2927
|
]
|
|
2876
2928
|
}
|
|
2877
2929
|
),
|
|
2878
2930
|
onSettings && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2879
|
-
|
|
2931
|
+
chunkPG7QBH3G_cjs.Button,
|
|
2880
2932
|
{
|
|
2881
2933
|
variant: "ghost",
|
|
2882
2934
|
size: "sm",
|
|
2883
2935
|
onClick: onSettings,
|
|
2884
2936
|
children: [
|
|
2885
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2937
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "settings", size: 16 }),
|
|
2886
2938
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { marginLeft: theme.spacing.xs }, children: "Settings" })
|
|
2887
2939
|
]
|
|
2888
2940
|
}
|
|
@@ -2892,7 +2944,7 @@ function EditorToolbar({
|
|
|
2892
2944
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: rightSectionStyle, children: [
|
|
2893
2945
|
hasChanges && /* @__PURE__ */ jsxRuntime.jsx("span", { style: unsavedStyle, children: "Unsaved changes" }),
|
|
2894
2946
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2895
|
-
|
|
2947
|
+
chunkPG7QBH3G_cjs.Button,
|
|
2896
2948
|
{
|
|
2897
2949
|
variant: "ghost",
|
|
2898
2950
|
size: "sm",
|
|
@@ -2902,7 +2954,7 @@ function EditorToolbar({
|
|
|
2902
2954
|
}
|
|
2903
2955
|
),
|
|
2904
2956
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2905
|
-
|
|
2957
|
+
chunkPG7QBH3G_cjs.Button,
|
|
2906
2958
|
{
|
|
2907
2959
|
variant: "primary",
|
|
2908
2960
|
size: "sm",
|
|
@@ -2997,7 +3049,9 @@ function WidgetTypeSelector({
|
|
|
2997
3049
|
borderRadius: theme.radius.sm,
|
|
2998
3050
|
border: `2px solid ${isSelected ? theme.colors.primary : theme.colors.border}`,
|
|
2999
3051
|
cursor: "pointer",
|
|
3000
|
-
transition: "all 0.15s ease"
|
|
3052
|
+
transition: "all 0.15s ease",
|
|
3053
|
+
minWidth: 0
|
|
3054
|
+
// Allow grid item to shrink below content width
|
|
3001
3055
|
});
|
|
3002
3056
|
const iconStyle = (isSelected) => ({
|
|
3003
3057
|
width: "28px",
|
|
@@ -3024,9 +3078,7 @@ function WidgetTypeSelector({
|
|
|
3024
3078
|
const descStyle = {
|
|
3025
3079
|
fontSize: theme.fontSizes.xs,
|
|
3026
3080
|
color: theme.colors.textMuted,
|
|
3027
|
-
whiteSpace: "nowrap"
|
|
3028
|
-
overflow: "hidden",
|
|
3029
|
-
textOverflow: "ellipsis"
|
|
3081
|
+
whiteSpace: "nowrap"
|
|
3030
3082
|
};
|
|
3031
3083
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `prismiq-widget-type-selector ${className}`, style: containerStyle, children: [
|
|
3032
3084
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Widget Type" }),
|
|
@@ -3049,7 +3101,7 @@ function WidgetTypeSelector({
|
|
|
3049
3101
|
}
|
|
3050
3102
|
},
|
|
3051
3103
|
children: [
|
|
3052
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: iconStyle(isSelected), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3104
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: iconStyle(isSelected), children: /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: widgetType.icon, size: 16 }) }),
|
|
3053
3105
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: textContainerStyle, children: [
|
|
3054
3106
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: nameLabelStyle, children: widgetType.label }),
|
|
3055
3107
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: descStyle, children: widgetType.description })
|
|
@@ -3076,6 +3128,7 @@ function WidgetPreview({
|
|
|
3076
3128
|
title,
|
|
3077
3129
|
config,
|
|
3078
3130
|
query,
|
|
3131
|
+
rawSql,
|
|
3079
3132
|
result,
|
|
3080
3133
|
isLoading = false,
|
|
3081
3134
|
error,
|
|
@@ -3130,13 +3183,14 @@ function WidgetPreview({
|
|
|
3130
3183
|
};
|
|
3131
3184
|
const previewWidget = createPreviewWidget(type, title, config, query);
|
|
3132
3185
|
const needsQuery = type !== "text";
|
|
3133
|
-
const
|
|
3134
|
-
|
|
3186
|
+
const hasDataSource = !!query || !!rawSql;
|
|
3187
|
+
const showEmptyState = needsQuery && !hasDataSource && !isLoading;
|
|
3188
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `prismiq-widget-preview ${className}`, style: containerStyle, "data-testid": "widget-preview", children: [
|
|
3135
3189
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerStyle, children: [
|
|
3136
3190
|
/* @__PURE__ */ jsxRuntime.jsx("h3", { style: titleStyle, children: title || "Widget Preview" }),
|
|
3137
3191
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: labelStyle, children: "Preview" })
|
|
3138
3192
|
] }),
|
|
3139
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: contentStyle, children: showEmptyState ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: emptyStateStyle, children: [
|
|
3193
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: contentStyle, children: showEmptyState ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: emptyStateStyle, "data-testid": "widget-preview-empty", children: [
|
|
3140
3194
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3141
3195
|
"div",
|
|
3142
3196
|
{
|
|
@@ -3193,19 +3247,26 @@ function MetricConfig({
|
|
|
3193
3247
|
onChange
|
|
3194
3248
|
}) {
|
|
3195
3249
|
const { theme } = chunkLMTG3LRC_cjs.useTheme();
|
|
3250
|
+
const { getDisplayName } = chunkPG7QBH3G_cjs.useSchema();
|
|
3196
3251
|
const initialTable = query?.tables[0]?.name ?? "";
|
|
3197
3252
|
const initialAggregation = query?.columns[0]?.aggregation ?? "count";
|
|
3198
|
-
const
|
|
3253
|
+
const rawInitialColumn = query?.columns[0]?.column ?? "*";
|
|
3254
|
+
const needsColumnForInitial = AGGREGATIONS.find((a) => a.value === initialAggregation)?.needsColumn ?? false;
|
|
3255
|
+
const initialColumn = rawInitialColumn === "*" && needsColumnForInitial ? "" : rawInitialColumn;
|
|
3256
|
+
const initialFilters = (query?.filters ?? []).map((f) => ({
|
|
3257
|
+
...f,
|
|
3258
|
+
table_id: "t1"
|
|
3259
|
+
}));
|
|
3199
3260
|
const [selectedTable, setSelectedTable] = react.useState(initialTable);
|
|
3200
3261
|
const [aggregation, setAggregation] = react.useState(initialAggregation);
|
|
3201
3262
|
const [selectedColumn, setSelectedColumn] = react.useState(initialColumn);
|
|
3202
|
-
const [filters, setFilters] = react.useState(
|
|
3263
|
+
const [filters, setFilters] = react.useState(initialFilters);
|
|
3203
3264
|
const tableOptions = react.useMemo(() => {
|
|
3204
3265
|
return schema.tables.map((t) => ({
|
|
3205
3266
|
value: t.name,
|
|
3206
|
-
label: t.name
|
|
3267
|
+
label: getDisplayName(t.name)
|
|
3207
3268
|
}));
|
|
3208
|
-
}, [schema.tables]);
|
|
3269
|
+
}, [schema.tables, getDisplayName]);
|
|
3209
3270
|
const currentTable = react.useMemo(() => {
|
|
3210
3271
|
return schema.tables.find((t) => t.name === selectedTable);
|
|
3211
3272
|
}, [schema.tables, selectedTable]);
|
|
@@ -3220,8 +3281,12 @@ function MetricConfig({
|
|
|
3220
3281
|
const needsColumn = react.useMemo(() => {
|
|
3221
3282
|
return AGGREGATIONS.find((a) => a.value === aggregation)?.needsColumn ?? false;
|
|
3222
3283
|
}, [aggregation]);
|
|
3284
|
+
const isValidAggregation = react.useMemo(() => {
|
|
3285
|
+
return AGGREGATIONS.some((a) => a.value === aggregation);
|
|
3286
|
+
}, [aggregation]);
|
|
3223
3287
|
react.useEffect(() => {
|
|
3224
3288
|
if (!selectedTable) return;
|
|
3289
|
+
if (!isValidAggregation) return;
|
|
3225
3290
|
const tableId = "t1";
|
|
3226
3291
|
const tables = [{ id: tableId, name: selectedTable }];
|
|
3227
3292
|
const column = needsColumn ? selectedColumn : "*";
|
|
@@ -3239,7 +3304,7 @@ function MetricConfig({
|
|
|
3239
3304
|
filters: filters.length > 0 ? filters : void 0
|
|
3240
3305
|
};
|
|
3241
3306
|
onChange(queryDef);
|
|
3242
|
-
}, [selectedTable, aggregation, selectedColumn, needsColumn, filters, onChange]);
|
|
3307
|
+
}, [selectedTable, aggregation, selectedColumn, needsColumn, isValidAggregation, filters, onChange]);
|
|
3243
3308
|
const handleTableChange = react.useCallback((value) => {
|
|
3244
3309
|
setSelectedTable(value);
|
|
3245
3310
|
setSelectedColumn("");
|
|
@@ -3268,7 +3333,7 @@ function MetricConfig({
|
|
|
3268
3333
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
3269
3334
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "From Table" }),
|
|
3270
3335
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3271
|
-
|
|
3336
|
+
chunkPG7QBH3G_cjs.Select,
|
|
3272
3337
|
{
|
|
3273
3338
|
value: selectedTable,
|
|
3274
3339
|
onChange: handleTableChange,
|
|
@@ -3279,7 +3344,7 @@ function MetricConfig({
|
|
|
3279
3344
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
3280
3345
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Metric" }),
|
|
3281
3346
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3282
|
-
|
|
3347
|
+
chunkPG7QBH3G_cjs.Select,
|
|
3283
3348
|
{
|
|
3284
3349
|
value: aggregation,
|
|
3285
3350
|
onChange: (value) => setAggregation(value),
|
|
@@ -3294,7 +3359,7 @@ function MetricConfig({
|
|
|
3294
3359
|
needsColumn && selectedTable && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
3295
3360
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Column" }),
|
|
3296
3361
|
columnOptions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3297
|
-
|
|
3362
|
+
chunkPG7QBH3G_cjs.Select,
|
|
3298
3363
|
{
|
|
3299
3364
|
value: selectedColumn,
|
|
3300
3365
|
onChange: setSelectedColumn,
|
|
@@ -3305,7 +3370,7 @@ function MetricConfig({
|
|
|
3305
3370
|
selectedTable && currentTable && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
3306
3371
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Filters (optional)" }),
|
|
3307
3372
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3308
|
-
|
|
3373
|
+
chunkPG7QBH3G_cjs.FilterBuilder,
|
|
3309
3374
|
{
|
|
3310
3375
|
tables: [{ id: "t1", name: selectedTable }],
|
|
3311
3376
|
filters,
|
|
@@ -3364,17 +3429,23 @@ function ChartConfig({
|
|
|
3364
3429
|
onChange
|
|
3365
3430
|
}) {
|
|
3366
3431
|
const { theme } = chunkLMTG3LRC_cjs.useTheme();
|
|
3432
|
+
const { getDisplayName } = chunkPG7QBH3G_cjs.useSchema();
|
|
3367
3433
|
const initialTables = query?.tables ?? [];
|
|
3368
3434
|
const groupByCol = query?.columns.find((c) => c.aggregation === "none");
|
|
3369
3435
|
const initialGroupBy = groupByCol?.column ?? query?.group_by?.[0]?.column ?? "";
|
|
3370
3436
|
const initialGroupByTableId = groupByCol?.table_id ?? query?.tables?.[0]?.id ?? "t1";
|
|
3371
3437
|
const initialDateTrunc = groupByCol?.date_trunc ?? "";
|
|
3372
|
-
const initialMeasures = query?.columns.filter((c) => c.aggregation !== "none").map((c) =>
|
|
3373
|
-
|
|
3374
|
-
column: c.table_id ? `${c.table_id}.${c.column}` : c.column
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3438
|
+
const initialMeasures = query?.columns.filter((c) => c.aggregation !== "none").map((c) => {
|
|
3439
|
+
const isStarWithNonCount = (c.column === "*" || c.column.endsWith(".*")) && c.aggregation !== "count";
|
|
3440
|
+
const column = isStarWithNonCount ? "" : c.table_id ? `${c.table_id}.${c.column}` : c.column;
|
|
3441
|
+
return {
|
|
3442
|
+
column,
|
|
3443
|
+
aggregation: c.aggregation,
|
|
3444
|
+
table_id: c.table_id,
|
|
3445
|
+
// Preserve original alias to maintain compatibility with widget config
|
|
3446
|
+
alias: c.alias
|
|
3447
|
+
};
|
|
3448
|
+
}) ?? [];
|
|
3378
3449
|
const initialJoins = query?.joins ?? [];
|
|
3379
3450
|
const [tables, setTables] = react.useState(initialTables);
|
|
3380
3451
|
const [joins, setJoins] = react.useState(initialJoins);
|
|
@@ -3395,9 +3466,9 @@ function ChartConfig({
|
|
|
3395
3466
|
const tableOptions = react.useMemo(() => {
|
|
3396
3467
|
return schema.tables.map((t) => ({
|
|
3397
3468
|
value: t.name,
|
|
3398
|
-
label: t.name
|
|
3469
|
+
label: getDisplayName(t.name)
|
|
3399
3470
|
}));
|
|
3400
|
-
}, [schema.tables]);
|
|
3471
|
+
}, [schema.tables, getDisplayName]);
|
|
3401
3472
|
const currentTable = react.useMemo(() => {
|
|
3402
3473
|
return schema.tables.find((t) => t.name === selectedTable);
|
|
3403
3474
|
}, [schema.tables, selectedTable]);
|
|
@@ -3467,7 +3538,7 @@ function ChartConfig({
|
|
|
3467
3538
|
const parsedMeasures = [];
|
|
3468
3539
|
const invalidColumns = [];
|
|
3469
3540
|
validMeasures.forEach((m, i) => {
|
|
3470
|
-
const measureAlias = validMeasures.length > 1 ? `value_${i + 1}` : "value";
|
|
3541
|
+
const measureAlias = m.alias ?? (validMeasures.length > 1 ? `value_${i + 1}` : "value");
|
|
3471
3542
|
if (m.aggregation === "count" && (!m.column || m.column.endsWith(".*") || m.column === "*")) {
|
|
3472
3543
|
parsedMeasures.push({
|
|
3473
3544
|
table_id: m.table_id ?? tables[0]?.id ?? "t1",
|
|
@@ -3477,7 +3548,7 @@ function ChartConfig({
|
|
|
3477
3548
|
});
|
|
3478
3549
|
return;
|
|
3479
3550
|
}
|
|
3480
|
-
const parsed =
|
|
3551
|
+
const parsed = chunkKXB2IZI2_cjs.parseColumnRef(m.column, tables[0]?.id ?? "t1");
|
|
3481
3552
|
if (!parsed) {
|
|
3482
3553
|
invalidColumns.push(m.column);
|
|
3483
3554
|
return;
|
|
@@ -3531,6 +3602,9 @@ function ChartConfig({
|
|
|
3531
3602
|
setJoins(
|
|
3532
3603
|
(prev) => prev.filter((j) => tableIds.has(j.from_table_id) && tableIds.has(j.to_table_id))
|
|
3533
3604
|
);
|
|
3605
|
+
setFilters(
|
|
3606
|
+
(prev) => prev.filter((f) => tableIds.has(f.table_id))
|
|
3607
|
+
);
|
|
3534
3608
|
if (!tableIds.has(groupByTableId)) {
|
|
3535
3609
|
setGroupByColumn("");
|
|
3536
3610
|
setGroupByTableId(newTables[0]?.id ?? "t1");
|
|
@@ -3542,7 +3616,7 @@ function ChartConfig({
|
|
|
3542
3616
|
setDateTrunc("");
|
|
3543
3617
|
return;
|
|
3544
3618
|
}
|
|
3545
|
-
const parsed =
|
|
3619
|
+
const parsed = chunkKXB2IZI2_cjs.parseColumnRef(value, groupByTableId);
|
|
3546
3620
|
if (parsed) {
|
|
3547
3621
|
setGroupByTableId(parsed.tableId);
|
|
3548
3622
|
setGroupByColumn(parsed.column);
|
|
@@ -3601,7 +3675,7 @@ function ChartConfig({
|
|
|
3601
3675
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
3602
3676
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "From Table" }),
|
|
3603
3677
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3604
|
-
|
|
3678
|
+
chunkPG7QBH3G_cjs.Select,
|
|
3605
3679
|
{
|
|
3606
3680
|
value: selectedTable,
|
|
3607
3681
|
onChange: handleTableChange,
|
|
@@ -3609,9 +3683,9 @@ function ChartConfig({
|
|
|
3609
3683
|
}
|
|
3610
3684
|
)
|
|
3611
3685
|
] }),
|
|
3612
|
-
selectedTable && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3686
|
+
selectedTable && /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_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
3687
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3614
|
-
|
|
3688
|
+
chunkPG7QBH3G_cjs.TableSelector,
|
|
3615
3689
|
{
|
|
3616
3690
|
schema,
|
|
3617
3691
|
tables,
|
|
@@ -3623,7 +3697,7 @@ function ChartConfig({
|
|
|
3623
3697
|
tables.length >= 2 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
3624
3698
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Join Conditions" }),
|
|
3625
3699
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3626
|
-
|
|
3700
|
+
chunkPG7QBH3G_cjs.JoinBuilder,
|
|
3627
3701
|
{
|
|
3628
3702
|
schema,
|
|
3629
3703
|
tables,
|
|
@@ -3637,7 +3711,7 @@ function ChartConfig({
|
|
|
3637
3711
|
selectedTable && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
3638
3712
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Group By (X-Axis)" }),
|
|
3639
3713
|
groupByOptions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3640
|
-
|
|
3714
|
+
chunkPG7QBH3G_cjs.Select,
|
|
3641
3715
|
{
|
|
3642
3716
|
value: groupByValue,
|
|
3643
3717
|
onChange: handleGroupByChange,
|
|
@@ -3649,7 +3723,7 @@ function ChartConfig({
|
|
|
3649
3723
|
selectedTable && groupByColumn && isGroupByDate && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
3650
3724
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Date Granularity" }),
|
|
3651
3725
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3652
|
-
|
|
3726
|
+
chunkPG7QBH3G_cjs.Select,
|
|
3653
3727
|
{
|
|
3654
3728
|
value: dateTrunc,
|
|
3655
3729
|
onChange: (value) => setDateTrunc(value),
|
|
@@ -3658,8 +3732,8 @@ function ChartConfig({
|
|
|
3658
3732
|
),
|
|
3659
3733
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: helpTextStyle, children: "Truncate dates to this interval" })
|
|
3660
3734
|
] }),
|
|
3661
|
-
selectedTable && isGroupByDate && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3662
|
-
|
|
3735
|
+
selectedTable && isGroupByDate && /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.CollapsibleSection, { title: "Time Series Options", defaultOpen: timeSeries !== void 0, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3736
|
+
chunkPG7QBH3G_cjs.TimeSeriesConfig,
|
|
3663
3737
|
{
|
|
3664
3738
|
schema,
|
|
3665
3739
|
tables,
|
|
@@ -3672,7 +3746,7 @@ function ChartConfig({
|
|
|
3672
3746
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Measures (Y-Axis)" }),
|
|
3673
3747
|
measures.map((measure, index) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: measureRowStyle, children: [
|
|
3674
3748
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3675
|
-
|
|
3749
|
+
chunkPG7QBH3G_cjs.Select,
|
|
3676
3750
|
{
|
|
3677
3751
|
value: measure.aggregation,
|
|
3678
3752
|
onChange: (value) => updateMeasure(index, { aggregation: value }),
|
|
@@ -3683,7 +3757,7 @@ function ChartConfig({
|
|
|
3683
3757
|
measure.aggregation !== "count" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3684
3758
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: theme.colors.textMuted }, children: "of" }),
|
|
3685
3759
|
measureColumnOptions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3686
|
-
|
|
3760
|
+
chunkPG7QBH3G_cjs.Select,
|
|
3687
3761
|
{
|
|
3688
3762
|
value: measure.column,
|
|
3689
3763
|
onChange: (value) => updateMeasure(index, { column: value }),
|
|
@@ -3692,17 +3766,17 @@ function ChartConfig({
|
|
|
3692
3766
|
}
|
|
3693
3767
|
) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...helpTextStyle, flex: 1 }, children: "No numeric columns" })
|
|
3694
3768
|
] }),
|
|
3695
|
-
measures.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3769
|
+
measures.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Button, { variant: "ghost", size: "sm", onClick: () => removeMeasure(index), children: /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "x", size: 14 }) })
|
|
3696
3770
|
] }, measureIdsRef.current[index])),
|
|
3697
3771
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3698
|
-
|
|
3772
|
+
chunkPG7QBH3G_cjs.Button,
|
|
3699
3773
|
{
|
|
3700
3774
|
variant: "ghost",
|
|
3701
3775
|
size: "sm",
|
|
3702
3776
|
onClick: addMeasure,
|
|
3703
3777
|
style: { alignSelf: "flex-start" },
|
|
3704
3778
|
children: [
|
|
3705
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3779
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "plus", size: 14 }),
|
|
3706
3780
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { marginLeft: theme.spacing.xs }, children: "Add measure" })
|
|
3707
3781
|
]
|
|
3708
3782
|
}
|
|
@@ -3712,7 +3786,7 @@ function ChartConfig({
|
|
|
3712
3786
|
selectedTable && currentTable && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
3713
3787
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Filters (optional)" }),
|
|
3714
3788
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3715
|
-
|
|
3789
|
+
chunkPG7QBH3G_cjs.FilterBuilder,
|
|
3716
3790
|
{
|
|
3717
3791
|
tables,
|
|
3718
3792
|
filters,
|
|
@@ -3722,12 +3796,12 @@ function ChartConfig({
|
|
|
3722
3796
|
)
|
|
3723
3797
|
] }),
|
|
3724
3798
|
selectedTable && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3725
|
-
|
|
3799
|
+
chunkPG7QBH3G_cjs.CollapsibleSection,
|
|
3726
3800
|
{
|
|
3727
3801
|
title: "Calculated Fields",
|
|
3728
3802
|
defaultOpen: calculatedFields.length > 0,
|
|
3729
3803
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3730
|
-
|
|
3804
|
+
chunkPG7QBH3G_cjs.CalculatedFieldBuilder,
|
|
3731
3805
|
{
|
|
3732
3806
|
fields: calculatedFields,
|
|
3733
3807
|
onChange: setCalculatedFields,
|
|
@@ -3785,25 +3859,31 @@ function PieConfig({
|
|
|
3785
3859
|
onChange
|
|
3786
3860
|
}) {
|
|
3787
3861
|
const { theme } = chunkLMTG3LRC_cjs.useTheme();
|
|
3862
|
+
const { getDisplayName } = chunkPG7QBH3G_cjs.useSchema();
|
|
3788
3863
|
const initialTable = query?.tables[0]?.name ?? "";
|
|
3789
3864
|
const labelCol = query?.columns.find((c) => c.aggregation === "none");
|
|
3790
3865
|
const initialLabel = labelCol?.column ?? "";
|
|
3791
3866
|
const initialDateTrunc = labelCol?.date_trunc ?? "";
|
|
3792
3867
|
const measureCol = query?.columns.find((c) => c.aggregation !== "none");
|
|
3793
|
-
const
|
|
3868
|
+
const rawInitialValueColumn = measureCol?.column ?? "";
|
|
3794
3869
|
const initialAggregation = measureCol?.aggregation ?? "sum";
|
|
3870
|
+
const initialValueColumn = rawInitialValueColumn === "*" && initialAggregation !== "count" ? "" : rawInitialValueColumn;
|
|
3871
|
+
const initialFilters = (query?.filters ?? []).map((f) => ({
|
|
3872
|
+
...f,
|
|
3873
|
+
table_id: "t1"
|
|
3874
|
+
}));
|
|
3795
3875
|
const [selectedTable, setSelectedTable] = react.useState(initialTable);
|
|
3796
3876
|
const [labelColumn, setLabelColumn] = react.useState(initialLabel);
|
|
3797
3877
|
const [dateTrunc, setDateTrunc] = react.useState(initialDateTrunc);
|
|
3798
3878
|
const [valueColumn, setValueColumn] = react.useState(initialValueColumn);
|
|
3799
3879
|
const [aggregation, setAggregation] = react.useState(initialAggregation);
|
|
3800
|
-
const [filters, setFilters] = react.useState(
|
|
3880
|
+
const [filters, setFilters] = react.useState(initialFilters);
|
|
3801
3881
|
const tableOptions = react.useMemo(() => {
|
|
3802
3882
|
return schema.tables.map((t) => ({
|
|
3803
3883
|
value: t.name,
|
|
3804
|
-
label: t.name
|
|
3884
|
+
label: getDisplayName(t.name)
|
|
3805
3885
|
}));
|
|
3806
|
-
}, [schema.tables]);
|
|
3886
|
+
}, [schema.tables, getDisplayName]);
|
|
3807
3887
|
const currentTable = react.useMemo(() => {
|
|
3808
3888
|
return schema.tables.find((t) => t.name === selectedTable);
|
|
3809
3889
|
}, [schema.tables, selectedTable]);
|
|
@@ -3828,8 +3908,12 @@ function PieConfig({
|
|
|
3828
3908
|
label: `${c.name} (${c.data_type})`
|
|
3829
3909
|
}));
|
|
3830
3910
|
}, [currentTable]);
|
|
3911
|
+
const isValidAggregation = react.useMemo(() => {
|
|
3912
|
+
return AGGREGATIONS3.some((a) => a.value === aggregation);
|
|
3913
|
+
}, [aggregation]);
|
|
3831
3914
|
react.useEffect(() => {
|
|
3832
3915
|
if (!selectedTable || !labelColumn) return;
|
|
3916
|
+
if (!isValidAggregation) return;
|
|
3833
3917
|
const needsValueColumn = aggregation !== "count";
|
|
3834
3918
|
if (needsValueColumn && !valueColumn) return;
|
|
3835
3919
|
const tableId = "t1";
|
|
@@ -3859,7 +3943,7 @@ function PieConfig({
|
|
|
3859
3943
|
order_by: [{ table_id: tableId, column: labelColumn, direction: "ASC" }]
|
|
3860
3944
|
};
|
|
3861
3945
|
onChange(queryDef);
|
|
3862
|
-
}, [selectedTable, labelColumn, dateTrunc, valueColumn, aggregation, filters, onChange]);
|
|
3946
|
+
}, [selectedTable, labelColumn, dateTrunc, valueColumn, aggregation, isValidAggregation, filters, onChange]);
|
|
3863
3947
|
const handleTableChange = react.useCallback((value) => {
|
|
3864
3948
|
setSelectedTable(value);
|
|
3865
3949
|
setLabelColumn("");
|
|
@@ -3901,7 +3985,7 @@ function PieConfig({
|
|
|
3901
3985
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
3902
3986
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "From Table" }),
|
|
3903
3987
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3904
|
-
|
|
3988
|
+
chunkPG7QBH3G_cjs.Select,
|
|
3905
3989
|
{
|
|
3906
3990
|
value: selectedTable,
|
|
3907
3991
|
onChange: handleTableChange,
|
|
@@ -3912,7 +3996,7 @@ function PieConfig({
|
|
|
3912
3996
|
selectedTable && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
3913
3997
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Slices (Labels)" }),
|
|
3914
3998
|
labelOptions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3915
|
-
|
|
3999
|
+
chunkPG7QBH3G_cjs.Select,
|
|
3916
4000
|
{
|
|
3917
4001
|
value: labelColumn,
|
|
3918
4002
|
onChange: handleLabelChange,
|
|
@@ -3924,7 +4008,7 @@ function PieConfig({
|
|
|
3924
4008
|
selectedTable && labelColumn && isLabelDate && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
3925
4009
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Date Granularity" }),
|
|
3926
4010
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3927
|
-
|
|
4011
|
+
chunkPG7QBH3G_cjs.Select,
|
|
3928
4012
|
{
|
|
3929
4013
|
value: dateTrunc,
|
|
3930
4014
|
onChange: (value) => setDateTrunc(value),
|
|
@@ -3937,7 +4021,7 @@ function PieConfig({
|
|
|
3937
4021
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Size (Value)" }),
|
|
3938
4022
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: rowStyle, children: [
|
|
3939
4023
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3940
|
-
|
|
4024
|
+
chunkPG7QBH3G_cjs.Select,
|
|
3941
4025
|
{
|
|
3942
4026
|
value: aggregation,
|
|
3943
4027
|
onChange: (value) => setAggregation(value),
|
|
@@ -3948,7 +4032,7 @@ function PieConfig({
|
|
|
3948
4032
|
aggregation !== "count" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3949
4033
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: theme.colors.textMuted }, children: "of" }),
|
|
3950
4034
|
valueColumnOptions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3951
|
-
|
|
4035
|
+
chunkPG7QBH3G_cjs.Select,
|
|
3952
4036
|
{
|
|
3953
4037
|
value: valueColumn,
|
|
3954
4038
|
onChange: setValueColumn,
|
|
@@ -3963,7 +4047,7 @@ function PieConfig({
|
|
|
3963
4047
|
selectedTable && currentTable && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
3964
4048
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Filters (optional)" }),
|
|
3965
4049
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3966
|
-
|
|
4050
|
+
chunkPG7QBH3G_cjs.FilterBuilder,
|
|
3967
4051
|
{
|
|
3968
4052
|
tables: [{ id: "t1", name: selectedTable }],
|
|
3969
4053
|
filters,
|
|
@@ -3980,18 +4064,23 @@ function TableConfig({
|
|
|
3980
4064
|
onChange
|
|
3981
4065
|
}) {
|
|
3982
4066
|
const { theme } = chunkLMTG3LRC_cjs.useTheme();
|
|
4067
|
+
const { getDisplayName } = chunkPG7QBH3G_cjs.useSchema();
|
|
3983
4068
|
const initialTable = query?.tables[0]?.name ?? "";
|
|
3984
4069
|
const initialColumns = query?.columns.map((c) => c.column) ?? [];
|
|
4070
|
+
const initialFilters = (query?.filters ?? []).map((f) => ({
|
|
4071
|
+
...f,
|
|
4072
|
+
table_id: "t1"
|
|
4073
|
+
}));
|
|
3985
4074
|
const [selectedTable, setSelectedTable] = react.useState(initialTable);
|
|
3986
4075
|
const [selectedColumns, setSelectedColumns] = react.useState(initialColumns);
|
|
3987
|
-
const [filters, setFilters] = react.useState(
|
|
4076
|
+
const [filters, setFilters] = react.useState(initialFilters);
|
|
3988
4077
|
const [limit, setLimit] = react.useState(query?.limit ?? 100);
|
|
3989
4078
|
const tableOptions = react.useMemo(() => {
|
|
3990
4079
|
return schema.tables.map((t) => ({
|
|
3991
4080
|
value: t.name,
|
|
3992
|
-
label: t.name
|
|
4081
|
+
label: getDisplayName(t.name)
|
|
3993
4082
|
}));
|
|
3994
|
-
}, [schema.tables]);
|
|
4083
|
+
}, [schema.tables, getDisplayName]);
|
|
3995
4084
|
const currentTable = react.useMemo(() => {
|
|
3996
4085
|
return schema.tables.find((t) => t.name === selectedTable);
|
|
3997
4086
|
}, [schema.tables, selectedTable]);
|
|
@@ -4081,7 +4170,7 @@ function TableConfig({
|
|
|
4081
4170
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
4082
4171
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "From Table" }),
|
|
4083
4172
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4084
|
-
|
|
4173
|
+
chunkPG7QBH3G_cjs.Select,
|
|
4085
4174
|
{
|
|
4086
4175
|
value: selectedTable,
|
|
4087
4176
|
onChange: handleTableChange,
|
|
@@ -4098,7 +4187,7 @@ function TableConfig({
|
|
|
4098
4187
|
] })
|
|
4099
4188
|
] }),
|
|
4100
4189
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: columnsContainerStyle, children: currentTable.columns.map((col) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
4101
|
-
|
|
4190
|
+
chunkPG7QBH3G_cjs.Checkbox,
|
|
4102
4191
|
{
|
|
4103
4192
|
label: `${col.name} (${col.data_type})`,
|
|
4104
4193
|
checked: selectedColumns.includes(col.name),
|
|
@@ -4111,7 +4200,7 @@ function TableConfig({
|
|
|
4111
4200
|
selectedTable && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
4112
4201
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Maximum Rows" }),
|
|
4113
4202
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: rowStyle, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4114
|
-
|
|
4203
|
+
chunkPG7QBH3G_cjs.Select,
|
|
4115
4204
|
{
|
|
4116
4205
|
value: String(limit),
|
|
4117
4206
|
onChange: (value) => setLimit(parseInt(value, 10)),
|
|
@@ -4130,7 +4219,7 @@ function TableConfig({
|
|
|
4130
4219
|
selectedTable && currentTable && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
4131
4220
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Filters (optional)" }),
|
|
4132
4221
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4133
|
-
|
|
4222
|
+
chunkPG7QBH3G_cjs.FilterBuilder,
|
|
4134
4223
|
{
|
|
4135
4224
|
tables: [{ id: "t1", name: selectedTable }],
|
|
4136
4225
|
filters,
|
|
@@ -4214,11 +4303,11 @@ function HyperlinkSection({
|
|
|
4214
4303
|
target
|
|
4215
4304
|
});
|
|
4216
4305
|
};
|
|
4217
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4306
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(chunkPG7QBH3G_cjs.CollapsibleSection, { title: "Hyperlink", defaultOpen, children: [
|
|
4218
4307
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
4219
4308
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "URL" }),
|
|
4220
4309
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4221
|
-
|
|
4310
|
+
chunkPG7QBH3G_cjs.Input,
|
|
4222
4311
|
{
|
|
4223
4312
|
value: hyperlink?.url || "",
|
|
4224
4313
|
onChange: (e) => handleUrlChange(e.target.value),
|
|
@@ -4231,7 +4320,7 @@ function HyperlinkSection({
|
|
|
4231
4320
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
4232
4321
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Tooltip Text" }),
|
|
4233
4322
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4234
|
-
|
|
4323
|
+
chunkPG7QBH3G_cjs.Input,
|
|
4235
4324
|
{
|
|
4236
4325
|
value: hyperlink?.title || "",
|
|
4237
4326
|
onChange: (e) => handleTitleChange(e.target.value),
|
|
@@ -4242,7 +4331,7 @@ function HyperlinkSection({
|
|
|
4242
4331
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
4243
4332
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Open In" }),
|
|
4244
4333
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4245
|
-
|
|
4334
|
+
chunkPG7QBH3G_cjs.Select,
|
|
4246
4335
|
{
|
|
4247
4336
|
value: hyperlink?.target || "_blank",
|
|
4248
4337
|
onChange: handleTargetChange,
|
|
@@ -4318,14 +4407,14 @@ function ReferenceLinesSection({
|
|
|
4318
4407
|
onChange(lines.filter((_, i) => i !== index));
|
|
4319
4408
|
};
|
|
4320
4409
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4321
|
-
|
|
4410
|
+
chunkPG7QBH3G_cjs.CollapsibleSection,
|
|
4322
4411
|
{
|
|
4323
4412
|
title: "Reference Lines",
|
|
4324
4413
|
defaultOpen: defaultOpen || lines.length > 0,
|
|
4325
4414
|
children: [
|
|
4326
4415
|
lines.map((line, index) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: lineRowStyle, children: [
|
|
4327
4416
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4328
|
-
|
|
4417
|
+
chunkPG7QBH3G_cjs.Input,
|
|
4329
4418
|
{
|
|
4330
4419
|
type: "number",
|
|
4331
4420
|
value: String(line.value),
|
|
@@ -4335,7 +4424,7 @@ function ReferenceLinesSection({
|
|
|
4335
4424
|
}
|
|
4336
4425
|
),
|
|
4337
4426
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4338
|
-
|
|
4427
|
+
chunkPG7QBH3G_cjs.Input,
|
|
4339
4428
|
{
|
|
4340
4429
|
value: line.label ?? "",
|
|
4341
4430
|
onChange: (e) => updateLine(index, { label: e.target.value || void 0 }),
|
|
@@ -4354,7 +4443,7 @@ function ReferenceLinesSection({
|
|
|
4354
4443
|
}
|
|
4355
4444
|
),
|
|
4356
4445
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4357
|
-
|
|
4446
|
+
chunkPG7QBH3G_cjs.Select,
|
|
4358
4447
|
{
|
|
4359
4448
|
value: line.lineStyle ?? "dashed",
|
|
4360
4449
|
onChange: (value) => updateLine(index, {
|
|
@@ -4364,10 +4453,10 @@ function ReferenceLinesSection({
|
|
|
4364
4453
|
style: { width: "90px" }
|
|
4365
4454
|
}
|
|
4366
4455
|
),
|
|
4367
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4456
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Button, { variant: "ghost", size: "sm", onClick: () => removeLine(index), children: /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "x", size: 14 }) })
|
|
4368
4457
|
] }, lineIdsRef.current[index])),
|
|
4369
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: addButtonStyle, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4370
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4458
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: addButtonStyle, children: /* @__PURE__ */ jsxRuntime.jsxs(chunkPG7QBH3G_cjs.Button, { variant: "ghost", size: "sm", onClick: addLine, children: [
|
|
4459
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "plus", size: 14 }),
|
|
4371
4460
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { marginLeft: theme.spacing.xs }, children: "Add reference line" })
|
|
4372
4461
|
] }) })
|
|
4373
4462
|
]
|
|
@@ -4451,7 +4540,7 @@ function TextFormattingSection({
|
|
|
4451
4540
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerStyle, children: [
|
|
4452
4541
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Content" }),
|
|
4453
4542
|
config.markdown && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4454
|
-
|
|
4543
|
+
chunkPG7QBH3G_cjs.Checkbox,
|
|
4455
4544
|
{
|
|
4456
4545
|
label: "Preview",
|
|
4457
4546
|
checked: showPreview,
|
|
@@ -4465,7 +4554,7 @@ function TextFormattingSection({
|
|
|
4465
4554
|
"div",
|
|
4466
4555
|
{
|
|
4467
4556
|
dangerouslySetInnerHTML: {
|
|
4468
|
-
__html:
|
|
4557
|
+
__html: chunkKXB2IZI2_cjs.parseMarkdownSafe(config.content ?? "")
|
|
4469
4558
|
}
|
|
4470
4559
|
}
|
|
4471
4560
|
)
|
|
@@ -4481,7 +4570,7 @@ function TextFormattingSection({
|
|
|
4481
4570
|
)
|
|
4482
4571
|
] }),
|
|
4483
4572
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: fieldStyle, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4484
|
-
|
|
4573
|
+
chunkPG7QBH3G_cjs.Checkbox,
|
|
4485
4574
|
{
|
|
4486
4575
|
label: "Enable Markdown",
|
|
4487
4576
|
checked: config.markdown ?? false,
|
|
@@ -4492,7 +4581,7 @@ function TextFormattingSection({
|
|
|
4492
4581
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: halfFieldStyle, children: [
|
|
4493
4582
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Alignment" }),
|
|
4494
4583
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4495
|
-
|
|
4584
|
+
chunkPG7QBH3G_cjs.Select,
|
|
4496
4585
|
{
|
|
4497
4586
|
value: config.alignment ?? "Left",
|
|
4498
4587
|
onChange: (value) => onChange("alignment", value),
|
|
@@ -4503,7 +4592,7 @@ function TextFormattingSection({
|
|
|
4503
4592
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: halfFieldStyle, children: [
|
|
4504
4593
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Font Size" }),
|
|
4505
4594
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4506
|
-
|
|
4595
|
+
chunkPG7QBH3G_cjs.Select,
|
|
4507
4596
|
{
|
|
4508
4597
|
value: config.fontSize ?? "Normal",
|
|
4509
4598
|
onChange: (value) => onChange("fontSize", value),
|
|
@@ -4620,13 +4709,13 @@ function PivotConfigSection({
|
|
|
4620
4709
|
).map((col) => col.column);
|
|
4621
4710
|
}, [query, config.pivot_column, config.value_column]);
|
|
4622
4711
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4623
|
-
|
|
4712
|
+
chunkPG7QBH3G_cjs.CollapsibleSection,
|
|
4624
4713
|
{
|
|
4625
4714
|
title: "Pivot Table",
|
|
4626
4715
|
defaultOpen: defaultOpen || isPivotEnabled,
|
|
4627
4716
|
children: [
|
|
4628
4717
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: fieldStyle, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4629
|
-
|
|
4718
|
+
chunkPG7QBH3G_cjs.Checkbox,
|
|
4630
4719
|
{
|
|
4631
4720
|
label: "Enable Pivot Mode",
|
|
4632
4721
|
checked: isPivotEnabled,
|
|
@@ -4637,7 +4726,7 @@ function PivotConfigSection({
|
|
|
4637
4726
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
4638
4727
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Pivot Column" }),
|
|
4639
4728
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4640
|
-
|
|
4729
|
+
chunkPG7QBH3G_cjs.Select,
|
|
4641
4730
|
{
|
|
4642
4731
|
value: config.pivot_column ?? "",
|
|
4643
4732
|
onChange: (value) => onChange("pivot_column", value || void 0),
|
|
@@ -4652,7 +4741,7 @@ function PivotConfigSection({
|
|
|
4652
4741
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
4653
4742
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Value Column" }),
|
|
4654
4743
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4655
|
-
|
|
4744
|
+
chunkPG7QBH3G_cjs.Select,
|
|
4656
4745
|
{
|
|
4657
4746
|
value: config.value_column ?? "",
|
|
4658
4747
|
onChange: (value) => onChange("value_column", value || void 0),
|
|
@@ -4715,7 +4804,7 @@ function LayoutConstraintsSection({
|
|
|
4715
4804
|
};
|
|
4716
4805
|
const hasConstraints = position.minW !== void 0 || position.maxW !== void 0 || position.minH !== void 0 || position.maxH !== void 0;
|
|
4717
4806
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4718
|
-
|
|
4807
|
+
chunkPG7QBH3G_cjs.CollapsibleSection,
|
|
4719
4808
|
{
|
|
4720
4809
|
title: "Size Constraints",
|
|
4721
4810
|
defaultOpen: defaultOpen || hasConstraints,
|
|
@@ -4723,7 +4812,7 @@ function LayoutConstraintsSection({
|
|
|
4723
4812
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
4724
4813
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Min Width" }),
|
|
4725
4814
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4726
|
-
|
|
4815
|
+
chunkPG7QBH3G_cjs.Input,
|
|
4727
4816
|
{
|
|
4728
4817
|
type: "number",
|
|
4729
4818
|
value: position.minW !== void 0 ? String(position.minW) : "",
|
|
@@ -4737,7 +4826,7 @@ function LayoutConstraintsSection({
|
|
|
4737
4826
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
4738
4827
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Max Width" }),
|
|
4739
4828
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4740
|
-
|
|
4829
|
+
chunkPG7QBH3G_cjs.Input,
|
|
4741
4830
|
{
|
|
4742
4831
|
type: "number",
|
|
4743
4832
|
value: position.maxW !== void 0 ? String(position.maxW) : "",
|
|
@@ -4751,7 +4840,7 @@ function LayoutConstraintsSection({
|
|
|
4751
4840
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
4752
4841
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Min Height" }),
|
|
4753
4842
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4754
|
-
|
|
4843
|
+
chunkPG7QBH3G_cjs.Input,
|
|
4755
4844
|
{
|
|
4756
4845
|
type: "number",
|
|
4757
4846
|
value: position.minH !== void 0 ? String(position.minH) : "",
|
|
@@ -4764,7 +4853,7 @@ function LayoutConstraintsSection({
|
|
|
4764
4853
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
4765
4854
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Max Height" }),
|
|
4766
4855
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4767
|
-
|
|
4856
|
+
chunkPG7QBH3G_cjs.Input,
|
|
4768
4857
|
{
|
|
4769
4858
|
type: "number",
|
|
4770
4859
|
value: position.maxH !== void 0 ? String(position.maxH) : "",
|
|
@@ -4832,14 +4921,14 @@ function CrossFilterSection({
|
|
|
4832
4921
|
});
|
|
4833
4922
|
};
|
|
4834
4923
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4835
|
-
|
|
4924
|
+
chunkPG7QBH3G_cjs.CollapsibleSection,
|
|
4836
4925
|
{
|
|
4837
4926
|
title: "Cross-Filtering",
|
|
4838
4927
|
defaultOpen: defaultOpen || crossFilterEnabled,
|
|
4839
4928
|
children: [
|
|
4840
4929
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
4841
4930
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4842
|
-
|
|
4931
|
+
chunkPG7QBH3G_cjs.Checkbox,
|
|
4843
4932
|
{
|
|
4844
4933
|
label: "Enable as filter source",
|
|
4845
4934
|
checked: crossFilterEnabled,
|
|
@@ -4851,7 +4940,7 @@ function CrossFilterSection({
|
|
|
4851
4940
|
crossFilterEnabled && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
4852
4941
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Filter Column" }),
|
|
4853
4942
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4854
|
-
|
|
4943
|
+
chunkPG7QBH3G_cjs.Select,
|
|
4855
4944
|
{
|
|
4856
4945
|
value: config.cross_filter?.column ?? config.x_axis ?? "",
|
|
4857
4946
|
onChange: handleColumnChange,
|
|
@@ -4950,11 +5039,11 @@ function ValueFormattingSection({
|
|
|
4950
5039
|
marginBottom: theme.spacing.xs
|
|
4951
5040
|
};
|
|
4952
5041
|
const isCurrency = config.valueFormat === "currency" || config.format === "currency";
|
|
4953
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5042
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(chunkPG7QBH3G_cjs.CollapsibleSection, { title: "Value Formatting", defaultOpen, children: [
|
|
4954
5043
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
4955
5044
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Format" }),
|
|
4956
5045
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4957
|
-
|
|
5046
|
+
chunkPG7QBH3G_cjs.Select,
|
|
4958
5047
|
{
|
|
4959
5048
|
value: config.valueFormat || config.format || "number",
|
|
4960
5049
|
onChange: (value) => {
|
|
@@ -4969,7 +5058,7 @@ function ValueFormattingSection({
|
|
|
4969
5058
|
isCurrency && showCurrency && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
4970
5059
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Currency Symbol" }),
|
|
4971
5060
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4972
|
-
|
|
5061
|
+
chunkPG7QBH3G_cjs.Input,
|
|
4973
5062
|
{
|
|
4974
5063
|
value: config.currencySymbol ?? "$",
|
|
4975
5064
|
onChange: (e) => onChange("currencySymbol", e.target.value),
|
|
@@ -4981,7 +5070,7 @@ function ValueFormattingSection({
|
|
|
4981
5070
|
showCompact && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
4982
5071
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Compact Notation" }),
|
|
4983
5072
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4984
|
-
|
|
5073
|
+
chunkPG7QBH3G_cjs.Select,
|
|
4985
5074
|
{
|
|
4986
5075
|
value: config.compactNotation || "",
|
|
4987
5076
|
onChange: (value) => onChange("compactNotation", value ? value : null),
|
|
@@ -4992,7 +5081,7 @@ function ValueFormattingSection({
|
|
|
4992
5081
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
4993
5082
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Decimal Places" }),
|
|
4994
5083
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4995
|
-
|
|
5084
|
+
chunkPG7QBH3G_cjs.Select,
|
|
4996
5085
|
{
|
|
4997
5086
|
value: String(config.decimalDigits ?? 2),
|
|
4998
5087
|
onChange: (value) => onChange("decimalDigits", parseInt(value, 10)),
|
|
@@ -5033,9 +5122,9 @@ function DisplayConfigSection({
|
|
|
5033
5122
|
"pie_chart",
|
|
5034
5123
|
"scatter_chart"
|
|
5035
5124
|
].includes(widgetType);
|
|
5036
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5125
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(chunkPG7QBH3G_cjs.CollapsibleSection, { title: "Display Options", defaultOpen, children: [
|
|
5037
5126
|
showColorPalette && /* @__PURE__ */ jsxRuntime.jsx("div", { style: fieldStyle, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5038
|
-
|
|
5127
|
+
chunkPG7QBH3G_cjs.ColorPaletteSelector,
|
|
5039
5128
|
{
|
|
5040
5129
|
value: config.colors,
|
|
5041
5130
|
onChange: (colors) => onChange("colors", colors)
|
|
@@ -5044,7 +5133,7 @@ function DisplayConfigSection({
|
|
|
5044
5133
|
showOrientation && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
5045
5134
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Orientation" }),
|
|
5046
5135
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5047
|
-
|
|
5136
|
+
chunkPG7QBH3G_cjs.Select,
|
|
5048
5137
|
{
|
|
5049
5138
|
value: config.orientation || "vertical",
|
|
5050
5139
|
onChange: (value) => onChange("orientation", value),
|
|
@@ -5057,7 +5146,7 @@ function DisplayConfigSection({
|
|
|
5057
5146
|
] }),
|
|
5058
5147
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: rowStyle, children: [
|
|
5059
5148
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5060
|
-
|
|
5149
|
+
chunkPG7QBH3G_cjs.Checkbox,
|
|
5061
5150
|
{
|
|
5062
5151
|
label: "Show Legend",
|
|
5063
5152
|
checked: config.show_legend ?? true,
|
|
@@ -5065,7 +5154,7 @@ function DisplayConfigSection({
|
|
|
5065
5154
|
}
|
|
5066
5155
|
),
|
|
5067
5156
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5068
|
-
|
|
5157
|
+
chunkPG7QBH3G_cjs.Checkbox,
|
|
5069
5158
|
{
|
|
5070
5159
|
label: "Data Labels",
|
|
5071
5160
|
checked: config.show_data_labels ?? false,
|
|
@@ -5073,7 +5162,7 @@ function DisplayConfigSection({
|
|
|
5073
5162
|
}
|
|
5074
5163
|
),
|
|
5075
5164
|
showStacked && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5076
|
-
|
|
5165
|
+
chunkPG7QBH3G_cjs.Checkbox,
|
|
5077
5166
|
{
|
|
5078
5167
|
label: "Stacked",
|
|
5079
5168
|
checked: config.stacked ?? false,
|
|
@@ -5158,10 +5247,10 @@ function DateFormattingSection({
|
|
|
5158
5247
|
fontSize: theme.fontSizes.sm,
|
|
5159
5248
|
color: theme.colors.textMuted
|
|
5160
5249
|
};
|
|
5161
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5250
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.CollapsibleSection, { title: "Date Formatting", defaultOpen, children: dateColumns.map((col) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
5162
5251
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: columnNameStyle, children: col.alias }) }),
|
|
5163
5252
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5164
|
-
|
|
5253
|
+
chunkPG7QBH3G_cjs.Select,
|
|
5165
5254
|
{
|
|
5166
5255
|
value: config.dateFormats?.[col.name] || "",
|
|
5167
5256
|
onChange: (value) => handleFormatChange(col.name, value),
|
|
@@ -5219,10 +5308,10 @@ function TrendConfigSection({
|
|
|
5219
5308
|
color: theme.colors.textMuted,
|
|
5220
5309
|
marginTop: theme.spacing.xs
|
|
5221
5310
|
};
|
|
5222
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5311
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(chunkPG7QBH3G_cjs.CollapsibleSection, { title: "Trend Comparison", defaultOpen, children: [
|
|
5223
5312
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
5224
5313
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5225
|
-
|
|
5314
|
+
chunkPG7QBH3G_cjs.Checkbox,
|
|
5226
5315
|
{
|
|
5227
5316
|
label: "Show Trend Indicator",
|
|
5228
5317
|
checked: config.showTrend ?? false,
|
|
@@ -5235,7 +5324,7 @@ function TrendConfigSection({
|
|
|
5235
5324
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
5236
5325
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Comparison Period" }),
|
|
5237
5326
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5238
|
-
|
|
5327
|
+
chunkPG7QBH3G_cjs.Select,
|
|
5239
5328
|
{
|
|
5240
5329
|
value: config.trendPeriod || "previous_period",
|
|
5241
5330
|
onChange: (value) => onChange("trendPeriod", value),
|
|
@@ -5246,7 +5335,7 @@ function TrendConfigSection({
|
|
|
5246
5335
|
dateColumnOptions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
5247
5336
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Date Column" }),
|
|
5248
5337
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5249
|
-
|
|
5338
|
+
chunkPG7QBH3G_cjs.Select,
|
|
5250
5339
|
{
|
|
5251
5340
|
value: config.trendDateColumn || "",
|
|
5252
5341
|
onChange: (value) => onChange("trendDateColumn", value || void 0),
|
|
@@ -5292,7 +5381,8 @@ function WidgetEditorPage({
|
|
|
5292
5381
|
onCancel
|
|
5293
5382
|
}) {
|
|
5294
5383
|
const { theme } = chunkLMTG3LRC_cjs.useTheme();
|
|
5295
|
-
const { client } =
|
|
5384
|
+
const { client } = chunkPG7QBH3G_cjs.useAnalytics();
|
|
5385
|
+
const { enabled: llmEnabled, isLoading: llmStatusLoading } = chunkPG7QBH3G_cjs.useLLMStatus();
|
|
5296
5386
|
const isNew = widget === null;
|
|
5297
5387
|
const [type, setType] = react.useState(widget?.type ?? "bar_chart");
|
|
5298
5388
|
const [title, setTitle] = react.useState(widget?.title ?? "New Widget");
|
|
@@ -5304,8 +5394,10 @@ function WidgetEditorPage({
|
|
|
5304
5394
|
const [position, setPosition] = react.useState(
|
|
5305
5395
|
widget?.position ?? { x: 0, y: 0, w: 6, h: 4, minW: 2, minH: 2 }
|
|
5306
5396
|
);
|
|
5397
|
+
const [rawSql, setRawSql] = react.useState(widget?.config?.raw_sql ?? "");
|
|
5398
|
+
const [schemaOpen, setSchemaOpen] = react.useState(true);
|
|
5307
5399
|
const [dataSourceMode, setDataSourceMode] = react.useState(
|
|
5308
|
-
isNew ? "guided" : widget?.
|
|
5400
|
+
isNew ? "guided" : widget?.config?.data_source_mode ?? "guided"
|
|
5309
5401
|
);
|
|
5310
5402
|
const [previewResult, setPreviewResult] = react.useState(null);
|
|
5311
5403
|
const [previewLoading, setPreviewLoading] = react.useState(false);
|
|
@@ -5328,6 +5420,24 @@ function WidgetEditorPage({
|
|
|
5328
5420
|
[]
|
|
5329
5421
|
);
|
|
5330
5422
|
const refreshPreview = react.useCallback(async () => {
|
|
5423
|
+
if (dataSourceMode === "sql") {
|
|
5424
|
+
if (!rawSql.trim() || !client) {
|
|
5425
|
+
setPreviewResult(null);
|
|
5426
|
+
return;
|
|
5427
|
+
}
|
|
5428
|
+
setPreviewLoading(true);
|
|
5429
|
+
setPreviewError(null);
|
|
5430
|
+
try {
|
|
5431
|
+
const result = await client.executeSQL(rawSql);
|
|
5432
|
+
setPreviewResult(result);
|
|
5433
|
+
} catch (err) {
|
|
5434
|
+
setPreviewError(err instanceof Error ? err : new Error("SQL execution failed"));
|
|
5435
|
+
setPreviewResult(null);
|
|
5436
|
+
} finally {
|
|
5437
|
+
setPreviewLoading(false);
|
|
5438
|
+
}
|
|
5439
|
+
return;
|
|
5440
|
+
}
|
|
5331
5441
|
if (!query || !client) {
|
|
5332
5442
|
setPreviewResult(null);
|
|
5333
5443
|
return;
|
|
@@ -5343,15 +5453,38 @@ function WidgetEditorPage({
|
|
|
5343
5453
|
} finally {
|
|
5344
5454
|
setPreviewLoading(false);
|
|
5345
5455
|
}
|
|
5346
|
-
}, [query, client]);
|
|
5456
|
+
}, [query, rawSql, dataSourceMode, client]);
|
|
5347
5457
|
react.useEffect(() => {
|
|
5458
|
+
if (dataSourceMode === "sql") {
|
|
5459
|
+
return;
|
|
5460
|
+
}
|
|
5348
5461
|
if (query) {
|
|
5349
5462
|
void refreshPreview();
|
|
5350
5463
|
} else {
|
|
5351
5464
|
setPreviewResult(null);
|
|
5352
5465
|
setPreviewError(null);
|
|
5353
5466
|
}
|
|
5354
|
-
}, [query, refreshPreview]);
|
|
5467
|
+
}, [query, dataSourceMode, refreshPreview]);
|
|
5468
|
+
const queryHasAdvancedFeatures = react.useCallback((q) => {
|
|
5469
|
+
if (!q) return false;
|
|
5470
|
+
if (q.tables && q.tables.length > 1 && q.joins && q.joins.length > 0) return true;
|
|
5471
|
+
if (q.calculated_fields && q.calculated_fields.length > 0) return true;
|
|
5472
|
+
if (q.group_by && q.group_by.length > 0) return true;
|
|
5473
|
+
if (q.order_by && q.order_by.length > 0) return true;
|
|
5474
|
+
if (q.limit != null) return true;
|
|
5475
|
+
if (q.offset != null) return true;
|
|
5476
|
+
if (q.time_series) return true;
|
|
5477
|
+
return false;
|
|
5478
|
+
}, []);
|
|
5479
|
+
const handleModeSwitch = react.useCallback((newMode) => {
|
|
5480
|
+
if (newMode === "guided" && (dataSourceMode === "advanced" || dataSourceMode === "saved") && queryHasAdvancedFeatures(query)) {
|
|
5481
|
+
const confirmed = window.confirm(
|
|
5482
|
+
"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?"
|
|
5483
|
+
);
|
|
5484
|
+
if (!confirmed) return;
|
|
5485
|
+
}
|
|
5486
|
+
setDataSourceMode(newMode);
|
|
5487
|
+
}, [dataSourceMode, query, queryHasAdvancedFeatures]);
|
|
5355
5488
|
const handleSavedQuerySelect = react.useCallback((savedQuery) => {
|
|
5356
5489
|
setQuery(savedQuery.query);
|
|
5357
5490
|
}, []);
|
|
@@ -5363,19 +5496,25 @@ function WidgetEditorPage({
|
|
|
5363
5496
|
setPreviewResult(null);
|
|
5364
5497
|
setPreviewError(null);
|
|
5365
5498
|
}, []);
|
|
5499
|
+
const handleApplySql = react.useCallback((sql) => {
|
|
5500
|
+
setRawSql(sql);
|
|
5501
|
+
}, []);
|
|
5366
5502
|
const handleSave = react.useCallback(() => {
|
|
5503
|
+
const savedConfig = { ...config, data_source_mode: dataSourceMode };
|
|
5504
|
+
if (dataSourceMode === "sql") {
|
|
5505
|
+
savedConfig.raw_sql = rawSql.trim() || void 0;
|
|
5506
|
+
}
|
|
5367
5507
|
const savedWidget = {
|
|
5368
5508
|
id: widget?.id ?? generateId(),
|
|
5369
5509
|
type,
|
|
5370
5510
|
title,
|
|
5371
|
-
config,
|
|
5372
|
-
query,
|
|
5511
|
+
config: savedConfig,
|
|
5512
|
+
query: dataSourceMode === "sql" ? null : query,
|
|
5373
5513
|
position,
|
|
5374
|
-
hyperlink
|
|
5375
|
-
dataSourceMode
|
|
5514
|
+
hyperlink
|
|
5376
5515
|
};
|
|
5377
5516
|
onSave(savedWidget);
|
|
5378
|
-
}, [widget, type, title, config, query, position, hyperlink, dataSourceMode, onSave]);
|
|
5517
|
+
}, [widget, type, title, config, query, rawSql, position, hyperlink, dataSourceMode, onSave]);
|
|
5379
5518
|
const columnSelectOptions = react.useMemo(() => {
|
|
5380
5519
|
if (!schema) return [];
|
|
5381
5520
|
return schema.tables.flatMap(
|
|
@@ -5398,7 +5537,8 @@ function WidgetEditorPage({
|
|
|
5398
5537
|
justifyContent: "space-between",
|
|
5399
5538
|
padding: `${theme.spacing.md} ${theme.spacing.lg}`,
|
|
5400
5539
|
borderBottom: `1px solid ${theme.colors.border}`,
|
|
5401
|
-
backgroundColor: theme.colors.surface
|
|
5540
|
+
backgroundColor: theme.colors.surface,
|
|
5541
|
+
flexShrink: 0
|
|
5402
5542
|
};
|
|
5403
5543
|
const headerLeftStyle = {
|
|
5404
5544
|
display: "flex",
|
|
@@ -5429,38 +5569,28 @@ function WidgetEditorPage({
|
|
|
5429
5569
|
};
|
|
5430
5570
|
const bodyStyle = {
|
|
5431
5571
|
flex: 1,
|
|
5432
|
-
|
|
5433
|
-
|
|
5572
|
+
overflow: "auto",
|
|
5573
|
+
display: "grid",
|
|
5574
|
+
gridTemplateColumns: "360px 1fr"
|
|
5434
5575
|
};
|
|
5435
5576
|
const leftPanelStyle = {
|
|
5436
|
-
width: "320px",
|
|
5437
|
-
flexShrink: 0,
|
|
5438
5577
|
borderRight: `1px solid ${theme.colors.border}`,
|
|
5439
|
-
overflow: "auto",
|
|
5440
5578
|
padding: theme.spacing.md,
|
|
5579
|
+
paddingBottom: theme.spacing.xl,
|
|
5441
5580
|
display: "flex",
|
|
5442
5581
|
flexDirection: "column",
|
|
5443
5582
|
gap: theme.spacing.lg
|
|
5444
5583
|
};
|
|
5445
5584
|
const mainPanelStyle = {
|
|
5446
|
-
|
|
5447
|
-
display: "flex",
|
|
5448
|
-
flexDirection: "column",
|
|
5449
|
-
minHeight: 0
|
|
5585
|
+
minWidth: 0
|
|
5450
5586
|
};
|
|
5451
5587
|
const previewPanelStyle = {
|
|
5452
|
-
height: "
|
|
5453
|
-
|
|
5454
|
-
|
|
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,
|
|
5588
|
+
height: "440px",
|
|
5589
|
+
padding: theme.spacing.lg,
|
|
5590
|
+
borderBottom: `1px solid ${theme.colors.border}`,
|
|
5462
5591
|
overflow: "hidden"
|
|
5463
5592
|
};
|
|
5593
|
+
const dataSourcePanelStyle = {};
|
|
5464
5594
|
const dataSourceHeaderStyle = {
|
|
5465
5595
|
display: "flex",
|
|
5466
5596
|
alignItems: "center",
|
|
@@ -5480,15 +5610,12 @@ function WidgetEditorPage({
|
|
|
5480
5610
|
transition: "all 0.15s ease"
|
|
5481
5611
|
});
|
|
5482
5612
|
const dataSourceContentStyle = {
|
|
5483
|
-
flex: "1 1 auto",
|
|
5484
|
-
overflow: "auto",
|
|
5485
5613
|
padding: theme.spacing.md,
|
|
5486
|
-
paddingBottom: "
|
|
5487
|
-
// Extra
|
|
5488
|
-
minHeight: "250px"
|
|
5614
|
+
paddingBottom: "200px"
|
|
5615
|
+
// Extra padding to create scroll room for filters
|
|
5489
5616
|
};
|
|
5490
5617
|
const sectionStyle = {
|
|
5491
|
-
|
|
5618
|
+
// Note: Parent has flex gap for spacing between sections
|
|
5492
5619
|
};
|
|
5493
5620
|
const sectionTitleStyle = {
|
|
5494
5621
|
fontSize: theme.fontSizes.xs,
|
|
@@ -5537,7 +5664,7 @@ function WidgetEditorPage({
|
|
|
5537
5664
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
5538
5665
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "X-Axis Column" }),
|
|
5539
5666
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5540
|
-
|
|
5667
|
+
chunkPG7QBH3G_cjs.Select,
|
|
5541
5668
|
{
|
|
5542
5669
|
value: config.x_axis || "",
|
|
5543
5670
|
onChange: (value) => updateConfig("x_axis", value || void 0),
|
|
@@ -5598,7 +5725,7 @@ function WidgetEditorPage({
|
|
|
5598
5725
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
5599
5726
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "X-Axis Column" }),
|
|
5600
5727
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5601
|
-
|
|
5728
|
+
chunkPG7QBH3G_cjs.Select,
|
|
5602
5729
|
{
|
|
5603
5730
|
value: config.x_axis || "",
|
|
5604
5731
|
onChange: (value) => updateConfig("x_axis", value || void 0),
|
|
@@ -5679,7 +5806,7 @@ function WidgetEditorPage({
|
|
|
5679
5806
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
5680
5807
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "X-Axis Column" }),
|
|
5681
5808
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5682
|
-
|
|
5809
|
+
chunkPG7QBH3G_cjs.Select,
|
|
5683
5810
|
{
|
|
5684
5811
|
value: config.x_axis || "",
|
|
5685
5812
|
onChange: (value) => updateConfig("x_axis", value || void 0),
|
|
@@ -5690,7 +5817,7 @@ function WidgetEditorPage({
|
|
|
5690
5817
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
5691
5818
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Y-Axis Column" }),
|
|
5692
5819
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5693
|
-
|
|
5820
|
+
chunkPG7QBH3G_cjs.Select,
|
|
5694
5821
|
{
|
|
5695
5822
|
value: config.y_axis?.[0] || "",
|
|
5696
5823
|
onChange: (value) => updateConfig("y_axis", value ? [value] : void 0),
|
|
@@ -5723,7 +5850,7 @@ function WidgetEditorPage({
|
|
|
5723
5850
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
5724
5851
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Page Size" }),
|
|
5725
5852
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5726
|
-
|
|
5853
|
+
chunkPG7QBH3G_cjs.Select,
|
|
5727
5854
|
{
|
|
5728
5855
|
value: String(config.page_size || 10),
|
|
5729
5856
|
onChange: (value) => updateConfig("page_size", parseInt(value, 10)),
|
|
@@ -5737,7 +5864,7 @@ function WidgetEditorPage({
|
|
|
5737
5864
|
)
|
|
5738
5865
|
] }),
|
|
5739
5866
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5740
|
-
|
|
5867
|
+
chunkPG7QBH3G_cjs.Checkbox,
|
|
5741
5868
|
{
|
|
5742
5869
|
label: "Sortable Columns",
|
|
5743
5870
|
checked: config.sortable ?? true,
|
|
@@ -5795,10 +5922,10 @@ function WidgetEditorPage({
|
|
|
5795
5922
|
},
|
|
5796
5923
|
children: [
|
|
5797
5924
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: theme.spacing.sm }, children: [
|
|
5798
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5925
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "table", size: 16 }),
|
|
5799
5926
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 500, color: theme.colors.text }, children: "Query configured" })
|
|
5800
5927
|
] }),
|
|
5801
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5928
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Button, { variant: "ghost", size: "sm", onClick: handleClearQuery, children: /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "x", size: 16 }) })
|
|
5802
5929
|
]
|
|
5803
5930
|
}
|
|
5804
5931
|
),
|
|
@@ -5817,14 +5944,14 @@ function WidgetEditorPage({
|
|
|
5817
5944
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerStyle, children: [
|
|
5818
5945
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerLeftStyle, children: [
|
|
5819
5946
|
/* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", style: backButtonStyle, onClick: onCancel, children: [
|
|
5820
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5947
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "chevron-left", size: 16 }),
|
|
5821
5948
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Back" })
|
|
5822
5949
|
] }),
|
|
5823
5950
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: headerTitleStyle, children: isNew ? "Add Widget" : "Edit Widget" })
|
|
5824
5951
|
] }),
|
|
5825
5952
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerActionsStyle, children: [
|
|
5826
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5827
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5953
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Button, { variant: "ghost", onClick: onCancel, children: "Cancel" }),
|
|
5954
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Button, { variant: "primary", onClick: handleSave, children: isNew ? "Add Widget" : "Save Changes" })
|
|
5828
5955
|
] })
|
|
5829
5956
|
] }),
|
|
5830
5957
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: bodyStyle, children: [
|
|
@@ -5835,7 +5962,7 @@ function WidgetEditorPage({
|
|
|
5835
5962
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
5836
5963
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Title" }),
|
|
5837
5964
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5838
|
-
|
|
5965
|
+
chunkPG7QBH3G_cjs.Input,
|
|
5839
5966
|
{
|
|
5840
5967
|
value: title,
|
|
5841
5968
|
onChange: (e) => setTitle(e.target.value),
|
|
@@ -5873,6 +6000,7 @@ function WidgetEditorPage({
|
|
|
5873
6000
|
title,
|
|
5874
6001
|
config,
|
|
5875
6002
|
query,
|
|
6003
|
+
rawSql: dataSourceMode === "sql" ? rawSql : void 0,
|
|
5876
6004
|
result: previewResult,
|
|
5877
6005
|
isLoading: previewLoading,
|
|
5878
6006
|
error: previewError
|
|
@@ -5882,30 +6010,57 @@ function WidgetEditorPage({
|
|
|
5882
6010
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: dataSourceHeaderStyle, children: [
|
|
5883
6011
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: theme.fontSizes.sm, fontWeight: 500, marginRight: "auto" }, children: "Data Source" }),
|
|
5884
6012
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5885
|
-
|
|
6013
|
+
chunkPG7QBH3G_cjs.Tooltip,
|
|
5886
6014
|
{
|
|
5887
|
-
|
|
5888
|
-
|
|
5889
|
-
|
|
5890
|
-
children:
|
|
6015
|
+
content: "Quick setup: pick columns from dropdowns to build your chart",
|
|
6016
|
+
position: "bottom",
|
|
6017
|
+
style: { whiteSpace: "normal" },
|
|
6018
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6019
|
+
"button",
|
|
6020
|
+
{
|
|
6021
|
+
type: "button",
|
|
6022
|
+
"data-testid": "data-source-mode-guided",
|
|
6023
|
+
style: tabStyle(dataSourceMode === "guided"),
|
|
6024
|
+
onClick: () => handleModeSwitch("guided"),
|
|
6025
|
+
children: "Guided"
|
|
6026
|
+
}
|
|
6027
|
+
)
|
|
5891
6028
|
}
|
|
5892
6029
|
),
|
|
5893
6030
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5894
|
-
|
|
6031
|
+
chunkPG7QBH3G_cjs.Tooltip,
|
|
5895
6032
|
{
|
|
5896
|
-
|
|
5897
|
-
|
|
5898
|
-
|
|
5899
|
-
children:
|
|
6033
|
+
content: "Full control: combine tables, add filters, and create custom calculations",
|
|
6034
|
+
position: "bottom",
|
|
6035
|
+
style: { whiteSpace: "normal" },
|
|
6036
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6037
|
+
"button",
|
|
6038
|
+
{
|
|
6039
|
+
type: "button",
|
|
6040
|
+
"data-testid": "data-source-mode-advanced",
|
|
6041
|
+
style: tabStyle(dataSourceMode === "advanced"),
|
|
6042
|
+
onClick: () => handleModeSwitch("advanced"),
|
|
6043
|
+
children: "Advanced"
|
|
6044
|
+
}
|
|
6045
|
+
)
|
|
5900
6046
|
}
|
|
5901
6047
|
),
|
|
5902
6048
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5903
|
-
|
|
6049
|
+
chunkPG7QBH3G_cjs.Tooltip,
|
|
5904
6050
|
{
|
|
5905
|
-
|
|
5906
|
-
|
|
5907
|
-
|
|
5908
|
-
children:
|
|
6051
|
+
content: "Write raw SQL queries directly, with optional AI assistance",
|
|
6052
|
+
position: "bottom",
|
|
6053
|
+
style: { whiteSpace: "normal" },
|
|
6054
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6055
|
+
"button",
|
|
6056
|
+
{
|
|
6057
|
+
type: "button",
|
|
6058
|
+
"data-testid": "data-source-mode-sql",
|
|
6059
|
+
style: tabStyle(dataSourceMode === "sql"),
|
|
6060
|
+
onClick: () => handleModeSwitch("sql"),
|
|
6061
|
+
children: "SQL"
|
|
6062
|
+
}
|
|
6063
|
+
)
|
|
5909
6064
|
}
|
|
5910
6065
|
)
|
|
5911
6066
|
] }),
|
|
@@ -5921,7 +6076,7 @@ function WidgetEditorPage({
|
|
|
5921
6076
|
}
|
|
5922
6077
|
),
|
|
5923
6078
|
dataSourceMode === "advanced" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5924
|
-
|
|
6079
|
+
chunkPG7QBH3G_cjs.QueryBuilder,
|
|
5925
6080
|
{
|
|
5926
6081
|
initialQuery: query ?? void 0,
|
|
5927
6082
|
onQueryChange: handleQueryChange,
|
|
@@ -5932,13 +6087,106 @@ function WidgetEditorPage({
|
|
|
5932
6087
|
}
|
|
5933
6088
|
),
|
|
5934
6089
|
dataSourceMode === "saved" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5935
|
-
|
|
6090
|
+
chunkPG7QBH3G_cjs.SavedQueryPicker,
|
|
5936
6091
|
{
|
|
5937
6092
|
currentQuery: query,
|
|
5938
6093
|
onSelect: handleSavedQuerySelect,
|
|
5939
6094
|
showSave: false
|
|
5940
6095
|
}
|
|
5941
|
-
)
|
|
6096
|
+
),
|
|
6097
|
+
dataSourceMode === "sql" && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: 0, height: "100%", minHeight: "400px" }, children: [
|
|
6098
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { "data-testid": "schema-panel", style: {
|
|
6099
|
+
width: schemaOpen ? "220px" : "36px",
|
|
6100
|
+
flexShrink: 0,
|
|
6101
|
+
transition: "width 0.2s ease",
|
|
6102
|
+
borderRight: `1px solid ${theme.colors.border}`,
|
|
6103
|
+
display: "flex",
|
|
6104
|
+
flexDirection: "column",
|
|
6105
|
+
overflow: "hidden"
|
|
6106
|
+
}, children: schemaOpen ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6107
|
+
chunkPG7QBH3G_cjs.SchemaExplorer,
|
|
6108
|
+
{
|
|
6109
|
+
searchable: true,
|
|
6110
|
+
collapsible: true,
|
|
6111
|
+
onColumnSelect: (table, col) => {
|
|
6112
|
+
const ref = `"${table.name}"."${col.name}"`;
|
|
6113
|
+
setRawSql((prev) => prev ? `${prev} ${ref}` : ref);
|
|
6114
|
+
},
|
|
6115
|
+
headerAction: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6116
|
+
"button",
|
|
6117
|
+
{
|
|
6118
|
+
type: "button",
|
|
6119
|
+
onClick: () => setSchemaOpen(false),
|
|
6120
|
+
title: "Collapse schema panel",
|
|
6121
|
+
"data-testid": "schema-toggle-open",
|
|
6122
|
+
style: {
|
|
6123
|
+
display: "flex",
|
|
6124
|
+
alignItems: "center",
|
|
6125
|
+
justifyContent: "center",
|
|
6126
|
+
width: "22px",
|
|
6127
|
+
height: "22px",
|
|
6128
|
+
backgroundColor: "transparent",
|
|
6129
|
+
border: `1px solid ${theme.colors.border}`,
|
|
6130
|
+
borderRadius: theme.radius.sm,
|
|
6131
|
+
cursor: "pointer",
|
|
6132
|
+
color: theme.colors.textMuted,
|
|
6133
|
+
flexShrink: 0
|
|
6134
|
+
},
|
|
6135
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "chevron-left", size: 12 })
|
|
6136
|
+
}
|
|
6137
|
+
),
|
|
6138
|
+
style: { flex: 1, border: "none", borderRadius: 0 }
|
|
6139
|
+
}
|
|
6140
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6141
|
+
"button",
|
|
6142
|
+
{
|
|
6143
|
+
type: "button",
|
|
6144
|
+
onClick: () => setSchemaOpen(true),
|
|
6145
|
+
title: "Show schema browser",
|
|
6146
|
+
"data-testid": "schema-toggle-collapsed",
|
|
6147
|
+
style: {
|
|
6148
|
+
display: "flex",
|
|
6149
|
+
flexDirection: "column",
|
|
6150
|
+
alignItems: "center",
|
|
6151
|
+
gap: "6px",
|
|
6152
|
+
paddingTop: theme.spacing.sm,
|
|
6153
|
+
width: "100%",
|
|
6154
|
+
height: "100%",
|
|
6155
|
+
backgroundColor: theme.colors.surface,
|
|
6156
|
+
border: "none",
|
|
6157
|
+
cursor: "pointer",
|
|
6158
|
+
color: theme.colors.textMuted,
|
|
6159
|
+
fontFamily: theme.fonts.sans
|
|
6160
|
+
},
|
|
6161
|
+
children: [
|
|
6162
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "table", size: 16 }),
|
|
6163
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: {
|
|
6164
|
+
writingMode: "vertical-rl",
|
|
6165
|
+
fontSize: "11px",
|
|
6166
|
+
fontWeight: 500,
|
|
6167
|
+
letterSpacing: "0.04em"
|
|
6168
|
+
}, children: "Schema" })
|
|
6169
|
+
]
|
|
6170
|
+
}
|
|
6171
|
+
) }),
|
|
6172
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: 1, minWidth: 0 }, "data-testid": "sql-editor", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6173
|
+
chunkPG7QBH3G_cjs.CustomSQLEditor,
|
|
6174
|
+
{
|
|
6175
|
+
initialSql: rawSql,
|
|
6176
|
+
onSqlChange: setRawSql,
|
|
6177
|
+
onExecute: () => void refreshPreview(),
|
|
6178
|
+
showResults: false,
|
|
6179
|
+
placeholder: "Write your SQL query here..."
|
|
6180
|
+
}
|
|
6181
|
+
) }),
|
|
6182
|
+
!llmStatusLoading && llmEnabled && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: "340px", flexShrink: 0 }, "data-testid": "chat-panel", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6183
|
+
chunkPG7QBH3G_cjs.ChatPanel,
|
|
6184
|
+
{
|
|
6185
|
+
currentSql: rawSql || null,
|
|
6186
|
+
onApplySql: handleApplySql
|
|
6187
|
+
}
|
|
6188
|
+
) })
|
|
6189
|
+
] })
|
|
5942
6190
|
] })
|
|
5943
6191
|
] })
|
|
5944
6192
|
] })
|
|
@@ -5982,8 +6230,8 @@ function DashboardEditor({
|
|
|
5982
6230
|
className = ""
|
|
5983
6231
|
}) {
|
|
5984
6232
|
const { theme } = chunkLMTG3LRC_cjs.useTheme();
|
|
5985
|
-
const { client } =
|
|
5986
|
-
const { schema } =
|
|
6233
|
+
const { client } = chunkPG7QBH3G_cjs.useAnalytics();
|
|
6234
|
+
const { schema } = chunkPG7QBH3G_cjs.useSchema();
|
|
5987
6235
|
const [currentDashboardId, setCurrentDashboardId] = react.useState(dashboardId);
|
|
5988
6236
|
react.useEffect(() => {
|
|
5989
6237
|
setCurrentDashboardId(dashboardId);
|
|
@@ -6020,7 +6268,9 @@ function DashboardEditor({
|
|
|
6020
6268
|
clientRef.current = client;
|
|
6021
6269
|
const loadedDashboardRef = react.useRef(null);
|
|
6022
6270
|
const executeWidgetQueries = react.useCallback(async (widgets, currentClient) => {
|
|
6023
|
-
const widgetsWithQueries = widgets.filter(
|
|
6271
|
+
const widgetsWithQueries = widgets.filter(
|
|
6272
|
+
(w) => w.query || w.config?.data_source_mode === "sql" && w.config?.raw_sql
|
|
6273
|
+
);
|
|
6024
6274
|
if (widgetsWithQueries.length === 0) return;
|
|
6025
6275
|
for (let i = 0; i < widgetsWithQueries.length; i += batchSize) {
|
|
6026
6276
|
const batch = widgetsWithQueries.slice(i, i + batchSize);
|
|
@@ -6034,7 +6284,8 @@ function DashboardEditor({
|
|
|
6034
6284
|
await Promise.all(
|
|
6035
6285
|
batch.map(async (widget) => {
|
|
6036
6286
|
try {
|
|
6037
|
-
const
|
|
6287
|
+
const isSqlMode = widget.config?.data_source_mode === "sql" && widget.config?.raw_sql;
|
|
6288
|
+
const result = isSqlMode ? await currentClient.executeSQL(widget.config.raw_sql) : await currentClient.executeQuery(widget.query);
|
|
6038
6289
|
setWidgetResults((prev) => ({ ...prev, [widget.id]: result }));
|
|
6039
6290
|
setWidgetRefreshTimes((prev) => ({ ...prev, [widget.id]: Math.floor(Date.now() / 1e3) }));
|
|
6040
6291
|
} catch (err) {
|
|
@@ -6111,11 +6362,12 @@ function DashboardEditor({
|
|
|
6111
6362
|
const refreshWidget = react.useCallback(
|
|
6112
6363
|
async (widgetId, widgetOverride) => {
|
|
6113
6364
|
const widget = widgetOverride ?? dashboard.widgets.find((w) => w.id === widgetId);
|
|
6114
|
-
|
|
6365
|
+
const isSqlMode = widget?.config?.data_source_mode === "sql" && widget?.config?.raw_sql;
|
|
6366
|
+
if (!widget?.query && !isSqlMode || !client) return;
|
|
6115
6367
|
setWidgetLoading((prev) => ({ ...prev, [widgetId]: true }));
|
|
6116
6368
|
setRefreshingWidgets((prev) => new Set(prev).add(widgetId));
|
|
6117
6369
|
try {
|
|
6118
|
-
const result = await client.executeQuery(widget.query, true);
|
|
6370
|
+
const result = isSqlMode ? await client.executeSQL(widget.config.raw_sql) : await client.executeQuery(widget.query, true);
|
|
6119
6371
|
setWidgetResults((prev) => ({ ...prev, [widgetId]: result }));
|
|
6120
6372
|
setWidgetRefreshTimes((prev) => ({ ...prev, [widgetId]: Math.floor(Date.now() / 1e3) }));
|
|
6121
6373
|
setWidgetErrors((prev) => {
|
|
@@ -6610,7 +6862,7 @@ function WidgetPalette({
|
|
|
6610
6862
|
Object.assign(e.currentTarget.style, itemStyle);
|
|
6611
6863
|
},
|
|
6612
6864
|
children: [
|
|
6613
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: iconContainerStyle, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6865
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: iconContainerStyle, children: /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: widgetType.icon, size: 24 }) }),
|
|
6614
6866
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: labelStyle, children: widgetType.label }),
|
|
6615
6867
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: descriptionStyle, children: widgetType.description })
|
|
6616
6868
|
]
|
|
@@ -6762,7 +7014,7 @@ function WidgetEditor({
|
|
|
6762
7014
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
6763
7015
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Format" }),
|
|
6764
7016
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6765
|
-
|
|
7017
|
+
chunkPG7QBH3G_cjs.Select,
|
|
6766
7018
|
{
|
|
6767
7019
|
value: config.format || "number",
|
|
6768
7020
|
onChange: (value) => updateConfig("format", value),
|
|
@@ -6778,7 +7030,7 @@ function WidgetEditor({
|
|
|
6778
7030
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
6779
7031
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Trend Comparison Field" }),
|
|
6780
7032
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6781
|
-
|
|
7033
|
+
chunkPG7QBH3G_cjs.Select,
|
|
6782
7034
|
{
|
|
6783
7035
|
value: config.trend_comparison || "",
|
|
6784
7036
|
onChange: (value) => updateConfig("trend_comparison", value || void 0),
|
|
@@ -6795,7 +7047,7 @@ function WidgetEditor({
|
|
|
6795
7047
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
6796
7048
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "X-Axis Column" }),
|
|
6797
7049
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6798
|
-
|
|
7050
|
+
chunkPG7QBH3G_cjs.Select,
|
|
6799
7051
|
{
|
|
6800
7052
|
value: config.x_axis || "",
|
|
6801
7053
|
onChange: (value) => updateConfig("x_axis", value),
|
|
@@ -6806,7 +7058,7 @@ function WidgetEditor({
|
|
|
6806
7058
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
6807
7059
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Orientation" }),
|
|
6808
7060
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6809
|
-
|
|
7061
|
+
chunkPG7QBH3G_cjs.Select,
|
|
6810
7062
|
{
|
|
6811
7063
|
value: config.orientation || "vertical",
|
|
6812
7064
|
onChange: (value) => updateConfig("orientation", value),
|
|
@@ -6819,7 +7071,7 @@ function WidgetEditor({
|
|
|
6819
7071
|
] }),
|
|
6820
7072
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: rowStyle, children: [
|
|
6821
7073
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6822
|
-
|
|
7074
|
+
chunkPG7QBH3G_cjs.Checkbox,
|
|
6823
7075
|
{
|
|
6824
7076
|
label: "Show Legend",
|
|
6825
7077
|
checked: config.show_legend ?? true,
|
|
@@ -6827,7 +7079,7 @@ function WidgetEditor({
|
|
|
6827
7079
|
}
|
|
6828
7080
|
),
|
|
6829
7081
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6830
|
-
|
|
7082
|
+
chunkPG7QBH3G_cjs.Checkbox,
|
|
6831
7083
|
{
|
|
6832
7084
|
label: "Stacked",
|
|
6833
7085
|
checked: config.stacked ?? false,
|
|
@@ -6835,7 +7087,7 @@ function WidgetEditor({
|
|
|
6835
7087
|
}
|
|
6836
7088
|
),
|
|
6837
7089
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6838
|
-
|
|
7090
|
+
chunkPG7QBH3G_cjs.Checkbox,
|
|
6839
7091
|
{
|
|
6840
7092
|
label: "Show Data Labels",
|
|
6841
7093
|
checked: config.show_data_labels ?? false,
|
|
@@ -6850,7 +7102,7 @@ function WidgetEditor({
|
|
|
6850
7102
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
6851
7103
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "X-Axis Column" }),
|
|
6852
7104
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6853
|
-
|
|
7105
|
+
chunkPG7QBH3G_cjs.Select,
|
|
6854
7106
|
{
|
|
6855
7107
|
value: config.x_axis || "",
|
|
6856
7108
|
onChange: (value) => updateConfig("x_axis", value),
|
|
@@ -6860,7 +7112,7 @@ function WidgetEditor({
|
|
|
6860
7112
|
] }),
|
|
6861
7113
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: rowStyle, children: [
|
|
6862
7114
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6863
|
-
|
|
7115
|
+
chunkPG7QBH3G_cjs.Checkbox,
|
|
6864
7116
|
{
|
|
6865
7117
|
label: "Show Legend",
|
|
6866
7118
|
checked: config.show_legend ?? true,
|
|
@@ -6868,7 +7120,7 @@ function WidgetEditor({
|
|
|
6868
7120
|
}
|
|
6869
7121
|
),
|
|
6870
7122
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6871
|
-
|
|
7123
|
+
chunkPG7QBH3G_cjs.Checkbox,
|
|
6872
7124
|
{
|
|
6873
7125
|
label: "Show Data Labels",
|
|
6874
7126
|
checked: config.show_data_labels ?? false,
|
|
@@ -6880,7 +7132,7 @@ function WidgetEditor({
|
|
|
6880
7132
|
case "pie_chart":
|
|
6881
7133
|
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: rowStyle, children: [
|
|
6882
7134
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6883
|
-
|
|
7135
|
+
chunkPG7QBH3G_cjs.Checkbox,
|
|
6884
7136
|
{
|
|
6885
7137
|
label: "Show Legend",
|
|
6886
7138
|
checked: config.show_legend ?? true,
|
|
@@ -6888,7 +7140,7 @@ function WidgetEditor({
|
|
|
6888
7140
|
}
|
|
6889
7141
|
),
|
|
6890
7142
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6891
|
-
|
|
7143
|
+
chunkPG7QBH3G_cjs.Checkbox,
|
|
6892
7144
|
{
|
|
6893
7145
|
label: "Show Data Labels",
|
|
6894
7146
|
checked: config.show_data_labels ?? true,
|
|
@@ -6901,7 +7153,7 @@ function WidgetEditor({
|
|
|
6901
7153
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
6902
7154
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Page Size" }),
|
|
6903
7155
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6904
|
-
|
|
7156
|
+
chunkPG7QBH3G_cjs.Select,
|
|
6905
7157
|
{
|
|
6906
7158
|
value: String(config.page_size || 10),
|
|
6907
7159
|
onChange: (value) => updateConfig("page_size", parseInt(value, 10)),
|
|
@@ -6916,7 +7168,7 @@ function WidgetEditor({
|
|
|
6916
7168
|
)
|
|
6917
7169
|
] }),
|
|
6918
7170
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6919
|
-
|
|
7171
|
+
chunkPG7QBH3G_cjs.Checkbox,
|
|
6920
7172
|
{
|
|
6921
7173
|
label: "Sortable Columns",
|
|
6922
7174
|
checked: config.sortable ?? true,
|
|
@@ -6949,7 +7201,7 @@ function WidgetEditor({
|
|
|
6949
7201
|
)
|
|
6950
7202
|
] }),
|
|
6951
7203
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6952
|
-
|
|
7204
|
+
chunkPG7QBH3G_cjs.Checkbox,
|
|
6953
7205
|
{
|
|
6954
7206
|
label: "Enable Markdown",
|
|
6955
7207
|
checked: config.markdown ?? true,
|
|
@@ -6964,7 +7216,7 @@ function WidgetEditor({
|
|
|
6964
7216
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: overlayStyle, onClick: onCancel, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: modalStyle, onClick: (e) => e.stopPropagation(), children: [
|
|
6965
7217
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerStyle, children: [
|
|
6966
7218
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: titleStyle, children: "Edit Widget" }),
|
|
6967
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7219
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Button, { variant: "ghost", size: "sm", onClick: onCancel, children: /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "x", size: 20 }) })
|
|
6968
7220
|
] }),
|
|
6969
7221
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: bodyStyle, children: [
|
|
6970
7222
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: sectionStyle, children: [
|
|
@@ -6972,7 +7224,7 @@ function WidgetEditor({
|
|
|
6972
7224
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
|
|
6973
7225
|
/* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle, children: "Title" }),
|
|
6974
7226
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6975
|
-
|
|
7227
|
+
chunkPG7QBH3G_cjs.Input,
|
|
6976
7228
|
{
|
|
6977
7229
|
value: title,
|
|
6978
7230
|
onChange: (e) => setTitle(e.target.value),
|
|
@@ -7008,10 +7260,10 @@ function WidgetEditor({
|
|
|
7008
7260
|
},
|
|
7009
7261
|
children: [
|
|
7010
7262
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: theme.spacing.sm }, children: [
|
|
7011
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7263
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "table", size: 16 }),
|
|
7012
7264
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 500, color: theme.colors.text }, children: queryName || "Custom Query" })
|
|
7013
7265
|
] }),
|
|
7014
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7266
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Button, { variant: "ghost", size: "sm", onClick: handleClearQuery, children: /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "x", size: 16 }) })
|
|
7015
7267
|
]
|
|
7016
7268
|
}
|
|
7017
7269
|
),
|
|
@@ -7039,11 +7291,11 @@ function WidgetEditor({
|
|
|
7039
7291
|
},
|
|
7040
7292
|
children: [
|
|
7041
7293
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { textAlign: "center", color: theme.colors.textMuted }, children: [
|
|
7042
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7294
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "table", size: 24, style: { marginBottom: theme.spacing.xs } }),
|
|
7043
7295
|
/* @__PURE__ */ jsxRuntime.jsx("div", { children: "Select a saved query to power this widget" })
|
|
7044
7296
|
] }),
|
|
7045
7297
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7046
|
-
|
|
7298
|
+
chunkPG7QBH3G_cjs.SavedQueryPicker,
|
|
7047
7299
|
{
|
|
7048
7300
|
currentQuery: null,
|
|
7049
7301
|
onSelect: handleSelectSavedQuery,
|
|
@@ -7056,8 +7308,8 @@ function WidgetEditor({
|
|
|
7056
7308
|
] })
|
|
7057
7309
|
] }),
|
|
7058
7310
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: footerStyle, children: [
|
|
7059
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7060
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7311
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Button, { variant: "ghost", onClick: onCancel, children: "Cancel" }),
|
|
7312
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Button, { variant: "primary", onClick: handleSave, children: "Save Widget" })
|
|
7061
7313
|
] })
|
|
7062
7314
|
] }) });
|
|
7063
7315
|
}
|
|
@@ -7202,31 +7454,31 @@ var DashboardCard = react.forwardRef(
|
|
|
7202
7454
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerStyles, children: [
|
|
7203
7455
|
/* @__PURE__ */ jsxRuntime.jsx("h3", { style: titleStyles, children: dashboard.name }),
|
|
7204
7456
|
actions ? actions : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7205
|
-
|
|
7457
|
+
chunkPG7QBH3G_cjs.Dropdown,
|
|
7206
7458
|
{
|
|
7207
7459
|
trigger: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7208
|
-
|
|
7460
|
+
chunkPG7QBH3G_cjs.Button,
|
|
7209
7461
|
{
|
|
7210
7462
|
variant: "ghost",
|
|
7211
7463
|
size: "sm",
|
|
7212
7464
|
onClick: (e) => e.stopPropagation(),
|
|
7213
7465
|
disabled: actionsDisabled,
|
|
7214
7466
|
"aria-label": "Dashboard actions",
|
|
7215
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7467
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "more-vertical", size: 16 })
|
|
7216
7468
|
}
|
|
7217
7469
|
),
|
|
7218
7470
|
children: [
|
|
7219
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
7220
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7471
|
+
/* @__PURE__ */ jsxRuntime.jsxs(chunkPG7QBH3G_cjs.DropdownItem, { onClick: () => handleMenuAction("edit"), children: [
|
|
7472
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "edit", size: 14 }),
|
|
7221
7473
|
"Edit"
|
|
7222
7474
|
] }),
|
|
7223
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
7224
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7475
|
+
/* @__PURE__ */ jsxRuntime.jsxs(chunkPG7QBH3G_cjs.DropdownItem, { onClick: () => handleMenuAction("duplicate"), children: [
|
|
7476
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "copy", size: 14 }),
|
|
7225
7477
|
"Duplicate"
|
|
7226
7478
|
] }),
|
|
7227
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7228
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
7229
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7479
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.DropdownSeparator, {}),
|
|
7480
|
+
/* @__PURE__ */ jsxRuntime.jsxs(chunkPG7QBH3G_cjs.DropdownItem, { onClick: () => handleMenuAction("delete"), children: [
|
|
7481
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "trash", size: 14 }),
|
|
7230
7482
|
"Delete"
|
|
7231
7483
|
] })
|
|
7232
7484
|
]
|
|
@@ -7236,13 +7488,13 @@ var DashboardCard = react.forwardRef(
|
|
|
7236
7488
|
dashboard.description && /* @__PURE__ */ jsxRuntime.jsx("p", { style: descriptionStyles, children: dashboard.description }),
|
|
7237
7489
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: metaStyles, children: [
|
|
7238
7490
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: metaItemStyles, children: [
|
|
7239
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7491
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "grid", size: 12 }),
|
|
7240
7492
|
dashboard.widgets.length,
|
|
7241
7493
|
" widget",
|
|
7242
7494
|
dashboard.widgets.length !== 1 ? "s" : ""
|
|
7243
7495
|
] }),
|
|
7244
7496
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: metaItemStyles, children: [
|
|
7245
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7497
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "calendar", size: 12 }),
|
|
7246
7498
|
formatDate(dashboard.updated_at)
|
|
7247
7499
|
] }),
|
|
7248
7500
|
dashboard.is_public ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: publicBadgeStyles, children: "Public" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: privateBadgeStyles, children: "Private" })
|
|
@@ -7300,32 +7552,32 @@ var DashboardList = react.forwardRef(
|
|
|
7300
7552
|
if (isLoading) {
|
|
7301
7553
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, style: { ...containerStyles, ...style }, ...props, children: [
|
|
7302
7554
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerStyles2, children: [
|
|
7303
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7304
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7555
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Skeleton, { width: 200, height: 32 }),
|
|
7556
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Skeleton, { width: 150, height: 40 })
|
|
7305
7557
|
] }),
|
|
7306
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: getGridStyles(columns), children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
7558
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: getGridStyles(columns), children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Skeleton, { height: 150, style: { borderRadius: "var(--prismiq-radius-lg)" } }, i)) })
|
|
7307
7559
|
] });
|
|
7308
7560
|
}
|
|
7309
7561
|
if (error) {
|
|
7310
7562
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, style: { ...containerStyles, ...style }, ...props, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: errorStyles, children: [
|
|
7311
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7563
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "alert-circle", size: 48 }),
|
|
7312
7564
|
/* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
|
|
7313
7565
|
"Failed to load dashboards: ",
|
|
7314
7566
|
error.message
|
|
7315
7567
|
] }),
|
|
7316
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7568
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Button, { variant: "secondary", onClick: () => window.location.reload(), children: "Retry" })
|
|
7317
7569
|
] }) });
|
|
7318
7570
|
}
|
|
7319
7571
|
if (!dashboards || dashboards.length === 0) {
|
|
7320
7572
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, style: { ...containerStyles, ...style }, ...props, children: [
|
|
7321
7573
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerStyles2, children: [
|
|
7322
7574
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: titleStyles2, children: "Dashboards" }),
|
|
7323
|
-
onCreate && /* @__PURE__ */ jsxRuntime.jsx(
|
|
7575
|
+
onCreate && /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Button, { onClick: onCreate, leftIcon: /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "plus", size: 16 }), children: "Create Dashboard" })
|
|
7324
7576
|
] }),
|
|
7325
7577
|
emptyState || /* @__PURE__ */ jsxRuntime.jsx(
|
|
7326
|
-
|
|
7578
|
+
chunkPG7QBH3G_cjs.EmptyState,
|
|
7327
7579
|
{
|
|
7328
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7580
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "layout", size: 64 }),
|
|
7329
7581
|
title: "No dashboards yet",
|
|
7330
7582
|
description: "Create your first dashboard to start visualizing your data.",
|
|
7331
7583
|
action: onCreate ? { label: "Create Dashboard", onClick: onCreate } : void 0
|
|
@@ -7340,7 +7592,7 @@ var DashboardList = react.forwardRef(
|
|
|
7340
7592
|
dashboards.length,
|
|
7341
7593
|
")"
|
|
7342
7594
|
] }),
|
|
7343
|
-
onCreate && /* @__PURE__ */ jsxRuntime.jsx(
|
|
7595
|
+
onCreate && /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Button, { onClick: onCreate, leftIcon: /* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Icon, { name: "plus", size: 16 }), children: "Create Dashboard" })
|
|
7344
7596
|
] }),
|
|
7345
7597
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: getGridStyles(columns), children: dashboards.map((dashboard) => {
|
|
7346
7598
|
const cardProps = {
|
|
@@ -7440,7 +7692,7 @@ var DashboardDialog = react.forwardRef(
|
|
|
7440
7692
|
);
|
|
7441
7693
|
const displayError = validationError || error;
|
|
7442
7694
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
7443
|
-
|
|
7695
|
+
chunkPG7QBH3G_cjs.Dialog,
|
|
7444
7696
|
{
|
|
7445
7697
|
open,
|
|
7446
7698
|
onClose,
|
|
@@ -7452,7 +7704,7 @@ var DashboardDialog = react.forwardRef(
|
|
|
7452
7704
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyles, children: [
|
|
7453
7705
|
/* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "dashboard-name", style: labelStyles, children: "Name" }),
|
|
7454
7706
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7455
|
-
|
|
7707
|
+
chunkPG7QBH3G_cjs.Input,
|
|
7456
7708
|
{
|
|
7457
7709
|
id: "dashboard-name",
|
|
7458
7710
|
value: formState.name,
|
|
@@ -7466,7 +7718,7 @@ var DashboardDialog = react.forwardRef(
|
|
|
7466
7718
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyles, children: [
|
|
7467
7719
|
/* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "dashboard-description", style: labelStyles, children: "Description (optional)" }),
|
|
7468
7720
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7469
|
-
|
|
7721
|
+
chunkPG7QBH3G_cjs.Input,
|
|
7470
7722
|
{
|
|
7471
7723
|
id: "dashboard-description",
|
|
7472
7724
|
value: formState.description,
|
|
@@ -7478,7 +7730,7 @@ var DashboardDialog = react.forwardRef(
|
|
|
7478
7730
|
] }),
|
|
7479
7731
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: checkboxContainerStyles, children: [
|
|
7480
7732
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7481
|
-
|
|
7733
|
+
chunkPG7QBH3G_cjs.Checkbox,
|
|
7482
7734
|
{
|
|
7483
7735
|
id: "dashboard-public",
|
|
7484
7736
|
checked: formState.isPublic,
|
|
@@ -7488,9 +7740,9 @@ var DashboardDialog = react.forwardRef(
|
|
|
7488
7740
|
),
|
|
7489
7741
|
/* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "dashboard-public", style: checkboxLabelStyles, children: "Make this dashboard public" })
|
|
7490
7742
|
] }),
|
|
7491
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
7743
|
+
/* @__PURE__ */ jsxRuntime.jsxs(chunkPG7QBH3G_cjs.DialogFooter, { children: [
|
|
7492
7744
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7493
|
-
|
|
7745
|
+
chunkPG7QBH3G_cjs.Button,
|
|
7494
7746
|
{
|
|
7495
7747
|
type: "button",
|
|
7496
7748
|
variant: "secondary",
|
|
@@ -7499,7 +7751,7 @@ var DashboardDialog = react.forwardRef(
|
|
|
7499
7751
|
children: "Cancel"
|
|
7500
7752
|
}
|
|
7501
7753
|
),
|
|
7502
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7754
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkPG7QBH3G_cjs.Button, { type: "submit", loading: isLoading, children: isEditMode ? "Save Changes" : "Create Dashboard" })
|
|
7503
7755
|
] })
|
|
7504
7756
|
] })
|
|
7505
7757
|
}
|
|
@@ -7539,5 +7791,5 @@ exports.useDashboardFilters = useDashboardFilters;
|
|
|
7539
7791
|
exports.useFullscreen = useFullscreen;
|
|
7540
7792
|
exports.useWidget = useWidget;
|
|
7541
7793
|
exports.useWidgetVisibility = useWidgetVisibility;
|
|
7542
|
-
//# sourceMappingURL=chunk-
|
|
7543
|
-
//# sourceMappingURL=chunk-
|
|
7794
|
+
//# sourceMappingURL=chunk-FKXCINUF.cjs.map
|
|
7795
|
+
//# sourceMappingURL=chunk-FKXCINUF.cjs.map
|