@smallwebco/tinypivot-react 1.0.51 → 1.0.52
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/index.cjs +1208 -639
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1167 -596
- package/dist/index.js.map +1 -1
- package/dist/style.css +439 -0
- package/package.json +4 -2
package/dist/index.js
CHANGED
|
@@ -188,21 +188,530 @@ function CalculatedFieldModal({
|
|
|
188
188
|
return createPortal(modalContent, document.body);
|
|
189
189
|
}
|
|
190
190
|
|
|
191
|
+
// src/components/ChartBuilder.tsx
|
|
192
|
+
import {
|
|
193
|
+
analyzeFieldsForChart,
|
|
194
|
+
CHART_AGGREGATIONS,
|
|
195
|
+
CHART_COLORS,
|
|
196
|
+
CHART_TYPES,
|
|
197
|
+
createDefaultChartConfig,
|
|
198
|
+
getChartGuidance,
|
|
199
|
+
isChartConfigValid,
|
|
200
|
+
processChartData,
|
|
201
|
+
processChartDataForPie,
|
|
202
|
+
processChartDataForScatter
|
|
203
|
+
} from "@smallwebco/tinypivot-core";
|
|
204
|
+
import { useCallback as useCallback2, useEffect as useEffect2, useMemo as useMemo2, useState as useState2 } from "react";
|
|
205
|
+
import Chart from "react-apexcharts";
|
|
206
|
+
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
207
|
+
function ChartBuilder({
|
|
208
|
+
data,
|
|
209
|
+
theme = "light",
|
|
210
|
+
onConfigChange
|
|
211
|
+
}) {
|
|
212
|
+
const [chartConfig, setChartConfig] = useState2(createDefaultChartConfig());
|
|
213
|
+
const [draggingField, setDraggingField] = useState2(null);
|
|
214
|
+
const [dragOverZone, setDragOverZone] = useState2(null);
|
|
215
|
+
const fieldInfos = useMemo2(() => analyzeFieldsForChart(data), [data]);
|
|
216
|
+
const dimensions = useMemo2(
|
|
217
|
+
() => fieldInfos.filter((f) => f.role === "dimension" || f.role === "temporal"),
|
|
218
|
+
[fieldInfos]
|
|
219
|
+
);
|
|
220
|
+
const measures = useMemo2(
|
|
221
|
+
() => fieldInfos.filter((f) => f.role === "measure"),
|
|
222
|
+
[fieldInfos]
|
|
223
|
+
);
|
|
224
|
+
const guidance = useMemo2(() => getChartGuidance(chartConfig), [chartConfig]);
|
|
225
|
+
const chartIsValid = useMemo2(() => isChartConfigValid(chartConfig), [chartConfig]);
|
|
226
|
+
const selectedChartType = useMemo2(
|
|
227
|
+
() => CHART_TYPES.find((ct) => ct.type === chartConfig.type),
|
|
228
|
+
[chartConfig.type]
|
|
229
|
+
);
|
|
230
|
+
const handleDragStart = useCallback2((field, event) => {
|
|
231
|
+
setDraggingField(field);
|
|
232
|
+
event.dataTransfer?.setData("text/plain", field.field);
|
|
233
|
+
}, []);
|
|
234
|
+
const handleDragEnd = useCallback2(() => {
|
|
235
|
+
setDraggingField(null);
|
|
236
|
+
setDragOverZone(null);
|
|
237
|
+
}, []);
|
|
238
|
+
const handleDragOver = useCallback2((zone, event) => {
|
|
239
|
+
event.preventDefault();
|
|
240
|
+
setDragOverZone(zone);
|
|
241
|
+
}, []);
|
|
242
|
+
const handleDragLeave = useCallback2(() => {
|
|
243
|
+
setDragOverZone(null);
|
|
244
|
+
}, []);
|
|
245
|
+
const handleDrop = useCallback2((zone, event) => {
|
|
246
|
+
event.preventDefault();
|
|
247
|
+
setDragOverZone(null);
|
|
248
|
+
if (!draggingField)
|
|
249
|
+
return;
|
|
250
|
+
const field = draggingField;
|
|
251
|
+
const chartField = {
|
|
252
|
+
field: field.field,
|
|
253
|
+
label: field.label,
|
|
254
|
+
role: field.role,
|
|
255
|
+
aggregation: field.role === "measure" ? "sum" : void 0
|
|
256
|
+
};
|
|
257
|
+
let newConfig = { ...chartConfig };
|
|
258
|
+
switch (zone) {
|
|
259
|
+
case "xAxis":
|
|
260
|
+
newConfig = { ...newConfig, xAxis: chartField };
|
|
261
|
+
break;
|
|
262
|
+
case "yAxis":
|
|
263
|
+
newConfig = { ...newConfig, yAxis: chartField };
|
|
264
|
+
break;
|
|
265
|
+
case "series":
|
|
266
|
+
newConfig = { ...newConfig, seriesField: chartField };
|
|
267
|
+
break;
|
|
268
|
+
case "size":
|
|
269
|
+
newConfig = { ...newConfig, sizeField: chartField };
|
|
270
|
+
break;
|
|
271
|
+
case "color":
|
|
272
|
+
newConfig = { ...newConfig, colorField: chartField };
|
|
273
|
+
break;
|
|
274
|
+
}
|
|
275
|
+
setChartConfig(newConfig);
|
|
276
|
+
onConfigChange?.(newConfig);
|
|
277
|
+
}, [chartConfig, draggingField, onConfigChange]);
|
|
278
|
+
const removeField = useCallback2((zone) => {
|
|
279
|
+
let newConfig = { ...chartConfig };
|
|
280
|
+
switch (zone) {
|
|
281
|
+
case "xAxis":
|
|
282
|
+
newConfig = { ...newConfig, xAxis: void 0 };
|
|
283
|
+
break;
|
|
284
|
+
case "yAxis":
|
|
285
|
+
newConfig = { ...newConfig, yAxis: void 0 };
|
|
286
|
+
break;
|
|
287
|
+
case "series":
|
|
288
|
+
newConfig = { ...newConfig, seriesField: void 0 };
|
|
289
|
+
break;
|
|
290
|
+
case "size":
|
|
291
|
+
newConfig = { ...newConfig, sizeField: void 0 };
|
|
292
|
+
break;
|
|
293
|
+
case "color":
|
|
294
|
+
newConfig = { ...newConfig, colorField: void 0 };
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
setChartConfig(newConfig);
|
|
298
|
+
onConfigChange?.(newConfig);
|
|
299
|
+
}, [chartConfig, onConfigChange]);
|
|
300
|
+
const selectChartType = useCallback2((type) => {
|
|
301
|
+
const newConfig = { ...chartConfig, type };
|
|
302
|
+
setChartConfig(newConfig);
|
|
303
|
+
onConfigChange?.(newConfig);
|
|
304
|
+
}, [chartConfig, onConfigChange]);
|
|
305
|
+
const updateAggregation = useCallback2((zone, aggregation) => {
|
|
306
|
+
const field = zone === "yAxis" ? chartConfig.yAxis : chartConfig.sizeField;
|
|
307
|
+
if (!field)
|
|
308
|
+
return;
|
|
309
|
+
const updated = { ...field, aggregation };
|
|
310
|
+
let newConfig = { ...chartConfig };
|
|
311
|
+
if (zone === "yAxis") {
|
|
312
|
+
newConfig = { ...newConfig, yAxis: updated };
|
|
313
|
+
} else if (zone === "size") {
|
|
314
|
+
newConfig = { ...newConfig, sizeField: updated };
|
|
315
|
+
}
|
|
316
|
+
setChartConfig(newConfig);
|
|
317
|
+
onConfigChange?.(newConfig);
|
|
318
|
+
}, [chartConfig, onConfigChange]);
|
|
319
|
+
const getApexChartType = useCallback2((type) => {
|
|
320
|
+
const mapping = {
|
|
321
|
+
bar: "bar",
|
|
322
|
+
line: "line",
|
|
323
|
+
area: "area",
|
|
324
|
+
pie: "pie",
|
|
325
|
+
donut: "donut",
|
|
326
|
+
scatter: "scatter",
|
|
327
|
+
bubble: "bubble",
|
|
328
|
+
heatmap: "heatmap",
|
|
329
|
+
treemap: "bar",
|
|
330
|
+
// Treemap rendered as bar (compatibility)
|
|
331
|
+
radar: "radar"
|
|
332
|
+
};
|
|
333
|
+
return mapping[type] || "bar";
|
|
334
|
+
}, []);
|
|
335
|
+
const formatValue = useCallback2((val, format, decimals) => {
|
|
336
|
+
const dec = decimals ?? 0;
|
|
337
|
+
if (format === "percent") {
|
|
338
|
+
return `${val.toFixed(dec)}%`;
|
|
339
|
+
}
|
|
340
|
+
if (format === "currency") {
|
|
341
|
+
return `$${val.toLocaleString(void 0, { minimumFractionDigits: dec, maximumFractionDigits: dec })}`;
|
|
342
|
+
}
|
|
343
|
+
if (Math.abs(val) >= 1e3) {
|
|
344
|
+
return val.toLocaleString(void 0, { maximumFractionDigits: dec });
|
|
345
|
+
}
|
|
346
|
+
return val.toFixed(dec);
|
|
347
|
+
}, []);
|
|
348
|
+
const chartOptions = useMemo2(() => {
|
|
349
|
+
const isDark = theme === "dark";
|
|
350
|
+
const config = chartConfig;
|
|
351
|
+
const options = config.options || {};
|
|
352
|
+
const baseOptions = {
|
|
353
|
+
chart: {
|
|
354
|
+
type: getApexChartType(config.type),
|
|
355
|
+
background: "transparent",
|
|
356
|
+
foreColor: isDark ? "#e2e8f0" : "#334155",
|
|
357
|
+
toolbar: {
|
|
358
|
+
show: true,
|
|
359
|
+
tools: {
|
|
360
|
+
download: true,
|
|
361
|
+
selection: false,
|
|
362
|
+
zoom: options.enableZoom ?? false,
|
|
363
|
+
zoomin: options.enableZoom ?? false,
|
|
364
|
+
zoomout: options.enableZoom ?? false,
|
|
365
|
+
pan: false,
|
|
366
|
+
reset: options.enableZoom ?? false
|
|
367
|
+
},
|
|
368
|
+
export: {
|
|
369
|
+
csv: { filename: "chart-data" },
|
|
370
|
+
svg: { filename: "chart" },
|
|
371
|
+
png: { filename: "chart" }
|
|
372
|
+
}
|
|
373
|
+
},
|
|
374
|
+
animations: {
|
|
375
|
+
enabled: options.animated ?? true,
|
|
376
|
+
speed: 400,
|
|
377
|
+
dynamicAnimation: { enabled: true, speed: 300 }
|
|
378
|
+
},
|
|
379
|
+
fontFamily: "system-ui, -apple-system, sans-serif"
|
|
380
|
+
},
|
|
381
|
+
colors: options.colors || CHART_COLORS,
|
|
382
|
+
theme: {
|
|
383
|
+
mode: isDark ? "dark" : "light"
|
|
384
|
+
},
|
|
385
|
+
grid: {
|
|
386
|
+
show: options.showGrid ?? true,
|
|
387
|
+
borderColor: isDark ? "#334155" : "#e2e8f0"
|
|
388
|
+
},
|
|
389
|
+
legend: {
|
|
390
|
+
show: options.showLegend ?? true,
|
|
391
|
+
position: options.legendPosition || "top"
|
|
392
|
+
},
|
|
393
|
+
dataLabels: {
|
|
394
|
+
enabled: options.showDataLabels ?? false
|
|
395
|
+
},
|
|
396
|
+
tooltip: {
|
|
397
|
+
theme: isDark ? "dark" : "light"
|
|
398
|
+
},
|
|
399
|
+
stroke: {
|
|
400
|
+
curve: "smooth",
|
|
401
|
+
width: config.type === "line" ? 3 : config.type === "area" ? 2 : 0
|
|
402
|
+
},
|
|
403
|
+
fill: {
|
|
404
|
+
opacity: config.type === "area" ? 0.4 : 1
|
|
405
|
+
}
|
|
406
|
+
};
|
|
407
|
+
if (config.xAxis) {
|
|
408
|
+
baseOptions.xaxis = {
|
|
409
|
+
...baseOptions.xaxis,
|
|
410
|
+
title: { text: options.xAxisTitle || config.xAxis.label },
|
|
411
|
+
labels: {
|
|
412
|
+
style: { colors: isDark ? "#94a3b8" : "#64748b" }
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
if (config.yAxis && !["pie", "donut", "radar", "treemap"].includes(config.type)) {
|
|
417
|
+
baseOptions.yaxis = {
|
|
418
|
+
title: { text: options.yAxisTitle || config.yAxis.label },
|
|
419
|
+
labels: {
|
|
420
|
+
style: { colors: isDark ? "#94a3b8" : "#64748b" },
|
|
421
|
+
formatter: (val) => formatValue(val, options.valueFormat, options.decimals)
|
|
422
|
+
}
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
if (options.title) {
|
|
426
|
+
baseOptions.title = {
|
|
427
|
+
text: options.title,
|
|
428
|
+
style: {
|
|
429
|
+
fontSize: "16px",
|
|
430
|
+
fontWeight: "600",
|
|
431
|
+
color: isDark ? "#e2e8f0" : "#334155"
|
|
432
|
+
}
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
if (options.stacked && ["bar", "area"].includes(config.type)) {
|
|
436
|
+
baseOptions.chart.stacked = true;
|
|
437
|
+
}
|
|
438
|
+
if (config.type === "pie" || config.type === "donut") {
|
|
439
|
+
baseOptions.plotOptions = {
|
|
440
|
+
pie: {
|
|
441
|
+
donut: {
|
|
442
|
+
size: config.type === "donut" ? "55%" : "0%",
|
|
443
|
+
labels: {
|
|
444
|
+
show: config.type === "donut",
|
|
445
|
+
total: {
|
|
446
|
+
show: true,
|
|
447
|
+
label: "Total",
|
|
448
|
+
formatter: (w) => {
|
|
449
|
+
const total = w.globals.seriesTotals.reduce((a, b) => a + b, 0);
|
|
450
|
+
return formatValue(total, options.valueFormat, options.decimals);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
if (config.type === "radar") {
|
|
459
|
+
baseOptions.plotOptions = {
|
|
460
|
+
radar: {
|
|
461
|
+
polygons: {
|
|
462
|
+
strokeColors: isDark ? "#334155" : "#e2e8f0",
|
|
463
|
+
fill: { colors: isDark ? ["#1e293b", "#0f172a"] : ["#f8fafc", "#f1f5f9"] }
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
return baseOptions;
|
|
469
|
+
}, [chartConfig, theme, getApexChartType, formatValue]);
|
|
470
|
+
const chartSeries = useMemo2(() => {
|
|
471
|
+
const config = chartConfig;
|
|
472
|
+
if (!chartIsValid)
|
|
473
|
+
return [];
|
|
474
|
+
if (config.type === "pie" || config.type === "donut") {
|
|
475
|
+
const chartData2 = processChartDataForPie(data, config);
|
|
476
|
+
return chartData2.series[0]?.data || [];
|
|
477
|
+
}
|
|
478
|
+
if (config.type === "scatter" || config.type === "bubble") {
|
|
479
|
+
const points = processChartDataForScatter(data, config);
|
|
480
|
+
return [{
|
|
481
|
+
name: config.yAxis?.label || "Data",
|
|
482
|
+
data: points
|
|
483
|
+
}];
|
|
484
|
+
}
|
|
485
|
+
const chartData = processChartData(data, config);
|
|
486
|
+
return chartData.series;
|
|
487
|
+
}, [data, chartConfig, chartIsValid]);
|
|
488
|
+
const chartLabels = useMemo2(() => {
|
|
489
|
+
const config = chartConfig;
|
|
490
|
+
if (!chartIsValid)
|
|
491
|
+
return [];
|
|
492
|
+
if (config.type === "pie" || config.type === "donut") {
|
|
493
|
+
const chartData2 = processChartDataForPie(data, config);
|
|
494
|
+
return chartData2.categories;
|
|
495
|
+
}
|
|
496
|
+
const chartData = processChartData(data, config);
|
|
497
|
+
return chartData.categories;
|
|
498
|
+
}, [data, chartConfig, chartIsValid]);
|
|
499
|
+
const chartOptionsWithCategories = useMemo2(() => {
|
|
500
|
+
const options = { ...chartOptions };
|
|
501
|
+
const config = chartConfig;
|
|
502
|
+
if (!["pie", "donut", "scatter", "bubble"].includes(config.type)) {
|
|
503
|
+
options.xaxis = {
|
|
504
|
+
...options.xaxis,
|
|
505
|
+
categories: chartLabels
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
if (config.type === "pie" || config.type === "donut") {
|
|
509
|
+
options.labels = chartLabels;
|
|
510
|
+
}
|
|
511
|
+
return options;
|
|
512
|
+
}, [chartOptions, chartConfig, chartLabels]);
|
|
513
|
+
const getChartIcon = useCallback2((type) => {
|
|
514
|
+
const icons = {
|
|
515
|
+
bar: "M3 3v18h18V3H3zm4 14H5v-6h2v6zm4 0H9V7h2v10zm4 0h-2V9h2v8zm4 0h-2v-4h2v4z",
|
|
516
|
+
line: "M3.5 18.5l6-6 4 4 8-8M14.5 8.5h6v6",
|
|
517
|
+
area: "M3 17l6-6 4 4 8-8v10H3z",
|
|
518
|
+
pie: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8v8l5.66 5.66C14.28 19.04 13.18 20 12 20z",
|
|
519
|
+
donut: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 14c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4z",
|
|
520
|
+
scatter: "M7 14c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm6-5c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm4 7c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2z",
|
|
521
|
+
bubble: "M12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm-6 3c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12 2c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5z",
|
|
522
|
+
heatmap: "M3 3h4v4H3V3zm6 0h4v4H9V3zm6 0h4v4h-4V3zM3 9h4v4H3V9zm6 0h4v4H9V9zm6 0h4v4h-4V9zM3 15h4v4H3v-4zm6 0h4v4H9v-4zm6 0h4v4h-4v-4z",
|
|
523
|
+
treemap: "M3 3h8v10H3V3zm10 0h8v6h-8V3zM3 15h8v6H3v-6zm10-4h8v10h-8V11z",
|
|
524
|
+
radar: "M12 2L4 6v6c0 5.55 3.84 10.74 8 12 4.16-1.26 8-6.45 8-12V6l-8-4zm0 3.18l6 3v5.09c0 4.08-2.76 7.91-6 9.14V5.18z"
|
|
525
|
+
};
|
|
526
|
+
return icons[type] || icons.bar;
|
|
527
|
+
}, []);
|
|
528
|
+
useEffect2(() => {
|
|
529
|
+
onConfigChange?.(chartConfig);
|
|
530
|
+
}, []);
|
|
531
|
+
return /* @__PURE__ */ jsxs2("div", { className: "vpg-chart-builder", children: [
|
|
532
|
+
/* @__PURE__ */ jsx2("div", { className: "vpg-chart-type-bar", children: CHART_TYPES.map((ct) => /* @__PURE__ */ jsxs2(
|
|
533
|
+
"button",
|
|
534
|
+
{
|
|
535
|
+
className: `vpg-chart-type-btn ${chartConfig.type === ct.type ? "active" : ""}`,
|
|
536
|
+
title: ct.description,
|
|
537
|
+
onClick: () => selectChartType(ct.type),
|
|
538
|
+
children: [
|
|
539
|
+
/* @__PURE__ */ jsx2("svg", { className: "vpg-icon", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx2("path", { d: getChartIcon(ct.type) }) }),
|
|
540
|
+
/* @__PURE__ */ jsx2("span", { className: "vpg-chart-type-label", children: ct.label.replace(" Chart", "") })
|
|
541
|
+
]
|
|
542
|
+
},
|
|
543
|
+
ct.type
|
|
544
|
+
)) }),
|
|
545
|
+
/* @__PURE__ */ jsxs2("div", { className: "vpg-chart-builder-content", children: [
|
|
546
|
+
/* @__PURE__ */ jsxs2("div", { className: "vpg-chart-fields-panel", children: [
|
|
547
|
+
/* @__PURE__ */ jsxs2("div", { className: "vpg-chart-fields-section", children: [
|
|
548
|
+
/* @__PURE__ */ jsxs2("h4", { className: "vpg-chart-fields-title", children: [
|
|
549
|
+
/* @__PURE__ */ jsx2("svg", { className: "vpg-icon-sm", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx2("path", { d: "M4 6h16M4 12h10M4 18h6" }) }),
|
|
550
|
+
"Dimensions"
|
|
551
|
+
] }),
|
|
552
|
+
/* @__PURE__ */ jsxs2("div", { className: "vpg-chart-fields-list", children: [
|
|
553
|
+
dimensions.map((field) => /* @__PURE__ */ jsxs2(
|
|
554
|
+
"div",
|
|
555
|
+
{
|
|
556
|
+
className: "vpg-chart-field-chip vpg-field-dimension",
|
|
557
|
+
draggable: true,
|
|
558
|
+
onDragStart: (e) => handleDragStart(field, e),
|
|
559
|
+
onDragEnd: handleDragEnd,
|
|
560
|
+
children: [
|
|
561
|
+
/* @__PURE__ */ jsx2("span", { className: "vpg-field-name", children: field.label }),
|
|
562
|
+
/* @__PURE__ */ jsx2("span", { className: "vpg-field-type", children: field.role === "temporal" ? "date" : "text" })
|
|
563
|
+
]
|
|
564
|
+
},
|
|
565
|
+
field.field
|
|
566
|
+
)),
|
|
567
|
+
dimensions.length === 0 && /* @__PURE__ */ jsx2("div", { className: "vpg-chart-fields-empty", children: "No dimension fields detected" })
|
|
568
|
+
] })
|
|
569
|
+
] }),
|
|
570
|
+
/* @__PURE__ */ jsxs2("div", { className: "vpg-chart-fields-section", children: [
|
|
571
|
+
/* @__PURE__ */ jsxs2("h4", { className: "vpg-chart-fields-title", children: [
|
|
572
|
+
/* @__PURE__ */ jsx2("svg", { className: "vpg-icon-sm", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx2("path", { d: "M16 8v8M12 11v5M8 14v2M4 4v16h16" }) }),
|
|
573
|
+
"Measures"
|
|
574
|
+
] }),
|
|
575
|
+
/* @__PURE__ */ jsxs2("div", { className: "vpg-chart-fields-list", children: [
|
|
576
|
+
measures.map((field) => /* @__PURE__ */ jsxs2(
|
|
577
|
+
"div",
|
|
578
|
+
{
|
|
579
|
+
className: "vpg-chart-field-chip vpg-field-measure",
|
|
580
|
+
draggable: true,
|
|
581
|
+
onDragStart: (e) => handleDragStart(field, e),
|
|
582
|
+
onDragEnd: handleDragEnd,
|
|
583
|
+
children: [
|
|
584
|
+
/* @__PURE__ */ jsx2("span", { className: "vpg-field-name", children: field.label }),
|
|
585
|
+
/* @__PURE__ */ jsx2("span", { className: "vpg-field-type", children: "#" })
|
|
586
|
+
]
|
|
587
|
+
},
|
|
588
|
+
field.field
|
|
589
|
+
)),
|
|
590
|
+
measures.length === 0 && /* @__PURE__ */ jsx2("div", { className: "vpg-chart-fields-empty", children: "No numeric fields detected" })
|
|
591
|
+
] })
|
|
592
|
+
] })
|
|
593
|
+
] }),
|
|
594
|
+
/* @__PURE__ */ jsxs2("div", { className: "vpg-chart-config-panel", children: [
|
|
595
|
+
/* @__PURE__ */ jsxs2("div", { className: "vpg-chart-drop-zone-wrapper", children: [
|
|
596
|
+
/* @__PURE__ */ jsx2("label", { className: "vpg-chart-zone-label", children: "X-Axis / Category" }),
|
|
597
|
+
/* @__PURE__ */ jsx2(
|
|
598
|
+
"div",
|
|
599
|
+
{
|
|
600
|
+
className: `vpg-chart-drop-zone ${dragOverZone === "xAxis" ? "drag-over" : ""} ${chartConfig.xAxis ? "has-field" : ""}`,
|
|
601
|
+
onDragOver: (e) => handleDragOver("xAxis", e),
|
|
602
|
+
onDragLeave: handleDragLeave,
|
|
603
|
+
onDrop: (e) => handleDrop("xAxis", e),
|
|
604
|
+
children: chartConfig.xAxis ? /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
605
|
+
/* @__PURE__ */ jsx2("span", { className: "vpg-zone-field-name", children: chartConfig.xAxis.label }),
|
|
606
|
+
/* @__PURE__ */ jsx2("button", { className: "vpg-zone-remove-btn", onClick: () => removeField("xAxis"), children: /* @__PURE__ */ jsx2("svg", { className: "vpg-icon-xs", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx2("path", { d: "M6 18L18 6M6 6l12 12" }) }) })
|
|
607
|
+
] }) : /* @__PURE__ */ jsx2("span", { className: "vpg-zone-placeholder", children: "Drop dimension here" })
|
|
608
|
+
}
|
|
609
|
+
)
|
|
610
|
+
] }),
|
|
611
|
+
/* @__PURE__ */ jsxs2("div", { className: "vpg-chart-drop-zone-wrapper", children: [
|
|
612
|
+
/* @__PURE__ */ jsx2("label", { className: "vpg-chart-zone-label", children: "Y-Axis / Value" }),
|
|
613
|
+
/* @__PURE__ */ jsx2(
|
|
614
|
+
"div",
|
|
615
|
+
{
|
|
616
|
+
className: `vpg-chart-drop-zone ${dragOverZone === "yAxis" ? "drag-over" : ""} ${chartConfig.yAxis ? "has-field" : ""}`,
|
|
617
|
+
onDragOver: (e) => handleDragOver("yAxis", e),
|
|
618
|
+
onDragLeave: handleDragLeave,
|
|
619
|
+
onDrop: (e) => handleDrop("yAxis", e),
|
|
620
|
+
children: chartConfig.yAxis ? /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
621
|
+
/* @__PURE__ */ jsx2("span", { className: "vpg-zone-field-name", children: chartConfig.yAxis.label }),
|
|
622
|
+
chartConfig.yAxis.role === "measure" && /* @__PURE__ */ jsx2(
|
|
623
|
+
"select",
|
|
624
|
+
{
|
|
625
|
+
className: "vpg-zone-aggregation",
|
|
626
|
+
value: chartConfig.yAxis.aggregation || "sum",
|
|
627
|
+
onChange: (e) => updateAggregation("yAxis", e.target.value),
|
|
628
|
+
children: CHART_AGGREGATIONS.map((agg) => /* @__PURE__ */ jsx2("option", { value: agg.value, children: agg.symbol }, agg.value))
|
|
629
|
+
}
|
|
630
|
+
),
|
|
631
|
+
/* @__PURE__ */ jsx2("button", { className: "vpg-zone-remove-btn", onClick: () => removeField("yAxis"), children: /* @__PURE__ */ jsx2("svg", { className: "vpg-icon-xs", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx2("path", { d: "M6 18L18 6M6 6l12 12" }) }) })
|
|
632
|
+
] }) : /* @__PURE__ */ jsx2("span", { className: "vpg-zone-placeholder", children: "Drop measure here" })
|
|
633
|
+
}
|
|
634
|
+
)
|
|
635
|
+
] }),
|
|
636
|
+
/* @__PURE__ */ jsxs2("div", { className: "vpg-chart-drop-zone-wrapper", children: [
|
|
637
|
+
/* @__PURE__ */ jsx2("label", { className: "vpg-chart-zone-label", children: "Color / Series (optional)" }),
|
|
638
|
+
/* @__PURE__ */ jsx2(
|
|
639
|
+
"div",
|
|
640
|
+
{
|
|
641
|
+
className: `vpg-chart-drop-zone vpg-zone-optional ${dragOverZone === "series" ? "drag-over" : ""} ${chartConfig.seriesField ? "has-field" : ""}`,
|
|
642
|
+
onDragOver: (e) => handleDragOver("series", e),
|
|
643
|
+
onDragLeave: handleDragLeave,
|
|
644
|
+
onDrop: (e) => handleDrop("series", e),
|
|
645
|
+
children: chartConfig.seriesField ? /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
646
|
+
/* @__PURE__ */ jsx2("span", { className: "vpg-zone-field-name", children: chartConfig.seriesField.label }),
|
|
647
|
+
/* @__PURE__ */ jsx2("button", { className: "vpg-zone-remove-btn", onClick: () => removeField("series"), children: /* @__PURE__ */ jsx2("svg", { className: "vpg-icon-xs", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx2("path", { d: "M6 18L18 6M6 6l12 12" }) }) })
|
|
648
|
+
] }) : /* @__PURE__ */ jsx2("span", { className: "vpg-zone-placeholder", children: "Group by dimension" })
|
|
649
|
+
}
|
|
650
|
+
)
|
|
651
|
+
] }),
|
|
652
|
+
(chartConfig.type === "scatter" || chartConfig.type === "bubble") && /* @__PURE__ */ jsxs2("div", { className: "vpg-chart-drop-zone-wrapper", children: [
|
|
653
|
+
/* @__PURE__ */ jsx2("label", { className: "vpg-chart-zone-label", children: "Size (bubble)" }),
|
|
654
|
+
/* @__PURE__ */ jsx2(
|
|
655
|
+
"div",
|
|
656
|
+
{
|
|
657
|
+
className: `vpg-chart-drop-zone vpg-zone-optional ${dragOverZone === "size" ? "drag-over" : ""} ${chartConfig.sizeField ? "has-field" : ""}`,
|
|
658
|
+
onDragOver: (e) => handleDragOver("size", e),
|
|
659
|
+
onDragLeave: handleDragLeave,
|
|
660
|
+
onDrop: (e) => handleDrop("size", e),
|
|
661
|
+
children: chartConfig.sizeField ? /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
662
|
+
/* @__PURE__ */ jsx2("span", { className: "vpg-zone-field-name", children: chartConfig.sizeField.label }),
|
|
663
|
+
/* @__PURE__ */ jsx2("button", { className: "vpg-zone-remove-btn", onClick: () => removeField("size"), children: /* @__PURE__ */ jsx2("svg", { className: "vpg-icon-xs", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx2("path", { d: "M6 18L18 6M6 6l12 12" }) }) })
|
|
664
|
+
] }) : /* @__PURE__ */ jsx2("span", { className: "vpg-zone-placeholder", children: "Drop measure for size" })
|
|
665
|
+
}
|
|
666
|
+
)
|
|
667
|
+
] }),
|
|
668
|
+
/* @__PURE__ */ jsxs2("div", { className: "vpg-chart-guidance", children: [
|
|
669
|
+
/* @__PURE__ */ jsxs2("svg", { className: "vpg-icon-sm", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
670
|
+
/* @__PURE__ */ jsx2("circle", { cx: "12", cy: "12", r: "10" }),
|
|
671
|
+
/* @__PURE__ */ jsx2("path", { d: "M12 16v-4M12 8h.01" })
|
|
672
|
+
] }),
|
|
673
|
+
/* @__PURE__ */ jsx2("span", { children: guidance })
|
|
674
|
+
] })
|
|
675
|
+
] }),
|
|
676
|
+
/* @__PURE__ */ jsx2("div", { className: "vpg-chart-preview-panel", children: chartIsValid ? /* @__PURE__ */ jsx2("div", { className: "vpg-chart-container", children: /* @__PURE__ */ jsx2(
|
|
677
|
+
Chart,
|
|
678
|
+
{
|
|
679
|
+
type: getApexChartType(chartConfig.type),
|
|
680
|
+
options: chartOptionsWithCategories,
|
|
681
|
+
series: chartSeries,
|
|
682
|
+
height: "100%"
|
|
683
|
+
},
|
|
684
|
+
`${chartConfig.type}-${JSON.stringify(chartConfig.xAxis)}-${JSON.stringify(chartConfig.yAxis)}`
|
|
685
|
+
) }) : /* @__PURE__ */ jsxs2("div", { className: "vpg-chart-empty-state", children: [
|
|
686
|
+
/* @__PURE__ */ jsx2("svg", { className: "vpg-icon-lg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ jsx2("path", { d: getChartIcon(chartConfig.type) }) }),
|
|
687
|
+
/* @__PURE__ */ jsx2("h3", { children: "Build your chart" }),
|
|
688
|
+
/* @__PURE__ */ jsx2("p", { children: "Drag fields from the left panel to configure your visualization" }),
|
|
689
|
+
/* @__PURE__ */ jsxs2("div", { className: "vpg-chart-hint", children: [
|
|
690
|
+
/* @__PURE__ */ jsx2("strong", { children: selectedChartType?.label }),
|
|
691
|
+
":",
|
|
692
|
+
" ",
|
|
693
|
+
selectedChartType?.description
|
|
694
|
+
] })
|
|
695
|
+
] }) })
|
|
696
|
+
] })
|
|
697
|
+
] });
|
|
698
|
+
}
|
|
699
|
+
|
|
191
700
|
// src/components/ColumnFilter.tsx
|
|
192
|
-
import { useCallback as
|
|
701
|
+
import { useCallback as useCallback4, useEffect as useEffect4, useMemo as useMemo4, useRef, useState as useState4 } from "react";
|
|
193
702
|
|
|
194
703
|
// src/components/NumericRangeFilter.tsx
|
|
195
|
-
import { useCallback as
|
|
196
|
-
import { jsx as
|
|
704
|
+
import { useCallback as useCallback3, useEffect as useEffect3, useMemo as useMemo3, useState as useState3 } from "react";
|
|
705
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
197
706
|
function NumericRangeFilter({
|
|
198
707
|
dataMin,
|
|
199
708
|
dataMax,
|
|
200
709
|
currentRange,
|
|
201
710
|
onChange
|
|
202
711
|
}) {
|
|
203
|
-
const [localMin, setLocalMin] =
|
|
204
|
-
const [localMax, setLocalMax] =
|
|
205
|
-
const step =
|
|
712
|
+
const [localMin, setLocalMin] = useState3(currentRange?.min ?? null);
|
|
713
|
+
const [localMax, setLocalMax] = useState3(currentRange?.max ?? null);
|
|
714
|
+
const step = useMemo3(() => {
|
|
206
715
|
const range = dataMax - dataMin;
|
|
207
716
|
if (range === 0)
|
|
208
717
|
return 1;
|
|
@@ -216,7 +725,7 @@ function NumericRangeFilter({
|
|
|
216
725
|
return 10;
|
|
217
726
|
return 10 ** (Math.floor(Math.log10(range)) - 2);
|
|
218
727
|
}, [dataMin, dataMax]);
|
|
219
|
-
const formatValue =
|
|
728
|
+
const formatValue = useCallback3((val) => {
|
|
220
729
|
if (val === null)
|
|
221
730
|
return "";
|
|
222
731
|
if (Number.isInteger(val))
|
|
@@ -224,17 +733,17 @@ function NumericRangeFilter({
|
|
|
224
733
|
return val.toLocaleString(void 0, { maximumFractionDigits: 2 });
|
|
225
734
|
}, []);
|
|
226
735
|
const isFilterActive = localMin !== null || localMax !== null;
|
|
227
|
-
const minPercent =
|
|
736
|
+
const minPercent = useMemo3(() => {
|
|
228
737
|
if (localMin === null || dataMax === dataMin)
|
|
229
738
|
return 0;
|
|
230
739
|
return (localMin - dataMin) / (dataMax - dataMin) * 100;
|
|
231
740
|
}, [localMin, dataMin, dataMax]);
|
|
232
|
-
const maxPercent =
|
|
741
|
+
const maxPercent = useMemo3(() => {
|
|
233
742
|
if (localMax === null || dataMax === dataMin)
|
|
234
743
|
return 100;
|
|
235
744
|
return (localMax - dataMin) / (dataMax - dataMin) * 100;
|
|
236
745
|
}, [localMax, dataMin, dataMax]);
|
|
237
|
-
const handleMinSlider =
|
|
746
|
+
const handleMinSlider = useCallback3((event) => {
|
|
238
747
|
const value = Number.parseFloat(event.target.value);
|
|
239
748
|
setLocalMin(() => {
|
|
240
749
|
if (localMax !== null && value > localMax) {
|
|
@@ -243,7 +752,7 @@ function NumericRangeFilter({
|
|
|
243
752
|
return value;
|
|
244
753
|
});
|
|
245
754
|
}, [localMax]);
|
|
246
|
-
const handleMaxSlider =
|
|
755
|
+
const handleMaxSlider = useCallback3((event) => {
|
|
247
756
|
const value = Number.parseFloat(event.target.value);
|
|
248
757
|
setLocalMax(() => {
|
|
249
758
|
if (localMin !== null && value < localMin) {
|
|
@@ -252,14 +761,14 @@ function NumericRangeFilter({
|
|
|
252
761
|
return value;
|
|
253
762
|
});
|
|
254
763
|
}, [localMin]);
|
|
255
|
-
const handleSliderChange =
|
|
764
|
+
const handleSliderChange = useCallback3(() => {
|
|
256
765
|
if (localMin === null && localMax === null) {
|
|
257
766
|
onChange(null);
|
|
258
767
|
} else {
|
|
259
768
|
onChange({ min: localMin, max: localMax });
|
|
260
769
|
}
|
|
261
770
|
}, [localMin, localMax, onChange]);
|
|
262
|
-
const handleMinInput =
|
|
771
|
+
const handleMinInput = useCallback3((event) => {
|
|
263
772
|
const value = event.target.value === "" ? null : Number.parseFloat(event.target.value);
|
|
264
773
|
if (value !== null && !Number.isNaN(value)) {
|
|
265
774
|
setLocalMin(Math.max(dataMin, Math.min(value, localMax ?? dataMax)));
|
|
@@ -267,7 +776,7 @@ function NumericRangeFilter({
|
|
|
267
776
|
setLocalMin(null);
|
|
268
777
|
}
|
|
269
778
|
}, [dataMin, dataMax, localMax]);
|
|
270
|
-
const handleMaxInput =
|
|
779
|
+
const handleMaxInput = useCallback3((event) => {
|
|
271
780
|
const value = event.target.value === "" ? null : Number.parseFloat(event.target.value);
|
|
272
781
|
if (value !== null && !Number.isNaN(value)) {
|
|
273
782
|
setLocalMax(Math.min(dataMax, Math.max(value, localMin ?? dataMin)));
|
|
@@ -275,39 +784,39 @@ function NumericRangeFilter({
|
|
|
275
784
|
setLocalMax(null);
|
|
276
785
|
}
|
|
277
786
|
}, [dataMin, dataMax, localMin]);
|
|
278
|
-
const handleInputBlur =
|
|
787
|
+
const handleInputBlur = useCallback3(() => {
|
|
279
788
|
if (localMin === null && localMax === null) {
|
|
280
789
|
onChange(null);
|
|
281
790
|
} else {
|
|
282
791
|
onChange({ min: localMin, max: localMax });
|
|
283
792
|
}
|
|
284
793
|
}, [localMin, localMax, onChange]);
|
|
285
|
-
const clearFilter =
|
|
794
|
+
const clearFilter = useCallback3(() => {
|
|
286
795
|
setLocalMin(null);
|
|
287
796
|
setLocalMax(null);
|
|
288
797
|
onChange(null);
|
|
289
798
|
}, [onChange]);
|
|
290
|
-
const setFullRange =
|
|
799
|
+
const setFullRange = useCallback3(() => {
|
|
291
800
|
setLocalMin(dataMin);
|
|
292
801
|
setLocalMax(dataMax);
|
|
293
802
|
onChange({ min: dataMin, max: dataMax });
|
|
294
803
|
}, [dataMin, dataMax, onChange]);
|
|
295
|
-
|
|
804
|
+
useEffect3(() => {
|
|
296
805
|
setLocalMin(currentRange?.min ?? null);
|
|
297
806
|
setLocalMax(currentRange?.max ?? null);
|
|
298
807
|
}, [currentRange]);
|
|
299
|
-
return /* @__PURE__ */
|
|
300
|
-
/* @__PURE__ */
|
|
301
|
-
/* @__PURE__ */
|
|
302
|
-
/* @__PURE__ */
|
|
808
|
+
return /* @__PURE__ */ jsxs3("div", { className: "vpg-range-filter", children: [
|
|
809
|
+
/* @__PURE__ */ jsxs3("div", { className: "vpg-range-info", children: [
|
|
810
|
+
/* @__PURE__ */ jsx3("span", { className: "vpg-range-label", children: "Data range:" }),
|
|
811
|
+
/* @__PURE__ */ jsxs3("span", { className: "vpg-range-bounds", children: [
|
|
303
812
|
formatValue(dataMin),
|
|
304
813
|
" ",
|
|
305
814
|
"\u2013",
|
|
306
815
|
formatValue(dataMax)
|
|
307
816
|
] })
|
|
308
817
|
] }),
|
|
309
|
-
/* @__PURE__ */
|
|
310
|
-
/* @__PURE__ */
|
|
818
|
+
/* @__PURE__ */ jsxs3("div", { className: "vpg-slider-container", children: [
|
|
819
|
+
/* @__PURE__ */ jsx3("div", { className: "vpg-slider-track", children: /* @__PURE__ */ jsx3(
|
|
311
820
|
"div",
|
|
312
821
|
{
|
|
313
822
|
className: "vpg-slider-fill",
|
|
@@ -317,7 +826,7 @@ function NumericRangeFilter({
|
|
|
317
826
|
}
|
|
318
827
|
}
|
|
319
828
|
) }),
|
|
320
|
-
/* @__PURE__ */
|
|
829
|
+
/* @__PURE__ */ jsx3(
|
|
321
830
|
"input",
|
|
322
831
|
{
|
|
323
832
|
type: "range",
|
|
@@ -331,7 +840,7 @@ function NumericRangeFilter({
|
|
|
331
840
|
onTouchEnd: handleSliderChange
|
|
332
841
|
}
|
|
333
842
|
),
|
|
334
|
-
/* @__PURE__ */
|
|
843
|
+
/* @__PURE__ */ jsx3(
|
|
335
844
|
"input",
|
|
336
845
|
{
|
|
337
846
|
type: "range",
|
|
@@ -346,10 +855,10 @@ function NumericRangeFilter({
|
|
|
346
855
|
}
|
|
347
856
|
)
|
|
348
857
|
] }),
|
|
349
|
-
/* @__PURE__ */
|
|
350
|
-
/* @__PURE__ */
|
|
351
|
-
/* @__PURE__ */
|
|
352
|
-
/* @__PURE__ */
|
|
858
|
+
/* @__PURE__ */ jsxs3("div", { className: "vpg-range-inputs", children: [
|
|
859
|
+
/* @__PURE__ */ jsxs3("div", { className: "vpg-input-group", children: [
|
|
860
|
+
/* @__PURE__ */ jsx3("label", { className: "vpg-input-label", children: "Min" }),
|
|
861
|
+
/* @__PURE__ */ jsx3(
|
|
353
862
|
"input",
|
|
354
863
|
{
|
|
355
864
|
type: "number",
|
|
@@ -362,10 +871,10 @@ function NumericRangeFilter({
|
|
|
362
871
|
}
|
|
363
872
|
)
|
|
364
873
|
] }),
|
|
365
|
-
/* @__PURE__ */
|
|
366
|
-
/* @__PURE__ */
|
|
367
|
-
/* @__PURE__ */
|
|
368
|
-
/* @__PURE__ */
|
|
874
|
+
/* @__PURE__ */ jsx3("span", { className: "vpg-input-separator", children: "to" }),
|
|
875
|
+
/* @__PURE__ */ jsxs3("div", { className: "vpg-input-group", children: [
|
|
876
|
+
/* @__PURE__ */ jsx3("label", { className: "vpg-input-label", children: "Max" }),
|
|
877
|
+
/* @__PURE__ */ jsx3(
|
|
369
878
|
"input",
|
|
370
879
|
{
|
|
371
880
|
type: "number",
|
|
@@ -379,15 +888,15 @@ function NumericRangeFilter({
|
|
|
379
888
|
)
|
|
380
889
|
] })
|
|
381
890
|
] }),
|
|
382
|
-
/* @__PURE__ */
|
|
383
|
-
/* @__PURE__ */
|
|
891
|
+
/* @__PURE__ */ jsxs3("div", { className: "vpg-range-actions", children: [
|
|
892
|
+
/* @__PURE__ */ jsxs3(
|
|
384
893
|
"button",
|
|
385
894
|
{
|
|
386
895
|
className: "vpg-range-btn",
|
|
387
896
|
disabled: !isFilterActive,
|
|
388
897
|
onClick: clearFilter,
|
|
389
898
|
children: [
|
|
390
|
-
/* @__PURE__ */
|
|
899
|
+
/* @__PURE__ */ jsx3("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3(
|
|
391
900
|
"path",
|
|
392
901
|
{
|
|
393
902
|
strokeLinecap: "round",
|
|
@@ -400,8 +909,8 @@ function NumericRangeFilter({
|
|
|
400
909
|
]
|
|
401
910
|
}
|
|
402
911
|
),
|
|
403
|
-
/* @__PURE__ */
|
|
404
|
-
/* @__PURE__ */
|
|
912
|
+
/* @__PURE__ */ jsxs3("button", { className: "vpg-range-btn", onClick: setFullRange, children: [
|
|
913
|
+
/* @__PURE__ */ jsx3("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3(
|
|
405
914
|
"path",
|
|
406
915
|
{
|
|
407
916
|
strokeLinecap: "round",
|
|
@@ -413,8 +922,8 @@ function NumericRangeFilter({
|
|
|
413
922
|
"Full Range"
|
|
414
923
|
] })
|
|
415
924
|
] }),
|
|
416
|
-
isFilterActive && /* @__PURE__ */
|
|
417
|
-
/* @__PURE__ */
|
|
925
|
+
isFilterActive && /* @__PURE__ */ jsxs3("div", { className: "vpg-filter-summary", children: [
|
|
926
|
+
/* @__PURE__ */ jsx3("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3(
|
|
418
927
|
"path",
|
|
419
928
|
{
|
|
420
929
|
strokeLinecap: "round",
|
|
@@ -423,15 +932,15 @@ function NumericRangeFilter({
|
|
|
423
932
|
d: "M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z"
|
|
424
933
|
}
|
|
425
934
|
) }),
|
|
426
|
-
/* @__PURE__ */
|
|
935
|
+
/* @__PURE__ */ jsxs3("span", { children: [
|
|
427
936
|
"Showing values",
|
|
428
937
|
" ",
|
|
429
|
-
localMin !== null && /* @__PURE__ */
|
|
938
|
+
localMin !== null && /* @__PURE__ */ jsxs3("strong", { children: [
|
|
430
939
|
"\u2265",
|
|
431
940
|
formatValue(localMin)
|
|
432
941
|
] }),
|
|
433
942
|
localMin !== null && localMax !== null && " and ",
|
|
434
|
-
localMax !== null && /* @__PURE__ */
|
|
943
|
+
localMax !== null && /* @__PURE__ */ jsxs3("strong", { children: [
|
|
435
944
|
"\u2264",
|
|
436
945
|
formatValue(localMax)
|
|
437
946
|
] })
|
|
@@ -441,7 +950,7 @@ function NumericRangeFilter({
|
|
|
441
950
|
}
|
|
442
951
|
|
|
443
952
|
// src/components/ColumnFilter.tsx
|
|
444
|
-
import { Fragment, jsx as
|
|
953
|
+
import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
445
954
|
function ColumnFilter({
|
|
446
955
|
columnName,
|
|
447
956
|
stats,
|
|
@@ -453,33 +962,33 @@ function ColumnFilter({
|
|
|
453
962
|
onClose,
|
|
454
963
|
onRangeFilter
|
|
455
964
|
}) {
|
|
456
|
-
const [searchQuery, setSearchQuery] =
|
|
457
|
-
const [localSelected, setLocalSelected] =
|
|
965
|
+
const [searchQuery, setSearchQuery] = useState4("");
|
|
966
|
+
const [localSelected, setLocalSelected] = useState4(new Set(selectedValues));
|
|
458
967
|
const dropdownRef = useRef(null);
|
|
459
968
|
const searchInputRef = useRef(null);
|
|
460
969
|
const isNumericColumn = stats.type === "number" && stats.numericMin !== void 0 && stats.numericMax !== void 0;
|
|
461
|
-
const [filterMode, setFilterMode] =
|
|
462
|
-
const [localRange, setLocalRange] =
|
|
970
|
+
const [filterMode, setFilterMode] = useState4(numericRange ? "range" : "values");
|
|
971
|
+
const [localRange, setLocalRange] = useState4(numericRange ?? null);
|
|
463
972
|
const hasBlankValues = stats.nullCount > 0;
|
|
464
|
-
const filteredValues =
|
|
973
|
+
const filteredValues = useMemo4(() => {
|
|
465
974
|
const values = stats.uniqueValues;
|
|
466
975
|
if (!searchQuery)
|
|
467
976
|
return values;
|
|
468
977
|
const query = searchQuery.toLowerCase();
|
|
469
978
|
return values.filter((v) => v.toLowerCase().includes(query));
|
|
470
979
|
}, [stats.uniqueValues, searchQuery]);
|
|
471
|
-
const allValues =
|
|
980
|
+
const allValues = useMemo4(() => {
|
|
472
981
|
const values = [...filteredValues];
|
|
473
982
|
if (hasBlankValues && (!searchQuery || "(blank)".includes(searchQuery.toLowerCase()))) {
|
|
474
983
|
values.unshift("(blank)");
|
|
475
984
|
}
|
|
476
985
|
return values;
|
|
477
986
|
}, [filteredValues, hasBlankValues, searchQuery]);
|
|
478
|
-
const _isAllSelected =
|
|
987
|
+
const _isAllSelected = useMemo4(
|
|
479
988
|
() => allValues.every((v) => localSelected.has(v)),
|
|
480
989
|
[allValues, localSelected]
|
|
481
990
|
);
|
|
482
|
-
const toggleValue =
|
|
991
|
+
const toggleValue = useCallback4((value) => {
|
|
483
992
|
setLocalSelected((prev) => {
|
|
484
993
|
const next = new Set(prev);
|
|
485
994
|
if (next.has(value)) {
|
|
@@ -490,7 +999,7 @@ function ColumnFilter({
|
|
|
490
999
|
return next;
|
|
491
1000
|
});
|
|
492
1001
|
}, []);
|
|
493
|
-
const selectAll =
|
|
1002
|
+
const selectAll = useCallback4(() => {
|
|
494
1003
|
setLocalSelected((prev) => {
|
|
495
1004
|
const next = new Set(prev);
|
|
496
1005
|
for (const value of allValues) {
|
|
@@ -499,10 +1008,10 @@ function ColumnFilter({
|
|
|
499
1008
|
return next;
|
|
500
1009
|
});
|
|
501
1010
|
}, [allValues]);
|
|
502
|
-
const clearAll =
|
|
1011
|
+
const clearAll = useCallback4(() => {
|
|
503
1012
|
setLocalSelected(/* @__PURE__ */ new Set());
|
|
504
1013
|
}, []);
|
|
505
|
-
const applyFilter =
|
|
1014
|
+
const applyFilter = useCallback4(() => {
|
|
506
1015
|
if (localSelected.size === 0) {
|
|
507
1016
|
onFilter([]);
|
|
508
1017
|
} else {
|
|
@@ -510,30 +1019,30 @@ function ColumnFilter({
|
|
|
510
1019
|
}
|
|
511
1020
|
onClose();
|
|
512
1021
|
}, [localSelected, onFilter, onClose]);
|
|
513
|
-
const sortAscending =
|
|
1022
|
+
const sortAscending = useCallback4(() => {
|
|
514
1023
|
onSort(sortDirection === "asc" ? null : "asc");
|
|
515
1024
|
}, [sortDirection, onSort]);
|
|
516
|
-
const sortDescending =
|
|
1025
|
+
const sortDescending = useCallback4(() => {
|
|
517
1026
|
onSort(sortDirection === "desc" ? null : "desc");
|
|
518
1027
|
}, [sortDirection, onSort]);
|
|
519
|
-
const clearFilter =
|
|
1028
|
+
const clearFilter = useCallback4(() => {
|
|
520
1029
|
setLocalSelected(/* @__PURE__ */ new Set());
|
|
521
1030
|
onFilter([]);
|
|
522
1031
|
onClose();
|
|
523
1032
|
}, [onFilter, onClose]);
|
|
524
|
-
const handleRangeChange =
|
|
1033
|
+
const handleRangeChange = useCallback4((range) => {
|
|
525
1034
|
setLocalRange(range);
|
|
526
1035
|
}, []);
|
|
527
|
-
const applyRangeFilter =
|
|
1036
|
+
const applyRangeFilter = useCallback4(() => {
|
|
528
1037
|
onRangeFilter?.(localRange);
|
|
529
1038
|
onClose();
|
|
530
1039
|
}, [localRange, onRangeFilter, onClose]);
|
|
531
|
-
const clearRangeFilter =
|
|
1040
|
+
const clearRangeFilter = useCallback4(() => {
|
|
532
1041
|
setLocalRange(null);
|
|
533
1042
|
onRangeFilter?.(null);
|
|
534
1043
|
onClose();
|
|
535
1044
|
}, [onRangeFilter, onClose]);
|
|
536
|
-
|
|
1045
|
+
useEffect4(() => {
|
|
537
1046
|
const handleClickOutside = (event) => {
|
|
538
1047
|
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
|
539
1048
|
onClose();
|
|
@@ -542,7 +1051,7 @@ function ColumnFilter({
|
|
|
542
1051
|
document.addEventListener("mousedown", handleClickOutside);
|
|
543
1052
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
544
1053
|
}, [onClose]);
|
|
545
|
-
|
|
1054
|
+
useEffect4(() => {
|
|
546
1055
|
const handleKeydown = (event) => {
|
|
547
1056
|
if (event.key === "Escape") {
|
|
548
1057
|
onClose();
|
|
@@ -553,36 +1062,36 @@ function ColumnFilter({
|
|
|
553
1062
|
document.addEventListener("keydown", handleKeydown);
|
|
554
1063
|
return () => document.removeEventListener("keydown", handleKeydown);
|
|
555
1064
|
}, [onClose, applyFilter]);
|
|
556
|
-
|
|
1065
|
+
useEffect4(() => {
|
|
557
1066
|
searchInputRef.current?.focus();
|
|
558
1067
|
}, []);
|
|
559
|
-
|
|
1068
|
+
useEffect4(() => {
|
|
560
1069
|
setLocalSelected(new Set(selectedValues));
|
|
561
1070
|
}, [selectedValues]);
|
|
562
|
-
|
|
1071
|
+
useEffect4(() => {
|
|
563
1072
|
setLocalRange(numericRange ?? null);
|
|
564
1073
|
if (numericRange) {
|
|
565
1074
|
setFilterMode("range");
|
|
566
1075
|
}
|
|
567
1076
|
}, [numericRange]);
|
|
568
|
-
return /* @__PURE__ */
|
|
569
|
-
/* @__PURE__ */
|
|
570
|
-
/* @__PURE__ */
|
|
571
|
-
/* @__PURE__ */
|
|
1077
|
+
return /* @__PURE__ */ jsxs4("div", { ref: dropdownRef, className: "vpg-filter-dropdown", children: [
|
|
1078
|
+
/* @__PURE__ */ jsxs4("div", { className: "vpg-filter-header", children: [
|
|
1079
|
+
/* @__PURE__ */ jsx4("span", { className: "vpg-filter-title", children: columnName }),
|
|
1080
|
+
/* @__PURE__ */ jsxs4("span", { className: "vpg-filter-count", children: [
|
|
572
1081
|
stats.uniqueValues.length.toLocaleString(),
|
|
573
1082
|
" ",
|
|
574
1083
|
"unique"
|
|
575
1084
|
] })
|
|
576
1085
|
] }),
|
|
577
|
-
/* @__PURE__ */
|
|
578
|
-
/* @__PURE__ */
|
|
1086
|
+
/* @__PURE__ */ jsxs4("div", { className: "vpg-sort-controls", children: [
|
|
1087
|
+
/* @__PURE__ */ jsxs4(
|
|
579
1088
|
"button",
|
|
580
1089
|
{
|
|
581
1090
|
className: `vpg-sort-btn ${sortDirection === "asc" ? "active" : ""}`,
|
|
582
1091
|
title: isNumericColumn ? "Sort Low to High" : "Sort A to Z",
|
|
583
1092
|
onClick: sortAscending,
|
|
584
1093
|
children: [
|
|
585
|
-
/* @__PURE__ */
|
|
1094
|
+
/* @__PURE__ */ jsx4("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
|
|
586
1095
|
"path",
|
|
587
1096
|
{
|
|
588
1097
|
strokeLinecap: "round",
|
|
@@ -591,18 +1100,18 @@ function ColumnFilter({
|
|
|
591
1100
|
d: "M3 4h13M3 8h9m-9 4h6m4 0l4-4m0 0l4 4m-4-4v12"
|
|
592
1101
|
}
|
|
593
1102
|
) }),
|
|
594
|
-
/* @__PURE__ */
|
|
1103
|
+
/* @__PURE__ */ jsx4("span", { children: isNumericColumn ? "1\u21929" : "A\u2192Z" })
|
|
595
1104
|
]
|
|
596
1105
|
}
|
|
597
1106
|
),
|
|
598
|
-
/* @__PURE__ */
|
|
1107
|
+
/* @__PURE__ */ jsxs4(
|
|
599
1108
|
"button",
|
|
600
1109
|
{
|
|
601
1110
|
className: `vpg-sort-btn ${sortDirection === "desc" ? "active" : ""}`,
|
|
602
1111
|
title: isNumericColumn ? "Sort High to Low" : "Sort Z to A",
|
|
603
1112
|
onClick: sortDescending,
|
|
604
1113
|
children: [
|
|
605
|
-
/* @__PURE__ */
|
|
1114
|
+
/* @__PURE__ */ jsx4("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
|
|
606
1115
|
"path",
|
|
607
1116
|
{
|
|
608
1117
|
strokeLinecap: "round",
|
|
@@ -611,20 +1120,20 @@ function ColumnFilter({
|
|
|
611
1120
|
d: "M3 4h13M3 8h9m-9 4h9m5-4v12m0 0l-4-4m4 4l4-4"
|
|
612
1121
|
}
|
|
613
1122
|
) }),
|
|
614
|
-
/* @__PURE__ */
|
|
1123
|
+
/* @__PURE__ */ jsx4("span", { children: isNumericColumn ? "9\u21921" : "Z\u2192A" })
|
|
615
1124
|
]
|
|
616
1125
|
}
|
|
617
1126
|
)
|
|
618
1127
|
] }),
|
|
619
|
-
/* @__PURE__ */
|
|
620
|
-
isNumericColumn && /* @__PURE__ */
|
|
621
|
-
/* @__PURE__ */
|
|
1128
|
+
/* @__PURE__ */ jsx4("div", { className: "vpg-divider" }),
|
|
1129
|
+
isNumericColumn && /* @__PURE__ */ jsxs4("div", { className: "vpg-filter-tabs", children: [
|
|
1130
|
+
/* @__PURE__ */ jsxs4(
|
|
622
1131
|
"button",
|
|
623
1132
|
{
|
|
624
1133
|
className: `vpg-tab-btn ${filterMode === "values" ? "active" : ""}`,
|
|
625
1134
|
onClick: () => setFilterMode("values"),
|
|
626
1135
|
children: [
|
|
627
|
-
/* @__PURE__ */
|
|
1136
|
+
/* @__PURE__ */ jsx4("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
|
|
628
1137
|
"path",
|
|
629
1138
|
{
|
|
630
1139
|
strokeLinecap: "round",
|
|
@@ -637,13 +1146,13 @@ function ColumnFilter({
|
|
|
637
1146
|
]
|
|
638
1147
|
}
|
|
639
1148
|
),
|
|
640
|
-
/* @__PURE__ */
|
|
1149
|
+
/* @__PURE__ */ jsxs4(
|
|
641
1150
|
"button",
|
|
642
1151
|
{
|
|
643
1152
|
className: `vpg-tab-btn ${filterMode === "range" ? "active" : ""}`,
|
|
644
1153
|
onClick: () => setFilterMode("range"),
|
|
645
1154
|
children: [
|
|
646
|
-
/* @__PURE__ */
|
|
1155
|
+
/* @__PURE__ */ jsx4("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
|
|
647
1156
|
"path",
|
|
648
1157
|
{
|
|
649
1158
|
strokeLinecap: "round",
|
|
@@ -657,9 +1166,9 @@ function ColumnFilter({
|
|
|
657
1166
|
}
|
|
658
1167
|
)
|
|
659
1168
|
] }),
|
|
660
|
-
(!isNumericColumn || filterMode === "values") && /* @__PURE__ */
|
|
661
|
-
/* @__PURE__ */
|
|
662
|
-
/* @__PURE__ */
|
|
1169
|
+
(!isNumericColumn || filterMode === "values") && /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
1170
|
+
/* @__PURE__ */ jsxs4("div", { className: "vpg-search-container", children: [
|
|
1171
|
+
/* @__PURE__ */ jsx4("svg", { className: "vpg-search-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
|
|
663
1172
|
"path",
|
|
664
1173
|
{
|
|
665
1174
|
strokeLinecap: "round",
|
|
@@ -668,7 +1177,7 @@ function ColumnFilter({
|
|
|
668
1177
|
d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
|
|
669
1178
|
}
|
|
670
1179
|
) }),
|
|
671
|
-
/* @__PURE__ */
|
|
1180
|
+
/* @__PURE__ */ jsx4(
|
|
672
1181
|
"input",
|
|
673
1182
|
{
|
|
674
1183
|
ref: searchInputRef,
|
|
@@ -679,11 +1188,11 @@ function ColumnFilter({
|
|
|
679
1188
|
className: "vpg-search-input"
|
|
680
1189
|
}
|
|
681
1190
|
),
|
|
682
|
-
searchQuery && /* @__PURE__ */
|
|
1191
|
+
searchQuery && /* @__PURE__ */ jsx4("button", { className: "vpg-clear-search", onClick: () => setSearchQuery(""), children: "\xD7" })
|
|
683
1192
|
] }),
|
|
684
|
-
/* @__PURE__ */
|
|
685
|
-
/* @__PURE__ */
|
|
686
|
-
/* @__PURE__ */
|
|
1193
|
+
/* @__PURE__ */ jsxs4("div", { className: "vpg-bulk-actions", children: [
|
|
1194
|
+
/* @__PURE__ */ jsxs4("button", { className: "vpg-bulk-btn", onClick: selectAll, children: [
|
|
1195
|
+
/* @__PURE__ */ jsx4("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
|
|
687
1196
|
"path",
|
|
688
1197
|
{
|
|
689
1198
|
strokeLinecap: "round",
|
|
@@ -694,8 +1203,8 @@ function ColumnFilter({
|
|
|
694
1203
|
) }),
|
|
695
1204
|
"Select All"
|
|
696
1205
|
] }),
|
|
697
|
-
/* @__PURE__ */
|
|
698
|
-
/* @__PURE__ */
|
|
1206
|
+
/* @__PURE__ */ jsxs4("button", { className: "vpg-bulk-btn", onClick: clearAll, children: [
|
|
1207
|
+
/* @__PURE__ */ jsx4("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4(
|
|
699
1208
|
"path",
|
|
700
1209
|
{
|
|
701
1210
|
strokeLinecap: "round",
|
|
@@ -707,13 +1216,13 @@ function ColumnFilter({
|
|
|
707
1216
|
"Clear All"
|
|
708
1217
|
] })
|
|
709
1218
|
] }),
|
|
710
|
-
/* @__PURE__ */
|
|
711
|
-
allValues.map((value) => /* @__PURE__ */
|
|
1219
|
+
/* @__PURE__ */ jsxs4("div", { className: "vpg-values-list", children: [
|
|
1220
|
+
allValues.map((value) => /* @__PURE__ */ jsxs4(
|
|
712
1221
|
"label",
|
|
713
1222
|
{
|
|
714
1223
|
className: `vpg-value-item ${localSelected.has(value) ? "selected" : ""}`,
|
|
715
1224
|
children: [
|
|
716
|
-
/* @__PURE__ */
|
|
1225
|
+
/* @__PURE__ */ jsx4(
|
|
717
1226
|
"input",
|
|
718
1227
|
{
|
|
719
1228
|
type: "checkbox",
|
|
@@ -722,20 +1231,20 @@ function ColumnFilter({
|
|
|
722
1231
|
className: "vpg-value-checkbox"
|
|
723
1232
|
}
|
|
724
1233
|
),
|
|
725
|
-
/* @__PURE__ */
|
|
1234
|
+
/* @__PURE__ */ jsx4("span", { className: `vpg-value-text ${value === "(blank)" ? "vpg-blank" : ""}`, children: value })
|
|
726
1235
|
]
|
|
727
1236
|
},
|
|
728
1237
|
value
|
|
729
1238
|
)),
|
|
730
|
-
allValues.length === 0 && /* @__PURE__ */
|
|
1239
|
+
allValues.length === 0 && /* @__PURE__ */ jsx4("div", { className: "vpg-no-results", children: "No matching values" })
|
|
731
1240
|
] }),
|
|
732
|
-
/* @__PURE__ */
|
|
733
|
-
/* @__PURE__ */
|
|
734
|
-
/* @__PURE__ */
|
|
1241
|
+
/* @__PURE__ */ jsxs4("div", { className: "vpg-filter-footer", children: [
|
|
1242
|
+
/* @__PURE__ */ jsx4("button", { className: "vpg-btn-clear", onClick: clearFilter, children: "Clear Filter" }),
|
|
1243
|
+
/* @__PURE__ */ jsx4("button", { className: "vpg-btn-apply", onClick: applyFilter, children: "Apply" })
|
|
735
1244
|
] })
|
|
736
1245
|
] }),
|
|
737
|
-
isNumericColumn && filterMode === "range" && /* @__PURE__ */
|
|
738
|
-
/* @__PURE__ */
|
|
1246
|
+
isNumericColumn && filterMode === "range" && /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
1247
|
+
/* @__PURE__ */ jsx4(
|
|
739
1248
|
NumericRangeFilter,
|
|
740
1249
|
{
|
|
741
1250
|
dataMin: stats.numericMin,
|
|
@@ -744,16 +1253,16 @@ function ColumnFilter({
|
|
|
744
1253
|
onChange: handleRangeChange
|
|
745
1254
|
}
|
|
746
1255
|
),
|
|
747
|
-
/* @__PURE__ */
|
|
748
|
-
/* @__PURE__ */
|
|
749
|
-
/* @__PURE__ */
|
|
1256
|
+
/* @__PURE__ */ jsxs4("div", { className: "vpg-filter-footer", children: [
|
|
1257
|
+
/* @__PURE__ */ jsx4("button", { className: "vpg-btn-clear", onClick: clearRangeFilter, children: "Clear Filter" }),
|
|
1258
|
+
/* @__PURE__ */ jsx4("button", { className: "vpg-btn-apply", onClick: applyRangeFilter, children: "Apply" })
|
|
750
1259
|
] })
|
|
751
1260
|
] })
|
|
752
1261
|
] });
|
|
753
1262
|
}
|
|
754
1263
|
|
|
755
1264
|
// src/components/DataGrid.tsx
|
|
756
|
-
import { useCallback as
|
|
1265
|
+
import { useCallback as useCallback11, useEffect as useEffect8, useMemo as useMemo11, useRef as useRef2, useState as useState11 } from "react";
|
|
757
1266
|
import { createPortal as createPortal2 } from "react-dom";
|
|
758
1267
|
|
|
759
1268
|
// src/hooks/useExcelGrid.ts
|
|
@@ -764,7 +1273,7 @@ import {
|
|
|
764
1273
|
getSortedRowModel,
|
|
765
1274
|
useReactTable
|
|
766
1275
|
} from "@tanstack/react-table";
|
|
767
|
-
import { useCallback as
|
|
1276
|
+
import { useCallback as useCallback5, useEffect as useEffect5, useMemo as useMemo5, useState as useState5 } from "react";
|
|
768
1277
|
var multiSelectFilter = (row, columnId, filterValue) => {
|
|
769
1278
|
if (!filterValue)
|
|
770
1279
|
return true;
|
|
@@ -792,21 +1301,21 @@ var multiSelectFilter = (row, columnId, filterValue) => {
|
|
|
792
1301
|
};
|
|
793
1302
|
function useExcelGrid(options) {
|
|
794
1303
|
const { data, enableSorting = true, enableFiltering = true } = options;
|
|
795
|
-
const [sorting, setSorting] =
|
|
796
|
-
const [columnFilters, setColumnFilters] =
|
|
797
|
-
const [columnVisibility, setColumnVisibility] =
|
|
798
|
-
const [globalFilter, setGlobalFilter] =
|
|
799
|
-
const [columnStatsCache, setColumnStatsCache] =
|
|
800
|
-
const dataSignature =
|
|
1304
|
+
const [sorting, setSorting] = useState5([]);
|
|
1305
|
+
const [columnFilters, setColumnFilters] = useState5([]);
|
|
1306
|
+
const [columnVisibility, setColumnVisibility] = useState5({});
|
|
1307
|
+
const [globalFilter, setGlobalFilter] = useState5("");
|
|
1308
|
+
const [columnStatsCache, setColumnStatsCache] = useState5({});
|
|
1309
|
+
const dataSignature = useMemo5(
|
|
801
1310
|
() => `${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
|
802
1311
|
[data]
|
|
803
1312
|
);
|
|
804
|
-
const columnKeys =
|
|
1313
|
+
const columnKeys = useMemo5(() => {
|
|
805
1314
|
if (data.length === 0)
|
|
806
1315
|
return [];
|
|
807
1316
|
return Object.keys(data[0]);
|
|
808
1317
|
}, [data]);
|
|
809
|
-
const getColumnStats =
|
|
1318
|
+
const getColumnStats = useCallback5(
|
|
810
1319
|
(columnKey) => {
|
|
811
1320
|
const cacheKey = `${columnKey}-${dataSignature}`;
|
|
812
1321
|
if (!columnStatsCache[cacheKey]) {
|
|
@@ -818,13 +1327,13 @@ function useExcelGrid(options) {
|
|
|
818
1327
|
},
|
|
819
1328
|
[data, columnStatsCache, dataSignature]
|
|
820
1329
|
);
|
|
821
|
-
const clearStatsCache =
|
|
1330
|
+
const clearStatsCache = useCallback5(() => {
|
|
822
1331
|
setColumnStatsCache({});
|
|
823
1332
|
}, []);
|
|
824
|
-
|
|
1333
|
+
useEffect5(() => {
|
|
825
1334
|
clearStatsCache();
|
|
826
1335
|
}, [dataSignature, clearStatsCache]);
|
|
827
|
-
const columnDefs =
|
|
1336
|
+
const columnDefs = useMemo5(() => {
|
|
828
1337
|
return columnKeys.map((key) => {
|
|
829
1338
|
const stats = getColumnStats(key);
|
|
830
1339
|
return {
|
|
@@ -864,7 +1373,7 @@ function useExcelGrid(options) {
|
|
|
864
1373
|
});
|
|
865
1374
|
const filteredRowCount = table.getFilteredRowModel().rows.length;
|
|
866
1375
|
const totalRowCount = data.length;
|
|
867
|
-
const activeFilters =
|
|
1376
|
+
const activeFilters = useMemo5(() => {
|
|
868
1377
|
return columnFilters.map((f) => {
|
|
869
1378
|
const filterValue = f.value;
|
|
870
1379
|
if (filterValue && isNumericRange(filterValue)) {
|
|
@@ -883,7 +1392,7 @@ function useExcelGrid(options) {
|
|
|
883
1392
|
};
|
|
884
1393
|
});
|
|
885
1394
|
}, [columnFilters]);
|
|
886
|
-
const hasActiveFilter =
|
|
1395
|
+
const hasActiveFilter = useCallback5(
|
|
887
1396
|
(columnId) => {
|
|
888
1397
|
const column = table.getColumn(columnId);
|
|
889
1398
|
if (!column)
|
|
@@ -898,7 +1407,7 @@ function useExcelGrid(options) {
|
|
|
898
1407
|
},
|
|
899
1408
|
[table]
|
|
900
1409
|
);
|
|
901
|
-
const setColumnFilter =
|
|
1410
|
+
const setColumnFilter = useCallback5(
|
|
902
1411
|
(columnId, values) => {
|
|
903
1412
|
const column = table.getColumn(columnId);
|
|
904
1413
|
if (column) {
|
|
@@ -907,7 +1416,7 @@ function useExcelGrid(options) {
|
|
|
907
1416
|
},
|
|
908
1417
|
[table]
|
|
909
1418
|
);
|
|
910
|
-
const setNumericRangeFilter =
|
|
1419
|
+
const setNumericRangeFilter = useCallback5(
|
|
911
1420
|
(columnId, range) => {
|
|
912
1421
|
const column = table.getColumn(columnId);
|
|
913
1422
|
if (column) {
|
|
@@ -920,7 +1429,7 @@ function useExcelGrid(options) {
|
|
|
920
1429
|
},
|
|
921
1430
|
[table]
|
|
922
1431
|
);
|
|
923
|
-
const getNumericRangeFilter =
|
|
1432
|
+
const getNumericRangeFilter = useCallback5(
|
|
924
1433
|
(columnId) => {
|
|
925
1434
|
const column = table.getColumn(columnId);
|
|
926
1435
|
if (!column)
|
|
@@ -933,12 +1442,12 @@ function useExcelGrid(options) {
|
|
|
933
1442
|
},
|
|
934
1443
|
[table]
|
|
935
1444
|
);
|
|
936
|
-
const clearAllFilters =
|
|
1445
|
+
const clearAllFilters = useCallback5(() => {
|
|
937
1446
|
table.resetColumnFilters();
|
|
938
1447
|
setGlobalFilter("");
|
|
939
1448
|
setColumnFilters([]);
|
|
940
1449
|
}, [table]);
|
|
941
|
-
const getColumnFilterValues =
|
|
1450
|
+
const getColumnFilterValues = useCallback5(
|
|
942
1451
|
(columnId) => {
|
|
943
1452
|
const column = table.getColumn(columnId);
|
|
944
1453
|
if (!column)
|
|
@@ -948,7 +1457,7 @@ function useExcelGrid(options) {
|
|
|
948
1457
|
},
|
|
949
1458
|
[table]
|
|
950
1459
|
);
|
|
951
|
-
const toggleSort =
|
|
1460
|
+
const toggleSort = useCallback5((columnId) => {
|
|
952
1461
|
setSorting((prev) => {
|
|
953
1462
|
const current = prev.find((s) => s.id === columnId);
|
|
954
1463
|
if (!current) {
|
|
@@ -960,7 +1469,7 @@ function useExcelGrid(options) {
|
|
|
960
1469
|
}
|
|
961
1470
|
});
|
|
962
1471
|
}, []);
|
|
963
|
-
const getSortDirection =
|
|
1472
|
+
const getSortDirection = useCallback5(
|
|
964
1473
|
(columnId) => {
|
|
965
1474
|
const sort = sorting.find((s) => s.id === columnId);
|
|
966
1475
|
if (!sort)
|
|
@@ -1007,7 +1516,7 @@ import {
|
|
|
1007
1516
|
exportToCSV as coreExportToCSV,
|
|
1008
1517
|
formatSelectionForClipboard as coreFormatSelection
|
|
1009
1518
|
} from "@smallwebco/tinypivot-core";
|
|
1010
|
-
import { useCallback as
|
|
1519
|
+
import { useCallback as useCallback6, useMemo as useMemo6, useState as useState6 } from "react";
|
|
1011
1520
|
function exportToCSV(data, columns, options) {
|
|
1012
1521
|
coreExportToCSV(data, columns, options);
|
|
1013
1522
|
}
|
|
@@ -1021,45 +1530,45 @@ function formatSelectionForClipboard(rows, columns, selectionBounds) {
|
|
|
1021
1530
|
return coreFormatSelection(rows, columns, selectionBounds);
|
|
1022
1531
|
}
|
|
1023
1532
|
function usePagination(data, options = {}) {
|
|
1024
|
-
const [pageSize, setPageSize] =
|
|
1025
|
-
const [currentPage, setCurrentPage] =
|
|
1026
|
-
const totalPages =
|
|
1533
|
+
const [pageSize, setPageSize] = useState6(options.pageSize ?? 50);
|
|
1534
|
+
const [currentPage, setCurrentPage] = useState6(options.currentPage ?? 1);
|
|
1535
|
+
const totalPages = useMemo6(
|
|
1027
1536
|
() => Math.max(1, Math.ceil(data.length / pageSize)),
|
|
1028
1537
|
[data.length, pageSize]
|
|
1029
1538
|
);
|
|
1030
|
-
const paginatedData =
|
|
1539
|
+
const paginatedData = useMemo6(() => {
|
|
1031
1540
|
const start = (currentPage - 1) * pageSize;
|
|
1032
1541
|
const end = start + pageSize;
|
|
1033
1542
|
return data.slice(start, end);
|
|
1034
1543
|
}, [data, currentPage, pageSize]);
|
|
1035
|
-
const startIndex =
|
|
1036
|
-
const endIndex =
|
|
1544
|
+
const startIndex = useMemo6(() => (currentPage - 1) * pageSize + 1, [currentPage, pageSize]);
|
|
1545
|
+
const endIndex = useMemo6(
|
|
1037
1546
|
() => Math.min(currentPage * pageSize, data.length),
|
|
1038
1547
|
[currentPage, pageSize, data.length]
|
|
1039
1548
|
);
|
|
1040
|
-
const goToPage =
|
|
1549
|
+
const goToPage = useCallback6(
|
|
1041
1550
|
(page) => {
|
|
1042
1551
|
setCurrentPage(Math.max(1, Math.min(page, totalPages)));
|
|
1043
1552
|
},
|
|
1044
1553
|
[totalPages]
|
|
1045
1554
|
);
|
|
1046
|
-
const nextPage =
|
|
1555
|
+
const nextPage = useCallback6(() => {
|
|
1047
1556
|
if (currentPage < totalPages) {
|
|
1048
1557
|
setCurrentPage((prev) => prev + 1);
|
|
1049
1558
|
}
|
|
1050
1559
|
}, [currentPage, totalPages]);
|
|
1051
|
-
const prevPage =
|
|
1560
|
+
const prevPage = useCallback6(() => {
|
|
1052
1561
|
if (currentPage > 1) {
|
|
1053
1562
|
setCurrentPage((prev) => prev - 1);
|
|
1054
1563
|
}
|
|
1055
1564
|
}, [currentPage]);
|
|
1056
|
-
const firstPage =
|
|
1565
|
+
const firstPage = useCallback6(() => {
|
|
1057
1566
|
setCurrentPage(1);
|
|
1058
1567
|
}, []);
|
|
1059
|
-
const lastPage =
|
|
1568
|
+
const lastPage = useCallback6(() => {
|
|
1060
1569
|
setCurrentPage(totalPages);
|
|
1061
1570
|
}, [totalPages]);
|
|
1062
|
-
const updatePageSize =
|
|
1571
|
+
const updatePageSize = useCallback6((size) => {
|
|
1063
1572
|
setPageSize(size);
|
|
1064
1573
|
setCurrentPage(1);
|
|
1065
1574
|
}, []);
|
|
@@ -1079,9 +1588,9 @@ function usePagination(data, options = {}) {
|
|
|
1079
1588
|
};
|
|
1080
1589
|
}
|
|
1081
1590
|
function useGlobalSearch(data, columns) {
|
|
1082
|
-
const [searchTerm, setSearchTerm] =
|
|
1083
|
-
const [caseSensitive, setCaseSensitive] =
|
|
1084
|
-
const filteredData =
|
|
1591
|
+
const [searchTerm, setSearchTerm] = useState6("");
|
|
1592
|
+
const [caseSensitive, setCaseSensitive] = useState6(false);
|
|
1593
|
+
const filteredData = useMemo6(() => {
|
|
1085
1594
|
if (!searchTerm.trim()) {
|
|
1086
1595
|
return data;
|
|
1087
1596
|
}
|
|
@@ -1099,7 +1608,7 @@ function useGlobalSearch(data, columns) {
|
|
|
1099
1608
|
return false;
|
|
1100
1609
|
});
|
|
1101
1610
|
}, [data, columns, searchTerm, caseSensitive]);
|
|
1102
|
-
const clearSearch =
|
|
1611
|
+
const clearSearch = useCallback6(() => {
|
|
1103
1612
|
setSearchTerm("");
|
|
1104
1613
|
}, []);
|
|
1105
1614
|
return {
|
|
@@ -1112,17 +1621,17 @@ function useGlobalSearch(data, columns) {
|
|
|
1112
1621
|
};
|
|
1113
1622
|
}
|
|
1114
1623
|
function useRowSelection(data) {
|
|
1115
|
-
const [selectedRowIndices, setSelectedRowIndices] =
|
|
1116
|
-
const selectedRows =
|
|
1624
|
+
const [selectedRowIndices, setSelectedRowIndices] = useState6(/* @__PURE__ */ new Set());
|
|
1625
|
+
const selectedRows = useMemo6(() => {
|
|
1117
1626
|
return Array.from(selectedRowIndices).sort((a, b) => a - b).map((idx) => data[idx]).filter(Boolean);
|
|
1118
1627
|
}, [data, selectedRowIndices]);
|
|
1119
|
-
const allSelected =
|
|
1628
|
+
const allSelected = useMemo6(() => {
|
|
1120
1629
|
return data.length > 0 && selectedRowIndices.size === data.length;
|
|
1121
1630
|
}, [data.length, selectedRowIndices.size]);
|
|
1122
|
-
const someSelected =
|
|
1631
|
+
const someSelected = useMemo6(() => {
|
|
1123
1632
|
return selectedRowIndices.size > 0 && selectedRowIndices.size < data.length;
|
|
1124
1633
|
}, [data.length, selectedRowIndices.size]);
|
|
1125
|
-
const toggleRow =
|
|
1634
|
+
const toggleRow = useCallback6((index) => {
|
|
1126
1635
|
setSelectedRowIndices((prev) => {
|
|
1127
1636
|
const next = new Set(prev);
|
|
1128
1637
|
if (next.has(index)) {
|
|
@@ -1133,36 +1642,36 @@ function useRowSelection(data) {
|
|
|
1133
1642
|
return next;
|
|
1134
1643
|
});
|
|
1135
1644
|
}, []);
|
|
1136
|
-
const selectRow =
|
|
1645
|
+
const selectRow = useCallback6((index) => {
|
|
1137
1646
|
setSelectedRowIndices((prev) => /* @__PURE__ */ new Set([...prev, index]));
|
|
1138
1647
|
}, []);
|
|
1139
|
-
const deselectRow =
|
|
1648
|
+
const deselectRow = useCallback6((index) => {
|
|
1140
1649
|
setSelectedRowIndices((prev) => {
|
|
1141
1650
|
const next = new Set(prev);
|
|
1142
1651
|
next.delete(index);
|
|
1143
1652
|
return next;
|
|
1144
1653
|
});
|
|
1145
1654
|
}, []);
|
|
1146
|
-
const selectAll =
|
|
1655
|
+
const selectAll = useCallback6(() => {
|
|
1147
1656
|
setSelectedRowIndices(new Set(data.map((_, idx) => idx)));
|
|
1148
1657
|
}, [data]);
|
|
1149
|
-
const deselectAll =
|
|
1658
|
+
const deselectAll = useCallback6(() => {
|
|
1150
1659
|
setSelectedRowIndices(/* @__PURE__ */ new Set());
|
|
1151
1660
|
}, []);
|
|
1152
|
-
const toggleAll =
|
|
1661
|
+
const toggleAll = useCallback6(() => {
|
|
1153
1662
|
if (allSelected) {
|
|
1154
1663
|
deselectAll();
|
|
1155
1664
|
} else {
|
|
1156
1665
|
selectAll();
|
|
1157
1666
|
}
|
|
1158
1667
|
}, [allSelected, selectAll, deselectAll]);
|
|
1159
|
-
const isSelected =
|
|
1668
|
+
const isSelected = useCallback6(
|
|
1160
1669
|
(index) => {
|
|
1161
1670
|
return selectedRowIndices.has(index);
|
|
1162
1671
|
},
|
|
1163
1672
|
[selectedRowIndices]
|
|
1164
1673
|
);
|
|
1165
|
-
const selectRange =
|
|
1674
|
+
const selectRange = useCallback6((startIndex, endIndex) => {
|
|
1166
1675
|
const min = Math.min(startIndex, endIndex);
|
|
1167
1676
|
const max = Math.max(startIndex, endIndex);
|
|
1168
1677
|
setSelectedRowIndices((prev) => {
|
|
@@ -1189,10 +1698,10 @@ function useRowSelection(data) {
|
|
|
1189
1698
|
};
|
|
1190
1699
|
}
|
|
1191
1700
|
function useColumnResize(initialWidths, minWidth = 60, maxWidth = 600) {
|
|
1192
|
-
const [columnWidths, setColumnWidths] =
|
|
1193
|
-
const [isResizing, setIsResizing] =
|
|
1194
|
-
const [resizingColumn, setResizingColumn] =
|
|
1195
|
-
const startResize =
|
|
1701
|
+
const [columnWidths, setColumnWidths] = useState6({ ...initialWidths });
|
|
1702
|
+
const [isResizing, setIsResizing] = useState6(false);
|
|
1703
|
+
const [resizingColumn, setResizingColumn] = useState6(null);
|
|
1704
|
+
const startResize = useCallback6(
|
|
1196
1705
|
(columnId, event) => {
|
|
1197
1706
|
setIsResizing(true);
|
|
1198
1707
|
setResizingColumn(columnId);
|
|
@@ -1217,7 +1726,7 @@ function useColumnResize(initialWidths, minWidth = 60, maxWidth = 600) {
|
|
|
1217
1726
|
},
|
|
1218
1727
|
[columnWidths, minWidth, maxWidth]
|
|
1219
1728
|
);
|
|
1220
|
-
const resetColumnWidth =
|
|
1729
|
+
const resetColumnWidth = useCallback6(
|
|
1221
1730
|
(columnId) => {
|
|
1222
1731
|
if (initialWidths[columnId]) {
|
|
1223
1732
|
setColumnWidths((prev) => ({
|
|
@@ -1228,7 +1737,7 @@ function useColumnResize(initialWidths, minWidth = 60, maxWidth = 600) {
|
|
|
1228
1737
|
},
|
|
1229
1738
|
[initialWidths]
|
|
1230
1739
|
);
|
|
1231
|
-
const resetAllWidths =
|
|
1740
|
+
const resetAllWidths = useCallback6(() => {
|
|
1232
1741
|
setColumnWidths({ ...initialWidths });
|
|
1233
1742
|
}, [initialWidths]);
|
|
1234
1743
|
return {
|
|
@@ -1244,6 +1753,7 @@ function useColumnResize(initialWidths, minWidth = 60, maxWidth = 600) {
|
|
|
1244
1753
|
|
|
1245
1754
|
// src/hooks/useLicense.ts
|
|
1246
1755
|
import {
|
|
1756
|
+
canUseCharts as coreCanUseCharts,
|
|
1247
1757
|
canUsePivot as coreCanUsePivot,
|
|
1248
1758
|
configureLicenseSecret as coreConfigureLicenseSecret,
|
|
1249
1759
|
isPro as coreIsPro,
|
|
@@ -1253,7 +1763,7 @@ import {
|
|
|
1253
1763
|
logProRequired,
|
|
1254
1764
|
validateLicenseKey
|
|
1255
1765
|
} from "@smallwebco/tinypivot-core";
|
|
1256
|
-
import { useCallback as
|
|
1766
|
+
import { useCallback as useCallback7, useMemo as useMemo7, useState as useState7 } from "react";
|
|
1257
1767
|
var globalLicenseInfo = getFreeLicenseInfo();
|
|
1258
1768
|
var globalDemoMode = false;
|
|
1259
1769
|
var listeners = /* @__PURE__ */ new Set();
|
|
@@ -1285,35 +1795,39 @@ function configureLicenseSecret(secret) {
|
|
|
1285
1795
|
coreConfigureLicenseSecret(secret);
|
|
1286
1796
|
}
|
|
1287
1797
|
function useLicense() {
|
|
1288
|
-
const [, forceUpdate] =
|
|
1289
|
-
|
|
1798
|
+
const [, forceUpdate] = useState7({});
|
|
1799
|
+
useState7(() => {
|
|
1290
1800
|
const update = () => forceUpdate({});
|
|
1291
1801
|
listeners.add(update);
|
|
1292
1802
|
return () => listeners.delete(update);
|
|
1293
1803
|
});
|
|
1294
1804
|
const isDemo = globalDemoMode;
|
|
1295
1805
|
const licenseInfo = globalLicenseInfo;
|
|
1296
|
-
const isPro =
|
|
1806
|
+
const isPro = useMemo7(
|
|
1297
1807
|
() => globalDemoMode || coreIsPro(licenseInfo),
|
|
1298
1808
|
[licenseInfo]
|
|
1299
1809
|
);
|
|
1300
|
-
const canUsePivot =
|
|
1810
|
+
const canUsePivot = useMemo7(
|
|
1301
1811
|
() => globalDemoMode || coreCanUsePivot(licenseInfo),
|
|
1302
1812
|
[licenseInfo]
|
|
1303
1813
|
);
|
|
1304
|
-
const canUseAdvancedAggregations =
|
|
1814
|
+
const canUseAdvancedAggregations = useMemo7(
|
|
1305
1815
|
() => globalDemoMode || licenseInfo.features.advancedAggregations,
|
|
1306
1816
|
[licenseInfo]
|
|
1307
1817
|
);
|
|
1308
|
-
const canUsePercentageMode =
|
|
1818
|
+
const canUsePercentageMode = useMemo7(
|
|
1309
1819
|
() => globalDemoMode || licenseInfo.features.percentageMode,
|
|
1310
1820
|
[licenseInfo]
|
|
1311
1821
|
);
|
|
1312
|
-
const
|
|
1822
|
+
const canUseCharts = useMemo7(
|
|
1823
|
+
() => globalDemoMode || coreCanUseCharts(licenseInfo),
|
|
1824
|
+
[licenseInfo]
|
|
1825
|
+
);
|
|
1826
|
+
const showWatermark = useMemo7(
|
|
1313
1827
|
() => coreShouldShowWatermark(licenseInfo, globalDemoMode),
|
|
1314
1828
|
[licenseInfo]
|
|
1315
1829
|
);
|
|
1316
|
-
const requirePro =
|
|
1830
|
+
const requirePro = useCallback7((feature) => {
|
|
1317
1831
|
if (!isPro) {
|
|
1318
1832
|
logProRequired(feature);
|
|
1319
1833
|
return false;
|
|
@@ -1327,6 +1841,7 @@ function useLicense() {
|
|
|
1327
1841
|
canUsePivot,
|
|
1328
1842
|
canUseAdvancedAggregations,
|
|
1329
1843
|
canUsePercentageMode,
|
|
1844
|
+
canUseCharts,
|
|
1330
1845
|
showWatermark,
|
|
1331
1846
|
requirePro
|
|
1332
1847
|
};
|
|
@@ -1346,23 +1861,23 @@ import {
|
|
|
1346
1861
|
saveCalculatedFields,
|
|
1347
1862
|
savePivotConfig
|
|
1348
1863
|
} from "@smallwebco/tinypivot-core";
|
|
1349
|
-
import { useCallback as
|
|
1864
|
+
import { useCallback as useCallback8, useEffect as useEffect6, useMemo as useMemo8, useState as useState8 } from "react";
|
|
1350
1865
|
function usePivotTable(data) {
|
|
1351
1866
|
const { canUsePivot, requirePro } = useLicense();
|
|
1352
|
-
const [rowFields, setRowFieldsState] =
|
|
1353
|
-
const [columnFields, setColumnFieldsState] =
|
|
1354
|
-
const [valueFields, setValueFields] =
|
|
1355
|
-
const [showRowTotals, setShowRowTotals] =
|
|
1356
|
-
const [showColumnTotals, setShowColumnTotals] =
|
|
1357
|
-
const [calculatedFields, setCalculatedFields] =
|
|
1358
|
-
const [currentStorageKey, setCurrentStorageKey] =
|
|
1359
|
-
const availableFields =
|
|
1867
|
+
const [rowFields, setRowFieldsState] = useState8([]);
|
|
1868
|
+
const [columnFields, setColumnFieldsState] = useState8([]);
|
|
1869
|
+
const [valueFields, setValueFields] = useState8([]);
|
|
1870
|
+
const [showRowTotals, setShowRowTotals] = useState8(true);
|
|
1871
|
+
const [showColumnTotals, setShowColumnTotals] = useState8(true);
|
|
1872
|
+
const [calculatedFields, setCalculatedFields] = useState8(() => loadCalculatedFields());
|
|
1873
|
+
const [currentStorageKey, setCurrentStorageKey] = useState8(null);
|
|
1874
|
+
const availableFields = useMemo8(() => {
|
|
1360
1875
|
return computeAvailableFields(data);
|
|
1361
1876
|
}, [data]);
|
|
1362
|
-
const unassignedFields =
|
|
1877
|
+
const unassignedFields = useMemo8(() => {
|
|
1363
1878
|
return getUnassignedFields(availableFields, rowFields, columnFields, valueFields);
|
|
1364
1879
|
}, [availableFields, rowFields, columnFields, valueFields]);
|
|
1365
|
-
const isConfigured =
|
|
1880
|
+
const isConfigured = useMemo8(() => {
|
|
1366
1881
|
return isPivotConfigured({
|
|
1367
1882
|
rowFields,
|
|
1368
1883
|
columnFields,
|
|
@@ -1371,7 +1886,7 @@ function usePivotTable(data) {
|
|
|
1371
1886
|
showColumnTotals
|
|
1372
1887
|
});
|
|
1373
1888
|
}, [rowFields, columnFields, valueFields, showRowTotals, showColumnTotals]);
|
|
1374
|
-
const pivotResult =
|
|
1889
|
+
const pivotResult = useMemo8(() => {
|
|
1375
1890
|
if (!isConfigured)
|
|
1376
1891
|
return null;
|
|
1377
1892
|
if (!canUsePivot)
|
|
@@ -1385,7 +1900,7 @@ function usePivotTable(data) {
|
|
|
1385
1900
|
calculatedFields
|
|
1386
1901
|
});
|
|
1387
1902
|
}, [data, isConfigured, canUsePivot, rowFields, columnFields, valueFields, showRowTotals, showColumnTotals, calculatedFields]);
|
|
1388
|
-
|
|
1903
|
+
useEffect6(() => {
|
|
1389
1904
|
if (data.length === 0)
|
|
1390
1905
|
return;
|
|
1391
1906
|
const newKeys = Object.keys(data[0]);
|
|
@@ -1418,7 +1933,7 @@ function usePivotTable(data) {
|
|
|
1418
1933
|
}
|
|
1419
1934
|
}
|
|
1420
1935
|
}, [data]);
|
|
1421
|
-
|
|
1936
|
+
useEffect6(() => {
|
|
1422
1937
|
if (!currentStorageKey)
|
|
1423
1938
|
return;
|
|
1424
1939
|
const config = {
|
|
@@ -1431,7 +1946,7 @@ function usePivotTable(data) {
|
|
|
1431
1946
|
};
|
|
1432
1947
|
savePivotConfig(currentStorageKey, config);
|
|
1433
1948
|
}, [currentStorageKey, rowFields, columnFields, valueFields, showRowTotals, showColumnTotals, calculatedFields]);
|
|
1434
|
-
const addRowField =
|
|
1949
|
+
const addRowField = useCallback8(
|
|
1435
1950
|
(field) => {
|
|
1436
1951
|
if (!rowFields.includes(field)) {
|
|
1437
1952
|
setRowFieldsState((prev) => [...prev, field]);
|
|
@@ -1439,13 +1954,13 @@ function usePivotTable(data) {
|
|
|
1439
1954
|
},
|
|
1440
1955
|
[rowFields]
|
|
1441
1956
|
);
|
|
1442
|
-
const removeRowField =
|
|
1957
|
+
const removeRowField = useCallback8((field) => {
|
|
1443
1958
|
setRowFieldsState((prev) => prev.filter((f) => f !== field));
|
|
1444
1959
|
}, []);
|
|
1445
|
-
const setRowFields =
|
|
1960
|
+
const setRowFields = useCallback8((fields) => {
|
|
1446
1961
|
setRowFieldsState(fields);
|
|
1447
1962
|
}, []);
|
|
1448
|
-
const addColumnField =
|
|
1963
|
+
const addColumnField = useCallback8(
|
|
1449
1964
|
(field) => {
|
|
1450
1965
|
if (!columnFields.includes(field)) {
|
|
1451
1966
|
setColumnFieldsState((prev) => [...prev, field]);
|
|
@@ -1453,13 +1968,13 @@ function usePivotTable(data) {
|
|
|
1453
1968
|
},
|
|
1454
1969
|
[columnFields]
|
|
1455
1970
|
);
|
|
1456
|
-
const removeColumnField =
|
|
1971
|
+
const removeColumnField = useCallback8((field) => {
|
|
1457
1972
|
setColumnFieldsState((prev) => prev.filter((f) => f !== field));
|
|
1458
1973
|
}, []);
|
|
1459
|
-
const setColumnFields =
|
|
1974
|
+
const setColumnFields = useCallback8((fields) => {
|
|
1460
1975
|
setColumnFieldsState(fields);
|
|
1461
1976
|
}, []);
|
|
1462
|
-
const addValueField =
|
|
1977
|
+
const addValueField = useCallback8(
|
|
1463
1978
|
(field, aggregation = "sum") => {
|
|
1464
1979
|
if (aggregation !== "sum" && !requirePro(`${aggregation} aggregation`)) {
|
|
1465
1980
|
return;
|
|
@@ -1473,7 +1988,7 @@ function usePivotTable(data) {
|
|
|
1473
1988
|
},
|
|
1474
1989
|
[requirePro]
|
|
1475
1990
|
);
|
|
1476
|
-
const removeValueField =
|
|
1991
|
+
const removeValueField = useCallback8((field, aggregation) => {
|
|
1477
1992
|
setValueFields((prev) => {
|
|
1478
1993
|
if (aggregation) {
|
|
1479
1994
|
return prev.filter((v) => !(v.field === field && v.aggregation === aggregation));
|
|
@@ -1481,7 +1996,7 @@ function usePivotTable(data) {
|
|
|
1481
1996
|
return prev.filter((v) => v.field !== field);
|
|
1482
1997
|
});
|
|
1483
1998
|
}, []);
|
|
1484
|
-
const updateValueFieldAggregation =
|
|
1999
|
+
const updateValueFieldAggregation = useCallback8(
|
|
1485
2000
|
(field, oldAgg, newAgg) => {
|
|
1486
2001
|
setValueFields(
|
|
1487
2002
|
(prev) => prev.map((v) => {
|
|
@@ -1494,12 +2009,12 @@ function usePivotTable(data) {
|
|
|
1494
2009
|
},
|
|
1495
2010
|
[]
|
|
1496
2011
|
);
|
|
1497
|
-
const clearConfig =
|
|
2012
|
+
const clearConfig = useCallback8(() => {
|
|
1498
2013
|
setRowFieldsState([]);
|
|
1499
2014
|
setColumnFieldsState([]);
|
|
1500
2015
|
setValueFields([]);
|
|
1501
2016
|
}, []);
|
|
1502
|
-
const autoSuggestConfig =
|
|
2017
|
+
const autoSuggestConfig = useCallback8(() => {
|
|
1503
2018
|
if (!requirePro("Pivot Table - Auto Suggest"))
|
|
1504
2019
|
return;
|
|
1505
2020
|
if (availableFields.length === 0)
|
|
@@ -1511,7 +2026,7 @@ function usePivotTable(data) {
|
|
|
1511
2026
|
setValueFields([{ field: numericFields[0].field, aggregation: "sum" }]);
|
|
1512
2027
|
}
|
|
1513
2028
|
}, [availableFields, requirePro]);
|
|
1514
|
-
const addCalculatedField =
|
|
2029
|
+
const addCalculatedField = useCallback8((field) => {
|
|
1515
2030
|
setCalculatedFields((prev) => {
|
|
1516
2031
|
const existing = prev.findIndex((f) => f.id === field.id);
|
|
1517
2032
|
let updated;
|
|
@@ -1524,7 +2039,7 @@ function usePivotTable(data) {
|
|
|
1524
2039
|
return updated;
|
|
1525
2040
|
});
|
|
1526
2041
|
}, []);
|
|
1527
|
-
const removeCalculatedField =
|
|
2042
|
+
const removeCalculatedField = useCallback8((id) => {
|
|
1528
2043
|
setCalculatedFields((prev) => {
|
|
1529
2044
|
const updated = prev.filter((f) => f.id !== id);
|
|
1530
2045
|
saveCalculatedFields(updated);
|
|
@@ -1566,8 +2081,8 @@ function usePivotTable(data) {
|
|
|
1566
2081
|
|
|
1567
2082
|
// src/components/PivotConfig.tsx
|
|
1568
2083
|
import { AGGREGATION_OPTIONS, getAggregationSymbol } from "@smallwebco/tinypivot-core";
|
|
1569
|
-
import { useCallback as
|
|
1570
|
-
import { Fragment as
|
|
2084
|
+
import { useCallback as useCallback9, useMemo as useMemo9, useState as useState9 } from "react";
|
|
2085
|
+
import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1571
2086
|
function aggregationRequiresPro(agg) {
|
|
1572
2087
|
return agg !== "sum";
|
|
1573
2088
|
}
|
|
@@ -1608,15 +2123,15 @@ function PivotConfig({
|
|
|
1608
2123
|
onRemoveCalculatedField,
|
|
1609
2124
|
onUpdateCalculatedField
|
|
1610
2125
|
}) {
|
|
1611
|
-
const [fieldSearch, setFieldSearch] =
|
|
1612
|
-
const [showCalcModal, setShowCalcModal] =
|
|
1613
|
-
const [editingCalcField, setEditingCalcField] =
|
|
2126
|
+
const [fieldSearch, setFieldSearch] = useState9("");
|
|
2127
|
+
const [showCalcModal, setShowCalcModal] = useState9(false);
|
|
2128
|
+
const [editingCalcField, setEditingCalcField] = useState9(null);
|
|
1614
2129
|
const { canUseAdvancedAggregations } = useLicense();
|
|
1615
|
-
const isAggregationAvailable =
|
|
2130
|
+
const isAggregationAvailable = useCallback9((agg) => {
|
|
1616
2131
|
return !aggregationRequiresPro(agg) || canUseAdvancedAggregations;
|
|
1617
2132
|
}, [canUseAdvancedAggregations]);
|
|
1618
|
-
const numericFieldNames =
|
|
1619
|
-
const calculatedFieldsAsStats =
|
|
2133
|
+
const numericFieldNames = useMemo9(() => availableFields.filter((f) => f.isNumeric).map((f) => f.field), [availableFields]);
|
|
2134
|
+
const calculatedFieldsAsStats = useMemo9(() => {
|
|
1620
2135
|
if (!calculatedFields)
|
|
1621
2136
|
return [];
|
|
1622
2137
|
return calculatedFields.map((calc) => ({
|
|
@@ -1630,11 +2145,11 @@ function PivotConfig({
|
|
|
1630
2145
|
calcFormula: calc.formula
|
|
1631
2146
|
}));
|
|
1632
2147
|
}, [calculatedFields]);
|
|
1633
|
-
const allAvailableFields =
|
|
2148
|
+
const allAvailableFields = useMemo9(() => [
|
|
1634
2149
|
...availableFields.map((f) => ({ ...f, isCalculated: false })),
|
|
1635
2150
|
...calculatedFieldsAsStats
|
|
1636
2151
|
], [availableFields, calculatedFieldsAsStats]);
|
|
1637
|
-
const assignedFields =
|
|
2152
|
+
const assignedFields = useMemo9(() => {
|
|
1638
2153
|
const rowSet = new Set(rowFields);
|
|
1639
2154
|
const colSet = new Set(columnFields);
|
|
1640
2155
|
const valueMap = new Map(valueFields.map((v) => [v.field, v]));
|
|
@@ -1644,7 +2159,7 @@ function PivotConfig({
|
|
|
1644
2159
|
valueConfig: valueMap.get(f.field)
|
|
1645
2160
|
}));
|
|
1646
2161
|
}, [allAvailableFields, rowFields, columnFields, valueFields]);
|
|
1647
|
-
const unassignedFields =
|
|
2162
|
+
const unassignedFields = useMemo9(() => {
|
|
1648
2163
|
const rowSet = new Set(rowFields);
|
|
1649
2164
|
const colSet = new Set(columnFields);
|
|
1650
2165
|
const valSet = new Set(valueFields.map((v) => v.field));
|
|
@@ -1652,7 +2167,7 @@ function PivotConfig({
|
|
|
1652
2167
|
(f) => !rowSet.has(f.field) && !colSet.has(f.field) && !valSet.has(f.field)
|
|
1653
2168
|
);
|
|
1654
2169
|
}, [allAvailableFields, rowFields, columnFields, valueFields]);
|
|
1655
|
-
const filteredUnassignedFields =
|
|
2170
|
+
const filteredUnassignedFields = useMemo9(() => {
|
|
1656
2171
|
if (!fieldSearch.trim())
|
|
1657
2172
|
return unassignedFields;
|
|
1658
2173
|
const search = fieldSearch.toLowerCase().trim();
|
|
@@ -1663,13 +2178,13 @@ function PivotConfig({
|
|
|
1663
2178
|
});
|
|
1664
2179
|
}, [unassignedFields, fieldSearch]);
|
|
1665
2180
|
const assignedCount = assignedFields.length;
|
|
1666
|
-
const getFieldDisplayName =
|
|
2181
|
+
const getFieldDisplayName = useCallback9((field) => {
|
|
1667
2182
|
if (field.isCalculated && field.calcName) {
|
|
1668
2183
|
return field.calcName;
|
|
1669
2184
|
}
|
|
1670
2185
|
return field.field;
|
|
1671
2186
|
}, []);
|
|
1672
|
-
const handleDragStart =
|
|
2187
|
+
const handleDragStart = useCallback9(
|
|
1673
2188
|
(field, event) => {
|
|
1674
2189
|
event.dataTransfer?.setData("text/plain", field);
|
|
1675
2190
|
event.dataTransfer.effectAllowed = "move";
|
|
@@ -1677,7 +2192,7 @@ function PivotConfig({
|
|
|
1677
2192
|
},
|
|
1678
2193
|
[onDragStart]
|
|
1679
2194
|
);
|
|
1680
|
-
const handleAggregationChange =
|
|
2195
|
+
const handleAggregationChange = useCallback9(
|
|
1681
2196
|
(field, currentAgg, newAgg) => {
|
|
1682
2197
|
if (!isAggregationAvailable(newAgg)) {
|
|
1683
2198
|
console.warn(`[TinyPivot] "${newAgg}" aggregation requires a Pro license. Visit https://tiny-pivot.com/#pricing to upgrade.`);
|
|
@@ -1687,7 +2202,7 @@ function PivotConfig({
|
|
|
1687
2202
|
},
|
|
1688
2203
|
[onUpdateAggregation, isAggregationAvailable]
|
|
1689
2204
|
);
|
|
1690
|
-
const toggleRowColumn =
|
|
2205
|
+
const toggleRowColumn = useCallback9(
|
|
1691
2206
|
(field, currentAssignment) => {
|
|
1692
2207
|
if (currentAssignment === "row") {
|
|
1693
2208
|
onRemoveRowField(field);
|
|
@@ -1699,7 +2214,7 @@ function PivotConfig({
|
|
|
1699
2214
|
},
|
|
1700
2215
|
[onRemoveRowField, onAddColumnField, onRemoveColumnField, onAddRowField]
|
|
1701
2216
|
);
|
|
1702
|
-
const removeField =
|
|
2217
|
+
const removeField = useCallback9(
|
|
1703
2218
|
(field, assignedTo, valueConfig) => {
|
|
1704
2219
|
if (assignedTo === "row") {
|
|
1705
2220
|
onRemoveRowField(field);
|
|
@@ -1711,15 +2226,15 @@ function PivotConfig({
|
|
|
1711
2226
|
},
|
|
1712
2227
|
[onRemoveRowField, onRemoveColumnField, onRemoveValueField]
|
|
1713
2228
|
);
|
|
1714
|
-
const handleTotalsToggle =
|
|
2229
|
+
const handleTotalsToggle = useCallback9((checked) => {
|
|
1715
2230
|
onShowRowTotalsChange(checked);
|
|
1716
2231
|
onShowColumnTotalsChange(checked);
|
|
1717
2232
|
}, [onShowRowTotalsChange, onShowColumnTotalsChange]);
|
|
1718
|
-
const openCalcModal =
|
|
2233
|
+
const openCalcModal = useCallback9((field) => {
|
|
1719
2234
|
setEditingCalcField(field || null);
|
|
1720
2235
|
setShowCalcModal(true);
|
|
1721
2236
|
}, []);
|
|
1722
|
-
const handleSaveCalcField =
|
|
2237
|
+
const handleSaveCalcField = useCallback9((field) => {
|
|
1723
2238
|
if (editingCalcField && onUpdateCalculatedField) {
|
|
1724
2239
|
onUpdateCalculatedField(field);
|
|
1725
2240
|
} else if (onAddCalculatedField) {
|
|
@@ -1728,14 +2243,14 @@ function PivotConfig({
|
|
|
1728
2243
|
setShowCalcModal(false);
|
|
1729
2244
|
setEditingCalcField(null);
|
|
1730
2245
|
}, [editingCalcField, onAddCalculatedField, onUpdateCalculatedField]);
|
|
1731
|
-
const handleCloseCalcModal =
|
|
2246
|
+
const handleCloseCalcModal = useCallback9(() => {
|
|
1732
2247
|
setShowCalcModal(false);
|
|
1733
2248
|
setEditingCalcField(null);
|
|
1734
2249
|
}, []);
|
|
1735
|
-
return /* @__PURE__ */
|
|
1736
|
-
/* @__PURE__ */
|
|
1737
|
-
/* @__PURE__ */
|
|
1738
|
-
/* @__PURE__ */
|
|
2250
|
+
return /* @__PURE__ */ jsxs5("div", { className: "vpg-pivot-config", children: [
|
|
2251
|
+
/* @__PURE__ */ jsxs5("div", { className: "vpg-config-header", children: [
|
|
2252
|
+
/* @__PURE__ */ jsxs5("h3", { className: "vpg-config-title", children: [
|
|
2253
|
+
/* @__PURE__ */ jsx5("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
|
|
1739
2254
|
"path",
|
|
1740
2255
|
{
|
|
1741
2256
|
strokeLinecap: "round",
|
|
@@ -1746,13 +2261,13 @@ function PivotConfig({
|
|
|
1746
2261
|
) }),
|
|
1747
2262
|
"Fields"
|
|
1748
2263
|
] }),
|
|
1749
|
-
/* @__PURE__ */
|
|
2264
|
+
/* @__PURE__ */ jsx5("div", { className: "vpg-header-actions", children: assignedCount > 0 && /* @__PURE__ */ jsx5(
|
|
1750
2265
|
"button",
|
|
1751
2266
|
{
|
|
1752
2267
|
className: "vpg-action-btn vpg-clear-btn",
|
|
1753
2268
|
title: "Clear all",
|
|
1754
2269
|
onClick: onClearConfig,
|
|
1755
|
-
children: /* @__PURE__ */
|
|
2270
|
+
children: /* @__PURE__ */ jsx5("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
|
|
1756
2271
|
"path",
|
|
1757
2272
|
{
|
|
1758
2273
|
strokeLinecap: "round",
|
|
@@ -1764,9 +2279,9 @@ function PivotConfig({
|
|
|
1764
2279
|
}
|
|
1765
2280
|
) })
|
|
1766
2281
|
] }),
|
|
1767
|
-
assignedCount > 0 && /* @__PURE__ */
|
|
1768
|
-
/* @__PURE__ */
|
|
1769
|
-
/* @__PURE__ */
|
|
2282
|
+
assignedCount > 0 && /* @__PURE__ */ jsxs5("div", { className: "vpg-assigned-section", children: [
|
|
2283
|
+
/* @__PURE__ */ jsx5("div", { className: "vpg-section-label", children: "Active" }),
|
|
2284
|
+
/* @__PURE__ */ jsx5("div", { className: "vpg-assigned-list", children: assignedFields.map((field) => /* @__PURE__ */ jsxs5(
|
|
1770
2285
|
"div",
|
|
1771
2286
|
{
|
|
1772
2287
|
className: `vpg-assigned-item vpg-type-${field.assignedTo}${field.isCalculated ? " vpg-type-calc" : ""}`,
|
|
@@ -1775,12 +2290,12 @@ function PivotConfig({
|
|
|
1775
2290
|
onDragStart: (e) => handleDragStart(field.field, e),
|
|
1776
2291
|
onDragEnd,
|
|
1777
2292
|
children: [
|
|
1778
|
-
/* @__PURE__ */
|
|
1779
|
-
/* @__PURE__ */
|
|
1780
|
-
/* @__PURE__ */
|
|
2293
|
+
/* @__PURE__ */ jsxs5("div", { className: "vpg-item-main", children: [
|
|
2294
|
+
/* @__PURE__ */ jsx5("span", { className: `vpg-item-badge ${field.assignedTo}${field.isCalculated ? " calc" : ""}`, children: field.isCalculated ? "\u0192" : field.assignedTo === "row" ? "R" : field.assignedTo === "column" ? "C" : getAggregationSymbol(field.valueConfig?.aggregation || "sum") }),
|
|
2295
|
+
/* @__PURE__ */ jsx5("span", { className: "vpg-item-name", children: getFieldDisplayName(field) })
|
|
1781
2296
|
] }),
|
|
1782
|
-
/* @__PURE__ */
|
|
1783
|
-
(field.assignedTo === "row" || field.assignedTo === "column") && /* @__PURE__ */
|
|
2297
|
+
/* @__PURE__ */ jsxs5("div", { className: "vpg-item-actions", children: [
|
|
2298
|
+
(field.assignedTo === "row" || field.assignedTo === "column") && /* @__PURE__ */ jsx5(
|
|
1784
2299
|
"button",
|
|
1785
2300
|
{
|
|
1786
2301
|
className: "vpg-toggle-btn",
|
|
@@ -1789,14 +2304,14 @@ function PivotConfig({
|
|
|
1789
2304
|
e.stopPropagation();
|
|
1790
2305
|
toggleRowColumn(field.field, field.assignedTo);
|
|
1791
2306
|
},
|
|
1792
|
-
children: /* @__PURE__ */
|
|
2307
|
+
children: /* @__PURE__ */ jsx5(
|
|
1793
2308
|
"svg",
|
|
1794
2309
|
{
|
|
1795
2310
|
className: "vpg-icon-xs",
|
|
1796
2311
|
fill: "none",
|
|
1797
2312
|
stroke: "currentColor",
|
|
1798
2313
|
viewBox: "0 0 24 24",
|
|
1799
|
-
children: /* @__PURE__ */
|
|
2314
|
+
children: /* @__PURE__ */ jsx5(
|
|
1800
2315
|
"path",
|
|
1801
2316
|
{
|
|
1802
2317
|
strokeLinecap: "round",
|
|
@@ -1809,7 +2324,7 @@ function PivotConfig({
|
|
|
1809
2324
|
)
|
|
1810
2325
|
}
|
|
1811
2326
|
),
|
|
1812
|
-
field.assignedTo === "value" && field.valueConfig && /* @__PURE__ */
|
|
2327
|
+
field.assignedTo === "value" && field.valueConfig && /* @__PURE__ */ jsx5(
|
|
1813
2328
|
"select",
|
|
1814
2329
|
{
|
|
1815
2330
|
className: "vpg-agg-select",
|
|
@@ -1823,7 +2338,7 @@ function PivotConfig({
|
|
|
1823
2338
|
);
|
|
1824
2339
|
},
|
|
1825
2340
|
onClick: (e) => e.stopPropagation(),
|
|
1826
|
-
children: AGGREGATION_OPTIONS.map((agg) => /* @__PURE__ */
|
|
2341
|
+
children: AGGREGATION_OPTIONS.map((agg) => /* @__PURE__ */ jsxs5(
|
|
1827
2342
|
"option",
|
|
1828
2343
|
{
|
|
1829
2344
|
value: agg.value,
|
|
@@ -1839,7 +2354,7 @@ function PivotConfig({
|
|
|
1839
2354
|
))
|
|
1840
2355
|
}
|
|
1841
2356
|
),
|
|
1842
|
-
/* @__PURE__ */
|
|
2357
|
+
/* @__PURE__ */ jsx5(
|
|
1843
2358
|
"button",
|
|
1844
2359
|
{
|
|
1845
2360
|
className: "vpg-remove-btn",
|
|
@@ -1857,14 +2372,14 @@ function PivotConfig({
|
|
|
1857
2372
|
field.field
|
|
1858
2373
|
)) })
|
|
1859
2374
|
] }),
|
|
1860
|
-
/* @__PURE__ */
|
|
1861
|
-
/* @__PURE__ */
|
|
2375
|
+
/* @__PURE__ */ jsxs5("div", { className: "vpg-unassigned-section", children: [
|
|
2376
|
+
/* @__PURE__ */ jsx5("div", { className: "vpg-section-header", children: /* @__PURE__ */ jsxs5("div", { className: "vpg-section-label", children: [
|
|
1862
2377
|
"Available",
|
|
1863
2378
|
" ",
|
|
1864
|
-
/* @__PURE__ */
|
|
2379
|
+
/* @__PURE__ */ jsx5("span", { className: "vpg-count", children: unassignedFields.length })
|
|
1865
2380
|
] }) }),
|
|
1866
|
-
/* @__PURE__ */
|
|
1867
|
-
/* @__PURE__ */
|
|
2381
|
+
/* @__PURE__ */ jsxs5("div", { className: "vpg-field-search", children: [
|
|
2382
|
+
/* @__PURE__ */ jsx5("svg", { className: "vpg-search-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
|
|
1868
2383
|
"path",
|
|
1869
2384
|
{
|
|
1870
2385
|
strokeLinecap: "round",
|
|
@@ -1873,7 +2388,7 @@ function PivotConfig({
|
|
|
1873
2388
|
d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
|
|
1874
2389
|
}
|
|
1875
2390
|
) }),
|
|
1876
|
-
/* @__PURE__ */
|
|
2391
|
+
/* @__PURE__ */ jsx5(
|
|
1877
2392
|
"input",
|
|
1878
2393
|
{
|
|
1879
2394
|
type: "text",
|
|
@@ -1883,7 +2398,7 @@ function PivotConfig({
|
|
|
1883
2398
|
className: "vpg-search-input"
|
|
1884
2399
|
}
|
|
1885
2400
|
),
|
|
1886
|
-
fieldSearch && /* @__PURE__ */
|
|
2401
|
+
fieldSearch && /* @__PURE__ */ jsx5("button", { className: "vpg-clear-search", onClick: () => setFieldSearch(""), children: /* @__PURE__ */ jsx5("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5(
|
|
1887
2402
|
"path",
|
|
1888
2403
|
{
|
|
1889
2404
|
strokeLinecap: "round",
|
|
@@ -1893,8 +2408,8 @@ function PivotConfig({
|
|
|
1893
2408
|
}
|
|
1894
2409
|
) }) })
|
|
1895
2410
|
] }),
|
|
1896
|
-
/* @__PURE__ */
|
|
1897
|
-
filteredUnassignedFields.map((field) => /* @__PURE__ */
|
|
2411
|
+
/* @__PURE__ */ jsxs5("div", { className: "vpg-field-list", children: [
|
|
2412
|
+
filteredUnassignedFields.map((field) => /* @__PURE__ */ jsxs5(
|
|
1898
2413
|
"div",
|
|
1899
2414
|
{
|
|
1900
2415
|
className: `vpg-field-item${field.isNumeric && !field.isCalculated ? " vpg-is-numeric" : ""}${field.isCalculated ? " vpg-is-calculated" : ""}`,
|
|
@@ -1903,10 +2418,10 @@ function PivotConfig({
|
|
|
1903
2418
|
onDragStart: (e) => handleDragStart(field.field, e),
|
|
1904
2419
|
onDragEnd,
|
|
1905
2420
|
children: [
|
|
1906
|
-
/* @__PURE__ */
|
|
1907
|
-
/* @__PURE__ */
|
|
1908
|
-
field.isCalculated ? /* @__PURE__ */
|
|
1909
|
-
/* @__PURE__ */
|
|
2421
|
+
/* @__PURE__ */ jsx5("span", { className: `vpg-field-type-icon${field.isCalculated ? " vpg-calc-type" : ""}`, title: field.type, children: getFieldIcon(field.type, field.isCalculated) }),
|
|
2422
|
+
/* @__PURE__ */ jsx5("span", { className: "vpg-field-name", children: getFieldDisplayName(field) }),
|
|
2423
|
+
field.isCalculated ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
2424
|
+
/* @__PURE__ */ jsx5(
|
|
1910
2425
|
"button",
|
|
1911
2426
|
{
|
|
1912
2427
|
className: "vpg-field-edit",
|
|
@@ -1920,7 +2435,7 @@ function PivotConfig({
|
|
|
1920
2435
|
children: "\u270E"
|
|
1921
2436
|
}
|
|
1922
2437
|
),
|
|
1923
|
-
/* @__PURE__ */
|
|
2438
|
+
/* @__PURE__ */ jsx5(
|
|
1924
2439
|
"button",
|
|
1925
2440
|
{
|
|
1926
2441
|
className: "vpg-field-delete",
|
|
@@ -1934,22 +2449,22 @@ function PivotConfig({
|
|
|
1934
2449
|
children: "\xD7"
|
|
1935
2450
|
}
|
|
1936
2451
|
)
|
|
1937
|
-
] }) : /* @__PURE__ */
|
|
2452
|
+
] }) : /* @__PURE__ */ jsx5("span", { className: "vpg-unique-count", children: field.uniqueCount })
|
|
1938
2453
|
]
|
|
1939
2454
|
},
|
|
1940
2455
|
field.field
|
|
1941
2456
|
)),
|
|
1942
|
-
filteredUnassignedFields.length === 0 && fieldSearch && /* @__PURE__ */
|
|
2457
|
+
filteredUnassignedFields.length === 0 && fieldSearch && /* @__PURE__ */ jsxs5("div", { className: "vpg-empty-hint", children: [
|
|
1943
2458
|
'No fields match "',
|
|
1944
2459
|
fieldSearch,
|
|
1945
2460
|
'"'
|
|
1946
2461
|
] }),
|
|
1947
|
-
unassignedFields.length === 0 && /* @__PURE__ */
|
|
2462
|
+
unassignedFields.length === 0 && /* @__PURE__ */ jsx5("div", { className: "vpg-empty-hint", children: "All fields assigned" })
|
|
1948
2463
|
] })
|
|
1949
2464
|
] }),
|
|
1950
|
-
/* @__PURE__ */
|
|
1951
|
-
/* @__PURE__ */
|
|
1952
|
-
/* @__PURE__ */
|
|
2465
|
+
/* @__PURE__ */ jsxs5("div", { className: "vpg-options-section", children: [
|
|
2466
|
+
/* @__PURE__ */ jsxs5("label", { className: "vpg-option-toggle", children: [
|
|
2467
|
+
/* @__PURE__ */ jsx5(
|
|
1953
2468
|
"input",
|
|
1954
2469
|
{
|
|
1955
2470
|
type: "checkbox",
|
|
@@ -1957,14 +2472,14 @@ function PivotConfig({
|
|
|
1957
2472
|
onChange: (e) => handleTotalsToggle(e.target.checked)
|
|
1958
2473
|
}
|
|
1959
2474
|
),
|
|
1960
|
-
/* @__PURE__ */
|
|
2475
|
+
/* @__PURE__ */ jsx5("span", { children: "Totals" })
|
|
1961
2476
|
] }),
|
|
1962
|
-
/* @__PURE__ */
|
|
1963
|
-
/* @__PURE__ */
|
|
1964
|
-
/* @__PURE__ */
|
|
2477
|
+
/* @__PURE__ */ jsxs5("button", { className: "vpg-calc-btn", onClick: () => openCalcModal(), title: "Add calculated field (e.g. Profit Margin %)", children: [
|
|
2478
|
+
/* @__PURE__ */ jsx5("span", { className: "vpg-calc-icon", children: "\u0192" }),
|
|
2479
|
+
/* @__PURE__ */ jsx5("span", { children: "+ Calc" })
|
|
1965
2480
|
] })
|
|
1966
2481
|
] }),
|
|
1967
|
-
/* @__PURE__ */
|
|
2482
|
+
/* @__PURE__ */ jsx5(
|
|
1968
2483
|
CalculatedFieldModal,
|
|
1969
2484
|
{
|
|
1970
2485
|
show: showCalcModal,
|
|
@@ -1979,8 +2494,8 @@ function PivotConfig({
|
|
|
1979
2494
|
|
|
1980
2495
|
// src/components/PivotSkeleton.tsx
|
|
1981
2496
|
import { getAggregationLabel as getAggregationLabel2, getAggregationSymbol as getAggregationSymbol2 } from "@smallwebco/tinypivot-core";
|
|
1982
|
-
import { useCallback as
|
|
1983
|
-
import { Fragment as
|
|
2497
|
+
import { useCallback as useCallback10, useEffect as useEffect7, useMemo as useMemo10, useState as useState10 } from "react";
|
|
2498
|
+
import { Fragment as Fragment4, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1984
2499
|
function PivotSkeleton({
|
|
1985
2500
|
rowFields,
|
|
1986
2501
|
columnFields,
|
|
@@ -2003,7 +2518,7 @@ function PivotSkeleton({
|
|
|
2003
2518
|
onReorderColumnFields
|
|
2004
2519
|
}) {
|
|
2005
2520
|
const { showWatermark, canUsePivot, isDemo } = useLicense();
|
|
2006
|
-
const getValueFieldDisplayName =
|
|
2521
|
+
const getValueFieldDisplayName = useCallback10((field) => {
|
|
2007
2522
|
if (field.startsWith("calc:")) {
|
|
2008
2523
|
const calcId = field.replace("calc:", "");
|
|
2009
2524
|
const calcField = calculatedFields?.find((c) => c.id === calcId);
|
|
@@ -2011,15 +2526,15 @@ function PivotSkeleton({
|
|
|
2011
2526
|
}
|
|
2012
2527
|
return field;
|
|
2013
2528
|
}, [calculatedFields]);
|
|
2014
|
-
const isCalculatedField =
|
|
2529
|
+
const isCalculatedField = useCallback10((field) => {
|
|
2015
2530
|
return field.startsWith("calc:");
|
|
2016
2531
|
}, []);
|
|
2017
|
-
const [dragOverArea, setDragOverArea] =
|
|
2018
|
-
const [reorderDragSource, setReorderDragSource] =
|
|
2019
|
-
const [reorderDropTarget, setReorderDropTarget] =
|
|
2020
|
-
const [sortDirection, setSortDirection] =
|
|
2021
|
-
const [sortTarget, setSortTarget] =
|
|
2022
|
-
const toggleSort =
|
|
2532
|
+
const [dragOverArea, setDragOverArea] = useState10(null);
|
|
2533
|
+
const [reorderDragSource, setReorderDragSource] = useState10(null);
|
|
2534
|
+
const [reorderDropTarget, setReorderDropTarget] = useState10(null);
|
|
2535
|
+
const [sortDirection, setSortDirection] = useState10("asc");
|
|
2536
|
+
const [sortTarget, setSortTarget] = useState10("row");
|
|
2537
|
+
const toggleSort = useCallback10((target = "row") => {
|
|
2023
2538
|
if (sortTarget === target) {
|
|
2024
2539
|
setSortDirection((prev) => prev === "asc" ? "desc" : "asc");
|
|
2025
2540
|
} else {
|
|
@@ -2027,13 +2542,13 @@ function PivotSkeleton({
|
|
|
2027
2542
|
setSortDirection("asc");
|
|
2028
2543
|
}
|
|
2029
2544
|
}, [sortTarget]);
|
|
2030
|
-
const [selectedCell, setSelectedCell] =
|
|
2031
|
-
const [selectionStart, setSelectionStart] =
|
|
2032
|
-
const [selectionEnd, setSelectionEnd] =
|
|
2033
|
-
const [isSelecting, setIsSelecting] =
|
|
2034
|
-
const [showCopyToast, setShowCopyToast] =
|
|
2035
|
-
const [copyToastMessage, setCopyToastMessage] =
|
|
2036
|
-
const selectionBounds =
|
|
2545
|
+
const [selectedCell, setSelectedCell] = useState10(null);
|
|
2546
|
+
const [selectionStart, setSelectionStart] = useState10(null);
|
|
2547
|
+
const [selectionEnd, setSelectionEnd] = useState10(null);
|
|
2548
|
+
const [isSelecting, setIsSelecting] = useState10(false);
|
|
2549
|
+
const [showCopyToast, setShowCopyToast] = useState10(false);
|
|
2550
|
+
const [copyToastMessage, setCopyToastMessage] = useState10("");
|
|
2551
|
+
const selectionBounds = useMemo10(() => {
|
|
2037
2552
|
if (!selectionStart || !selectionEnd)
|
|
2038
2553
|
return null;
|
|
2039
2554
|
return {
|
|
@@ -2043,7 +2558,7 @@ function PivotSkeleton({
|
|
|
2043
2558
|
maxCol: Math.max(selectionStart.col, selectionEnd.col)
|
|
2044
2559
|
};
|
|
2045
2560
|
}, [selectionStart, selectionEnd]);
|
|
2046
|
-
const handleCellMouseDown =
|
|
2561
|
+
const handleCellMouseDown = useCallback10(
|
|
2047
2562
|
(rowIndex, colIndex, event) => {
|
|
2048
2563
|
event.preventDefault();
|
|
2049
2564
|
if (event.shiftKey && selectedCell) {
|
|
@@ -2057,7 +2572,7 @@ function PivotSkeleton({
|
|
|
2057
2572
|
},
|
|
2058
2573
|
[selectedCell]
|
|
2059
2574
|
);
|
|
2060
|
-
const handleCellMouseEnter =
|
|
2575
|
+
const handleCellMouseEnter = useCallback10(
|
|
2061
2576
|
(rowIndex, colIndex) => {
|
|
2062
2577
|
if (isSelecting) {
|
|
2063
2578
|
setSelectionEnd({ row: rowIndex, col: colIndex });
|
|
@@ -2065,7 +2580,7 @@ function PivotSkeleton({
|
|
|
2065
2580
|
},
|
|
2066
2581
|
[isSelecting]
|
|
2067
2582
|
);
|
|
2068
|
-
const isCellSelected =
|
|
2583
|
+
const isCellSelected = useCallback10(
|
|
2069
2584
|
(rowIndex, colIndex) => {
|
|
2070
2585
|
if (!selectionBounds) {
|
|
2071
2586
|
return selectedCell?.row === rowIndex && selectedCell?.col === colIndex;
|
|
@@ -2075,12 +2590,12 @@ function PivotSkeleton({
|
|
|
2075
2590
|
},
|
|
2076
2591
|
[selectionBounds, selectedCell]
|
|
2077
2592
|
);
|
|
2078
|
-
|
|
2593
|
+
useEffect7(() => {
|
|
2079
2594
|
const handleMouseUp = () => setIsSelecting(false);
|
|
2080
2595
|
document.addEventListener("mouseup", handleMouseUp);
|
|
2081
2596
|
return () => document.removeEventListener("mouseup", handleMouseUp);
|
|
2082
2597
|
}, []);
|
|
2083
|
-
const sortedRowIndices =
|
|
2598
|
+
const sortedRowIndices = useMemo10(() => {
|
|
2084
2599
|
if (!pivotResult)
|
|
2085
2600
|
return [];
|
|
2086
2601
|
const indices = pivotResult.rowHeaders.map((_, i) => i);
|
|
@@ -2108,7 +2623,7 @@ function PivotSkeleton({
|
|
|
2108
2623
|
});
|
|
2109
2624
|
return indices;
|
|
2110
2625
|
}, [pivotResult, sortTarget, sortDirection]);
|
|
2111
|
-
const copySelectionToClipboard =
|
|
2626
|
+
const copySelectionToClipboard = useCallback10(() => {
|
|
2112
2627
|
if (!selectionBounds || !pivotResult)
|
|
2113
2628
|
return;
|
|
2114
2629
|
const { minRow, maxRow, minCol, maxCol } = selectionBounds;
|
|
@@ -2134,7 +2649,7 @@ function PivotSkeleton({
|
|
|
2134
2649
|
console.error("Copy failed:", err);
|
|
2135
2650
|
});
|
|
2136
2651
|
}, [selectionBounds, pivotResult, sortedRowIndices]);
|
|
2137
|
-
|
|
2652
|
+
useEffect7(() => {
|
|
2138
2653
|
const handleKeydown = (event) => {
|
|
2139
2654
|
if (!selectionBounds)
|
|
2140
2655
|
return;
|
|
@@ -2152,7 +2667,7 @@ function PivotSkeleton({
|
|
|
2152
2667
|
document.addEventListener("keydown", handleKeydown);
|
|
2153
2668
|
return () => document.removeEventListener("keydown", handleKeydown);
|
|
2154
2669
|
}, [selectionBounds, copySelectionToClipboard]);
|
|
2155
|
-
const selectionStats =
|
|
2670
|
+
const selectionStats = useMemo10(() => {
|
|
2156
2671
|
if (!selectionBounds || !pivotResult)
|
|
2157
2672
|
return null;
|
|
2158
2673
|
const { minRow, maxRow, minCol, maxCol } = selectionBounds;
|
|
@@ -2181,14 +2696,14 @@ function PivotSkeleton({
|
|
|
2181
2696
|
avg
|
|
2182
2697
|
};
|
|
2183
2698
|
}, [selectionBounds, pivotResult, sortedRowIndices]);
|
|
2184
|
-
const formatStatValue =
|
|
2699
|
+
const formatStatValue = useCallback10((val) => {
|
|
2185
2700
|
if (Math.abs(val) >= 1e6)
|
|
2186
2701
|
return `${(val / 1e6).toFixed(2)}M`;
|
|
2187
2702
|
if (Math.abs(val) >= 1e3)
|
|
2188
2703
|
return `${(val / 1e3).toFixed(2)}K`;
|
|
2189
2704
|
return val.toFixed(2);
|
|
2190
2705
|
}, []);
|
|
2191
|
-
const columnHeaderCells =
|
|
2706
|
+
const columnHeaderCells = useMemo10(() => {
|
|
2192
2707
|
if (!pivotResult || pivotResult.headers.length === 0) {
|
|
2193
2708
|
return [
|
|
2194
2709
|
valueFields.map((vf) => ({
|
|
@@ -2216,13 +2731,13 @@ function PivotSkeleton({
|
|
|
2216
2731
|
return result;
|
|
2217
2732
|
}, [pivotResult, valueFields]);
|
|
2218
2733
|
const hasActiveFilters = activeFilters && activeFilters.length > 0;
|
|
2219
|
-
const filterSummary =
|
|
2734
|
+
const filterSummary = useMemo10(() => {
|
|
2220
2735
|
if (!activeFilters || activeFilters.length === 0)
|
|
2221
2736
|
return "";
|
|
2222
2737
|
return activeFilters.map((f) => f.column).join(", ");
|
|
2223
2738
|
}, [activeFilters]);
|
|
2224
|
-
const [showFilterTooltip, setShowFilterTooltip] =
|
|
2225
|
-
const filterTooltipDetails =
|
|
2739
|
+
const [showFilterTooltip, setShowFilterTooltip] = useState10(false);
|
|
2740
|
+
const filterTooltipDetails = useMemo10(() => {
|
|
2226
2741
|
if (!activeFilters || activeFilters.length === 0)
|
|
2227
2742
|
return [];
|
|
2228
2743
|
return activeFilters.map((f) => {
|
|
@@ -2247,7 +2762,7 @@ function PivotSkeleton({
|
|
|
2247
2762
|
};
|
|
2248
2763
|
});
|
|
2249
2764
|
}, [activeFilters]);
|
|
2250
|
-
const handleDragOver =
|
|
2765
|
+
const handleDragOver = useCallback10(
|
|
2251
2766
|
(area, event) => {
|
|
2252
2767
|
event.preventDefault();
|
|
2253
2768
|
event.dataTransfer.dropEffect = "move";
|
|
@@ -2255,10 +2770,10 @@ function PivotSkeleton({
|
|
|
2255
2770
|
},
|
|
2256
2771
|
[]
|
|
2257
2772
|
);
|
|
2258
|
-
const handleDragLeave =
|
|
2773
|
+
const handleDragLeave = useCallback10(() => {
|
|
2259
2774
|
setDragOverArea(null);
|
|
2260
2775
|
}, []);
|
|
2261
|
-
const handleDrop =
|
|
2776
|
+
const handleDrop = useCallback10(
|
|
2262
2777
|
(area, event) => {
|
|
2263
2778
|
event.preventDefault();
|
|
2264
2779
|
const field = event.dataTransfer?.getData("text/plain");
|
|
@@ -2288,7 +2803,7 @@ function PivotSkeleton({
|
|
|
2288
2803
|
},
|
|
2289
2804
|
[rowFields, columnFields, valueFields, onAddRowField, onRemoveRowField, onAddColumnField, onRemoveColumnField, onAddValueField, onRemoveValueField]
|
|
2290
2805
|
);
|
|
2291
|
-
const handleChipDragStart =
|
|
2806
|
+
const handleChipDragStart = useCallback10(
|
|
2292
2807
|
(zone, index, event) => {
|
|
2293
2808
|
setReorderDragSource({ zone, index });
|
|
2294
2809
|
event.dataTransfer.effectAllowed = "move";
|
|
@@ -2299,11 +2814,11 @@ function PivotSkeleton({
|
|
|
2299
2814
|
},
|
|
2300
2815
|
[]
|
|
2301
2816
|
);
|
|
2302
|
-
const handleChipDragEnd =
|
|
2817
|
+
const handleChipDragEnd = useCallback10(() => {
|
|
2303
2818
|
setReorderDragSource(null);
|
|
2304
2819
|
setReorderDropTarget(null);
|
|
2305
2820
|
}, []);
|
|
2306
|
-
const handleChipDragOver =
|
|
2821
|
+
const handleChipDragOver = useCallback10(
|
|
2307
2822
|
(zone, index, event) => {
|
|
2308
2823
|
event.preventDefault();
|
|
2309
2824
|
if (reorderDragSource && reorderDragSource.zone === zone) {
|
|
@@ -2313,10 +2828,10 @@ function PivotSkeleton({
|
|
|
2313
2828
|
},
|
|
2314
2829
|
[reorderDragSource]
|
|
2315
2830
|
);
|
|
2316
|
-
const handleChipDragLeave =
|
|
2831
|
+
const handleChipDragLeave = useCallback10(() => {
|
|
2317
2832
|
setReorderDropTarget(null);
|
|
2318
2833
|
}, []);
|
|
2319
|
-
const handleChipDrop =
|
|
2834
|
+
const handleChipDrop = useCallback10(
|
|
2320
2835
|
(zone, targetIndex, event) => {
|
|
2321
2836
|
event.preventDefault();
|
|
2322
2837
|
event.stopPropagation();
|
|
@@ -2342,13 +2857,13 @@ function PivotSkeleton({
|
|
|
2342
2857
|
},
|
|
2343
2858
|
[reorderDragSource, rowFields, columnFields, onReorderRowFields, onReorderColumnFields]
|
|
2344
2859
|
);
|
|
2345
|
-
const isChipDragSource =
|
|
2860
|
+
const isChipDragSource = useCallback10(
|
|
2346
2861
|
(zone, index) => {
|
|
2347
2862
|
return reorderDragSource?.zone === zone && reorderDragSource?.index === index;
|
|
2348
2863
|
},
|
|
2349
2864
|
[reorderDragSource]
|
|
2350
2865
|
);
|
|
2351
|
-
const isChipDropTarget =
|
|
2866
|
+
const isChipDropTarget = useCallback10(
|
|
2352
2867
|
(zone, index) => {
|
|
2353
2868
|
return reorderDropTarget?.zone === zone && reorderDropTarget?.index === index;
|
|
2354
2869
|
},
|
|
@@ -2356,25 +2871,25 @@ function PivotSkeleton({
|
|
|
2356
2871
|
);
|
|
2357
2872
|
const currentFontSize = fontSize;
|
|
2358
2873
|
const rowHeaderWidth = 180;
|
|
2359
|
-
const rowHeaderColWidth =
|
|
2874
|
+
const rowHeaderColWidth = useMemo10(() => {
|
|
2360
2875
|
const numCols = Math.max(rowFields.length, 1);
|
|
2361
2876
|
return Math.max(rowHeaderWidth / numCols, 80);
|
|
2362
2877
|
}, [rowFields.length]);
|
|
2363
|
-
const getRowHeaderLeftOffset =
|
|
2878
|
+
const getRowHeaderLeftOffset = useCallback10((fieldIdx) => {
|
|
2364
2879
|
return fieldIdx * rowHeaderColWidth;
|
|
2365
2880
|
}, [rowHeaderColWidth]);
|
|
2366
|
-
return /* @__PURE__ */
|
|
2881
|
+
return /* @__PURE__ */ jsxs6(
|
|
2367
2882
|
"div",
|
|
2368
2883
|
{
|
|
2369
2884
|
className: `vpg-pivot-skeleton vpg-font-${currentFontSize} ${draggingField ? "vpg-is-dragging" : ""}`,
|
|
2370
2885
|
children: [
|
|
2371
|
-
showCopyToast && /* @__PURE__ */
|
|
2372
|
-
/* @__PURE__ */
|
|
2886
|
+
showCopyToast && /* @__PURE__ */ jsxs6("div", { className: "vpg-toast", children: [
|
|
2887
|
+
/* @__PURE__ */ jsx6("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }),
|
|
2373
2888
|
copyToastMessage
|
|
2374
2889
|
] }),
|
|
2375
|
-
/* @__PURE__ */
|
|
2376
|
-
/* @__PURE__ */
|
|
2377
|
-
/* @__PURE__ */
|
|
2890
|
+
/* @__PURE__ */ jsxs6("div", { className: "vpg-skeleton-header", children: [
|
|
2891
|
+
/* @__PURE__ */ jsxs6("div", { className: "vpg-skeleton-title", children: [
|
|
2892
|
+
/* @__PURE__ */ jsx6("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6(
|
|
2378
2893
|
"path",
|
|
2379
2894
|
{
|
|
2380
2895
|
strokeLinecap: "round",
|
|
@@ -2383,24 +2898,24 @@ function PivotSkeleton({
|
|
|
2383
2898
|
d: "M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z"
|
|
2384
2899
|
}
|
|
2385
2900
|
) }),
|
|
2386
|
-
/* @__PURE__ */
|
|
2901
|
+
/* @__PURE__ */ jsx6("span", { children: "Pivot Table" })
|
|
2387
2902
|
] }),
|
|
2388
|
-
/* @__PURE__ */
|
|
2389
|
-
hasActiveFilters && /* @__PURE__ */
|
|
2903
|
+
/* @__PURE__ */ jsxs6("div", { className: "vpg-header-right", children: [
|
|
2904
|
+
hasActiveFilters && /* @__PURE__ */ jsxs6(
|
|
2390
2905
|
"div",
|
|
2391
2906
|
{
|
|
2392
2907
|
className: "vpg-filter-indicator",
|
|
2393
2908
|
onMouseEnter: () => setShowFilterTooltip(true),
|
|
2394
2909
|
onMouseLeave: () => setShowFilterTooltip(false),
|
|
2395
2910
|
children: [
|
|
2396
|
-
/* @__PURE__ */
|
|
2911
|
+
/* @__PURE__ */ jsx6(
|
|
2397
2912
|
"svg",
|
|
2398
2913
|
{
|
|
2399
2914
|
className: "vpg-filter-icon",
|
|
2400
2915
|
fill: "none",
|
|
2401
2916
|
stroke: "currentColor",
|
|
2402
2917
|
viewBox: "0 0 24 24",
|
|
2403
|
-
children: /* @__PURE__ */
|
|
2918
|
+
children: /* @__PURE__ */ jsx6(
|
|
2404
2919
|
"path",
|
|
2405
2920
|
{
|
|
2406
2921
|
strokeLinecap: "round",
|
|
@@ -2411,11 +2926,11 @@ function PivotSkeleton({
|
|
|
2411
2926
|
)
|
|
2412
2927
|
}
|
|
2413
2928
|
),
|
|
2414
|
-
/* @__PURE__ */
|
|
2929
|
+
/* @__PURE__ */ jsxs6("span", { className: "vpg-filter-text", children: [
|
|
2415
2930
|
"Filtered:",
|
|
2416
2931
|
" ",
|
|
2417
|
-
/* @__PURE__ */
|
|
2418
|
-
filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */
|
|
2932
|
+
/* @__PURE__ */ jsx6("strong", { children: filterSummary }),
|
|
2933
|
+
filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ jsxs6("span", { className: "vpg-filter-count", children: [
|
|
2419
2934
|
"(",
|
|
2420
2935
|
filteredRowCount.toLocaleString(),
|
|
2421
2936
|
" ",
|
|
@@ -2426,13 +2941,13 @@ function PivotSkeleton({
|
|
|
2426
2941
|
"rows)"
|
|
2427
2942
|
] })
|
|
2428
2943
|
] }),
|
|
2429
|
-
showFilterTooltip && /* @__PURE__ */
|
|
2430
|
-
/* @__PURE__ */
|
|
2431
|
-
filterTooltipDetails.map((filter) => /* @__PURE__ */
|
|
2432
|
-
/* @__PURE__ */
|
|
2433
|
-
/* @__PURE__ */
|
|
2434
|
-
filter.values.map((val, idx) => /* @__PURE__ */
|
|
2435
|
-
filter.remaining > 0 && /* @__PURE__ */
|
|
2944
|
+
showFilterTooltip && /* @__PURE__ */ jsxs6("div", { className: "vpg-filter-tooltip", children: [
|
|
2945
|
+
/* @__PURE__ */ jsx6("div", { className: "vpg-tooltip-header", children: "Active Filters" }),
|
|
2946
|
+
filterTooltipDetails.map((filter) => /* @__PURE__ */ jsxs6("div", { className: "vpg-tooltip-filter", children: [
|
|
2947
|
+
/* @__PURE__ */ jsx6("div", { className: "vpg-tooltip-column", children: filter.column }),
|
|
2948
|
+
/* @__PURE__ */ jsx6("div", { className: "vpg-tooltip-values", children: filter.isRange ? /* @__PURE__ */ jsx6("span", { className: "vpg-tooltip-value vpg-range-value", children: filter.displayText }) : /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
2949
|
+
filter.values.map((val, idx) => /* @__PURE__ */ jsx6("span", { className: "vpg-tooltip-value", children: val }, idx)),
|
|
2950
|
+
filter.remaining > 0 && /* @__PURE__ */ jsxs6("span", { className: "vpg-tooltip-more", children: [
|
|
2436
2951
|
"+",
|
|
2437
2952
|
filter.remaining,
|
|
2438
2953
|
" ",
|
|
@@ -2440,7 +2955,7 @@ function PivotSkeleton({
|
|
|
2440
2955
|
] })
|
|
2441
2956
|
] }) })
|
|
2442
2957
|
] }, filter.column)),
|
|
2443
|
-
filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */
|
|
2958
|
+
filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ jsxs6("div", { className: "vpg-tooltip-summary", children: [
|
|
2444
2959
|
"Showing",
|
|
2445
2960
|
" ",
|
|
2446
2961
|
filteredRowCount.toLocaleString(),
|
|
@@ -2455,20 +2970,20 @@ function PivotSkeleton({
|
|
|
2455
2970
|
]
|
|
2456
2971
|
}
|
|
2457
2972
|
),
|
|
2458
|
-
isConfigured && /* @__PURE__ */
|
|
2459
|
-
/* @__PURE__ */
|
|
2973
|
+
isConfigured && /* @__PURE__ */ jsxs6("div", { className: "vpg-config-summary", children: [
|
|
2974
|
+
/* @__PURE__ */ jsxs6("span", { className: "vpg-summary-badge vpg-rows", children: [
|
|
2460
2975
|
rowFields.length,
|
|
2461
2976
|
" ",
|
|
2462
2977
|
"row",
|
|
2463
2978
|
rowFields.length !== 1 ? "s" : ""
|
|
2464
2979
|
] }),
|
|
2465
|
-
/* @__PURE__ */
|
|
2980
|
+
/* @__PURE__ */ jsxs6("span", { className: "vpg-summary-badge vpg-cols", children: [
|
|
2466
2981
|
columnFields.length,
|
|
2467
2982
|
" ",
|
|
2468
2983
|
"col",
|
|
2469
2984
|
columnFields.length !== 1 ? "s" : ""
|
|
2470
2985
|
] }),
|
|
2471
|
-
/* @__PURE__ */
|
|
2986
|
+
/* @__PURE__ */ jsxs6("span", { className: "vpg-summary-badge vpg-vals", children: [
|
|
2472
2987
|
valueFields.length,
|
|
2473
2988
|
" ",
|
|
2474
2989
|
"val",
|
|
@@ -2477,8 +2992,8 @@ function PivotSkeleton({
|
|
|
2477
2992
|
] })
|
|
2478
2993
|
] })
|
|
2479
2994
|
] }),
|
|
2480
|
-
!canUsePivot ? /* @__PURE__ */
|
|
2481
|
-
/* @__PURE__ */
|
|
2995
|
+
!canUsePivot ? /* @__PURE__ */ jsx6("div", { className: "vpg-pro-required", children: /* @__PURE__ */ jsxs6("div", { className: "vpg-pro-content", children: [
|
|
2996
|
+
/* @__PURE__ */ jsx6("svg", { className: "vpg-pro-icon", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx6(
|
|
2482
2997
|
"path",
|
|
2483
2998
|
{
|
|
2484
2999
|
strokeLinecap: "round",
|
|
@@ -2487,12 +3002,12 @@ function PivotSkeleton({
|
|
|
2487
3002
|
d: "M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
|
|
2488
3003
|
}
|
|
2489
3004
|
) }),
|
|
2490
|
-
/* @__PURE__ */
|
|
2491
|
-
/* @__PURE__ */
|
|
2492
|
-
/* @__PURE__ */
|
|
2493
|
-
] }) }) : /* @__PURE__ */
|
|
2494
|
-
/* @__PURE__ */
|
|
2495
|
-
/* @__PURE__ */
|
|
3005
|
+
/* @__PURE__ */ jsx6("h3", { children: "Pro Feature" }),
|
|
3006
|
+
/* @__PURE__ */ jsx6("p", { children: "Pivot Table functionality requires a Pro license." }),
|
|
3007
|
+
/* @__PURE__ */ jsx6("a", { href: "https://tiny-pivot.com/#pricing", target: "_blank", rel: "noopener noreferrer", className: "vpg-pro-link", children: "Get Pro License \u2192" })
|
|
3008
|
+
] }) }) : /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
3009
|
+
/* @__PURE__ */ jsxs6("div", { className: "vpg-config-bar", children: [
|
|
3010
|
+
/* @__PURE__ */ jsxs6(
|
|
2496
3011
|
"div",
|
|
2497
3012
|
{
|
|
2498
3013
|
className: `vpg-drop-zone vpg-row-zone ${dragOverArea === "row" ? "vpg-drag-over" : ""}`,
|
|
@@ -2500,12 +3015,12 @@ function PivotSkeleton({
|
|
|
2500
3015
|
onDragLeave: handleDragLeave,
|
|
2501
3016
|
onDrop: (e) => handleDrop("row", e),
|
|
2502
3017
|
children: [
|
|
2503
|
-
/* @__PURE__ */
|
|
2504
|
-
/* @__PURE__ */
|
|
2505
|
-
/* @__PURE__ */
|
|
3018
|
+
/* @__PURE__ */ jsxs6("div", { className: "vpg-zone-header", children: [
|
|
3019
|
+
/* @__PURE__ */ jsx6("span", { className: "vpg-zone-icon vpg-row-icon", children: "\u2193" }),
|
|
3020
|
+
/* @__PURE__ */ jsx6("span", { className: "vpg-zone-label", children: "Rows" })
|
|
2506
3021
|
] }),
|
|
2507
|
-
/* @__PURE__ */
|
|
2508
|
-
rowFields.map((field, idx) => /* @__PURE__ */
|
|
3022
|
+
/* @__PURE__ */ jsxs6("div", { className: "vpg-zone-chips", children: [
|
|
3023
|
+
rowFields.map((field, idx) => /* @__PURE__ */ jsxs6(
|
|
2509
3024
|
"div",
|
|
2510
3025
|
{
|
|
2511
3026
|
className: `vpg-mini-chip vpg-row-chip ${isChipDragSource("row", idx) ? "vpg-chip-dragging" : ""} ${isChipDropTarget("row", idx) ? "vpg-chip-drop-target" : ""}`,
|
|
@@ -2516,9 +3031,9 @@ function PivotSkeleton({
|
|
|
2516
3031
|
onDragLeave: handleChipDragLeave,
|
|
2517
3032
|
onDrop: (e) => handleChipDrop("row", idx, e),
|
|
2518
3033
|
children: [
|
|
2519
|
-
/* @__PURE__ */
|
|
2520
|
-
/* @__PURE__ */
|
|
2521
|
-
/* @__PURE__ */
|
|
3034
|
+
/* @__PURE__ */ jsx6("span", { className: "vpg-drag-handle", children: "\u22EE\u22EE" }),
|
|
3035
|
+
/* @__PURE__ */ jsx6("span", { className: "vpg-mini-name", children: field }),
|
|
3036
|
+
/* @__PURE__ */ jsx6(
|
|
2522
3037
|
"button",
|
|
2523
3038
|
{
|
|
2524
3039
|
className: "vpg-mini-remove",
|
|
@@ -2533,12 +3048,12 @@ function PivotSkeleton({
|
|
|
2533
3048
|
},
|
|
2534
3049
|
field
|
|
2535
3050
|
)),
|
|
2536
|
-
rowFields.length === 0 && /* @__PURE__ */
|
|
3051
|
+
rowFields.length === 0 && /* @__PURE__ */ jsx6("span", { className: "vpg-zone-hint", children: "Drop here" })
|
|
2537
3052
|
] })
|
|
2538
3053
|
]
|
|
2539
3054
|
}
|
|
2540
3055
|
),
|
|
2541
|
-
/* @__PURE__ */
|
|
3056
|
+
/* @__PURE__ */ jsxs6(
|
|
2542
3057
|
"div",
|
|
2543
3058
|
{
|
|
2544
3059
|
className: `vpg-drop-zone vpg-column-zone ${dragOverArea === "column" ? "vpg-drag-over" : ""}`,
|
|
@@ -2546,12 +3061,12 @@ function PivotSkeleton({
|
|
|
2546
3061
|
onDragLeave: handleDragLeave,
|
|
2547
3062
|
onDrop: (e) => handleDrop("column", e),
|
|
2548
3063
|
children: [
|
|
2549
|
-
/* @__PURE__ */
|
|
2550
|
-
/* @__PURE__ */
|
|
2551
|
-
/* @__PURE__ */
|
|
3064
|
+
/* @__PURE__ */ jsxs6("div", { className: "vpg-zone-header", children: [
|
|
3065
|
+
/* @__PURE__ */ jsx6("span", { className: "vpg-zone-icon vpg-column-icon", children: "\u2192" }),
|
|
3066
|
+
/* @__PURE__ */ jsx6("span", { className: "vpg-zone-label", children: "Columns" })
|
|
2552
3067
|
] }),
|
|
2553
|
-
/* @__PURE__ */
|
|
2554
|
-
columnFields.map((field, idx) => /* @__PURE__ */
|
|
3068
|
+
/* @__PURE__ */ jsxs6("div", { className: "vpg-zone-chips", children: [
|
|
3069
|
+
columnFields.map((field, idx) => /* @__PURE__ */ jsxs6(
|
|
2555
3070
|
"div",
|
|
2556
3071
|
{
|
|
2557
3072
|
className: `vpg-mini-chip vpg-column-chip ${isChipDragSource("column", idx) ? "vpg-chip-dragging" : ""} ${isChipDropTarget("column", idx) ? "vpg-chip-drop-target" : ""}`,
|
|
@@ -2562,9 +3077,9 @@ function PivotSkeleton({
|
|
|
2562
3077
|
onDragLeave: handleChipDragLeave,
|
|
2563
3078
|
onDrop: (e) => handleChipDrop("column", idx, e),
|
|
2564
3079
|
children: [
|
|
2565
|
-
/* @__PURE__ */
|
|
2566
|
-
/* @__PURE__ */
|
|
2567
|
-
/* @__PURE__ */
|
|
3080
|
+
/* @__PURE__ */ jsx6("span", { className: "vpg-drag-handle", children: "\u22EE\u22EE" }),
|
|
3081
|
+
/* @__PURE__ */ jsx6("span", { className: "vpg-mini-name", children: field }),
|
|
3082
|
+
/* @__PURE__ */ jsx6(
|
|
2568
3083
|
"button",
|
|
2569
3084
|
{
|
|
2570
3085
|
className: "vpg-mini-remove",
|
|
@@ -2579,12 +3094,12 @@ function PivotSkeleton({
|
|
|
2579
3094
|
},
|
|
2580
3095
|
field
|
|
2581
3096
|
)),
|
|
2582
|
-
columnFields.length === 0 && /* @__PURE__ */
|
|
3097
|
+
columnFields.length === 0 && /* @__PURE__ */ jsx6("span", { className: "vpg-zone-hint", children: "Drop here" })
|
|
2583
3098
|
] })
|
|
2584
3099
|
]
|
|
2585
3100
|
}
|
|
2586
3101
|
),
|
|
2587
|
-
/* @__PURE__ */
|
|
3102
|
+
/* @__PURE__ */ jsxs6(
|
|
2588
3103
|
"div",
|
|
2589
3104
|
{
|
|
2590
3105
|
className: `vpg-drop-zone vpg-value-zone ${dragOverArea === "value" ? "vpg-drag-over" : ""}`,
|
|
@@ -2592,19 +3107,19 @@ function PivotSkeleton({
|
|
|
2592
3107
|
onDragLeave: handleDragLeave,
|
|
2593
3108
|
onDrop: (e) => handleDrop("value", e),
|
|
2594
3109
|
children: [
|
|
2595
|
-
/* @__PURE__ */
|
|
2596
|
-
/* @__PURE__ */
|
|
2597
|
-
/* @__PURE__ */
|
|
3110
|
+
/* @__PURE__ */ jsxs6("div", { className: "vpg-zone-header", children: [
|
|
3111
|
+
/* @__PURE__ */ jsx6("span", { className: "vpg-zone-icon vpg-value-icon", children: "\u03A3" }),
|
|
3112
|
+
/* @__PURE__ */ jsx6("span", { className: "vpg-zone-label", children: "Values" })
|
|
2598
3113
|
] }),
|
|
2599
|
-
/* @__PURE__ */
|
|
2600
|
-
valueFields.map((vf) => /* @__PURE__ */
|
|
3114
|
+
/* @__PURE__ */ jsxs6("div", { className: "vpg-zone-chips", children: [
|
|
3115
|
+
valueFields.map((vf) => /* @__PURE__ */ jsxs6(
|
|
2601
3116
|
"div",
|
|
2602
3117
|
{
|
|
2603
3118
|
className: `vpg-mini-chip vpg-value-chip${isCalculatedField(vf.field) ? " vpg-calc-chip" : ""}`,
|
|
2604
3119
|
children: [
|
|
2605
|
-
/* @__PURE__ */
|
|
2606
|
-
/* @__PURE__ */
|
|
2607
|
-
/* @__PURE__ */
|
|
3120
|
+
/* @__PURE__ */ jsx6("span", { className: "vpg-agg-symbol", children: isCalculatedField(vf.field) ? "\u0192" : getAggregationSymbol2(vf.aggregation) }),
|
|
3121
|
+
/* @__PURE__ */ jsx6("span", { className: "vpg-mini-name", children: getValueFieldDisplayName(vf.field) }),
|
|
3122
|
+
/* @__PURE__ */ jsx6(
|
|
2608
3123
|
"button",
|
|
2609
3124
|
{
|
|
2610
3125
|
className: "vpg-mini-remove",
|
|
@@ -2616,21 +3131,21 @@ function PivotSkeleton({
|
|
|
2616
3131
|
},
|
|
2617
3132
|
`${vf.field}-${vf.aggregation}`
|
|
2618
3133
|
)),
|
|
2619
|
-
valueFields.length === 0 && /* @__PURE__ */
|
|
3134
|
+
valueFields.length === 0 && /* @__PURE__ */ jsx6("span", { className: "vpg-zone-hint", children: "Drop numeric" })
|
|
2620
3135
|
] })
|
|
2621
3136
|
]
|
|
2622
3137
|
}
|
|
2623
3138
|
)
|
|
2624
3139
|
] }),
|
|
2625
|
-
(!isConfigured || !pivotResult) && /* @__PURE__ */
|
|
2626
|
-
/* @__PURE__ */
|
|
3140
|
+
(!isConfigured || !pivotResult) && /* @__PURE__ */ jsx6("div", { className: "vpg-placeholder", children: /* @__PURE__ */ jsxs6("div", { className: "vpg-placeholder-content", children: [
|
|
3141
|
+
/* @__PURE__ */ jsx6(
|
|
2627
3142
|
"svg",
|
|
2628
3143
|
{
|
|
2629
3144
|
className: "vpg-placeholder-icon",
|
|
2630
3145
|
fill: "none",
|
|
2631
3146
|
viewBox: "0 0 24 24",
|
|
2632
3147
|
stroke: "currentColor",
|
|
2633
|
-
children: /* @__PURE__ */
|
|
3148
|
+
children: /* @__PURE__ */ jsx6(
|
|
2634
3149
|
"path",
|
|
2635
3150
|
{
|
|
2636
3151
|
strokeLinecap: "round",
|
|
@@ -2641,58 +3156,58 @@ function PivotSkeleton({
|
|
|
2641
3156
|
)
|
|
2642
3157
|
}
|
|
2643
3158
|
),
|
|
2644
|
-
/* @__PURE__ */
|
|
3159
|
+
/* @__PURE__ */ jsx6("span", { className: "vpg-placeholder-text", children: valueFields.length === 0 ? /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
2645
3160
|
"Add a",
|
|
2646
3161
|
" ",
|
|
2647
|
-
/* @__PURE__ */
|
|
3162
|
+
/* @__PURE__ */ jsx6("strong", { children: "Values" }),
|
|
2648
3163
|
" ",
|
|
2649
3164
|
"field to see your pivot table"
|
|
2650
|
-
] }) : rowFields.length === 0 && columnFields.length === 0 ? /* @__PURE__ */
|
|
3165
|
+
] }) : rowFields.length === 0 && columnFields.length === 0 ? /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
2651
3166
|
"Add",
|
|
2652
3167
|
" ",
|
|
2653
|
-
/* @__PURE__ */
|
|
3168
|
+
/* @__PURE__ */ jsx6("strong", { children: "Row" }),
|
|
2654
3169
|
" ",
|
|
2655
3170
|
"or",
|
|
2656
3171
|
" ",
|
|
2657
|
-
/* @__PURE__ */
|
|
3172
|
+
/* @__PURE__ */ jsx6("strong", { children: "Column" }),
|
|
2658
3173
|
" ",
|
|
2659
3174
|
"fields to group your data"
|
|
2660
3175
|
] }) : "Your pivot table will appear here" })
|
|
2661
3176
|
] }) }),
|
|
2662
|
-
isConfigured && pivotResult && /* @__PURE__ */
|
|
2663
|
-
/* @__PURE__ */
|
|
2664
|
-
levelIdx === 0 && (rowFields.length > 0 ? rowFields : ["Rows"]).map((field, fieldIdx) => /* @__PURE__ */
|
|
3177
|
+
isConfigured && pivotResult && /* @__PURE__ */ jsx6("div", { className: "vpg-table-container", children: /* @__PURE__ */ jsxs6("table", { className: "vpg-pivot-table", children: [
|
|
3178
|
+
/* @__PURE__ */ jsx6("thead", { children: columnHeaderCells.map((headerRow, levelIdx) => /* @__PURE__ */ jsxs6("tr", { className: "vpg-column-header-row", children: [
|
|
3179
|
+
levelIdx === 0 && (rowFields.length > 0 ? rowFields : ["Rows"]).map((field, fieldIdx) => /* @__PURE__ */ jsx6(
|
|
2665
3180
|
"th",
|
|
2666
3181
|
{
|
|
2667
3182
|
className: "vpg-row-header-label",
|
|
2668
3183
|
rowSpan: columnHeaderCells.length,
|
|
2669
3184
|
style: { width: `${rowHeaderColWidth}px`, minWidth: "80px", left: `${getRowHeaderLeftOffset(fieldIdx)}px` },
|
|
2670
3185
|
onClick: () => toggleSort("row"),
|
|
2671
|
-
children: /* @__PURE__ */
|
|
2672
|
-
/* @__PURE__ */
|
|
2673
|
-
(fieldIdx === rowFields.length - 1 || rowFields.length === 0) && /* @__PURE__ */
|
|
3186
|
+
children: /* @__PURE__ */ jsxs6("div", { className: "vpg-header-content", children: [
|
|
3187
|
+
/* @__PURE__ */ jsx6("span", { children: field }),
|
|
3188
|
+
(fieldIdx === rowFields.length - 1 || rowFields.length === 0) && /* @__PURE__ */ jsx6("span", { className: `vpg-sort-indicator ${sortTarget === "row" ? "active" : ""}`, children: sortTarget === "row" ? sortDirection === "asc" ? "\u2191" : "\u2193" : "\u21C5" })
|
|
2674
3189
|
] })
|
|
2675
3190
|
},
|
|
2676
3191
|
`row-header-${fieldIdx}`
|
|
2677
3192
|
)),
|
|
2678
|
-
headerRow.map((cell, idx) => /* @__PURE__ */
|
|
3193
|
+
headerRow.map((cell, idx) => /* @__PURE__ */ jsx6(
|
|
2679
3194
|
"th",
|
|
2680
3195
|
{
|
|
2681
3196
|
className: "vpg-column-header-cell",
|
|
2682
3197
|
colSpan: cell.colspan,
|
|
2683
3198
|
onClick: () => levelIdx === columnHeaderCells.length - 1 && toggleSort(idx),
|
|
2684
|
-
children: /* @__PURE__ */
|
|
2685
|
-
/* @__PURE__ */
|
|
2686
|
-
levelIdx === columnHeaderCells.length - 1 && /* @__PURE__ */
|
|
3199
|
+
children: /* @__PURE__ */ jsxs6("div", { className: "vpg-header-content", children: [
|
|
3200
|
+
/* @__PURE__ */ jsx6("span", { children: cell.label }),
|
|
3201
|
+
levelIdx === columnHeaderCells.length - 1 && /* @__PURE__ */ jsx6("span", { className: `vpg-sort-indicator ${sortTarget === idx ? "active" : ""}`, children: sortTarget === idx ? sortDirection === "asc" ? "\u2191" : "\u2193" : "\u21C5" })
|
|
2687
3202
|
] })
|
|
2688
3203
|
},
|
|
2689
3204
|
idx
|
|
2690
3205
|
)),
|
|
2691
|
-
pivotResult.rowTotals.length > 0 && levelIdx === 0 && /* @__PURE__ */
|
|
3206
|
+
pivotResult.rowTotals.length > 0 && levelIdx === 0 && /* @__PURE__ */ jsx6("th", { className: "vpg-total-header", rowSpan: columnHeaderCells.length, children: "Total" })
|
|
2692
3207
|
] }, `header-${levelIdx}`)) }),
|
|
2693
|
-
/* @__PURE__ */
|
|
2694
|
-
sortedRowIndices.map((sortedIdx) => /* @__PURE__ */
|
|
2695
|
-
pivotResult.rowHeaders[sortedIdx].map((val, idx) => /* @__PURE__ */
|
|
3208
|
+
/* @__PURE__ */ jsxs6("tbody", { children: [
|
|
3209
|
+
sortedRowIndices.map((sortedIdx) => /* @__PURE__ */ jsxs6("tr", { className: "vpg-data-row", children: [
|
|
3210
|
+
pivotResult.rowHeaders[sortedIdx].map((val, idx) => /* @__PURE__ */ jsx6(
|
|
2696
3211
|
"th",
|
|
2697
3212
|
{
|
|
2698
3213
|
className: "vpg-row-header-cell",
|
|
@@ -2703,7 +3218,7 @@ function PivotSkeleton({
|
|
|
2703
3218
|
)),
|
|
2704
3219
|
pivotResult.data[sortedIdx].map((cell, colIdx) => {
|
|
2705
3220
|
const displayRowIdx = sortedRowIndices.indexOf(sortedIdx);
|
|
2706
|
-
return /* @__PURE__ */
|
|
3221
|
+
return /* @__PURE__ */ jsx6(
|
|
2707
3222
|
"td",
|
|
2708
3223
|
{
|
|
2709
3224
|
className: `vpg-data-cell ${isCellSelected(displayRowIdx, colIdx) ? "selected" : ""} ${cell.value === null ? "vpg-is-null" : ""}`,
|
|
@@ -2714,10 +3229,10 @@ function PivotSkeleton({
|
|
|
2714
3229
|
colIdx
|
|
2715
3230
|
);
|
|
2716
3231
|
}),
|
|
2717
|
-
pivotResult.rowTotals[sortedIdx] && /* @__PURE__ */
|
|
3232
|
+
pivotResult.rowTotals[sortedIdx] && /* @__PURE__ */ jsx6("td", { className: "vpg-data-cell vpg-total-cell", children: pivotResult.rowTotals[sortedIdx].formattedValue })
|
|
2718
3233
|
] }, sortedIdx)),
|
|
2719
|
-
pivotResult.columnTotals.length > 0 && /* @__PURE__ */
|
|
2720
|
-
/* @__PURE__ */
|
|
3234
|
+
pivotResult.columnTotals.length > 0 && /* @__PURE__ */ jsxs6("tr", { className: "vpg-totals-row", children: [
|
|
3235
|
+
/* @__PURE__ */ jsx6(
|
|
2721
3236
|
"th",
|
|
2722
3237
|
{
|
|
2723
3238
|
className: "vpg-row-header-cell vpg-total-label",
|
|
@@ -2726,13 +3241,13 @@ function PivotSkeleton({
|
|
|
2726
3241
|
children: "Total"
|
|
2727
3242
|
}
|
|
2728
3243
|
),
|
|
2729
|
-
pivotResult.columnTotals.map((cell, colIdx) => /* @__PURE__ */
|
|
2730
|
-
pivotResult.rowTotals.length > 0 && /* @__PURE__ */
|
|
3244
|
+
pivotResult.columnTotals.map((cell, colIdx) => /* @__PURE__ */ jsx6("td", { className: "vpg-data-cell vpg-total-cell", children: cell.formattedValue }, colIdx)),
|
|
3245
|
+
pivotResult.rowTotals.length > 0 && /* @__PURE__ */ jsx6("td", { className: "vpg-data-cell vpg-grand-total-cell", children: pivotResult.grandTotal.formattedValue })
|
|
2731
3246
|
] })
|
|
2732
3247
|
] })
|
|
2733
3248
|
] }) }),
|
|
2734
|
-
isConfigured && pivotResult && /* @__PURE__ */
|
|
2735
|
-
/* @__PURE__ */
|
|
3249
|
+
isConfigured && pivotResult && /* @__PURE__ */ jsxs6("div", { className: "vpg-skeleton-footer", children: [
|
|
3250
|
+
/* @__PURE__ */ jsxs6("span", { className: "vpg-footer-info", children: [
|
|
2736
3251
|
pivotResult.rowHeaders.length,
|
|
2737
3252
|
" ",
|
|
2738
3253
|
"rows \xD7",
|
|
@@ -2740,30 +3255,30 @@ function PivotSkeleton({
|
|
|
2740
3255
|
" ",
|
|
2741
3256
|
"columns"
|
|
2742
3257
|
] }),
|
|
2743
|
-
selectionStats && selectionStats.count > 1 && /* @__PURE__ */
|
|
2744
|
-
/* @__PURE__ */
|
|
2745
|
-
/* @__PURE__ */
|
|
2746
|
-
/* @__PURE__ */
|
|
3258
|
+
selectionStats && selectionStats.count > 1 && /* @__PURE__ */ jsxs6("div", { className: "vpg-selection-stats", children: [
|
|
3259
|
+
/* @__PURE__ */ jsxs6("span", { className: "vpg-stat", children: [
|
|
3260
|
+
/* @__PURE__ */ jsx6("span", { className: "vpg-stat-label", children: "Count:" }),
|
|
3261
|
+
/* @__PURE__ */ jsx6("span", { className: "vpg-stat-value", children: selectionStats.count })
|
|
2747
3262
|
] }),
|
|
2748
|
-
selectionStats.numericCount > 0 && /* @__PURE__ */
|
|
2749
|
-
/* @__PURE__ */
|
|
2750
|
-
/* @__PURE__ */
|
|
2751
|
-
/* @__PURE__ */
|
|
2752
|
-
/* @__PURE__ */
|
|
3263
|
+
selectionStats.numericCount > 0 && /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
3264
|
+
/* @__PURE__ */ jsx6("span", { className: "vpg-stat-divider", children: "|" }),
|
|
3265
|
+
/* @__PURE__ */ jsxs6("span", { className: "vpg-stat", children: [
|
|
3266
|
+
/* @__PURE__ */ jsx6("span", { className: "vpg-stat-label", children: "Sum:" }),
|
|
3267
|
+
/* @__PURE__ */ jsx6("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.sum) })
|
|
2753
3268
|
] }),
|
|
2754
|
-
/* @__PURE__ */
|
|
2755
|
-
/* @__PURE__ */
|
|
2756
|
-
/* @__PURE__ */
|
|
2757
|
-
/* @__PURE__ */
|
|
3269
|
+
/* @__PURE__ */ jsx6("span", { className: "vpg-stat-divider", children: "|" }),
|
|
3270
|
+
/* @__PURE__ */ jsxs6("span", { className: "vpg-stat", children: [
|
|
3271
|
+
/* @__PURE__ */ jsx6("span", { className: "vpg-stat-label", children: "Avg:" }),
|
|
3272
|
+
/* @__PURE__ */ jsx6("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.avg) })
|
|
2758
3273
|
] })
|
|
2759
3274
|
] })
|
|
2760
3275
|
] })
|
|
2761
3276
|
] })
|
|
2762
3277
|
] }),
|
|
2763
|
-
showWatermark && canUsePivot && /* @__PURE__ */
|
|
2764
|
-
/* @__PURE__ */
|
|
2765
|
-
/* @__PURE__ */
|
|
2766
|
-
/* @__PURE__ */
|
|
3278
|
+
showWatermark && canUsePivot && /* @__PURE__ */ jsx6("div", { className: `vpg-watermark ${isDemo ? "vpg-demo-mode" : ""}`, children: isDemo ? /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
3279
|
+
/* @__PURE__ */ jsx6("span", { className: "vpg-demo-badge", children: "DEMO" }),
|
|
3280
|
+
/* @__PURE__ */ jsx6("span", { children: "Pro features unlocked for evaluation" }),
|
|
3281
|
+
/* @__PURE__ */ jsx6(
|
|
2767
3282
|
"a",
|
|
2768
3283
|
{
|
|
2769
3284
|
href: "https://tiny-pivot.com/#pricing",
|
|
@@ -2773,14 +3288,14 @@ function PivotSkeleton({
|
|
|
2773
3288
|
children: "Get Pro License \u2192"
|
|
2774
3289
|
}
|
|
2775
3290
|
)
|
|
2776
|
-
] }) : /* @__PURE__ */
|
|
3291
|
+
] }) : /* @__PURE__ */ jsx6("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: "Powered by TinyPivot" }) })
|
|
2777
3292
|
]
|
|
2778
3293
|
}
|
|
2779
3294
|
);
|
|
2780
3295
|
}
|
|
2781
3296
|
|
|
2782
3297
|
// src/components/DataGrid.tsx
|
|
2783
|
-
import { Fragment as
|
|
3298
|
+
import { Fragment as Fragment5, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2784
3299
|
var MIN_COL_WIDTH = 120;
|
|
2785
3300
|
var MAX_COL_WIDTH = 350;
|
|
2786
3301
|
function DataGrid({
|
|
@@ -2805,36 +3320,40 @@ function DataGrid({
|
|
|
2805
3320
|
onExport,
|
|
2806
3321
|
onCopy
|
|
2807
3322
|
}) {
|
|
2808
|
-
const { showWatermark, canUsePivot, isDemo, isPro } = useLicense();
|
|
2809
|
-
const currentTheme =
|
|
3323
|
+
const { showWatermark, canUsePivot, canUseCharts, isDemo, isPro } = useLicense();
|
|
3324
|
+
const currentTheme = useMemo11(() => {
|
|
2810
3325
|
if (theme === "auto") {
|
|
2811
3326
|
return window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
2812
3327
|
}
|
|
2813
3328
|
return theme;
|
|
2814
3329
|
}, [theme]);
|
|
2815
|
-
const [currentFontSize, setCurrentFontSize] =
|
|
2816
|
-
const [globalSearchTerm, setGlobalSearchTerm] =
|
|
2817
|
-
const [showSearchInput, setShowSearchInput] =
|
|
2818
|
-
const [currentPage, setCurrentPage] =
|
|
2819
|
-
const [columnWidths, setColumnWidths] =
|
|
2820
|
-
const [resizingColumnId, setResizingColumnId] =
|
|
2821
|
-
const [resizeStartX, setResizeStartX] =
|
|
2822
|
-
const [resizeStartWidth, setResizeStartWidth] =
|
|
2823
|
-
const [gridHeight, setGridHeight] =
|
|
2824
|
-
const [isResizingVertically, setIsResizingVertically] =
|
|
2825
|
-
const [verticalResizeStartY, setVerticalResizeStartY] =
|
|
2826
|
-
const [verticalResizeStartHeight, setVerticalResizeStartHeight] =
|
|
2827
|
-
const [showCopyToast, setShowCopyToast] =
|
|
2828
|
-
const [copyToastMessage, setCopyToastMessage] =
|
|
2829
|
-
const [viewMode, setViewMode] =
|
|
2830
|
-
const [
|
|
2831
|
-
const
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
const [
|
|
2835
|
-
const [
|
|
2836
|
-
const [
|
|
2837
|
-
const [
|
|
3330
|
+
const [currentFontSize, setCurrentFontSize] = useState11(initialFontSize);
|
|
3331
|
+
const [globalSearchTerm, setGlobalSearchTerm] = useState11("");
|
|
3332
|
+
const [showSearchInput, setShowSearchInput] = useState11(false);
|
|
3333
|
+
const [currentPage, setCurrentPage] = useState11(1);
|
|
3334
|
+
const [columnWidths, setColumnWidths] = useState11({});
|
|
3335
|
+
const [resizingColumnId, setResizingColumnId] = useState11(null);
|
|
3336
|
+
const [resizeStartX, setResizeStartX] = useState11(0);
|
|
3337
|
+
const [resizeStartWidth, setResizeStartWidth] = useState11(0);
|
|
3338
|
+
const [gridHeight, setGridHeight] = useState11(initialHeight);
|
|
3339
|
+
const [isResizingVertically, setIsResizingVertically] = useState11(false);
|
|
3340
|
+
const [verticalResizeStartY, setVerticalResizeStartY] = useState11(0);
|
|
3341
|
+
const [verticalResizeStartHeight, setVerticalResizeStartHeight] = useState11(0);
|
|
3342
|
+
const [showCopyToast, setShowCopyToast] = useState11(false);
|
|
3343
|
+
const [copyToastMessage, setCopyToastMessage] = useState11("");
|
|
3344
|
+
const [viewMode, setViewMode] = useState11("grid");
|
|
3345
|
+
const [_chartConfig, setChartConfig] = useState11(null);
|
|
3346
|
+
const handleChartConfigChange = useCallback11((config) => {
|
|
3347
|
+
setChartConfig(config);
|
|
3348
|
+
}, []);
|
|
3349
|
+
const [showPivotConfig, setShowPivotConfig] = useState11(true);
|
|
3350
|
+
const [draggingField, setDraggingField] = useState11(null);
|
|
3351
|
+
const [activeFilterColumn, setActiveFilterColumn] = useState11(null);
|
|
3352
|
+
const [filterDropdownPosition, setFilterDropdownPosition] = useState11({ top: 0, left: 0, maxHeight: 400 });
|
|
3353
|
+
const [selectedCell, setSelectedCell] = useState11(null);
|
|
3354
|
+
const [selectionStart, setSelectionStart] = useState11(null);
|
|
3355
|
+
const [selectionEnd, setSelectionEnd] = useState11(null);
|
|
3356
|
+
const [isSelecting, setIsSelecting] = useState11(false);
|
|
2838
3357
|
const tableContainerRef = useRef2(null);
|
|
2839
3358
|
const tableBodyRef = useRef2(null);
|
|
2840
3359
|
const fontSizeOptions = [
|
|
@@ -2860,7 +3379,7 @@ function DataGrid({
|
|
|
2860
3379
|
setNumericRangeFilter,
|
|
2861
3380
|
getNumericRangeFilter
|
|
2862
3381
|
} = useExcelGrid({ data, enableSorting: true, enableFiltering: true });
|
|
2863
|
-
const filteredDataForPivot =
|
|
3382
|
+
const filteredDataForPivot = useMemo11(() => {
|
|
2864
3383
|
const filteredRows = table.getFilteredRowModel().rows;
|
|
2865
3384
|
return filteredRows.map((row) => row.original);
|
|
2866
3385
|
}, [table, columnFilters]);
|
|
@@ -2890,7 +3409,7 @@ function DataGrid({
|
|
|
2890
3409
|
addCalculatedField,
|
|
2891
3410
|
removeCalculatedField
|
|
2892
3411
|
} = usePivotTable(filteredDataForPivot);
|
|
2893
|
-
const activeFilterInfo =
|
|
3412
|
+
const activeFilterInfo = useMemo11(() => {
|
|
2894
3413
|
if (activeFilters.length === 0)
|
|
2895
3414
|
return null;
|
|
2896
3415
|
return activeFilters.map((f) => {
|
|
@@ -2915,8 +3434,8 @@ function DataGrid({
|
|
|
2915
3434
|
};
|
|
2916
3435
|
});
|
|
2917
3436
|
}, [activeFilters]);
|
|
2918
|
-
const rows =
|
|
2919
|
-
const searchFilteredData =
|
|
3437
|
+
const rows = useMemo11(() => table.getFilteredRowModel().rows, [table, columnFilters]);
|
|
3438
|
+
const searchFilteredData = useMemo11(() => {
|
|
2920
3439
|
if (!globalSearchTerm.trim() || !enableSearch) {
|
|
2921
3440
|
return rows;
|
|
2922
3441
|
}
|
|
@@ -2934,22 +3453,22 @@ function DataGrid({
|
|
|
2934
3453
|
});
|
|
2935
3454
|
}, [rows, globalSearchTerm, enableSearch, columnKeys]);
|
|
2936
3455
|
const totalSearchedRows = searchFilteredData.length;
|
|
2937
|
-
const totalPages =
|
|
3456
|
+
const totalPages = useMemo11(() => {
|
|
2938
3457
|
if (!enablePagination)
|
|
2939
3458
|
return 1;
|
|
2940
3459
|
return Math.max(1, Math.ceil(totalSearchedRows / pageSize));
|
|
2941
3460
|
}, [enablePagination, totalSearchedRows, pageSize]);
|
|
2942
|
-
const paginatedRows =
|
|
3461
|
+
const paginatedRows = useMemo11(() => {
|
|
2943
3462
|
if (!enablePagination)
|
|
2944
3463
|
return searchFilteredData;
|
|
2945
3464
|
const start = (currentPage - 1) * pageSize;
|
|
2946
3465
|
const end = start + pageSize;
|
|
2947
3466
|
return searchFilteredData.slice(start, end);
|
|
2948
3467
|
}, [enablePagination, searchFilteredData, currentPage, pageSize]);
|
|
2949
|
-
|
|
3468
|
+
useEffect8(() => {
|
|
2950
3469
|
setCurrentPage(1);
|
|
2951
3470
|
}, [columnFilters, globalSearchTerm]);
|
|
2952
|
-
const selectionBounds =
|
|
3471
|
+
const selectionBounds = useMemo11(() => {
|
|
2953
3472
|
if (!selectionStart || !selectionEnd)
|
|
2954
3473
|
return null;
|
|
2955
3474
|
return {
|
|
@@ -2959,7 +3478,7 @@ function DataGrid({
|
|
|
2959
3478
|
maxCol: Math.max(selectionStart.col, selectionEnd.col)
|
|
2960
3479
|
};
|
|
2961
3480
|
}, [selectionStart, selectionEnd]);
|
|
2962
|
-
const selectionStats =
|
|
3481
|
+
const selectionStats = useMemo11(() => {
|
|
2963
3482
|
if (!selectionBounds)
|
|
2964
3483
|
return null;
|
|
2965
3484
|
const { minRow, maxRow, minCol, maxCol } = selectionBounds;
|
|
@@ -2989,7 +3508,7 @@ function DataGrid({
|
|
|
2989
3508
|
const avg = sum / values.length;
|
|
2990
3509
|
return { count, sum, avg, numericCount: values.length };
|
|
2991
3510
|
}, [selectionBounds, rows, columnKeys]);
|
|
2992
|
-
|
|
3511
|
+
useEffect8(() => {
|
|
2993
3512
|
if (typeof document === "undefined")
|
|
2994
3513
|
return;
|
|
2995
3514
|
if (data.length === 0)
|
|
@@ -3013,7 +3532,7 @@ function DataGrid({
|
|
|
3013
3532
|
}
|
|
3014
3533
|
setColumnWidths(widths);
|
|
3015
3534
|
}, [data, columnKeys]);
|
|
3016
|
-
const startColumnResize =
|
|
3535
|
+
const startColumnResize = useCallback11(
|
|
3017
3536
|
(columnId, event) => {
|
|
3018
3537
|
if (!enableColumnResize)
|
|
3019
3538
|
return;
|
|
@@ -3025,7 +3544,7 @@ function DataGrid({
|
|
|
3025
3544
|
},
|
|
3026
3545
|
[enableColumnResize, columnWidths]
|
|
3027
3546
|
);
|
|
3028
|
-
|
|
3547
|
+
useEffect8(() => {
|
|
3029
3548
|
if (!resizingColumnId)
|
|
3030
3549
|
return;
|
|
3031
3550
|
const handleResizeMove = (event) => {
|
|
@@ -3046,7 +3565,7 @@ function DataGrid({
|
|
|
3046
3565
|
document.removeEventListener("mouseup", handleResizeEnd);
|
|
3047
3566
|
};
|
|
3048
3567
|
}, [resizingColumnId, resizeStartX, resizeStartWidth]);
|
|
3049
|
-
const startVerticalResize =
|
|
3568
|
+
const startVerticalResize = useCallback11(
|
|
3050
3569
|
(event) => {
|
|
3051
3570
|
if (!enableVerticalResize)
|
|
3052
3571
|
return;
|
|
@@ -3057,7 +3576,7 @@ function DataGrid({
|
|
|
3057
3576
|
},
|
|
3058
3577
|
[enableVerticalResize, gridHeight]
|
|
3059
3578
|
);
|
|
3060
|
-
|
|
3579
|
+
useEffect8(() => {
|
|
3061
3580
|
if (!isResizingVertically)
|
|
3062
3581
|
return;
|
|
3063
3582
|
const handleVerticalResizeMove = (event) => {
|
|
@@ -3075,7 +3594,7 @@ function DataGrid({
|
|
|
3075
3594
|
document.removeEventListener("mouseup", handleVerticalResizeEnd);
|
|
3076
3595
|
};
|
|
3077
3596
|
}, [isResizingVertically, verticalResizeStartY, verticalResizeStartHeight, minHeight, maxHeight]);
|
|
3078
|
-
const handleExport =
|
|
3597
|
+
const handleExport = useCallback11(() => {
|
|
3079
3598
|
if (viewMode === "pivot") {
|
|
3080
3599
|
if (!pivotResult)
|
|
3081
3600
|
return;
|
|
@@ -3121,7 +3640,7 @@ function DataGrid({
|
|
|
3121
3640
|
columnKeys,
|
|
3122
3641
|
onExport
|
|
3123
3642
|
]);
|
|
3124
|
-
const copySelectionToClipboard =
|
|
3643
|
+
const copySelectionToClipboard = useCallback11(() => {
|
|
3125
3644
|
if (!selectionBounds || !enableClipboard)
|
|
3126
3645
|
return;
|
|
3127
3646
|
const text = formatSelectionForClipboard(
|
|
@@ -3146,7 +3665,7 @@ function DataGrid({
|
|
|
3146
3665
|
}
|
|
3147
3666
|
);
|
|
3148
3667
|
}, [selectionBounds, enableClipboard, rows, columnKeys, onCopy]);
|
|
3149
|
-
const handleMouseDown =
|
|
3668
|
+
const handleMouseDown = useCallback11(
|
|
3150
3669
|
(rowIndex, colIndex, event) => {
|
|
3151
3670
|
event.preventDefault();
|
|
3152
3671
|
if (event.shiftKey && selectedCell) {
|
|
@@ -3170,7 +3689,7 @@ function DataGrid({
|
|
|
3170
3689
|
},
|
|
3171
3690
|
[selectedCell, rows, columnKeys, onCellClick]
|
|
3172
3691
|
);
|
|
3173
|
-
const handleMouseEnter =
|
|
3692
|
+
const handleMouseEnter = useCallback11(
|
|
3174
3693
|
(rowIndex, colIndex) => {
|
|
3175
3694
|
if (isSelecting) {
|
|
3176
3695
|
setSelectionEnd({ row: rowIndex, col: colIndex });
|
|
@@ -3178,12 +3697,12 @@ function DataGrid({
|
|
|
3178
3697
|
},
|
|
3179
3698
|
[isSelecting]
|
|
3180
3699
|
);
|
|
3181
|
-
|
|
3700
|
+
useEffect8(() => {
|
|
3182
3701
|
const handleMouseUp = () => setIsSelecting(false);
|
|
3183
3702
|
document.addEventListener("mouseup", handleMouseUp);
|
|
3184
3703
|
return () => document.removeEventListener("mouseup", handleMouseUp);
|
|
3185
3704
|
}, []);
|
|
3186
|
-
|
|
3705
|
+
useEffect8(() => {
|
|
3187
3706
|
const handleKeydown = (event) => {
|
|
3188
3707
|
if ((event.ctrlKey || event.metaKey) && event.key === "c" && selectionBounds) {
|
|
3189
3708
|
event.preventDefault();
|
|
@@ -3201,7 +3720,7 @@ function DataGrid({
|
|
|
3201
3720
|
document.addEventListener("keydown", handleKeydown);
|
|
3202
3721
|
return () => document.removeEventListener("keydown", handleKeydown);
|
|
3203
3722
|
}, [selectionBounds, copySelectionToClipboard]);
|
|
3204
|
-
const openFilterDropdown =
|
|
3723
|
+
const openFilterDropdown = useCallback11(
|
|
3205
3724
|
(columnId, event) => {
|
|
3206
3725
|
event.stopPropagation();
|
|
3207
3726
|
const target = event.currentTarget;
|
|
@@ -3230,22 +3749,22 @@ function DataGrid({
|
|
|
3230
3749
|
},
|
|
3231
3750
|
[]
|
|
3232
3751
|
);
|
|
3233
|
-
const closeFilterDropdown =
|
|
3752
|
+
const closeFilterDropdown = useCallback11(() => {
|
|
3234
3753
|
setActiveFilterColumn(null);
|
|
3235
3754
|
}, []);
|
|
3236
|
-
const handleFilter =
|
|
3755
|
+
const handleFilter = useCallback11(
|
|
3237
3756
|
(columnId, values) => {
|
|
3238
3757
|
setColumnFilter(columnId, values);
|
|
3239
3758
|
},
|
|
3240
3759
|
[setColumnFilter]
|
|
3241
3760
|
);
|
|
3242
|
-
const handleRangeFilter =
|
|
3761
|
+
const handleRangeFilter = useCallback11(
|
|
3243
3762
|
(columnId, range) => {
|
|
3244
3763
|
setNumericRangeFilter(columnId, range);
|
|
3245
3764
|
},
|
|
3246
3765
|
[setNumericRangeFilter]
|
|
3247
3766
|
);
|
|
3248
|
-
const handleSort =
|
|
3767
|
+
const handleSort = useCallback11(
|
|
3249
3768
|
(columnId, direction) => {
|
|
3250
3769
|
if (direction === null) {
|
|
3251
3770
|
const current = getSortDirection(columnId);
|
|
@@ -3269,7 +3788,7 @@ function DataGrid({
|
|
|
3269
3788
|
},
|
|
3270
3789
|
[getSortDirection, toggleSort]
|
|
3271
3790
|
);
|
|
3272
|
-
const isCellSelected =
|
|
3791
|
+
const isCellSelected = useCallback11(
|
|
3273
3792
|
(rowIndex, colIndex) => {
|
|
3274
3793
|
if (!selectionBounds) {
|
|
3275
3794
|
return selectedCell?.row === rowIndex && selectedCell?.col === colIndex;
|
|
@@ -3311,30 +3830,30 @@ function DataGrid({
|
|
|
3311
3830
|
}
|
|
3312
3831
|
return String(value);
|
|
3313
3832
|
};
|
|
3314
|
-
const totalTableWidth =
|
|
3833
|
+
const totalTableWidth = useMemo11(() => {
|
|
3315
3834
|
return columnKeys.reduce((sum, key) => sum + (columnWidths[key] || MIN_COL_WIDTH), 0);
|
|
3316
3835
|
}, [columnKeys, columnWidths]);
|
|
3317
3836
|
const activeFilterCount = columnFilters.length;
|
|
3318
|
-
return /* @__PURE__ */
|
|
3837
|
+
return /* @__PURE__ */ jsxs7(
|
|
3319
3838
|
"div",
|
|
3320
3839
|
{
|
|
3321
3840
|
className: `vpg-data-grid vpg-font-${currentFontSize} vpg-theme-${currentTheme} ${stripedRows ? "vpg-striped" : ""} ${resizingColumnId ? "vpg-resizing" : ""} ${isResizingVertically ? "vpg-resizing-vertical" : ""}`,
|
|
3322
3841
|
style: { height: `${gridHeight}px` },
|
|
3323
3842
|
children: [
|
|
3324
|
-
showCopyToast && /* @__PURE__ */
|
|
3325
|
-
/* @__PURE__ */
|
|
3843
|
+
showCopyToast && /* @__PURE__ */ jsxs7("div", { className: "vpg-toast", children: [
|
|
3844
|
+
/* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }),
|
|
3326
3845
|
copyToastMessage
|
|
3327
3846
|
] }),
|
|
3328
|
-
/* @__PURE__ */
|
|
3329
|
-
/* @__PURE__ */
|
|
3330
|
-
showPivot && /* @__PURE__ */
|
|
3331
|
-
/* @__PURE__ */
|
|
3847
|
+
/* @__PURE__ */ jsxs7("div", { className: "vpg-toolbar", children: [
|
|
3848
|
+
/* @__PURE__ */ jsxs7("div", { className: "vpg-toolbar-left", children: [
|
|
3849
|
+
showPivot && /* @__PURE__ */ jsxs7("div", { className: "vpg-view-toggle", children: [
|
|
3850
|
+
/* @__PURE__ */ jsxs7(
|
|
3332
3851
|
"button",
|
|
3333
3852
|
{
|
|
3334
3853
|
className: `vpg-view-btn ${viewMode === "grid" ? "active" : ""}`,
|
|
3335
3854
|
onClick: () => setViewMode("grid"),
|
|
3336
3855
|
children: [
|
|
3337
|
-
/* @__PURE__ */
|
|
3856
|
+
/* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
|
|
3338
3857
|
"path",
|
|
3339
3858
|
{
|
|
3340
3859
|
strokeLinecap: "round",
|
|
@@ -3347,13 +3866,13 @@ function DataGrid({
|
|
|
3347
3866
|
]
|
|
3348
3867
|
}
|
|
3349
3868
|
),
|
|
3350
|
-
/* @__PURE__ */
|
|
3869
|
+
/* @__PURE__ */ jsxs7(
|
|
3351
3870
|
"button",
|
|
3352
3871
|
{
|
|
3353
3872
|
className: `vpg-view-btn vpg-pivot-btn ${viewMode === "pivot" ? "active" : ""}`,
|
|
3354
3873
|
onClick: () => setViewMode("pivot"),
|
|
3355
3874
|
children: [
|
|
3356
|
-
/* @__PURE__ */
|
|
3875
|
+
/* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
|
|
3357
3876
|
"path",
|
|
3358
3877
|
{
|
|
3359
3878
|
strokeLinecap: "round",
|
|
@@ -3365,16 +3884,37 @@ function DataGrid({
|
|
|
3365
3884
|
"Pivot"
|
|
3366
3885
|
]
|
|
3367
3886
|
}
|
|
3887
|
+
),
|
|
3888
|
+
/* @__PURE__ */ jsxs7(
|
|
3889
|
+
"button",
|
|
3890
|
+
{
|
|
3891
|
+
className: `vpg-view-btn vpg-chart-btn ${viewMode === "chart" ? "active" : ""} ${!canUseCharts ? "vpg-pro-feature" : ""}`,
|
|
3892
|
+
title: canUseCharts ? "Chart Builder" : "Chart Builder (Pro feature)",
|
|
3893
|
+
onClick: () => canUseCharts && setViewMode("chart"),
|
|
3894
|
+
children: [
|
|
3895
|
+
/* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
|
|
3896
|
+
"path",
|
|
3897
|
+
{
|
|
3898
|
+
strokeLinecap: "round",
|
|
3899
|
+
strokeLinejoin: "round",
|
|
3900
|
+
strokeWidth: 2,
|
|
3901
|
+
d: "M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"
|
|
3902
|
+
}
|
|
3903
|
+
) }),
|
|
3904
|
+
"Chart",
|
|
3905
|
+
!canUseCharts && /* @__PURE__ */ jsx7("span", { className: "vpg-pro-badge", children: "Pro" })
|
|
3906
|
+
]
|
|
3907
|
+
}
|
|
3368
3908
|
)
|
|
3369
3909
|
] }),
|
|
3370
|
-
viewMode === "grid" && /* @__PURE__ */
|
|
3371
|
-
enableSearch && /* @__PURE__ */
|
|
3910
|
+
viewMode === "grid" && /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
3911
|
+
enableSearch && /* @__PURE__ */ jsx7("div", { className: "vpg-search-container", children: !showSearchInput ? /* @__PURE__ */ jsx7(
|
|
3372
3912
|
"button",
|
|
3373
3913
|
{
|
|
3374
3914
|
className: "vpg-icon-btn",
|
|
3375
3915
|
title: "Search (Ctrl+F)",
|
|
3376
3916
|
onClick: () => setShowSearchInput(true),
|
|
3377
|
-
children: /* @__PURE__ */
|
|
3917
|
+
children: /* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
|
|
3378
3918
|
"path",
|
|
3379
3919
|
{
|
|
3380
3920
|
strokeLinecap: "round",
|
|
@@ -3384,15 +3924,15 @@ function DataGrid({
|
|
|
3384
3924
|
}
|
|
3385
3925
|
) })
|
|
3386
3926
|
}
|
|
3387
|
-
) : /* @__PURE__ */
|
|
3388
|
-
/* @__PURE__ */
|
|
3927
|
+
) : /* @__PURE__ */ jsxs7("div", { className: "vpg-search-box", children: [
|
|
3928
|
+
/* @__PURE__ */ jsx7(
|
|
3389
3929
|
"svg",
|
|
3390
3930
|
{
|
|
3391
3931
|
className: "vpg-search-icon",
|
|
3392
3932
|
fill: "none",
|
|
3393
3933
|
stroke: "currentColor",
|
|
3394
3934
|
viewBox: "0 0 24 24",
|
|
3395
|
-
children: /* @__PURE__ */
|
|
3935
|
+
children: /* @__PURE__ */ jsx7(
|
|
3396
3936
|
"path",
|
|
3397
3937
|
{
|
|
3398
3938
|
strokeLinecap: "round",
|
|
@@ -3403,7 +3943,7 @@ function DataGrid({
|
|
|
3403
3943
|
)
|
|
3404
3944
|
}
|
|
3405
3945
|
),
|
|
3406
|
-
/* @__PURE__ */
|
|
3946
|
+
/* @__PURE__ */ jsx7(
|
|
3407
3947
|
"input",
|
|
3408
3948
|
{
|
|
3409
3949
|
type: "text",
|
|
@@ -3420,14 +3960,14 @@ function DataGrid({
|
|
|
3420
3960
|
autoFocus: true
|
|
3421
3961
|
}
|
|
3422
3962
|
),
|
|
3423
|
-
globalSearchTerm && /* @__PURE__ */
|
|
3963
|
+
globalSearchTerm && /* @__PURE__ */ jsx7("button", { className: "vpg-search-clear", onClick: () => setGlobalSearchTerm(""), children: /* @__PURE__ */ jsx7(
|
|
3424
3964
|
"svg",
|
|
3425
3965
|
{
|
|
3426
3966
|
className: "vpg-icon-xs",
|
|
3427
3967
|
fill: "none",
|
|
3428
3968
|
stroke: "currentColor",
|
|
3429
3969
|
viewBox: "0 0 24 24",
|
|
3430
|
-
children: /* @__PURE__ */
|
|
3970
|
+
children: /* @__PURE__ */ jsx7(
|
|
3431
3971
|
"path",
|
|
3432
3972
|
{
|
|
3433
3973
|
strokeLinecap: "round",
|
|
@@ -3439,9 +3979,9 @@ function DataGrid({
|
|
|
3439
3979
|
}
|
|
3440
3980
|
) })
|
|
3441
3981
|
] }) }),
|
|
3442
|
-
/* @__PURE__ */
|
|
3443
|
-
/* @__PURE__ */
|
|
3444
|
-
/* @__PURE__ */
|
|
3982
|
+
/* @__PURE__ */ jsxs7("div", { className: "vpg-font-size-control", children: [
|
|
3983
|
+
/* @__PURE__ */ jsx7("span", { className: "vpg-label", children: "Size:" }),
|
|
3984
|
+
/* @__PURE__ */ jsx7("div", { className: "vpg-font-size-toggle", children: fontSizeOptions.map((opt) => /* @__PURE__ */ jsx7(
|
|
3445
3985
|
"button",
|
|
3446
3986
|
{
|
|
3447
3987
|
className: `vpg-font-size-btn ${currentFontSize === opt.value ? "active" : ""}`,
|
|
@@ -3451,8 +3991,8 @@ function DataGrid({
|
|
|
3451
3991
|
opt.value
|
|
3452
3992
|
)) })
|
|
3453
3993
|
] }),
|
|
3454
|
-
activeFilterCount > 0 && /* @__PURE__ */
|
|
3455
|
-
/* @__PURE__ */
|
|
3994
|
+
activeFilterCount > 0 && /* @__PURE__ */ jsxs7("div", { className: "vpg-filter-info", children: [
|
|
3995
|
+
/* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx7(
|
|
3456
3996
|
"path",
|
|
3457
3997
|
{
|
|
3458
3998
|
fillRule: "evenodd",
|
|
@@ -3460,28 +4000,28 @@ function DataGrid({
|
|
|
3460
4000
|
clipRule: "evenodd"
|
|
3461
4001
|
}
|
|
3462
4002
|
) }),
|
|
3463
|
-
/* @__PURE__ */
|
|
4003
|
+
/* @__PURE__ */ jsxs7("span", { children: [
|
|
3464
4004
|
activeFilterCount,
|
|
3465
4005
|
" ",
|
|
3466
4006
|
"filter",
|
|
3467
4007
|
activeFilterCount > 1 ? "s" : ""
|
|
3468
4008
|
] })
|
|
3469
4009
|
] }),
|
|
3470
|
-
globalSearchTerm && /* @__PURE__ */
|
|
4010
|
+
globalSearchTerm && /* @__PURE__ */ jsx7("div", { className: "vpg-search-info", children: /* @__PURE__ */ jsxs7("span", { children: [
|
|
3471
4011
|
totalSearchedRows,
|
|
3472
4012
|
" ",
|
|
3473
4013
|
"match",
|
|
3474
4014
|
totalSearchedRows !== 1 ? "es" : ""
|
|
3475
4015
|
] }) })
|
|
3476
4016
|
] }),
|
|
3477
|
-
viewMode === "pivot" && canUsePivot && /* @__PURE__ */
|
|
3478
|
-
/* @__PURE__ */
|
|
4017
|
+
viewMode === "pivot" && canUsePivot && /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
4018
|
+
/* @__PURE__ */ jsxs7(
|
|
3479
4019
|
"button",
|
|
3480
4020
|
{
|
|
3481
4021
|
className: `vpg-config-toggle ${showPivotConfig ? "active" : ""}`,
|
|
3482
4022
|
onClick: () => setShowPivotConfig(!showPivotConfig),
|
|
3483
4023
|
children: [
|
|
3484
|
-
/* @__PURE__ */
|
|
4024
|
+
/* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
|
|
3485
4025
|
"path",
|
|
3486
4026
|
{
|
|
3487
4027
|
strokeLinecap: "round",
|
|
@@ -3496,8 +4036,8 @@ function DataGrid({
|
|
|
3496
4036
|
]
|
|
3497
4037
|
}
|
|
3498
4038
|
),
|
|
3499
|
-
pivotIsConfigured && /* @__PURE__ */
|
|
3500
|
-
/* @__PURE__ */
|
|
4039
|
+
pivotIsConfigured && /* @__PURE__ */ jsxs7("div", { className: "vpg-pivot-status", children: [
|
|
4040
|
+
/* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx7(
|
|
3501
4041
|
"path",
|
|
3502
4042
|
{
|
|
3503
4043
|
fillRule: "evenodd",
|
|
@@ -3505,13 +4045,13 @@ function DataGrid({
|
|
|
3505
4045
|
clipRule: "evenodd"
|
|
3506
4046
|
}
|
|
3507
4047
|
) }),
|
|
3508
|
-
/* @__PURE__ */
|
|
4048
|
+
/* @__PURE__ */ jsx7("span", { children: "Pivot configured" })
|
|
3509
4049
|
] })
|
|
3510
4050
|
] })
|
|
3511
4051
|
] }),
|
|
3512
|
-
/* @__PURE__ */
|
|
3513
|
-
viewMode === "grid" && activeFilterCount > 0 && /* @__PURE__ */
|
|
3514
|
-
/* @__PURE__ */
|
|
4052
|
+
/* @__PURE__ */ jsxs7("div", { className: "vpg-toolbar-right", children: [
|
|
4053
|
+
viewMode === "grid" && activeFilterCount > 0 && /* @__PURE__ */ jsxs7("button", { className: "vpg-clear-filters", onClick: clearAllFilters, children: [
|
|
4054
|
+
/* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
|
|
3515
4055
|
"path",
|
|
3516
4056
|
{
|
|
3517
4057
|
strokeLinecap: "round",
|
|
@@ -3522,13 +4062,13 @@ function DataGrid({
|
|
|
3522
4062
|
) }),
|
|
3523
4063
|
"Clear Filters"
|
|
3524
4064
|
] }),
|
|
3525
|
-
enableClipboard && selectionBounds && viewMode === "grid" && /* @__PURE__ */
|
|
4065
|
+
enableClipboard && selectionBounds && viewMode === "grid" && /* @__PURE__ */ jsx7(
|
|
3526
4066
|
"button",
|
|
3527
4067
|
{
|
|
3528
4068
|
className: "vpg-icon-btn",
|
|
3529
4069
|
title: "Copy selection (Ctrl+C)",
|
|
3530
4070
|
onClick: copySelectionToClipboard,
|
|
3531
|
-
children: /* @__PURE__ */
|
|
4071
|
+
children: /* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
|
|
3532
4072
|
"path",
|
|
3533
4073
|
{
|
|
3534
4074
|
strokeLinecap: "round",
|
|
@@ -3539,14 +4079,14 @@ function DataGrid({
|
|
|
3539
4079
|
) })
|
|
3540
4080
|
}
|
|
3541
4081
|
),
|
|
3542
|
-
enableExport && viewMode === "grid" && /* @__PURE__ */
|
|
4082
|
+
enableExport && viewMode === "grid" && /* @__PURE__ */ jsxs7(
|
|
3543
4083
|
"button",
|
|
3544
4084
|
{
|
|
3545
4085
|
className: "vpg-export-btn",
|
|
3546
4086
|
title: "Export to CSV",
|
|
3547
4087
|
onClick: handleExport,
|
|
3548
4088
|
children: [
|
|
3549
|
-
/* @__PURE__ */
|
|
4089
|
+
/* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
|
|
3550
4090
|
"path",
|
|
3551
4091
|
{
|
|
3552
4092
|
strokeLinecap: "round",
|
|
@@ -3559,7 +4099,7 @@ function DataGrid({
|
|
|
3559
4099
|
]
|
|
3560
4100
|
}
|
|
3561
4101
|
),
|
|
3562
|
-
enableExport && viewMode === "pivot" && pivotIsConfigured && /* @__PURE__ */
|
|
4102
|
+
enableExport && viewMode === "pivot" && pivotIsConfigured && /* @__PURE__ */ jsxs7(
|
|
3563
4103
|
"button",
|
|
3564
4104
|
{
|
|
3565
4105
|
className: `vpg-export-btn ${!isPro ? "vpg-export-btn-disabled" : ""}`,
|
|
@@ -3567,7 +4107,7 @@ function DataGrid({
|
|
|
3567
4107
|
title: isPro ? "Export Pivot to CSV" : "Export Pivot to CSV (Pro feature)",
|
|
3568
4108
|
onClick: () => isPro && handleExport(),
|
|
3569
4109
|
children: [
|
|
3570
|
-
/* @__PURE__ */
|
|
4110
|
+
/* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
|
|
3571
4111
|
"path",
|
|
3572
4112
|
{
|
|
3573
4113
|
strokeLinecap: "round",
|
|
@@ -3583,13 +4123,13 @@ function DataGrid({
|
|
|
3583
4123
|
)
|
|
3584
4124
|
] })
|
|
3585
4125
|
] }),
|
|
3586
|
-
viewMode === "grid" && /* @__PURE__ */
|
|
3587
|
-
loading && /* @__PURE__ */
|
|
3588
|
-
/* @__PURE__ */
|
|
3589
|
-
/* @__PURE__ */
|
|
4126
|
+
viewMode === "grid" && /* @__PURE__ */ jsxs7("div", { ref: tableContainerRef, className: "vpg-grid-container", tabIndex: 0, children: [
|
|
4127
|
+
loading && /* @__PURE__ */ jsxs7("div", { className: "vpg-loading", children: [
|
|
4128
|
+
/* @__PURE__ */ jsx7("div", { className: "vpg-spinner" }),
|
|
4129
|
+
/* @__PURE__ */ jsx7("span", { children: "Loading data..." })
|
|
3590
4130
|
] }),
|
|
3591
|
-
!loading && data.length === 0 && /* @__PURE__ */
|
|
3592
|
-
/* @__PURE__ */
|
|
4131
|
+
!loading && data.length === 0 && /* @__PURE__ */ jsxs7("div", { className: "vpg-empty", children: [
|
|
4132
|
+
/* @__PURE__ */ jsx7("div", { className: "vpg-empty-icon", children: /* @__PURE__ */ jsx7("svg", { className: "vpg-icon-lg", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
|
|
3593
4133
|
"path",
|
|
3594
4134
|
{
|
|
3595
4135
|
strokeLinecap: "round",
|
|
@@ -3598,10 +4138,10 @@ function DataGrid({
|
|
|
3598
4138
|
d: "M9 17v-2m3 2v-4m3 4v-6m2 10H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
|
|
3599
4139
|
}
|
|
3600
4140
|
) }) }),
|
|
3601
|
-
/* @__PURE__ */
|
|
4141
|
+
/* @__PURE__ */ jsx7("span", { children: "No data available" })
|
|
3602
4142
|
] }),
|
|
3603
|
-
!loading && data.length > 0 && filteredRowCount === 0 && /* @__PURE__ */
|
|
3604
|
-
/* @__PURE__ */
|
|
4143
|
+
!loading && data.length > 0 && filteredRowCount === 0 && /* @__PURE__ */ jsxs7("div", { className: "vpg-empty", children: [
|
|
4144
|
+
/* @__PURE__ */ jsx7("div", { className: "vpg-empty-icon vpg-warning", children: /* @__PURE__ */ jsx7("svg", { className: "vpg-icon-lg", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
|
|
3605
4145
|
"path",
|
|
3606
4146
|
{
|
|
3607
4147
|
strokeLinecap: "round",
|
|
@@ -3610,11 +4150,11 @@ function DataGrid({
|
|
|
3610
4150
|
d: "M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z"
|
|
3611
4151
|
}
|
|
3612
4152
|
) }) }),
|
|
3613
|
-
/* @__PURE__ */
|
|
3614
|
-
/* @__PURE__ */
|
|
4153
|
+
/* @__PURE__ */ jsx7("span", { children: "No matching records" }),
|
|
4154
|
+
/* @__PURE__ */ jsx7("button", { className: "vpg-clear-link", onClick: clearAllFilters, children: "Clear all filters" })
|
|
3615
4155
|
] }),
|
|
3616
|
-
!loading && filteredRowCount > 0 && /* @__PURE__ */
|
|
3617
|
-
/* @__PURE__ */
|
|
4156
|
+
!loading && filteredRowCount > 0 && /* @__PURE__ */ jsx7("div", { className: "vpg-table-wrapper", children: /* @__PURE__ */ jsxs7("table", { className: "vpg-table", style: { minWidth: `${totalTableWidth}px` }, children: [
|
|
4157
|
+
/* @__PURE__ */ jsx7("thead", { children: /* @__PURE__ */ jsx7("tr", { children: columnKeys.map((colId) => /* @__PURE__ */ jsxs7(
|
|
3618
4158
|
"th",
|
|
3619
4159
|
{
|
|
3620
4160
|
className: `vpg-header-cell ${hasActiveFilter(colId) ? "vpg-has-filter" : ""} ${getSortDirection(colId) !== null ? "vpg-is-sorted" : ""} ${activeFilterColumn === colId ? "vpg-is-active" : ""}`,
|
|
@@ -3629,16 +4169,16 @@ function DataGrid({
|
|
|
3629
4169
|
}
|
|
3630
4170
|
},
|
|
3631
4171
|
children: [
|
|
3632
|
-
/* @__PURE__ */
|
|
3633
|
-
/* @__PURE__ */
|
|
3634
|
-
/* @__PURE__ */
|
|
3635
|
-
getSortDirection(colId) && /* @__PURE__ */
|
|
4172
|
+
/* @__PURE__ */ jsxs7("div", { className: "vpg-header-content", children: [
|
|
4173
|
+
/* @__PURE__ */ jsx7("span", { className: "vpg-header-text", children: colId }),
|
|
4174
|
+
/* @__PURE__ */ jsxs7("div", { className: "vpg-header-icons", children: [
|
|
4175
|
+
getSortDirection(colId) && /* @__PURE__ */ jsx7("span", { className: "vpg-sort-indicator", children: getSortDirection(colId) === "asc" ? /* @__PURE__ */ jsx7(
|
|
3636
4176
|
"svg",
|
|
3637
4177
|
{
|
|
3638
4178
|
className: "vpg-icon-sm",
|
|
3639
4179
|
fill: "currentColor",
|
|
3640
4180
|
viewBox: "0 0 20 20",
|
|
3641
|
-
children: /* @__PURE__ */
|
|
4181
|
+
children: /* @__PURE__ */ jsx7(
|
|
3642
4182
|
"path",
|
|
3643
4183
|
{
|
|
3644
4184
|
fillRule: "evenodd",
|
|
@@ -3647,13 +4187,13 @@ function DataGrid({
|
|
|
3647
4187
|
}
|
|
3648
4188
|
)
|
|
3649
4189
|
}
|
|
3650
|
-
) : /* @__PURE__ */
|
|
4190
|
+
) : /* @__PURE__ */ jsx7(
|
|
3651
4191
|
"svg",
|
|
3652
4192
|
{
|
|
3653
4193
|
className: "vpg-icon-sm",
|
|
3654
4194
|
fill: "currentColor",
|
|
3655
4195
|
viewBox: "0 0 20 20",
|
|
3656
|
-
children: /* @__PURE__ */
|
|
4196
|
+
children: /* @__PURE__ */ jsx7(
|
|
3657
4197
|
"path",
|
|
3658
4198
|
{
|
|
3659
4199
|
fillRule: "evenodd",
|
|
@@ -3663,13 +4203,13 @@ function DataGrid({
|
|
|
3663
4203
|
)
|
|
3664
4204
|
}
|
|
3665
4205
|
) }),
|
|
3666
|
-
hasActiveFilter(colId) && /* @__PURE__ */
|
|
4206
|
+
hasActiveFilter(colId) && /* @__PURE__ */ jsx7("span", { className: "vpg-filter-indicator", children: /* @__PURE__ */ jsx7(
|
|
3667
4207
|
"svg",
|
|
3668
4208
|
{
|
|
3669
4209
|
className: "vpg-icon-xs",
|
|
3670
4210
|
fill: "currentColor",
|
|
3671
4211
|
viewBox: "0 0 20 20",
|
|
3672
|
-
children: /* @__PURE__ */
|
|
4212
|
+
children: /* @__PURE__ */ jsx7(
|
|
3673
4213
|
"path",
|
|
3674
4214
|
{
|
|
3675
4215
|
fillRule: "evenodd",
|
|
@@ -3679,14 +4219,14 @@ function DataGrid({
|
|
|
3679
4219
|
)
|
|
3680
4220
|
}
|
|
3681
4221
|
) }),
|
|
3682
|
-
/* @__PURE__ */
|
|
4222
|
+
/* @__PURE__ */ jsx7("span", { className: "vpg-dropdown-arrow", title: "Filter & Sort", children: /* @__PURE__ */ jsx7(
|
|
3683
4223
|
"svg",
|
|
3684
4224
|
{
|
|
3685
4225
|
className: "vpg-icon-sm",
|
|
3686
4226
|
fill: "none",
|
|
3687
4227
|
stroke: "currentColor",
|
|
3688
4228
|
viewBox: "0 0 24 24",
|
|
3689
|
-
children: /* @__PURE__ */
|
|
4229
|
+
children: /* @__PURE__ */ jsx7(
|
|
3690
4230
|
"path",
|
|
3691
4231
|
{
|
|
3692
4232
|
strokeLinecap: "round",
|
|
@@ -3699,7 +4239,7 @@ function DataGrid({
|
|
|
3699
4239
|
) })
|
|
3700
4240
|
] })
|
|
3701
4241
|
] }),
|
|
3702
|
-
enableColumnResize && /* @__PURE__ */
|
|
4242
|
+
enableColumnResize && /* @__PURE__ */ jsx7(
|
|
3703
4243
|
"div",
|
|
3704
4244
|
{
|
|
3705
4245
|
className: "vpg-resize-handle",
|
|
@@ -3710,7 +4250,7 @@ function DataGrid({
|
|
|
3710
4250
|
},
|
|
3711
4251
|
colId
|
|
3712
4252
|
)) }) }),
|
|
3713
|
-
/* @__PURE__ */
|
|
4253
|
+
/* @__PURE__ */ jsx7("tbody", { ref: tableBodyRef, children: paginatedRows.map((row, rowIndex) => /* @__PURE__ */ jsx7("tr", { className: "vpg-row", children: columnKeys.map((colId, colIndex) => /* @__PURE__ */ jsx7(
|
|
3714
4254
|
"td",
|
|
3715
4255
|
{
|
|
3716
4256
|
className: `vpg-cell ${isCellSelected(rowIndex, colIndex) ? "vpg-selected" : ""} ${getColumnStats(colId).type === "number" ? "vpg-is-number" : ""}`,
|
|
@@ -3728,8 +4268,8 @@ function DataGrid({
|
|
|
3728
4268
|
)) }, row.id)) })
|
|
3729
4269
|
] }) })
|
|
3730
4270
|
] }),
|
|
3731
|
-
viewMode === "pivot" && /* @__PURE__ */
|
|
3732
|
-
showPivotConfig && canUsePivot && /* @__PURE__ */
|
|
4271
|
+
viewMode === "pivot" && /* @__PURE__ */ jsxs7("div", { className: "vpg-pivot-container", children: [
|
|
4272
|
+
showPivotConfig && canUsePivot && /* @__PURE__ */ jsx7("div", { className: "vpg-pivot-config-panel", children: /* @__PURE__ */ jsx7(
|
|
3733
4273
|
PivotConfig,
|
|
3734
4274
|
{
|
|
3735
4275
|
availableFields: pivotAvailableFields,
|
|
@@ -3757,7 +4297,7 @@ function DataGrid({
|
|
|
3757
4297
|
onUpdateCalculatedField: addCalculatedField
|
|
3758
4298
|
}
|
|
3759
4299
|
) }),
|
|
3760
|
-
/* @__PURE__ */
|
|
4300
|
+
/* @__PURE__ */ jsx7("div", { className: `vpg-pivot-main ${!showPivotConfig ? "vpg-full-width" : ""}`, children: /* @__PURE__ */ jsx7(
|
|
3761
4301
|
PivotSkeleton,
|
|
3762
4302
|
{
|
|
3763
4303
|
rowFields: pivotRowFields,
|
|
@@ -3783,47 +4323,78 @@ function DataGrid({
|
|
|
3783
4323
|
}
|
|
3784
4324
|
) })
|
|
3785
4325
|
] }),
|
|
3786
|
-
/* @__PURE__ */
|
|
3787
|
-
/* @__PURE__ */
|
|
3788
|
-
/* @__PURE__ */
|
|
4326
|
+
viewMode === "chart" && /* @__PURE__ */ jsxs7("div", { className: "vpg-chart-view", children: [
|
|
4327
|
+
activeFilterInfo && activeFilterInfo.length > 0 && /* @__PURE__ */ jsxs7("div", { className: "vpg-chart-filter-bar", children: [
|
|
4328
|
+
/* @__PURE__ */ jsx7("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx7("path", { fillRule: "evenodd", d: "M3 3a1 1 0 011-1h12a1 1 0 011 1v3a1 1 0 01-.293.707L12 11.414V15a1 1 0 01-.293.707l-2 2A1 1 0 018 17v-5.586L3.293 6.707A1 1 0 013 6V3z", clipRule: "evenodd" }) }),
|
|
4329
|
+
/* @__PURE__ */ jsxs7("span", { children: [
|
|
4330
|
+
"Chart showing",
|
|
4331
|
+
filteredRowCount.toLocaleString(),
|
|
4332
|
+
" ",
|
|
4333
|
+
"of",
|
|
4334
|
+
totalRowCount.toLocaleString(),
|
|
4335
|
+
" ",
|
|
4336
|
+
"records"
|
|
4337
|
+
] }),
|
|
4338
|
+
/* @__PURE__ */ jsx7("button", { className: "vpg-chart-clear-filters", onClick: clearAllFilters, children: "Clear filters" })
|
|
4339
|
+
] }),
|
|
4340
|
+
/* @__PURE__ */ jsx7(
|
|
4341
|
+
ChartBuilder,
|
|
4342
|
+
{
|
|
4343
|
+
data: filteredDataForPivot,
|
|
4344
|
+
theme: currentTheme,
|
|
4345
|
+
onConfigChange: handleChartConfigChange
|
|
4346
|
+
}
|
|
4347
|
+
)
|
|
4348
|
+
] }),
|
|
4349
|
+
/* @__PURE__ */ jsxs7("div", { className: "vpg-footer", children: [
|
|
4350
|
+
/* @__PURE__ */ jsx7("div", { className: "vpg-footer-left", children: viewMode === "grid" ? enablePagination ? /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
4351
|
+
/* @__PURE__ */ jsxs7("span", { children: [
|
|
3789
4352
|
((currentPage - 1) * pageSize + 1).toLocaleString(),
|
|
3790
4353
|
"-",
|
|
3791
4354
|
Math.min(currentPage * pageSize, totalSearchedRows).toLocaleString()
|
|
3792
4355
|
] }),
|
|
3793
|
-
/* @__PURE__ */
|
|
3794
|
-
/* @__PURE__ */
|
|
3795
|
-
totalSearchedRows !== totalRowCount && /* @__PURE__ */
|
|
4356
|
+
/* @__PURE__ */ jsx7("span", { className: "vpg-separator", children: "of" }),
|
|
4357
|
+
/* @__PURE__ */ jsx7("span", { children: totalSearchedRows.toLocaleString() }),
|
|
4358
|
+
totalSearchedRows !== totalRowCount && /* @__PURE__ */ jsxs7("span", { className: "vpg-filtered-note", children: [
|
|
3796
4359
|
"(",
|
|
3797
4360
|
totalRowCount.toLocaleString(),
|
|
3798
4361
|
" ",
|
|
3799
4362
|
"total)"
|
|
3800
4363
|
] })
|
|
3801
|
-
] }) : filteredRowCount === totalRowCount && totalSearchedRows === totalRowCount ? /* @__PURE__ */
|
|
4364
|
+
] }) : filteredRowCount === totalRowCount && totalSearchedRows === totalRowCount ? /* @__PURE__ */ jsxs7("span", { children: [
|
|
3802
4365
|
totalRowCount.toLocaleString(),
|
|
3803
4366
|
" ",
|
|
3804
4367
|
"records"
|
|
3805
|
-
] }) : /* @__PURE__ */
|
|
3806
|
-
/* @__PURE__ */
|
|
3807
|
-
/* @__PURE__ */
|
|
3808
|
-
/* @__PURE__ */
|
|
3809
|
-
/* @__PURE__ */
|
|
3810
|
-
] }) : /* @__PURE__ */
|
|
3811
|
-
/* @__PURE__ */
|
|
3812
|
-
/* @__PURE__ */
|
|
3813
|
-
/* @__PURE__ */
|
|
4368
|
+
] }) : /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
4369
|
+
/* @__PURE__ */ jsx7("span", { className: "vpg-filtered-count", children: totalSearchedRows.toLocaleString() }),
|
|
4370
|
+
/* @__PURE__ */ jsx7("span", { className: "vpg-separator", children: "of" }),
|
|
4371
|
+
/* @__PURE__ */ jsx7("span", { children: totalRowCount.toLocaleString() }),
|
|
4372
|
+
/* @__PURE__ */ jsx7("span", { className: "vpg-separator", children: "records" })
|
|
4373
|
+
] }) : viewMode === "pivot" ? /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
4374
|
+
/* @__PURE__ */ jsx7("span", { className: "vpg-pivot-label", children: "Pivot Table" }),
|
|
4375
|
+
/* @__PURE__ */ jsx7("span", { className: "vpg-separator", children: "\u2022" }),
|
|
4376
|
+
/* @__PURE__ */ jsxs7("span", { children: [
|
|
3814
4377
|
totalRowCount.toLocaleString(),
|
|
3815
4378
|
" ",
|
|
3816
4379
|
"source records"
|
|
3817
4380
|
] })
|
|
4381
|
+
] }) : /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
4382
|
+
/* @__PURE__ */ jsx7("span", { className: "vpg-chart-label", children: "Chart Builder" }),
|
|
4383
|
+
/* @__PURE__ */ jsx7("span", { className: "vpg-separator", children: "\u2022" }),
|
|
4384
|
+
/* @__PURE__ */ jsxs7("span", { children: [
|
|
4385
|
+
totalRowCount.toLocaleString(),
|
|
4386
|
+
" ",
|
|
4387
|
+
"records"
|
|
4388
|
+
] })
|
|
3818
4389
|
] }) }),
|
|
3819
|
-
enablePagination && viewMode === "grid" && totalPages > 1 && /* @__PURE__ */
|
|
3820
|
-
/* @__PURE__ */
|
|
4390
|
+
enablePagination && viewMode === "grid" && totalPages > 1 && /* @__PURE__ */ jsxs7("div", { className: "vpg-pagination", children: [
|
|
4391
|
+
/* @__PURE__ */ jsx7(
|
|
3821
4392
|
"button",
|
|
3822
4393
|
{
|
|
3823
4394
|
className: "vpg-page-btn",
|
|
3824
4395
|
disabled: currentPage === 1,
|
|
3825
4396
|
onClick: () => setCurrentPage(1),
|
|
3826
|
-
children: /* @__PURE__ */
|
|
4397
|
+
children: /* @__PURE__ */ jsx7("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
|
|
3827
4398
|
"path",
|
|
3828
4399
|
{
|
|
3829
4400
|
strokeLinecap: "round",
|
|
@@ -3834,13 +4405,13 @@ function DataGrid({
|
|
|
3834
4405
|
) })
|
|
3835
4406
|
}
|
|
3836
4407
|
),
|
|
3837
|
-
/* @__PURE__ */
|
|
4408
|
+
/* @__PURE__ */ jsx7(
|
|
3838
4409
|
"button",
|
|
3839
4410
|
{
|
|
3840
4411
|
className: "vpg-page-btn",
|
|
3841
4412
|
disabled: currentPage === 1,
|
|
3842
4413
|
onClick: () => setCurrentPage((p) => Math.max(1, p - 1)),
|
|
3843
|
-
children: /* @__PURE__ */
|
|
4414
|
+
children: /* @__PURE__ */ jsx7("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
|
|
3844
4415
|
"path",
|
|
3845
4416
|
{
|
|
3846
4417
|
strokeLinecap: "round",
|
|
@@ -3851,7 +4422,7 @@ function DataGrid({
|
|
|
3851
4422
|
) })
|
|
3852
4423
|
}
|
|
3853
4424
|
),
|
|
3854
|
-
/* @__PURE__ */
|
|
4425
|
+
/* @__PURE__ */ jsxs7("span", { className: "vpg-page-info", children: [
|
|
3855
4426
|
"Page",
|
|
3856
4427
|
" ",
|
|
3857
4428
|
currentPage,
|
|
@@ -3860,13 +4431,13 @@ function DataGrid({
|
|
|
3860
4431
|
" ",
|
|
3861
4432
|
totalPages
|
|
3862
4433
|
] }),
|
|
3863
|
-
/* @__PURE__ */
|
|
4434
|
+
/* @__PURE__ */ jsx7(
|
|
3864
4435
|
"button",
|
|
3865
4436
|
{
|
|
3866
4437
|
className: "vpg-page-btn",
|
|
3867
4438
|
disabled: currentPage === totalPages,
|
|
3868
4439
|
onClick: () => setCurrentPage((p) => Math.min(totalPages, p + 1)),
|
|
3869
|
-
children: /* @__PURE__ */
|
|
4440
|
+
children: /* @__PURE__ */ jsx7("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
|
|
3870
4441
|
"path",
|
|
3871
4442
|
{
|
|
3872
4443
|
strokeLinecap: "round",
|
|
@@ -3877,13 +4448,13 @@ function DataGrid({
|
|
|
3877
4448
|
) })
|
|
3878
4449
|
}
|
|
3879
4450
|
),
|
|
3880
|
-
/* @__PURE__ */
|
|
4451
|
+
/* @__PURE__ */ jsx7(
|
|
3881
4452
|
"button",
|
|
3882
4453
|
{
|
|
3883
4454
|
className: "vpg-page-btn",
|
|
3884
4455
|
disabled: currentPage === totalPages,
|
|
3885
4456
|
onClick: () => setCurrentPage(totalPages),
|
|
3886
|
-
children: /* @__PURE__ */
|
|
4457
|
+
children: /* @__PURE__ */ jsx7("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7(
|
|
3887
4458
|
"path",
|
|
3888
4459
|
{
|
|
3889
4460
|
strokeLinecap: "round",
|
|
@@ -3895,45 +4466,45 @@ function DataGrid({
|
|
|
3895
4466
|
}
|
|
3896
4467
|
)
|
|
3897
4468
|
] }),
|
|
3898
|
-
viewMode === "grid" && selectionStats && selectionStats.count > 1 && /* @__PURE__ */
|
|
3899
|
-
/* @__PURE__ */
|
|
3900
|
-
/* @__PURE__ */
|
|
3901
|
-
/* @__PURE__ */
|
|
4469
|
+
viewMode === "grid" && selectionStats && selectionStats.count > 1 && /* @__PURE__ */ jsxs7("div", { className: "vpg-selection-stats", children: [
|
|
4470
|
+
/* @__PURE__ */ jsxs7("span", { className: "vpg-stat", children: [
|
|
4471
|
+
/* @__PURE__ */ jsx7("span", { className: "vpg-stat-label", children: "Count:" }),
|
|
4472
|
+
/* @__PURE__ */ jsx7("span", { className: "vpg-stat-value", children: selectionStats.count })
|
|
3902
4473
|
] }),
|
|
3903
|
-
selectionStats.numericCount > 0 && /* @__PURE__ */
|
|
3904
|
-
/* @__PURE__ */
|
|
3905
|
-
/* @__PURE__ */
|
|
3906
|
-
/* @__PURE__ */
|
|
3907
|
-
/* @__PURE__ */
|
|
4474
|
+
selectionStats.numericCount > 0 && /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
4475
|
+
/* @__PURE__ */ jsx7("span", { className: "vpg-stat-divider", children: "|" }),
|
|
4476
|
+
/* @__PURE__ */ jsxs7("span", { className: "vpg-stat", children: [
|
|
4477
|
+
/* @__PURE__ */ jsx7("span", { className: "vpg-stat-label", children: "Sum:" }),
|
|
4478
|
+
/* @__PURE__ */ jsx7("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.sum) })
|
|
3908
4479
|
] }),
|
|
3909
|
-
/* @__PURE__ */
|
|
3910
|
-
/* @__PURE__ */
|
|
3911
|
-
/* @__PURE__ */
|
|
3912
|
-
/* @__PURE__ */
|
|
4480
|
+
/* @__PURE__ */ jsx7("span", { className: "vpg-stat-divider", children: "|" }),
|
|
4481
|
+
/* @__PURE__ */ jsxs7("span", { className: "vpg-stat", children: [
|
|
4482
|
+
/* @__PURE__ */ jsx7("span", { className: "vpg-stat-label", children: "Avg:" }),
|
|
4483
|
+
/* @__PURE__ */ jsx7("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.avg) })
|
|
3913
4484
|
] })
|
|
3914
4485
|
] })
|
|
3915
4486
|
] }),
|
|
3916
|
-
/* @__PURE__ */
|
|
3917
|
-
/* @__PURE__ */
|
|
3918
|
-
/* @__PURE__ */
|
|
3919
|
-
/* @__PURE__ */
|
|
3920
|
-
] }) : showWatermark ? /* @__PURE__ */
|
|
3921
|
-
/* @__PURE__ */
|
|
3922
|
-
/* @__PURE__ */
|
|
3923
|
-
/* @__PURE__ */
|
|
3924
|
-
/* @__PURE__ */
|
|
3925
|
-
/* @__PURE__ */
|
|
4487
|
+
/* @__PURE__ */ jsx7("div", { className: "vpg-footer-right", children: isDemo ? /* @__PURE__ */ jsxs7("div", { className: "vpg-demo-banner", children: [
|
|
4488
|
+
/* @__PURE__ */ jsx7("span", { className: "vpg-demo-badge", children: "DEMO" }),
|
|
4489
|
+
/* @__PURE__ */ jsx7("span", { children: "Pro features enabled" }),
|
|
4490
|
+
/* @__PURE__ */ jsx7("a", { href: "https://tiny-pivot.com/#pricing", target: "_blank", rel: "noopener noreferrer", children: "Get License \u2192" })
|
|
4491
|
+
] }) : showWatermark ? /* @__PURE__ */ jsx7("span", { className: "vpg-watermark-inline", children: /* @__PURE__ */ jsxs7("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: [
|
|
4492
|
+
/* @__PURE__ */ jsxs7("svg", { xmlns: "http://www.w3.org/2000/svg", width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
4493
|
+
/* @__PURE__ */ jsx7("rect", { x: "3", y: "3", width: "7", height: "7" }),
|
|
4494
|
+
/* @__PURE__ */ jsx7("rect", { x: "14", y: "3", width: "7", height: "7" }),
|
|
4495
|
+
/* @__PURE__ */ jsx7("rect", { x: "14", y: "14", width: "7", height: "7" }),
|
|
4496
|
+
/* @__PURE__ */ jsx7("rect", { x: "3", y: "14", width: "7", height: "7" })
|
|
3926
4497
|
] }),
|
|
3927
4498
|
"Powered by TinyPivot"
|
|
3928
4499
|
] }) }) : null })
|
|
3929
4500
|
] }),
|
|
3930
|
-
enableVerticalResize && /* @__PURE__ */
|
|
3931
|
-
/* @__PURE__ */
|
|
3932
|
-
/* @__PURE__ */
|
|
3933
|
-
/* @__PURE__ */
|
|
4501
|
+
enableVerticalResize && /* @__PURE__ */ jsx7("div", { className: "vpg-vertical-resize-handle", onMouseDown: startVerticalResize, children: /* @__PURE__ */ jsxs7("div", { className: "vpg-resize-grip", children: [
|
|
4502
|
+
/* @__PURE__ */ jsx7("span", {}),
|
|
4503
|
+
/* @__PURE__ */ jsx7("span", {}),
|
|
4504
|
+
/* @__PURE__ */ jsx7("span", {})
|
|
3934
4505
|
] }) }),
|
|
3935
4506
|
activeFilterColumn && typeof document !== "undefined" && createPortal2(
|
|
3936
|
-
/* @__PURE__ */
|
|
4507
|
+
/* @__PURE__ */ jsx7(
|
|
3937
4508
|
"div",
|
|
3938
4509
|
{
|
|
3939
4510
|
className: "vpg-filter-portal",
|
|
@@ -3944,7 +4515,7 @@ function DataGrid({
|
|
|
3944
4515
|
maxHeight: `${filterDropdownPosition.maxHeight}px`,
|
|
3945
4516
|
zIndex: 9999
|
|
3946
4517
|
},
|
|
3947
|
-
children: /* @__PURE__ */
|
|
4518
|
+
children: /* @__PURE__ */ jsx7(
|
|
3948
4519
|
ColumnFilter,
|
|
3949
4520
|
{
|
|
3950
4521
|
columnId: activeFilterColumn,
|