@smallwebco/tinypivot-react 1.0.51 → 1.0.53
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 +1379 -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 +1339 -596
- package/dist/index.js.map +1 -1
- package/dist/style.css +469 -0
- package/package.json +4 -2
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/index.ts
|
|
@@ -29,10 +39,10 @@ __export(index_exports, {
|
|
|
29
39
|
enableDemoMode: () => enableDemoMode,
|
|
30
40
|
exportPivotToCSV: () => exportPivotToCSV,
|
|
31
41
|
exportToCSV: () => exportToCSV,
|
|
32
|
-
formatCellValue: () =>
|
|
42
|
+
formatCellValue: () => import_tinypivot_core3.formatCellValue,
|
|
33
43
|
formatSelectionForClipboard: () => formatSelectionForClipboard,
|
|
34
|
-
getAggregationLabel: () =>
|
|
35
|
-
getColumnUniqueValues: () =>
|
|
44
|
+
getAggregationLabel: () => import_tinypivot_core6.getAggregationLabel,
|
|
45
|
+
getColumnUniqueValues: () => import_tinypivot_core3.getColumnUniqueValues,
|
|
36
46
|
setLicenseKey: () => setLicenseKey,
|
|
37
47
|
useColumnResize: () => useColumnResize,
|
|
38
48
|
useExcelGrid: () => useExcelGrid,
|
|
@@ -234,21 +244,690 @@ function CalculatedFieldModal({
|
|
|
234
244
|
return (0, import_react_dom.createPortal)(modalContent, document.body);
|
|
235
245
|
}
|
|
236
246
|
|
|
247
|
+
// src/components/ChartBuilder.tsx
|
|
248
|
+
var import_tinypivot_core2 = require("@smallwebco/tinypivot-core");
|
|
249
|
+
var import_react2 = require("react");
|
|
250
|
+
var import_react_apexcharts = __toESM(require("react-apexcharts"), 1);
|
|
251
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
252
|
+
function ChartBuilder({
|
|
253
|
+
data,
|
|
254
|
+
theme = "light",
|
|
255
|
+
onConfigChange
|
|
256
|
+
}) {
|
|
257
|
+
const [chartConfig, setChartConfig] = (0, import_react2.useState)((0, import_tinypivot_core2.createDefaultChartConfig)());
|
|
258
|
+
const [draggingField, setDraggingField] = (0, import_react2.useState)(null);
|
|
259
|
+
const [dragOverZone, setDragOverZone] = (0, import_react2.useState)(null);
|
|
260
|
+
const fieldInfos = (0, import_react2.useMemo)(() => (0, import_tinypivot_core2.analyzeFieldsForChart)(data), [data]);
|
|
261
|
+
const dimensions = (0, import_react2.useMemo)(
|
|
262
|
+
() => fieldInfos.filter((f) => f.role === "dimension" || f.role === "temporal"),
|
|
263
|
+
[fieldInfos]
|
|
264
|
+
);
|
|
265
|
+
const measures = (0, import_react2.useMemo)(
|
|
266
|
+
() => fieldInfos.filter((f) => f.role === "measure"),
|
|
267
|
+
[fieldInfos]
|
|
268
|
+
);
|
|
269
|
+
const guidance = (0, import_react2.useMemo)(() => (0, import_tinypivot_core2.getChartGuidance)(chartConfig), [chartConfig]);
|
|
270
|
+
const chartIsValid = (0, import_react2.useMemo)(() => (0, import_tinypivot_core2.isChartConfigValid)(chartConfig), [chartConfig]);
|
|
271
|
+
const selectedChartType = (0, import_react2.useMemo)(
|
|
272
|
+
() => import_tinypivot_core2.CHART_TYPES.find((ct) => ct.type === chartConfig.type),
|
|
273
|
+
[chartConfig.type]
|
|
274
|
+
);
|
|
275
|
+
const isScatterType = (0, import_react2.useMemo)(
|
|
276
|
+
() => ["scatter", "bubble"].includes(chartConfig.type),
|
|
277
|
+
[chartConfig.type]
|
|
278
|
+
);
|
|
279
|
+
const isHeatmapType = (0, import_react2.useMemo)(
|
|
280
|
+
() => chartConfig.type === "heatmap",
|
|
281
|
+
[chartConfig.type]
|
|
282
|
+
);
|
|
283
|
+
const zoneLabels = (0, import_react2.useMemo)(() => {
|
|
284
|
+
const type = chartConfig.type;
|
|
285
|
+
switch (type) {
|
|
286
|
+
case "scatter":
|
|
287
|
+
case "bubble":
|
|
288
|
+
return {
|
|
289
|
+
xAxis: "X-Axis (measure)",
|
|
290
|
+
xAxisPlaceholder: "Drop a measure",
|
|
291
|
+
yAxis: "Y-Axis (measure)",
|
|
292
|
+
yAxisPlaceholder: "Drop a measure",
|
|
293
|
+
series: "Color by (optional)",
|
|
294
|
+
seriesPlaceholder: "Group points by dimension",
|
|
295
|
+
showSize: type === "bubble",
|
|
296
|
+
showSeries: true
|
|
297
|
+
};
|
|
298
|
+
case "heatmap":
|
|
299
|
+
return {
|
|
300
|
+
xAxis: "X-Axis (dimension)",
|
|
301
|
+
xAxisPlaceholder: "Drop a dimension",
|
|
302
|
+
yAxis: "Y-Axis (dimension)",
|
|
303
|
+
yAxisPlaceholder: "Drop a dimension",
|
|
304
|
+
series: "Value / Intensity",
|
|
305
|
+
seriesPlaceholder: "Drop a measure for color intensity",
|
|
306
|
+
showSize: false,
|
|
307
|
+
showSeries: true
|
|
308
|
+
};
|
|
309
|
+
case "pie":
|
|
310
|
+
case "donut":
|
|
311
|
+
return {
|
|
312
|
+
xAxis: "Slices (dimension)",
|
|
313
|
+
xAxisPlaceholder: "Drop a dimension",
|
|
314
|
+
yAxis: "Values (measure)",
|
|
315
|
+
yAxisPlaceholder: "Drop a measure",
|
|
316
|
+
series: "",
|
|
317
|
+
seriesPlaceholder: "",
|
|
318
|
+
showSize: false,
|
|
319
|
+
showSeries: false
|
|
320
|
+
};
|
|
321
|
+
case "radar":
|
|
322
|
+
return {
|
|
323
|
+
xAxis: "Axes (dimension)",
|
|
324
|
+
xAxisPlaceholder: "Drop a dimension",
|
|
325
|
+
yAxis: "Values (measure)",
|
|
326
|
+
yAxisPlaceholder: "Drop a measure",
|
|
327
|
+
series: "Compare by (optional)",
|
|
328
|
+
seriesPlaceholder: "Group by dimension",
|
|
329
|
+
showSize: false,
|
|
330
|
+
showSeries: true
|
|
331
|
+
};
|
|
332
|
+
default:
|
|
333
|
+
return {
|
|
334
|
+
xAxis: "X-Axis (dimension)",
|
|
335
|
+
xAxisPlaceholder: "Drop a dimension",
|
|
336
|
+
yAxis: "Y-Axis (measure)",
|
|
337
|
+
yAxisPlaceholder: "Drop a measure",
|
|
338
|
+
series: "Color / Series (optional)",
|
|
339
|
+
seriesPlaceholder: "Group by dimension",
|
|
340
|
+
showSize: false,
|
|
341
|
+
showSeries: true
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
}, [chartConfig.type]);
|
|
345
|
+
const handleDragStart = (0, import_react2.useCallback)((field, event) => {
|
|
346
|
+
setDraggingField(field);
|
|
347
|
+
event.dataTransfer?.setData("text/plain", field.field);
|
|
348
|
+
}, []);
|
|
349
|
+
const handleDragEnd = (0, import_react2.useCallback)(() => {
|
|
350
|
+
setDraggingField(null);
|
|
351
|
+
setDragOverZone(null);
|
|
352
|
+
}, []);
|
|
353
|
+
const handleDragOver = (0, import_react2.useCallback)((zone, event) => {
|
|
354
|
+
event.preventDefault();
|
|
355
|
+
setDragOverZone(zone);
|
|
356
|
+
}, []);
|
|
357
|
+
const handleDragLeave = (0, import_react2.useCallback)(() => {
|
|
358
|
+
setDragOverZone(null);
|
|
359
|
+
}, []);
|
|
360
|
+
const handleDrop = (0, import_react2.useCallback)((zone, event) => {
|
|
361
|
+
event.preventDefault();
|
|
362
|
+
setDragOverZone(null);
|
|
363
|
+
if (!draggingField)
|
|
364
|
+
return;
|
|
365
|
+
const field = draggingField;
|
|
366
|
+
const chartField = {
|
|
367
|
+
field: field.field,
|
|
368
|
+
label: field.label,
|
|
369
|
+
role: field.role,
|
|
370
|
+
aggregation: field.role === "measure" ? "sum" : void 0
|
|
371
|
+
};
|
|
372
|
+
let newConfig = { ...chartConfig };
|
|
373
|
+
switch (zone) {
|
|
374
|
+
case "xAxis":
|
|
375
|
+
newConfig = { ...newConfig, xAxis: chartField };
|
|
376
|
+
break;
|
|
377
|
+
case "yAxis":
|
|
378
|
+
newConfig = { ...newConfig, yAxis: chartField };
|
|
379
|
+
break;
|
|
380
|
+
case "series":
|
|
381
|
+
newConfig = { ...newConfig, seriesField: chartField };
|
|
382
|
+
break;
|
|
383
|
+
case "size":
|
|
384
|
+
newConfig = { ...newConfig, sizeField: chartField };
|
|
385
|
+
break;
|
|
386
|
+
case "color":
|
|
387
|
+
newConfig = { ...newConfig, colorField: chartField };
|
|
388
|
+
break;
|
|
389
|
+
}
|
|
390
|
+
setChartConfig(newConfig);
|
|
391
|
+
onConfigChange?.(newConfig);
|
|
392
|
+
}, [chartConfig, draggingField, onConfigChange]);
|
|
393
|
+
const removeField = (0, import_react2.useCallback)((zone) => {
|
|
394
|
+
let newConfig = { ...chartConfig };
|
|
395
|
+
switch (zone) {
|
|
396
|
+
case "xAxis":
|
|
397
|
+
newConfig = { ...newConfig, xAxis: void 0 };
|
|
398
|
+
break;
|
|
399
|
+
case "yAxis":
|
|
400
|
+
newConfig = { ...newConfig, yAxis: void 0 };
|
|
401
|
+
break;
|
|
402
|
+
case "series":
|
|
403
|
+
newConfig = { ...newConfig, seriesField: void 0 };
|
|
404
|
+
break;
|
|
405
|
+
case "size":
|
|
406
|
+
newConfig = { ...newConfig, sizeField: void 0 };
|
|
407
|
+
break;
|
|
408
|
+
case "color":
|
|
409
|
+
newConfig = { ...newConfig, colorField: void 0 };
|
|
410
|
+
break;
|
|
411
|
+
}
|
|
412
|
+
setChartConfig(newConfig);
|
|
413
|
+
onConfigChange?.(newConfig);
|
|
414
|
+
}, [chartConfig, onConfigChange]);
|
|
415
|
+
const selectChartType = (0, import_react2.useCallback)((type) => {
|
|
416
|
+
const newConfig = { ...chartConfig, type };
|
|
417
|
+
setChartConfig(newConfig);
|
|
418
|
+
onConfigChange?.(newConfig);
|
|
419
|
+
}, [chartConfig, onConfigChange]);
|
|
420
|
+
const updateAggregation = (0, import_react2.useCallback)((zone, aggregation) => {
|
|
421
|
+
let field;
|
|
422
|
+
switch (zone) {
|
|
423
|
+
case "xAxis":
|
|
424
|
+
field = chartConfig.xAxis;
|
|
425
|
+
break;
|
|
426
|
+
case "yAxis":
|
|
427
|
+
field = chartConfig.yAxis;
|
|
428
|
+
break;
|
|
429
|
+
case "size":
|
|
430
|
+
field = chartConfig.sizeField;
|
|
431
|
+
break;
|
|
432
|
+
case "color":
|
|
433
|
+
field = chartConfig.colorField;
|
|
434
|
+
break;
|
|
435
|
+
default:
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
if (!field)
|
|
439
|
+
return;
|
|
440
|
+
const updated = { ...field, aggregation };
|
|
441
|
+
let newConfig = { ...chartConfig };
|
|
442
|
+
switch (zone) {
|
|
443
|
+
case "xAxis":
|
|
444
|
+
newConfig = { ...newConfig, xAxis: updated };
|
|
445
|
+
break;
|
|
446
|
+
case "yAxis":
|
|
447
|
+
newConfig = { ...newConfig, yAxis: updated };
|
|
448
|
+
break;
|
|
449
|
+
case "size":
|
|
450
|
+
newConfig = { ...newConfig, sizeField: updated };
|
|
451
|
+
break;
|
|
452
|
+
case "color":
|
|
453
|
+
newConfig = { ...newConfig, colorField: updated };
|
|
454
|
+
break;
|
|
455
|
+
}
|
|
456
|
+
setChartConfig(newConfig);
|
|
457
|
+
onConfigChange?.(newConfig);
|
|
458
|
+
}, [chartConfig, onConfigChange]);
|
|
459
|
+
const getApexChartType = (0, import_react2.useCallback)((type) => {
|
|
460
|
+
const mapping = {
|
|
461
|
+
bar: "bar",
|
|
462
|
+
line: "line",
|
|
463
|
+
area: "area",
|
|
464
|
+
pie: "pie",
|
|
465
|
+
donut: "donut",
|
|
466
|
+
radar: "radar",
|
|
467
|
+
scatter: "scatter",
|
|
468
|
+
bubble: "bubble",
|
|
469
|
+
heatmap: "heatmap"
|
|
470
|
+
};
|
|
471
|
+
return mapping[type] || "bar";
|
|
472
|
+
}, []);
|
|
473
|
+
const formatValue = (0, import_react2.useCallback)((val, format, decimals) => {
|
|
474
|
+
if (val === null || val === void 0)
|
|
475
|
+
return "";
|
|
476
|
+
if (typeof val !== "number")
|
|
477
|
+
return String(val);
|
|
478
|
+
if (Number.isNaN(val))
|
|
479
|
+
return "";
|
|
480
|
+
const dec = decimals ?? 0;
|
|
481
|
+
if (format === "percent") {
|
|
482
|
+
return `${val.toFixed(dec)}%`;
|
|
483
|
+
}
|
|
484
|
+
if (format === "currency") {
|
|
485
|
+
return `$${val.toLocaleString(void 0, { minimumFractionDigits: dec, maximumFractionDigits: dec })}`;
|
|
486
|
+
}
|
|
487
|
+
if (Math.abs(val) >= 1e3) {
|
|
488
|
+
return val.toLocaleString(void 0, { maximumFractionDigits: dec });
|
|
489
|
+
}
|
|
490
|
+
return val.toFixed(dec);
|
|
491
|
+
}, []);
|
|
492
|
+
const chartOptions = (0, import_react2.useMemo)(() => {
|
|
493
|
+
const isDark = theme === "dark";
|
|
494
|
+
const config = chartConfig;
|
|
495
|
+
const options = config.options || {};
|
|
496
|
+
const baseOptions = {
|
|
497
|
+
chart: {
|
|
498
|
+
type: getApexChartType(config.type),
|
|
499
|
+
background: "transparent",
|
|
500
|
+
foreColor: isDark ? "#e2e8f0" : "#334155",
|
|
501
|
+
toolbar: {
|
|
502
|
+
show: true,
|
|
503
|
+
tools: {
|
|
504
|
+
download: true,
|
|
505
|
+
selection: false,
|
|
506
|
+
zoom: options.enableZoom ?? false,
|
|
507
|
+
zoomin: options.enableZoom ?? false,
|
|
508
|
+
zoomout: options.enableZoom ?? false,
|
|
509
|
+
pan: false,
|
|
510
|
+
reset: options.enableZoom ?? false
|
|
511
|
+
},
|
|
512
|
+
export: {
|
|
513
|
+
csv: { filename: "chart-data" },
|
|
514
|
+
svg: { filename: "chart" },
|
|
515
|
+
png: { filename: "chart" }
|
|
516
|
+
}
|
|
517
|
+
},
|
|
518
|
+
animations: {
|
|
519
|
+
enabled: options.animated ?? true,
|
|
520
|
+
speed: 400,
|
|
521
|
+
dynamicAnimation: { enabled: true, speed: 300 }
|
|
522
|
+
},
|
|
523
|
+
fontFamily: "system-ui, -apple-system, sans-serif"
|
|
524
|
+
},
|
|
525
|
+
colors: options.colors || import_tinypivot_core2.CHART_COLORS,
|
|
526
|
+
theme: {
|
|
527
|
+
mode: isDark ? "dark" : "light"
|
|
528
|
+
},
|
|
529
|
+
grid: {
|
|
530
|
+
show: options.showGrid ?? true,
|
|
531
|
+
borderColor: isDark ? "#334155" : "#e2e8f0"
|
|
532
|
+
},
|
|
533
|
+
legend: {
|
|
534
|
+
show: options.showLegend ?? true,
|
|
535
|
+
position: options.legendPosition || "top"
|
|
536
|
+
},
|
|
537
|
+
dataLabels: {
|
|
538
|
+
enabled: options.showDataLabels ?? false
|
|
539
|
+
},
|
|
540
|
+
tooltip: {
|
|
541
|
+
theme: isDark ? "dark" : "light",
|
|
542
|
+
style: {
|
|
543
|
+
fontSize: "12px"
|
|
544
|
+
}
|
|
545
|
+
},
|
|
546
|
+
stroke: {
|
|
547
|
+
curve: "smooth",
|
|
548
|
+
width: config.type === "line" ? 3 : config.type === "area" ? 2 : 0
|
|
549
|
+
},
|
|
550
|
+
fill: {
|
|
551
|
+
opacity: config.type === "area" ? 0.4 : 1
|
|
552
|
+
}
|
|
553
|
+
};
|
|
554
|
+
if (config.xAxis) {
|
|
555
|
+
baseOptions.xaxis = {
|
|
556
|
+
...baseOptions.xaxis,
|
|
557
|
+
title: { text: options.xAxisTitle || config.xAxis.label },
|
|
558
|
+
labels: {
|
|
559
|
+
style: { colors: isDark ? "#94a3b8" : "#64748b" }
|
|
560
|
+
}
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
if (config.yAxis && !["pie", "donut", "radar"].includes(config.type)) {
|
|
564
|
+
baseOptions.yaxis = {
|
|
565
|
+
title: { text: options.yAxisTitle || config.yAxis.label },
|
|
566
|
+
labels: {
|
|
567
|
+
style: { colors: isDark ? "#94a3b8" : "#64748b" },
|
|
568
|
+
formatter: (val) => formatValue(val, options.valueFormat, options.decimals)
|
|
569
|
+
}
|
|
570
|
+
};
|
|
571
|
+
}
|
|
572
|
+
if (options.title) {
|
|
573
|
+
baseOptions.title = {
|
|
574
|
+
text: options.title,
|
|
575
|
+
style: {
|
|
576
|
+
fontSize: "16px",
|
|
577
|
+
fontWeight: "600",
|
|
578
|
+
color: isDark ? "#e2e8f0" : "#334155"
|
|
579
|
+
}
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
if (options.stacked && ["bar", "area"].includes(config.type)) {
|
|
583
|
+
baseOptions.chart.stacked = true;
|
|
584
|
+
}
|
|
585
|
+
if (config.type === "pie" || config.type === "donut") {
|
|
586
|
+
baseOptions.plotOptions = {
|
|
587
|
+
pie: {
|
|
588
|
+
donut: {
|
|
589
|
+
size: config.type === "donut" ? "55%" : "0%",
|
|
590
|
+
labels: {
|
|
591
|
+
show: config.type === "donut",
|
|
592
|
+
total: {
|
|
593
|
+
show: true,
|
|
594
|
+
label: "Total",
|
|
595
|
+
formatter: (w) => {
|
|
596
|
+
const total = w.globals.seriesTotals.reduce((a, b) => a + b, 0);
|
|
597
|
+
return formatValue(total, options.valueFormat, options.decimals);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
};
|
|
604
|
+
}
|
|
605
|
+
if (config.type === "radar") {
|
|
606
|
+
baseOptions.plotOptions = {
|
|
607
|
+
radar: {
|
|
608
|
+
polygons: {
|
|
609
|
+
strokeColors: isDark ? "#334155" : "#e2e8f0",
|
|
610
|
+
fill: { colors: isDark ? ["#1e293b", "#0f172a"] : ["#f8fafc", "#f1f5f9"] }
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
};
|
|
614
|
+
}
|
|
615
|
+
return baseOptions;
|
|
616
|
+
}, [chartConfig, theme, getApexChartType, formatValue]);
|
|
617
|
+
const chartSeries = (0, import_react2.useMemo)(() => {
|
|
618
|
+
const config = chartConfig;
|
|
619
|
+
if (!chartIsValid)
|
|
620
|
+
return [];
|
|
621
|
+
if (config.type === "pie" || config.type === "donut") {
|
|
622
|
+
const chartData2 = (0, import_tinypivot_core2.processChartDataForPie)(data, config);
|
|
623
|
+
return chartData2.series[0]?.data || [];
|
|
624
|
+
}
|
|
625
|
+
if (config.type === "scatter" || config.type === "bubble") {
|
|
626
|
+
const scatterData = (0, import_tinypivot_core2.processChartDataForScatter)(data, config);
|
|
627
|
+
return scatterData.series;
|
|
628
|
+
}
|
|
629
|
+
if (config.type === "heatmap") {
|
|
630
|
+
const heatmapData = (0, import_tinypivot_core2.processChartDataForHeatmap)(data, config);
|
|
631
|
+
return heatmapData.series;
|
|
632
|
+
}
|
|
633
|
+
const chartData = (0, import_tinypivot_core2.processChartData)(data, config);
|
|
634
|
+
return chartData.series;
|
|
635
|
+
}, [data, chartConfig, chartIsValid]);
|
|
636
|
+
const chartLabels = (0, import_react2.useMemo)(() => {
|
|
637
|
+
const config = chartConfig;
|
|
638
|
+
if (!chartIsValid)
|
|
639
|
+
return [];
|
|
640
|
+
if (config.type === "pie" || config.type === "donut") {
|
|
641
|
+
const chartData2 = (0, import_tinypivot_core2.processChartDataForPie)(data, config);
|
|
642
|
+
return chartData2.categories;
|
|
643
|
+
}
|
|
644
|
+
const chartData = (0, import_tinypivot_core2.processChartData)(data, config);
|
|
645
|
+
return chartData.categories;
|
|
646
|
+
}, [data, chartConfig, chartIsValid]);
|
|
647
|
+
const chartOptionsWithCategories = (0, import_react2.useMemo)(() => {
|
|
648
|
+
const options = { ...chartOptions };
|
|
649
|
+
const config = chartConfig;
|
|
650
|
+
if (!["pie", "donut", "scatter", "bubble", "heatmap"].includes(config.type)) {
|
|
651
|
+
options.xaxis = {
|
|
652
|
+
...options.xaxis,
|
|
653
|
+
categories: chartLabels
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
if (config.type === "pie" || config.type === "donut") {
|
|
657
|
+
options.labels = chartLabels;
|
|
658
|
+
}
|
|
659
|
+
if (config.type === "heatmap") {
|
|
660
|
+
options.chart = {
|
|
661
|
+
...options.chart,
|
|
662
|
+
type: "heatmap"
|
|
663
|
+
};
|
|
664
|
+
options.xaxis = {
|
|
665
|
+
...options.xaxis,
|
|
666
|
+
type: "category"
|
|
667
|
+
};
|
|
668
|
+
options.dataLabels = {
|
|
669
|
+
enabled: true,
|
|
670
|
+
style: {
|
|
671
|
+
colors: ["#fff"],
|
|
672
|
+
fontSize: "10px"
|
|
673
|
+
},
|
|
674
|
+
formatter: (val) => {
|
|
675
|
+
if (val === null || val === void 0)
|
|
676
|
+
return "";
|
|
677
|
+
if (typeof val !== "number")
|
|
678
|
+
return String(val);
|
|
679
|
+
if (val >= 1e6)
|
|
680
|
+
return `${(val / 1e6).toFixed(1)}M`;
|
|
681
|
+
if (val >= 1e3)
|
|
682
|
+
return `${(val / 1e3).toFixed(0)}K`;
|
|
683
|
+
return Math.round(val).toLocaleString();
|
|
684
|
+
}
|
|
685
|
+
};
|
|
686
|
+
options.plotOptions = {
|
|
687
|
+
heatmap: {
|
|
688
|
+
shadeIntensity: 0.5,
|
|
689
|
+
radius: 2,
|
|
690
|
+
enableShades: true,
|
|
691
|
+
colorScale: {
|
|
692
|
+
inverse: false
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
};
|
|
696
|
+
options.colors = ["#6366f1"];
|
|
697
|
+
options.legend = { show: false };
|
|
698
|
+
}
|
|
699
|
+
return options;
|
|
700
|
+
}, [chartOptions, chartConfig, chartLabels]);
|
|
701
|
+
const getChartIcon = (0, import_react2.useCallback)((type) => {
|
|
702
|
+
const icons = {
|
|
703
|
+
bar: "M3 3v18h18V3H3zm4 14H5v-6h2v6zm4 0H9V7h2v10zm4 0h-2V9h2v8zm4 0h-2v-4h2v4z",
|
|
704
|
+
line: "M3.5 18.5l6-6 4 4 8-8M14.5 8.5h6v6",
|
|
705
|
+
area: "M3 17l6-6 4 4 8-8v10H3z",
|
|
706
|
+
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",
|
|
707
|
+
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",
|
|
708
|
+
scatter: "M7 14a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm5-6a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm5 8a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm-3 4a2 2 0 1 0 0-4 2 2 0 0 0 0 4z",
|
|
709
|
+
bubble: "M7 14a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm5-5a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm5 7a4 4 0 1 0 0-8 4 4 0 0 0 0 8z",
|
|
710
|
+
heatmap: "M3 3h4v4H3V3zm6 0h4v4H9V3zm6 0h4v4h-4V3zM3 9h4v4H3V9zm6 0h4v4H9V9zm6 0h4v4h-4V9zM3 15h4v4H3v-4zm6 0h4v4H9v-4zm6 0h4v4h-4v-4z",
|
|
711
|
+
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"
|
|
712
|
+
};
|
|
713
|
+
return icons[type] || icons.bar;
|
|
714
|
+
}, []);
|
|
715
|
+
(0, import_react2.useEffect)(() => {
|
|
716
|
+
onConfigChange?.(chartConfig);
|
|
717
|
+
}, []);
|
|
718
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-chart-builder", children: [
|
|
719
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "vpg-chart-type-bar", children: import_tinypivot_core2.CHART_TYPES.map((ct) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
720
|
+
"button",
|
|
721
|
+
{
|
|
722
|
+
className: `vpg-chart-type-btn ${chartConfig.type === ct.type ? "active" : ""}`,
|
|
723
|
+
title: ct.description,
|
|
724
|
+
onClick: () => selectChartType(ct.type),
|
|
725
|
+
children: [
|
|
726
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { className: "vpg-icon", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: getChartIcon(ct.type) }) }),
|
|
727
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "vpg-chart-type-label", children: ct.label.replace(" Chart", "") })
|
|
728
|
+
]
|
|
729
|
+
},
|
|
730
|
+
ct.type
|
|
731
|
+
)) }),
|
|
732
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-chart-builder-content", children: [
|
|
733
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-chart-fields-panel", children: [
|
|
734
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-chart-fields-section", children: [
|
|
735
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("h4", { className: "vpg-chart-fields-title", children: [
|
|
736
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { className: "vpg-icon-sm", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M4 6h16M4 12h10M4 18h6" }) }),
|
|
737
|
+
"Dimensions",
|
|
738
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "vpg-chart-fields-hint", children: "(text/date)" })
|
|
739
|
+
] }),
|
|
740
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-chart-fields-list", children: [
|
|
741
|
+
dimensions.map((field) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
742
|
+
"div",
|
|
743
|
+
{
|
|
744
|
+
className: "vpg-chart-field-chip vpg-field-dimension",
|
|
745
|
+
draggable: true,
|
|
746
|
+
onDragStart: (e) => handleDragStart(field, e),
|
|
747
|
+
onDragEnd: handleDragEnd,
|
|
748
|
+
children: [
|
|
749
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "vpg-field-name", children: field.label }),
|
|
750
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "vpg-field-type", children: field.role === "temporal" ? "date" : "text" })
|
|
751
|
+
]
|
|
752
|
+
},
|
|
753
|
+
field.field
|
|
754
|
+
)),
|
|
755
|
+
dimensions.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "vpg-chart-fields-empty", children: "No dimension fields detected" })
|
|
756
|
+
] })
|
|
757
|
+
] }),
|
|
758
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-chart-fields-section", children: [
|
|
759
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("h4", { className: "vpg-chart-fields-title", children: [
|
|
760
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { className: "vpg-icon-sm", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M16 8v8M12 11v5M8 14v2M4 4v16h16" }) }),
|
|
761
|
+
"Measures",
|
|
762
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "vpg-chart-fields-hint", children: "(numbers)" })
|
|
763
|
+
] }),
|
|
764
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-chart-fields-list", children: [
|
|
765
|
+
measures.map((field) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
766
|
+
"div",
|
|
767
|
+
{
|
|
768
|
+
className: "vpg-chart-field-chip vpg-field-measure",
|
|
769
|
+
draggable: true,
|
|
770
|
+
onDragStart: (e) => handleDragStart(field, e),
|
|
771
|
+
onDragEnd: handleDragEnd,
|
|
772
|
+
children: [
|
|
773
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "vpg-field-name", children: field.label }),
|
|
774
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "vpg-field-type", children: "#" })
|
|
775
|
+
]
|
|
776
|
+
},
|
|
777
|
+
field.field
|
|
778
|
+
)),
|
|
779
|
+
measures.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "vpg-chart-fields-empty", children: "No numeric fields detected" })
|
|
780
|
+
] })
|
|
781
|
+
] })
|
|
782
|
+
] }),
|
|
783
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-chart-config-panel", children: [
|
|
784
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-chart-drop-zone-wrapper", children: [
|
|
785
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { className: "vpg-chart-zone-label", children: zoneLabels.xAxis }),
|
|
786
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
787
|
+
"div",
|
|
788
|
+
{
|
|
789
|
+
className: `vpg-chart-drop-zone ${dragOverZone === "xAxis" ? "drag-over" : ""} ${chartConfig.xAxis ? "has-field" : ""}`,
|
|
790
|
+
onDragOver: (e) => handleDragOver("xAxis", e),
|
|
791
|
+
onDragLeave: handleDragLeave,
|
|
792
|
+
onDrop: (e) => handleDrop("xAxis", e),
|
|
793
|
+
children: chartConfig.xAxis ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
794
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "vpg-zone-field-name", children: chartConfig.xAxis.label }),
|
|
795
|
+
isScatterType && chartConfig.xAxis.role === "measure" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
796
|
+
"select",
|
|
797
|
+
{
|
|
798
|
+
className: "vpg-zone-aggregation",
|
|
799
|
+
value: chartConfig.xAxis.aggregation || "sum",
|
|
800
|
+
onChange: (e) => updateAggregation("xAxis", e.target.value),
|
|
801
|
+
children: import_tinypivot_core2.CHART_AGGREGATIONS.map((agg) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("option", { value: agg.value, children: agg.symbol }, agg.value))
|
|
802
|
+
}
|
|
803
|
+
),
|
|
804
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "vpg-zone-remove-btn", onClick: () => removeField("xAxis"), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { className: "vpg-icon-xs", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M6 18L18 6M6 6l12 12" }) }) })
|
|
805
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "vpg-zone-placeholder", children: zoneLabels.xAxisPlaceholder })
|
|
806
|
+
}
|
|
807
|
+
)
|
|
808
|
+
] }),
|
|
809
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-chart-drop-zone-wrapper", children: [
|
|
810
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { className: "vpg-chart-zone-label", children: zoneLabels.yAxis }),
|
|
811
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
812
|
+
"div",
|
|
813
|
+
{
|
|
814
|
+
className: `vpg-chart-drop-zone ${dragOverZone === "yAxis" ? "drag-over" : ""} ${chartConfig.yAxis ? "has-field" : ""}`,
|
|
815
|
+
onDragOver: (e) => handleDragOver("yAxis", e),
|
|
816
|
+
onDragLeave: handleDragLeave,
|
|
817
|
+
onDrop: (e) => handleDrop("yAxis", e),
|
|
818
|
+
children: chartConfig.yAxis ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
819
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "vpg-zone-field-name", children: chartConfig.yAxis.label }),
|
|
820
|
+
chartConfig.yAxis.role === "measure" && !isHeatmapType && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
821
|
+
"select",
|
|
822
|
+
{
|
|
823
|
+
className: "vpg-zone-aggregation",
|
|
824
|
+
value: chartConfig.yAxis.aggregation || "sum",
|
|
825
|
+
onChange: (e) => updateAggregation("yAxis", e.target.value),
|
|
826
|
+
children: import_tinypivot_core2.CHART_AGGREGATIONS.map((agg) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("option", { value: agg.value, children: agg.symbol }, agg.value))
|
|
827
|
+
}
|
|
828
|
+
),
|
|
829
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "vpg-zone-remove-btn", onClick: () => removeField("yAxis"), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { className: "vpg-icon-xs", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M6 18L18 6M6 6l12 12" }) }) })
|
|
830
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "vpg-zone-placeholder", children: zoneLabels.yAxisPlaceholder })
|
|
831
|
+
}
|
|
832
|
+
)
|
|
833
|
+
] }),
|
|
834
|
+
zoneLabels.showSeries && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-chart-drop-zone-wrapper", children: [
|
|
835
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { className: "vpg-chart-zone-label", children: zoneLabels.series }),
|
|
836
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
837
|
+
"div",
|
|
838
|
+
{
|
|
839
|
+
className: `vpg-chart-drop-zone vpg-zone-optional ${dragOverZone === "series" ? "drag-over" : ""} ${(isHeatmapType ? chartConfig.colorField : chartConfig.seriesField) ? "has-field" : ""}`,
|
|
840
|
+
onDragOver: (e) => handleDragOver(isHeatmapType ? "color" : "series", e),
|
|
841
|
+
onDragLeave: handleDragLeave,
|
|
842
|
+
onDrop: (e) => handleDrop(isHeatmapType ? "color" : "series", e),
|
|
843
|
+
children: (isHeatmapType ? chartConfig.colorField : chartConfig.seriesField) ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
844
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "vpg-zone-field-name", children: isHeatmapType ? chartConfig.colorField?.label : chartConfig.seriesField?.label }),
|
|
845
|
+
isHeatmapType && chartConfig.colorField?.role === "measure" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
846
|
+
"select",
|
|
847
|
+
{
|
|
848
|
+
className: "vpg-zone-aggregation",
|
|
849
|
+
value: chartConfig.colorField?.aggregation || "sum",
|
|
850
|
+
onChange: (e) => updateAggregation("color", e.target.value),
|
|
851
|
+
children: import_tinypivot_core2.CHART_AGGREGATIONS.map((agg) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("option", { value: agg.value, children: agg.symbol }, agg.value))
|
|
852
|
+
}
|
|
853
|
+
),
|
|
854
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "vpg-zone-remove-btn", onClick: () => removeField(isHeatmapType ? "color" : "series"), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { className: "vpg-icon-xs", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M6 18L18 6M6 6l12 12" }) }) })
|
|
855
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "vpg-zone-placeholder", children: zoneLabels.seriesPlaceholder })
|
|
856
|
+
}
|
|
857
|
+
)
|
|
858
|
+
] }),
|
|
859
|
+
zoneLabels.showSize && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-chart-drop-zone-wrapper", children: [
|
|
860
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { className: "vpg-chart-zone-label", children: "Size (number)" }),
|
|
861
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
862
|
+
"div",
|
|
863
|
+
{
|
|
864
|
+
className: `vpg-chart-drop-zone vpg-zone-optional ${dragOverZone === "size" ? "drag-over" : ""} ${chartConfig.sizeField ? "has-field" : ""}`,
|
|
865
|
+
onDragOver: (e) => handleDragOver("size", e),
|
|
866
|
+
onDragLeave: handleDragLeave,
|
|
867
|
+
onDrop: (e) => handleDrop("size", e),
|
|
868
|
+
children: chartConfig.sizeField ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
869
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "vpg-zone-field-name", children: chartConfig.sizeField.label }),
|
|
870
|
+
chartConfig.sizeField.role === "measure" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
871
|
+
"select",
|
|
872
|
+
{
|
|
873
|
+
className: "vpg-zone-aggregation",
|
|
874
|
+
value: chartConfig.sizeField.aggregation || "sum",
|
|
875
|
+
onChange: (e) => updateAggregation("size", e.target.value),
|
|
876
|
+
children: import_tinypivot_core2.CHART_AGGREGATIONS.map((agg) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("option", { value: agg.value, children: agg.symbol }, agg.value))
|
|
877
|
+
}
|
|
878
|
+
),
|
|
879
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "vpg-zone-remove-btn", onClick: () => removeField("size"), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { className: "vpg-icon-xs", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M6 18L18 6M6 6l12 12" }) }) })
|
|
880
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "vpg-zone-placeholder", children: "Drop a number for bubble size" })
|
|
881
|
+
}
|
|
882
|
+
)
|
|
883
|
+
] }),
|
|
884
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-chart-guidance", children: [
|
|
885
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { className: "vpg-icon-sm", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
886
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
|
|
887
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12 16v-4M12 8h.01" })
|
|
888
|
+
] }),
|
|
889
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: guidance })
|
|
890
|
+
] })
|
|
891
|
+
] }),
|
|
892
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "vpg-chart-preview-panel", children: chartIsValid ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "vpg-chart-container", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
893
|
+
import_react_apexcharts.default,
|
|
894
|
+
{
|
|
895
|
+
type: getApexChartType(chartConfig.type),
|
|
896
|
+
options: chartOptionsWithCategories,
|
|
897
|
+
series: chartSeries,
|
|
898
|
+
height: "100%"
|
|
899
|
+
},
|
|
900
|
+
`${chartConfig.type}-${JSON.stringify(chartConfig.xAxis)}-${JSON.stringify(chartConfig.yAxis)}`
|
|
901
|
+
) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-chart-empty-state", children: [
|
|
902
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { className: "vpg-icon-lg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: getChartIcon(chartConfig.type) }) }),
|
|
903
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { children: "Build your chart" }),
|
|
904
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { children: "Drag fields from the left panel to configure your visualization" }),
|
|
905
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-chart-hint", children: [
|
|
906
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: selectedChartType?.label }),
|
|
907
|
+
":",
|
|
908
|
+
" ",
|
|
909
|
+
selectedChartType?.description
|
|
910
|
+
] })
|
|
911
|
+
] }) })
|
|
912
|
+
] })
|
|
913
|
+
] });
|
|
914
|
+
}
|
|
915
|
+
|
|
237
916
|
// src/components/ColumnFilter.tsx
|
|
238
|
-
var
|
|
917
|
+
var import_react4 = require("react");
|
|
239
918
|
|
|
240
919
|
// src/components/NumericRangeFilter.tsx
|
|
241
|
-
var
|
|
242
|
-
var
|
|
920
|
+
var import_react3 = require("react");
|
|
921
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
243
922
|
function NumericRangeFilter({
|
|
244
923
|
dataMin,
|
|
245
924
|
dataMax,
|
|
246
925
|
currentRange,
|
|
247
926
|
onChange
|
|
248
927
|
}) {
|
|
249
|
-
const [localMin, setLocalMin] = (0,
|
|
250
|
-
const [localMax, setLocalMax] = (0,
|
|
251
|
-
const step = (0,
|
|
928
|
+
const [localMin, setLocalMin] = (0, import_react3.useState)(currentRange?.min ?? null);
|
|
929
|
+
const [localMax, setLocalMax] = (0, import_react3.useState)(currentRange?.max ?? null);
|
|
930
|
+
const step = (0, import_react3.useMemo)(() => {
|
|
252
931
|
const range = dataMax - dataMin;
|
|
253
932
|
if (range === 0)
|
|
254
933
|
return 1;
|
|
@@ -262,7 +941,7 @@ function NumericRangeFilter({
|
|
|
262
941
|
return 10;
|
|
263
942
|
return 10 ** (Math.floor(Math.log10(range)) - 2);
|
|
264
943
|
}, [dataMin, dataMax]);
|
|
265
|
-
const formatValue = (0,
|
|
944
|
+
const formatValue = (0, import_react3.useCallback)((val) => {
|
|
266
945
|
if (val === null)
|
|
267
946
|
return "";
|
|
268
947
|
if (Number.isInteger(val))
|
|
@@ -270,17 +949,17 @@ function NumericRangeFilter({
|
|
|
270
949
|
return val.toLocaleString(void 0, { maximumFractionDigits: 2 });
|
|
271
950
|
}, []);
|
|
272
951
|
const isFilterActive = localMin !== null || localMax !== null;
|
|
273
|
-
const minPercent = (0,
|
|
952
|
+
const minPercent = (0, import_react3.useMemo)(() => {
|
|
274
953
|
if (localMin === null || dataMax === dataMin)
|
|
275
954
|
return 0;
|
|
276
955
|
return (localMin - dataMin) / (dataMax - dataMin) * 100;
|
|
277
956
|
}, [localMin, dataMin, dataMax]);
|
|
278
|
-
const maxPercent = (0,
|
|
957
|
+
const maxPercent = (0, import_react3.useMemo)(() => {
|
|
279
958
|
if (localMax === null || dataMax === dataMin)
|
|
280
959
|
return 100;
|
|
281
960
|
return (localMax - dataMin) / (dataMax - dataMin) * 100;
|
|
282
961
|
}, [localMax, dataMin, dataMax]);
|
|
283
|
-
const handleMinSlider = (0,
|
|
962
|
+
const handleMinSlider = (0, import_react3.useCallback)((event) => {
|
|
284
963
|
const value = Number.parseFloat(event.target.value);
|
|
285
964
|
setLocalMin(() => {
|
|
286
965
|
if (localMax !== null && value > localMax) {
|
|
@@ -289,7 +968,7 @@ function NumericRangeFilter({
|
|
|
289
968
|
return value;
|
|
290
969
|
});
|
|
291
970
|
}, [localMax]);
|
|
292
|
-
const handleMaxSlider = (0,
|
|
971
|
+
const handleMaxSlider = (0, import_react3.useCallback)((event) => {
|
|
293
972
|
const value = Number.parseFloat(event.target.value);
|
|
294
973
|
setLocalMax(() => {
|
|
295
974
|
if (localMin !== null && value < localMin) {
|
|
@@ -298,14 +977,14 @@ function NumericRangeFilter({
|
|
|
298
977
|
return value;
|
|
299
978
|
});
|
|
300
979
|
}, [localMin]);
|
|
301
|
-
const handleSliderChange = (0,
|
|
980
|
+
const handleSliderChange = (0, import_react3.useCallback)(() => {
|
|
302
981
|
if (localMin === null && localMax === null) {
|
|
303
982
|
onChange(null);
|
|
304
983
|
} else {
|
|
305
984
|
onChange({ min: localMin, max: localMax });
|
|
306
985
|
}
|
|
307
986
|
}, [localMin, localMax, onChange]);
|
|
308
|
-
const handleMinInput = (0,
|
|
987
|
+
const handleMinInput = (0, import_react3.useCallback)((event) => {
|
|
309
988
|
const value = event.target.value === "" ? null : Number.parseFloat(event.target.value);
|
|
310
989
|
if (value !== null && !Number.isNaN(value)) {
|
|
311
990
|
setLocalMin(Math.max(dataMin, Math.min(value, localMax ?? dataMax)));
|
|
@@ -313,7 +992,7 @@ function NumericRangeFilter({
|
|
|
313
992
|
setLocalMin(null);
|
|
314
993
|
}
|
|
315
994
|
}, [dataMin, dataMax, localMax]);
|
|
316
|
-
const handleMaxInput = (0,
|
|
995
|
+
const handleMaxInput = (0, import_react3.useCallback)((event) => {
|
|
317
996
|
const value = event.target.value === "" ? null : Number.parseFloat(event.target.value);
|
|
318
997
|
if (value !== null && !Number.isNaN(value)) {
|
|
319
998
|
setLocalMax(Math.min(dataMax, Math.max(value, localMin ?? dataMin)));
|
|
@@ -321,39 +1000,39 @@ function NumericRangeFilter({
|
|
|
321
1000
|
setLocalMax(null);
|
|
322
1001
|
}
|
|
323
1002
|
}, [dataMin, dataMax, localMin]);
|
|
324
|
-
const handleInputBlur = (0,
|
|
1003
|
+
const handleInputBlur = (0, import_react3.useCallback)(() => {
|
|
325
1004
|
if (localMin === null && localMax === null) {
|
|
326
1005
|
onChange(null);
|
|
327
1006
|
} else {
|
|
328
1007
|
onChange({ min: localMin, max: localMax });
|
|
329
1008
|
}
|
|
330
1009
|
}, [localMin, localMax, onChange]);
|
|
331
|
-
const clearFilter = (0,
|
|
1010
|
+
const clearFilter = (0, import_react3.useCallback)(() => {
|
|
332
1011
|
setLocalMin(null);
|
|
333
1012
|
setLocalMax(null);
|
|
334
1013
|
onChange(null);
|
|
335
1014
|
}, [onChange]);
|
|
336
|
-
const setFullRange = (0,
|
|
1015
|
+
const setFullRange = (0, import_react3.useCallback)(() => {
|
|
337
1016
|
setLocalMin(dataMin);
|
|
338
1017
|
setLocalMax(dataMax);
|
|
339
1018
|
onChange({ min: dataMin, max: dataMax });
|
|
340
1019
|
}, [dataMin, dataMax, onChange]);
|
|
341
|
-
(0,
|
|
1020
|
+
(0, import_react3.useEffect)(() => {
|
|
342
1021
|
setLocalMin(currentRange?.min ?? null);
|
|
343
1022
|
setLocalMax(currentRange?.max ?? null);
|
|
344
1023
|
}, [currentRange]);
|
|
345
|
-
return /* @__PURE__ */ (0,
|
|
346
|
-
/* @__PURE__ */ (0,
|
|
347
|
-
/* @__PURE__ */ (0,
|
|
348
|
-
/* @__PURE__ */ (0,
|
|
1024
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-range-filter", children: [
|
|
1025
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-range-info", children: [
|
|
1026
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-range-label", children: "Data range:" }),
|
|
1027
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "vpg-range-bounds", children: [
|
|
349
1028
|
formatValue(dataMin),
|
|
350
1029
|
" ",
|
|
351
1030
|
"\u2013",
|
|
352
1031
|
formatValue(dataMax)
|
|
353
1032
|
] })
|
|
354
1033
|
] }),
|
|
355
|
-
/* @__PURE__ */ (0,
|
|
356
|
-
/* @__PURE__ */ (0,
|
|
1034
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-slider-container", children: [
|
|
1035
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "vpg-slider-track", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
357
1036
|
"div",
|
|
358
1037
|
{
|
|
359
1038
|
className: "vpg-slider-fill",
|
|
@@ -363,7 +1042,7 @@ function NumericRangeFilter({
|
|
|
363
1042
|
}
|
|
364
1043
|
}
|
|
365
1044
|
) }),
|
|
366
|
-
/* @__PURE__ */ (0,
|
|
1045
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
367
1046
|
"input",
|
|
368
1047
|
{
|
|
369
1048
|
type: "range",
|
|
@@ -377,7 +1056,7 @@ function NumericRangeFilter({
|
|
|
377
1056
|
onTouchEnd: handleSliderChange
|
|
378
1057
|
}
|
|
379
1058
|
),
|
|
380
|
-
/* @__PURE__ */ (0,
|
|
1059
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
381
1060
|
"input",
|
|
382
1061
|
{
|
|
383
1062
|
type: "range",
|
|
@@ -392,10 +1071,10 @@ function NumericRangeFilter({
|
|
|
392
1071
|
}
|
|
393
1072
|
)
|
|
394
1073
|
] }),
|
|
395
|
-
/* @__PURE__ */ (0,
|
|
396
|
-
/* @__PURE__ */ (0,
|
|
397
|
-
/* @__PURE__ */ (0,
|
|
398
|
-
/* @__PURE__ */ (0,
|
|
1074
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-range-inputs", children: [
|
|
1075
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-input-group", children: [
|
|
1076
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { className: "vpg-input-label", children: "Min" }),
|
|
1077
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
399
1078
|
"input",
|
|
400
1079
|
{
|
|
401
1080
|
type: "number",
|
|
@@ -408,10 +1087,10 @@ function NumericRangeFilter({
|
|
|
408
1087
|
}
|
|
409
1088
|
)
|
|
410
1089
|
] }),
|
|
411
|
-
/* @__PURE__ */ (0,
|
|
412
|
-
/* @__PURE__ */ (0,
|
|
413
|
-
/* @__PURE__ */ (0,
|
|
414
|
-
/* @__PURE__ */ (0,
|
|
1090
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-input-separator", children: "to" }),
|
|
1091
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-input-group", children: [
|
|
1092
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { className: "vpg-input-label", children: "Max" }),
|
|
1093
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
415
1094
|
"input",
|
|
416
1095
|
{
|
|
417
1096
|
type: "number",
|
|
@@ -425,15 +1104,15 @@ function NumericRangeFilter({
|
|
|
425
1104
|
)
|
|
426
1105
|
] })
|
|
427
1106
|
] }),
|
|
428
|
-
/* @__PURE__ */ (0,
|
|
429
|
-
/* @__PURE__ */ (0,
|
|
1107
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-range-actions", children: [
|
|
1108
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
430
1109
|
"button",
|
|
431
1110
|
{
|
|
432
1111
|
className: "vpg-range-btn",
|
|
433
1112
|
disabled: !isFilterActive,
|
|
434
1113
|
onClick: clearFilter,
|
|
435
1114
|
children: [
|
|
436
|
-
/* @__PURE__ */ (0,
|
|
1115
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
437
1116
|
"path",
|
|
438
1117
|
{
|
|
439
1118
|
strokeLinecap: "round",
|
|
@@ -446,8 +1125,8 @@ function NumericRangeFilter({
|
|
|
446
1125
|
]
|
|
447
1126
|
}
|
|
448
1127
|
),
|
|
449
|
-
/* @__PURE__ */ (0,
|
|
450
|
-
/* @__PURE__ */ (0,
|
|
1128
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("button", { className: "vpg-range-btn", onClick: setFullRange, children: [
|
|
1129
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
451
1130
|
"path",
|
|
452
1131
|
{
|
|
453
1132
|
strokeLinecap: "round",
|
|
@@ -459,8 +1138,8 @@ function NumericRangeFilter({
|
|
|
459
1138
|
"Full Range"
|
|
460
1139
|
] })
|
|
461
1140
|
] }),
|
|
462
|
-
isFilterActive && /* @__PURE__ */ (0,
|
|
463
|
-
/* @__PURE__ */ (0,
|
|
1141
|
+
isFilterActive && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-filter-summary", children: [
|
|
1142
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
464
1143
|
"path",
|
|
465
1144
|
{
|
|
466
1145
|
strokeLinecap: "round",
|
|
@@ -469,15 +1148,15 @@ function NumericRangeFilter({
|
|
|
469
1148
|
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"
|
|
470
1149
|
}
|
|
471
1150
|
) }),
|
|
472
|
-
/* @__PURE__ */ (0,
|
|
1151
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { children: [
|
|
473
1152
|
"Showing values",
|
|
474
1153
|
" ",
|
|
475
|
-
localMin !== null && /* @__PURE__ */ (0,
|
|
1154
|
+
localMin !== null && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("strong", { children: [
|
|
476
1155
|
"\u2265",
|
|
477
1156
|
formatValue(localMin)
|
|
478
1157
|
] }),
|
|
479
1158
|
localMin !== null && localMax !== null && " and ",
|
|
480
|
-
localMax !== null && /* @__PURE__ */ (0,
|
|
1159
|
+
localMax !== null && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("strong", { children: [
|
|
481
1160
|
"\u2264",
|
|
482
1161
|
formatValue(localMax)
|
|
483
1162
|
] })
|
|
@@ -487,7 +1166,7 @@ function NumericRangeFilter({
|
|
|
487
1166
|
}
|
|
488
1167
|
|
|
489
1168
|
// src/components/ColumnFilter.tsx
|
|
490
|
-
var
|
|
1169
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
491
1170
|
function ColumnFilter({
|
|
492
1171
|
columnName,
|
|
493
1172
|
stats,
|
|
@@ -499,33 +1178,33 @@ function ColumnFilter({
|
|
|
499
1178
|
onClose,
|
|
500
1179
|
onRangeFilter
|
|
501
1180
|
}) {
|
|
502
|
-
const [searchQuery, setSearchQuery] = (0,
|
|
503
|
-
const [localSelected, setLocalSelected] = (0,
|
|
504
|
-
const dropdownRef = (0,
|
|
505
|
-
const searchInputRef = (0,
|
|
1181
|
+
const [searchQuery, setSearchQuery] = (0, import_react4.useState)("");
|
|
1182
|
+
const [localSelected, setLocalSelected] = (0, import_react4.useState)(new Set(selectedValues));
|
|
1183
|
+
const dropdownRef = (0, import_react4.useRef)(null);
|
|
1184
|
+
const searchInputRef = (0, import_react4.useRef)(null);
|
|
506
1185
|
const isNumericColumn = stats.type === "number" && stats.numericMin !== void 0 && stats.numericMax !== void 0;
|
|
507
|
-
const [filterMode, setFilterMode] = (0,
|
|
508
|
-
const [localRange, setLocalRange] = (0,
|
|
1186
|
+
const [filterMode, setFilterMode] = (0, import_react4.useState)(numericRange ? "range" : "values");
|
|
1187
|
+
const [localRange, setLocalRange] = (0, import_react4.useState)(numericRange ?? null);
|
|
509
1188
|
const hasBlankValues = stats.nullCount > 0;
|
|
510
|
-
const filteredValues = (0,
|
|
1189
|
+
const filteredValues = (0, import_react4.useMemo)(() => {
|
|
511
1190
|
const values = stats.uniqueValues;
|
|
512
1191
|
if (!searchQuery)
|
|
513
1192
|
return values;
|
|
514
1193
|
const query = searchQuery.toLowerCase();
|
|
515
1194
|
return values.filter((v) => v.toLowerCase().includes(query));
|
|
516
1195
|
}, [stats.uniqueValues, searchQuery]);
|
|
517
|
-
const allValues = (0,
|
|
1196
|
+
const allValues = (0, import_react4.useMemo)(() => {
|
|
518
1197
|
const values = [...filteredValues];
|
|
519
1198
|
if (hasBlankValues && (!searchQuery || "(blank)".includes(searchQuery.toLowerCase()))) {
|
|
520
1199
|
values.unshift("(blank)");
|
|
521
1200
|
}
|
|
522
1201
|
return values;
|
|
523
1202
|
}, [filteredValues, hasBlankValues, searchQuery]);
|
|
524
|
-
const _isAllSelected = (0,
|
|
1203
|
+
const _isAllSelected = (0, import_react4.useMemo)(
|
|
525
1204
|
() => allValues.every((v) => localSelected.has(v)),
|
|
526
1205
|
[allValues, localSelected]
|
|
527
1206
|
);
|
|
528
|
-
const toggleValue = (0,
|
|
1207
|
+
const toggleValue = (0, import_react4.useCallback)((value) => {
|
|
529
1208
|
setLocalSelected((prev) => {
|
|
530
1209
|
const next = new Set(prev);
|
|
531
1210
|
if (next.has(value)) {
|
|
@@ -536,7 +1215,7 @@ function ColumnFilter({
|
|
|
536
1215
|
return next;
|
|
537
1216
|
});
|
|
538
1217
|
}, []);
|
|
539
|
-
const selectAll = (0,
|
|
1218
|
+
const selectAll = (0, import_react4.useCallback)(() => {
|
|
540
1219
|
setLocalSelected((prev) => {
|
|
541
1220
|
const next = new Set(prev);
|
|
542
1221
|
for (const value of allValues) {
|
|
@@ -545,10 +1224,10 @@ function ColumnFilter({
|
|
|
545
1224
|
return next;
|
|
546
1225
|
});
|
|
547
1226
|
}, [allValues]);
|
|
548
|
-
const clearAll = (0,
|
|
1227
|
+
const clearAll = (0, import_react4.useCallback)(() => {
|
|
549
1228
|
setLocalSelected(/* @__PURE__ */ new Set());
|
|
550
1229
|
}, []);
|
|
551
|
-
const applyFilter = (0,
|
|
1230
|
+
const applyFilter = (0, import_react4.useCallback)(() => {
|
|
552
1231
|
if (localSelected.size === 0) {
|
|
553
1232
|
onFilter([]);
|
|
554
1233
|
} else {
|
|
@@ -556,30 +1235,30 @@ function ColumnFilter({
|
|
|
556
1235
|
}
|
|
557
1236
|
onClose();
|
|
558
1237
|
}, [localSelected, onFilter, onClose]);
|
|
559
|
-
const sortAscending = (0,
|
|
1238
|
+
const sortAscending = (0, import_react4.useCallback)(() => {
|
|
560
1239
|
onSort(sortDirection === "asc" ? null : "asc");
|
|
561
1240
|
}, [sortDirection, onSort]);
|
|
562
|
-
const sortDescending = (0,
|
|
1241
|
+
const sortDescending = (0, import_react4.useCallback)(() => {
|
|
563
1242
|
onSort(sortDirection === "desc" ? null : "desc");
|
|
564
1243
|
}, [sortDirection, onSort]);
|
|
565
|
-
const clearFilter = (0,
|
|
1244
|
+
const clearFilter = (0, import_react4.useCallback)(() => {
|
|
566
1245
|
setLocalSelected(/* @__PURE__ */ new Set());
|
|
567
1246
|
onFilter([]);
|
|
568
1247
|
onClose();
|
|
569
1248
|
}, [onFilter, onClose]);
|
|
570
|
-
const handleRangeChange = (0,
|
|
1249
|
+
const handleRangeChange = (0, import_react4.useCallback)((range) => {
|
|
571
1250
|
setLocalRange(range);
|
|
572
1251
|
}, []);
|
|
573
|
-
const applyRangeFilter = (0,
|
|
1252
|
+
const applyRangeFilter = (0, import_react4.useCallback)(() => {
|
|
574
1253
|
onRangeFilter?.(localRange);
|
|
575
1254
|
onClose();
|
|
576
1255
|
}, [localRange, onRangeFilter, onClose]);
|
|
577
|
-
const clearRangeFilter = (0,
|
|
1256
|
+
const clearRangeFilter = (0, import_react4.useCallback)(() => {
|
|
578
1257
|
setLocalRange(null);
|
|
579
1258
|
onRangeFilter?.(null);
|
|
580
1259
|
onClose();
|
|
581
1260
|
}, [onRangeFilter, onClose]);
|
|
582
|
-
(0,
|
|
1261
|
+
(0, import_react4.useEffect)(() => {
|
|
583
1262
|
const handleClickOutside = (event) => {
|
|
584
1263
|
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
|
585
1264
|
onClose();
|
|
@@ -588,7 +1267,7 @@ function ColumnFilter({
|
|
|
588
1267
|
document.addEventListener("mousedown", handleClickOutside);
|
|
589
1268
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
590
1269
|
}, [onClose]);
|
|
591
|
-
(0,
|
|
1270
|
+
(0, import_react4.useEffect)(() => {
|
|
592
1271
|
const handleKeydown = (event) => {
|
|
593
1272
|
if (event.key === "Escape") {
|
|
594
1273
|
onClose();
|
|
@@ -599,36 +1278,36 @@ function ColumnFilter({
|
|
|
599
1278
|
document.addEventListener("keydown", handleKeydown);
|
|
600
1279
|
return () => document.removeEventListener("keydown", handleKeydown);
|
|
601
1280
|
}, [onClose, applyFilter]);
|
|
602
|
-
(0,
|
|
1281
|
+
(0, import_react4.useEffect)(() => {
|
|
603
1282
|
searchInputRef.current?.focus();
|
|
604
1283
|
}, []);
|
|
605
|
-
(0,
|
|
1284
|
+
(0, import_react4.useEffect)(() => {
|
|
606
1285
|
setLocalSelected(new Set(selectedValues));
|
|
607
1286
|
}, [selectedValues]);
|
|
608
|
-
(0,
|
|
1287
|
+
(0, import_react4.useEffect)(() => {
|
|
609
1288
|
setLocalRange(numericRange ?? null);
|
|
610
1289
|
if (numericRange) {
|
|
611
1290
|
setFilterMode("range");
|
|
612
1291
|
}
|
|
613
1292
|
}, [numericRange]);
|
|
614
|
-
return /* @__PURE__ */ (0,
|
|
615
|
-
/* @__PURE__ */ (0,
|
|
616
|
-
/* @__PURE__ */ (0,
|
|
617
|
-
/* @__PURE__ */ (0,
|
|
1293
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { ref: dropdownRef, className: "vpg-filter-dropdown", children: [
|
|
1294
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-filter-header", children: [
|
|
1295
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-filter-title", children: columnName }),
|
|
1296
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "vpg-filter-count", children: [
|
|
618
1297
|
stats.uniqueValues.length.toLocaleString(),
|
|
619
1298
|
" ",
|
|
620
1299
|
"unique"
|
|
621
1300
|
] })
|
|
622
1301
|
] }),
|
|
623
|
-
/* @__PURE__ */ (0,
|
|
624
|
-
/* @__PURE__ */ (0,
|
|
1302
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-sort-controls", children: [
|
|
1303
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
625
1304
|
"button",
|
|
626
1305
|
{
|
|
627
1306
|
className: `vpg-sort-btn ${sortDirection === "asc" ? "active" : ""}`,
|
|
628
1307
|
title: isNumericColumn ? "Sort Low to High" : "Sort A to Z",
|
|
629
1308
|
onClick: sortAscending,
|
|
630
1309
|
children: [
|
|
631
|
-
/* @__PURE__ */ (0,
|
|
1310
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
632
1311
|
"path",
|
|
633
1312
|
{
|
|
634
1313
|
strokeLinecap: "round",
|
|
@@ -637,18 +1316,18 @@ function ColumnFilter({
|
|
|
637
1316
|
d: "M3 4h13M3 8h9m-9 4h6m4 0l4-4m0 0l4 4m-4-4v12"
|
|
638
1317
|
}
|
|
639
1318
|
) }),
|
|
640
|
-
/* @__PURE__ */ (0,
|
|
1319
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: isNumericColumn ? "1\u21929" : "A\u2192Z" })
|
|
641
1320
|
]
|
|
642
1321
|
}
|
|
643
1322
|
),
|
|
644
|
-
/* @__PURE__ */ (0,
|
|
1323
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
645
1324
|
"button",
|
|
646
1325
|
{
|
|
647
1326
|
className: `vpg-sort-btn ${sortDirection === "desc" ? "active" : ""}`,
|
|
648
1327
|
title: isNumericColumn ? "Sort High to Low" : "Sort Z to A",
|
|
649
1328
|
onClick: sortDescending,
|
|
650
1329
|
children: [
|
|
651
|
-
/* @__PURE__ */ (0,
|
|
1330
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
652
1331
|
"path",
|
|
653
1332
|
{
|
|
654
1333
|
strokeLinecap: "round",
|
|
@@ -657,20 +1336,20 @@ function ColumnFilter({
|
|
|
657
1336
|
d: "M3 4h13M3 8h9m-9 4h9m5-4v12m0 0l-4-4m4 4l4-4"
|
|
658
1337
|
}
|
|
659
1338
|
) }),
|
|
660
|
-
/* @__PURE__ */ (0,
|
|
1339
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: isNumericColumn ? "9\u21921" : "Z\u2192A" })
|
|
661
1340
|
]
|
|
662
1341
|
}
|
|
663
1342
|
)
|
|
664
1343
|
] }),
|
|
665
|
-
/* @__PURE__ */ (0,
|
|
666
|
-
isNumericColumn && /* @__PURE__ */ (0,
|
|
667
|
-
/* @__PURE__ */ (0,
|
|
1344
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "vpg-divider" }),
|
|
1345
|
+
isNumericColumn && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-filter-tabs", children: [
|
|
1346
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
668
1347
|
"button",
|
|
669
1348
|
{
|
|
670
1349
|
className: `vpg-tab-btn ${filterMode === "values" ? "active" : ""}`,
|
|
671
1350
|
onClick: () => setFilterMode("values"),
|
|
672
1351
|
children: [
|
|
673
|
-
/* @__PURE__ */ (0,
|
|
1352
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
674
1353
|
"path",
|
|
675
1354
|
{
|
|
676
1355
|
strokeLinecap: "round",
|
|
@@ -683,13 +1362,13 @@ function ColumnFilter({
|
|
|
683
1362
|
]
|
|
684
1363
|
}
|
|
685
1364
|
),
|
|
686
|
-
/* @__PURE__ */ (0,
|
|
1365
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
687
1366
|
"button",
|
|
688
1367
|
{
|
|
689
1368
|
className: `vpg-tab-btn ${filterMode === "range" ? "active" : ""}`,
|
|
690
1369
|
onClick: () => setFilterMode("range"),
|
|
691
1370
|
children: [
|
|
692
|
-
/* @__PURE__ */ (0,
|
|
1371
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
693
1372
|
"path",
|
|
694
1373
|
{
|
|
695
1374
|
strokeLinecap: "round",
|
|
@@ -703,9 +1382,9 @@ function ColumnFilter({
|
|
|
703
1382
|
}
|
|
704
1383
|
)
|
|
705
1384
|
] }),
|
|
706
|
-
(!isNumericColumn || filterMode === "values") && /* @__PURE__ */ (0,
|
|
707
|
-
/* @__PURE__ */ (0,
|
|
708
|
-
/* @__PURE__ */ (0,
|
|
1385
|
+
(!isNumericColumn || filterMode === "values") && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
1386
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-search-container", children: [
|
|
1387
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-search-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
709
1388
|
"path",
|
|
710
1389
|
{
|
|
711
1390
|
strokeLinecap: "round",
|
|
@@ -714,7 +1393,7 @@ function ColumnFilter({
|
|
|
714
1393
|
d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
|
|
715
1394
|
}
|
|
716
1395
|
) }),
|
|
717
|
-
/* @__PURE__ */ (0,
|
|
1396
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
718
1397
|
"input",
|
|
719
1398
|
{
|
|
720
1399
|
ref: searchInputRef,
|
|
@@ -725,11 +1404,11 @@ function ColumnFilter({
|
|
|
725
1404
|
className: "vpg-search-input"
|
|
726
1405
|
}
|
|
727
1406
|
),
|
|
728
|
-
searchQuery && /* @__PURE__ */ (0,
|
|
1407
|
+
searchQuery && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { className: "vpg-clear-search", onClick: () => setSearchQuery(""), children: "\xD7" })
|
|
729
1408
|
] }),
|
|
730
|
-
/* @__PURE__ */ (0,
|
|
731
|
-
/* @__PURE__ */ (0,
|
|
732
|
-
/* @__PURE__ */ (0,
|
|
1409
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-bulk-actions", children: [
|
|
1410
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("button", { className: "vpg-bulk-btn", onClick: selectAll, children: [
|
|
1411
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
733
1412
|
"path",
|
|
734
1413
|
{
|
|
735
1414
|
strokeLinecap: "round",
|
|
@@ -740,8 +1419,8 @@ function ColumnFilter({
|
|
|
740
1419
|
) }),
|
|
741
1420
|
"Select All"
|
|
742
1421
|
] }),
|
|
743
|
-
/* @__PURE__ */ (0,
|
|
744
|
-
/* @__PURE__ */ (0,
|
|
1422
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("button", { className: "vpg-bulk-btn", onClick: clearAll, children: [
|
|
1423
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
745
1424
|
"path",
|
|
746
1425
|
{
|
|
747
1426
|
strokeLinecap: "round",
|
|
@@ -753,13 +1432,13 @@ function ColumnFilter({
|
|
|
753
1432
|
"Clear All"
|
|
754
1433
|
] })
|
|
755
1434
|
] }),
|
|
756
|
-
/* @__PURE__ */ (0,
|
|
757
|
-
allValues.map((value) => /* @__PURE__ */ (0,
|
|
1435
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-values-list", children: [
|
|
1436
|
+
allValues.map((value) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
758
1437
|
"label",
|
|
759
1438
|
{
|
|
760
1439
|
className: `vpg-value-item ${localSelected.has(value) ? "selected" : ""}`,
|
|
761
1440
|
children: [
|
|
762
|
-
/* @__PURE__ */ (0,
|
|
1441
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
763
1442
|
"input",
|
|
764
1443
|
{
|
|
765
1444
|
type: "checkbox",
|
|
@@ -768,20 +1447,20 @@ function ColumnFilter({
|
|
|
768
1447
|
className: "vpg-value-checkbox"
|
|
769
1448
|
}
|
|
770
1449
|
),
|
|
771
|
-
/* @__PURE__ */ (0,
|
|
1450
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: `vpg-value-text ${value === "(blank)" ? "vpg-blank" : ""}`, children: value })
|
|
772
1451
|
]
|
|
773
1452
|
},
|
|
774
1453
|
value
|
|
775
1454
|
)),
|
|
776
|
-
allValues.length === 0 && /* @__PURE__ */ (0,
|
|
1455
|
+
allValues.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "vpg-no-results", children: "No matching values" })
|
|
777
1456
|
] }),
|
|
778
|
-
/* @__PURE__ */ (0,
|
|
779
|
-
/* @__PURE__ */ (0,
|
|
780
|
-
/* @__PURE__ */ (0,
|
|
1457
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-filter-footer", children: [
|
|
1458
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { className: "vpg-btn-clear", onClick: clearFilter, children: "Clear Filter" }),
|
|
1459
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { className: "vpg-btn-apply", onClick: applyFilter, children: "Apply" })
|
|
781
1460
|
] })
|
|
782
1461
|
] }),
|
|
783
|
-
isNumericColumn && filterMode === "range" && /* @__PURE__ */ (0,
|
|
784
|
-
/* @__PURE__ */ (0,
|
|
1462
|
+
isNumericColumn && filterMode === "range" && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
1463
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
785
1464
|
NumericRangeFilter,
|
|
786
1465
|
{
|
|
787
1466
|
dataMin: stats.numericMin,
|
|
@@ -790,26 +1469,26 @@ function ColumnFilter({
|
|
|
790
1469
|
onChange: handleRangeChange
|
|
791
1470
|
}
|
|
792
1471
|
),
|
|
793
|
-
/* @__PURE__ */ (0,
|
|
794
|
-
/* @__PURE__ */ (0,
|
|
795
|
-
/* @__PURE__ */ (0,
|
|
1472
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-filter-footer", children: [
|
|
1473
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { className: "vpg-btn-clear", onClick: clearRangeFilter, children: "Clear Filter" }),
|
|
1474
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { className: "vpg-btn-apply", onClick: applyRangeFilter, children: "Apply" })
|
|
796
1475
|
] })
|
|
797
1476
|
] })
|
|
798
1477
|
] });
|
|
799
1478
|
}
|
|
800
1479
|
|
|
801
1480
|
// src/components/DataGrid.tsx
|
|
802
|
-
var
|
|
1481
|
+
var import_react11 = require("react");
|
|
803
1482
|
var import_react_dom2 = require("react-dom");
|
|
804
1483
|
|
|
805
1484
|
// src/hooks/useExcelGrid.ts
|
|
806
|
-
var
|
|
1485
|
+
var import_tinypivot_core3 = require("@smallwebco/tinypivot-core");
|
|
807
1486
|
var import_react_table = require("@tanstack/react-table");
|
|
808
|
-
var
|
|
1487
|
+
var import_react5 = require("react");
|
|
809
1488
|
var multiSelectFilter = (row, columnId, filterValue) => {
|
|
810
1489
|
if (!filterValue)
|
|
811
1490
|
return true;
|
|
812
|
-
if ((0,
|
|
1491
|
+
if ((0, import_tinypivot_core3.isNumericRange)(filterValue)) {
|
|
813
1492
|
const cellValue = row.getValue(columnId);
|
|
814
1493
|
if (cellValue === null || cellValue === void 0 || cellValue === "") {
|
|
815
1494
|
return false;
|
|
@@ -833,25 +1512,25 @@ var multiSelectFilter = (row, columnId, filterValue) => {
|
|
|
833
1512
|
};
|
|
834
1513
|
function useExcelGrid(options) {
|
|
835
1514
|
const { data, enableSorting = true, enableFiltering = true } = options;
|
|
836
|
-
const [sorting, setSorting] = (0,
|
|
837
|
-
const [columnFilters, setColumnFilters] = (0,
|
|
838
|
-
const [columnVisibility, setColumnVisibility] = (0,
|
|
839
|
-
const [globalFilter, setGlobalFilter] = (0,
|
|
840
|
-
const [columnStatsCache, setColumnStatsCache] = (0,
|
|
841
|
-
const dataSignature = (0,
|
|
1515
|
+
const [sorting, setSorting] = (0, import_react5.useState)([]);
|
|
1516
|
+
const [columnFilters, setColumnFilters] = (0, import_react5.useState)([]);
|
|
1517
|
+
const [columnVisibility, setColumnVisibility] = (0, import_react5.useState)({});
|
|
1518
|
+
const [globalFilter, setGlobalFilter] = (0, import_react5.useState)("");
|
|
1519
|
+
const [columnStatsCache, setColumnStatsCache] = (0, import_react5.useState)({});
|
|
1520
|
+
const dataSignature = (0, import_react5.useMemo)(
|
|
842
1521
|
() => `${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
|
843
1522
|
[data]
|
|
844
1523
|
);
|
|
845
|
-
const columnKeys = (0,
|
|
1524
|
+
const columnKeys = (0, import_react5.useMemo)(() => {
|
|
846
1525
|
if (data.length === 0)
|
|
847
1526
|
return [];
|
|
848
1527
|
return Object.keys(data[0]);
|
|
849
1528
|
}, [data]);
|
|
850
|
-
const getColumnStats = (0,
|
|
1529
|
+
const getColumnStats = (0, import_react5.useCallback)(
|
|
851
1530
|
(columnKey) => {
|
|
852
1531
|
const cacheKey = `${columnKey}-${dataSignature}`;
|
|
853
1532
|
if (!columnStatsCache[cacheKey]) {
|
|
854
|
-
const stats = (0,
|
|
1533
|
+
const stats = (0, import_tinypivot_core3.getColumnUniqueValues)(data, columnKey);
|
|
855
1534
|
setColumnStatsCache((prev) => ({ ...prev, [cacheKey]: stats }));
|
|
856
1535
|
return stats;
|
|
857
1536
|
}
|
|
@@ -859,20 +1538,20 @@ function useExcelGrid(options) {
|
|
|
859
1538
|
},
|
|
860
1539
|
[data, columnStatsCache, dataSignature]
|
|
861
1540
|
);
|
|
862
|
-
const clearStatsCache = (0,
|
|
1541
|
+
const clearStatsCache = (0, import_react5.useCallback)(() => {
|
|
863
1542
|
setColumnStatsCache({});
|
|
864
1543
|
}, []);
|
|
865
|
-
(0,
|
|
1544
|
+
(0, import_react5.useEffect)(() => {
|
|
866
1545
|
clearStatsCache();
|
|
867
1546
|
}, [dataSignature, clearStatsCache]);
|
|
868
|
-
const columnDefs = (0,
|
|
1547
|
+
const columnDefs = (0, import_react5.useMemo)(() => {
|
|
869
1548
|
return columnKeys.map((key) => {
|
|
870
1549
|
const stats = getColumnStats(key);
|
|
871
1550
|
return {
|
|
872
1551
|
id: key,
|
|
873
1552
|
accessorKey: key,
|
|
874
1553
|
header: key,
|
|
875
|
-
cell: (info) => (0,
|
|
1554
|
+
cell: (info) => (0, import_tinypivot_core3.formatCellValue)(info.getValue(), stats.type),
|
|
876
1555
|
filterFn: multiSelectFilter,
|
|
877
1556
|
meta: {
|
|
878
1557
|
type: stats.type,
|
|
@@ -905,10 +1584,10 @@ function useExcelGrid(options) {
|
|
|
905
1584
|
});
|
|
906
1585
|
const filteredRowCount = table.getFilteredRowModel().rows.length;
|
|
907
1586
|
const totalRowCount = data.length;
|
|
908
|
-
const activeFilters = (0,
|
|
1587
|
+
const activeFilters = (0, import_react5.useMemo)(() => {
|
|
909
1588
|
return columnFilters.map((f) => {
|
|
910
1589
|
const filterValue = f.value;
|
|
911
|
-
if (filterValue && (0,
|
|
1590
|
+
if (filterValue && (0, import_tinypivot_core3.isNumericRange)(filterValue)) {
|
|
912
1591
|
return {
|
|
913
1592
|
column: f.id,
|
|
914
1593
|
type: "range",
|
|
@@ -924,7 +1603,7 @@ function useExcelGrid(options) {
|
|
|
924
1603
|
};
|
|
925
1604
|
});
|
|
926
1605
|
}, [columnFilters]);
|
|
927
|
-
const hasActiveFilter = (0,
|
|
1606
|
+
const hasActiveFilter = (0, import_react5.useCallback)(
|
|
928
1607
|
(columnId) => {
|
|
929
1608
|
const column = table.getColumn(columnId);
|
|
930
1609
|
if (!column)
|
|
@@ -932,14 +1611,14 @@ function useExcelGrid(options) {
|
|
|
932
1611
|
const filterValue = column.getFilterValue();
|
|
933
1612
|
if (!filterValue)
|
|
934
1613
|
return false;
|
|
935
|
-
if ((0,
|
|
1614
|
+
if ((0, import_tinypivot_core3.isNumericRange)(filterValue)) {
|
|
936
1615
|
return filterValue.min !== null || filterValue.max !== null;
|
|
937
1616
|
}
|
|
938
1617
|
return Array.isArray(filterValue) && filterValue.length > 0;
|
|
939
1618
|
},
|
|
940
1619
|
[table]
|
|
941
1620
|
);
|
|
942
|
-
const setColumnFilter = (0,
|
|
1621
|
+
const setColumnFilter = (0, import_react5.useCallback)(
|
|
943
1622
|
(columnId, values) => {
|
|
944
1623
|
const column = table.getColumn(columnId);
|
|
945
1624
|
if (column) {
|
|
@@ -948,7 +1627,7 @@ function useExcelGrid(options) {
|
|
|
948
1627
|
},
|
|
949
1628
|
[table]
|
|
950
1629
|
);
|
|
951
|
-
const setNumericRangeFilter = (0,
|
|
1630
|
+
const setNumericRangeFilter = (0, import_react5.useCallback)(
|
|
952
1631
|
(columnId, range) => {
|
|
953
1632
|
const column = table.getColumn(columnId);
|
|
954
1633
|
if (column) {
|
|
@@ -961,25 +1640,25 @@ function useExcelGrid(options) {
|
|
|
961
1640
|
},
|
|
962
1641
|
[table]
|
|
963
1642
|
);
|
|
964
|
-
const getNumericRangeFilter = (0,
|
|
1643
|
+
const getNumericRangeFilter = (0, import_react5.useCallback)(
|
|
965
1644
|
(columnId) => {
|
|
966
1645
|
const column = table.getColumn(columnId);
|
|
967
1646
|
if (!column)
|
|
968
1647
|
return null;
|
|
969
1648
|
const filterValue = column.getFilterValue();
|
|
970
|
-
if (filterValue && (0,
|
|
1649
|
+
if (filterValue && (0, import_tinypivot_core3.isNumericRange)(filterValue)) {
|
|
971
1650
|
return filterValue;
|
|
972
1651
|
}
|
|
973
1652
|
return null;
|
|
974
1653
|
},
|
|
975
1654
|
[table]
|
|
976
1655
|
);
|
|
977
|
-
const clearAllFilters = (0,
|
|
1656
|
+
const clearAllFilters = (0, import_react5.useCallback)(() => {
|
|
978
1657
|
table.resetColumnFilters();
|
|
979
1658
|
setGlobalFilter("");
|
|
980
1659
|
setColumnFilters([]);
|
|
981
1660
|
}, [table]);
|
|
982
|
-
const getColumnFilterValues = (0,
|
|
1661
|
+
const getColumnFilterValues = (0, import_react5.useCallback)(
|
|
983
1662
|
(columnId) => {
|
|
984
1663
|
const column = table.getColumn(columnId);
|
|
985
1664
|
if (!column)
|
|
@@ -989,7 +1668,7 @@ function useExcelGrid(options) {
|
|
|
989
1668
|
},
|
|
990
1669
|
[table]
|
|
991
1670
|
);
|
|
992
|
-
const toggleSort = (0,
|
|
1671
|
+
const toggleSort = (0, import_react5.useCallback)((columnId) => {
|
|
993
1672
|
setSorting((prev) => {
|
|
994
1673
|
const current = prev.find((s) => s.id === columnId);
|
|
995
1674
|
if (!current) {
|
|
@@ -1001,7 +1680,7 @@ function useExcelGrid(options) {
|
|
|
1001
1680
|
}
|
|
1002
1681
|
});
|
|
1003
1682
|
}, []);
|
|
1004
|
-
const getSortDirection = (0,
|
|
1683
|
+
const getSortDirection = (0, import_react5.useCallback)(
|
|
1005
1684
|
(columnId) => {
|
|
1006
1685
|
const sort = sorting.find((s) => s.id === columnId);
|
|
1007
1686
|
if (!sort)
|
|
@@ -1042,60 +1721,60 @@ function useExcelGrid(options) {
|
|
|
1042
1721
|
}
|
|
1043
1722
|
|
|
1044
1723
|
// src/hooks/useGridFeatures.ts
|
|
1045
|
-
var
|
|
1046
|
-
var
|
|
1724
|
+
var import_tinypivot_core4 = require("@smallwebco/tinypivot-core");
|
|
1725
|
+
var import_react6 = require("react");
|
|
1047
1726
|
function exportToCSV(data, columns, options) {
|
|
1048
|
-
(0,
|
|
1727
|
+
(0, import_tinypivot_core4.exportToCSV)(data, columns, options);
|
|
1049
1728
|
}
|
|
1050
1729
|
function exportPivotToCSV(pivotData, rowFields, columnFields, valueFields, options) {
|
|
1051
|
-
(0,
|
|
1730
|
+
(0, import_tinypivot_core4.exportPivotToCSV)(pivotData, rowFields, columnFields, valueFields, options);
|
|
1052
1731
|
}
|
|
1053
1732
|
function copyToClipboard(text, onSuccess, onError) {
|
|
1054
|
-
(0,
|
|
1733
|
+
(0, import_tinypivot_core4.copyToClipboard)(text, onSuccess, onError);
|
|
1055
1734
|
}
|
|
1056
1735
|
function formatSelectionForClipboard(rows, columns, selectionBounds) {
|
|
1057
|
-
return (0,
|
|
1736
|
+
return (0, import_tinypivot_core4.formatSelectionForClipboard)(rows, columns, selectionBounds);
|
|
1058
1737
|
}
|
|
1059
1738
|
function usePagination(data, options = {}) {
|
|
1060
|
-
const [pageSize, setPageSize] = (0,
|
|
1061
|
-
const [currentPage, setCurrentPage] = (0,
|
|
1062
|
-
const totalPages = (0,
|
|
1739
|
+
const [pageSize, setPageSize] = (0, import_react6.useState)(options.pageSize ?? 50);
|
|
1740
|
+
const [currentPage, setCurrentPage] = (0, import_react6.useState)(options.currentPage ?? 1);
|
|
1741
|
+
const totalPages = (0, import_react6.useMemo)(
|
|
1063
1742
|
() => Math.max(1, Math.ceil(data.length / pageSize)),
|
|
1064
1743
|
[data.length, pageSize]
|
|
1065
1744
|
);
|
|
1066
|
-
const paginatedData = (0,
|
|
1745
|
+
const paginatedData = (0, import_react6.useMemo)(() => {
|
|
1067
1746
|
const start = (currentPage - 1) * pageSize;
|
|
1068
1747
|
const end = start + pageSize;
|
|
1069
1748
|
return data.slice(start, end);
|
|
1070
1749
|
}, [data, currentPage, pageSize]);
|
|
1071
|
-
const startIndex = (0,
|
|
1072
|
-
const endIndex = (0,
|
|
1750
|
+
const startIndex = (0, import_react6.useMemo)(() => (currentPage - 1) * pageSize + 1, [currentPage, pageSize]);
|
|
1751
|
+
const endIndex = (0, import_react6.useMemo)(
|
|
1073
1752
|
() => Math.min(currentPage * pageSize, data.length),
|
|
1074
1753
|
[currentPage, pageSize, data.length]
|
|
1075
1754
|
);
|
|
1076
|
-
const goToPage = (0,
|
|
1755
|
+
const goToPage = (0, import_react6.useCallback)(
|
|
1077
1756
|
(page) => {
|
|
1078
1757
|
setCurrentPage(Math.max(1, Math.min(page, totalPages)));
|
|
1079
1758
|
},
|
|
1080
1759
|
[totalPages]
|
|
1081
1760
|
);
|
|
1082
|
-
const nextPage = (0,
|
|
1761
|
+
const nextPage = (0, import_react6.useCallback)(() => {
|
|
1083
1762
|
if (currentPage < totalPages) {
|
|
1084
1763
|
setCurrentPage((prev) => prev + 1);
|
|
1085
1764
|
}
|
|
1086
1765
|
}, [currentPage, totalPages]);
|
|
1087
|
-
const prevPage = (0,
|
|
1766
|
+
const prevPage = (0, import_react6.useCallback)(() => {
|
|
1088
1767
|
if (currentPage > 1) {
|
|
1089
1768
|
setCurrentPage((prev) => prev - 1);
|
|
1090
1769
|
}
|
|
1091
1770
|
}, [currentPage]);
|
|
1092
|
-
const firstPage = (0,
|
|
1771
|
+
const firstPage = (0, import_react6.useCallback)(() => {
|
|
1093
1772
|
setCurrentPage(1);
|
|
1094
1773
|
}, []);
|
|
1095
|
-
const lastPage = (0,
|
|
1774
|
+
const lastPage = (0, import_react6.useCallback)(() => {
|
|
1096
1775
|
setCurrentPage(totalPages);
|
|
1097
1776
|
}, [totalPages]);
|
|
1098
|
-
const updatePageSize = (0,
|
|
1777
|
+
const updatePageSize = (0, import_react6.useCallback)((size) => {
|
|
1099
1778
|
setPageSize(size);
|
|
1100
1779
|
setCurrentPage(1);
|
|
1101
1780
|
}, []);
|
|
@@ -1115,9 +1794,9 @@ function usePagination(data, options = {}) {
|
|
|
1115
1794
|
};
|
|
1116
1795
|
}
|
|
1117
1796
|
function useGlobalSearch(data, columns) {
|
|
1118
|
-
const [searchTerm, setSearchTerm] = (0,
|
|
1119
|
-
const [caseSensitive, setCaseSensitive] = (0,
|
|
1120
|
-
const filteredData = (0,
|
|
1797
|
+
const [searchTerm, setSearchTerm] = (0, import_react6.useState)("");
|
|
1798
|
+
const [caseSensitive, setCaseSensitive] = (0, import_react6.useState)(false);
|
|
1799
|
+
const filteredData = (0, import_react6.useMemo)(() => {
|
|
1121
1800
|
if (!searchTerm.trim()) {
|
|
1122
1801
|
return data;
|
|
1123
1802
|
}
|
|
@@ -1135,7 +1814,7 @@ function useGlobalSearch(data, columns) {
|
|
|
1135
1814
|
return false;
|
|
1136
1815
|
});
|
|
1137
1816
|
}, [data, columns, searchTerm, caseSensitive]);
|
|
1138
|
-
const clearSearch = (0,
|
|
1817
|
+
const clearSearch = (0, import_react6.useCallback)(() => {
|
|
1139
1818
|
setSearchTerm("");
|
|
1140
1819
|
}, []);
|
|
1141
1820
|
return {
|
|
@@ -1148,17 +1827,17 @@ function useGlobalSearch(data, columns) {
|
|
|
1148
1827
|
};
|
|
1149
1828
|
}
|
|
1150
1829
|
function useRowSelection(data) {
|
|
1151
|
-
const [selectedRowIndices, setSelectedRowIndices] = (0,
|
|
1152
|
-
const selectedRows = (0,
|
|
1830
|
+
const [selectedRowIndices, setSelectedRowIndices] = (0, import_react6.useState)(/* @__PURE__ */ new Set());
|
|
1831
|
+
const selectedRows = (0, import_react6.useMemo)(() => {
|
|
1153
1832
|
return Array.from(selectedRowIndices).sort((a, b) => a - b).map((idx) => data[idx]).filter(Boolean);
|
|
1154
1833
|
}, [data, selectedRowIndices]);
|
|
1155
|
-
const allSelected = (0,
|
|
1834
|
+
const allSelected = (0, import_react6.useMemo)(() => {
|
|
1156
1835
|
return data.length > 0 && selectedRowIndices.size === data.length;
|
|
1157
1836
|
}, [data.length, selectedRowIndices.size]);
|
|
1158
|
-
const someSelected = (0,
|
|
1837
|
+
const someSelected = (0, import_react6.useMemo)(() => {
|
|
1159
1838
|
return selectedRowIndices.size > 0 && selectedRowIndices.size < data.length;
|
|
1160
1839
|
}, [data.length, selectedRowIndices.size]);
|
|
1161
|
-
const toggleRow = (0,
|
|
1840
|
+
const toggleRow = (0, import_react6.useCallback)((index) => {
|
|
1162
1841
|
setSelectedRowIndices((prev) => {
|
|
1163
1842
|
const next = new Set(prev);
|
|
1164
1843
|
if (next.has(index)) {
|
|
@@ -1169,36 +1848,36 @@ function useRowSelection(data) {
|
|
|
1169
1848
|
return next;
|
|
1170
1849
|
});
|
|
1171
1850
|
}, []);
|
|
1172
|
-
const selectRow = (0,
|
|
1851
|
+
const selectRow = (0, import_react6.useCallback)((index) => {
|
|
1173
1852
|
setSelectedRowIndices((prev) => /* @__PURE__ */ new Set([...prev, index]));
|
|
1174
1853
|
}, []);
|
|
1175
|
-
const deselectRow = (0,
|
|
1854
|
+
const deselectRow = (0, import_react6.useCallback)((index) => {
|
|
1176
1855
|
setSelectedRowIndices((prev) => {
|
|
1177
1856
|
const next = new Set(prev);
|
|
1178
1857
|
next.delete(index);
|
|
1179
1858
|
return next;
|
|
1180
1859
|
});
|
|
1181
1860
|
}, []);
|
|
1182
|
-
const selectAll = (0,
|
|
1861
|
+
const selectAll = (0, import_react6.useCallback)(() => {
|
|
1183
1862
|
setSelectedRowIndices(new Set(data.map((_, idx) => idx)));
|
|
1184
1863
|
}, [data]);
|
|
1185
|
-
const deselectAll = (0,
|
|
1864
|
+
const deselectAll = (0, import_react6.useCallback)(() => {
|
|
1186
1865
|
setSelectedRowIndices(/* @__PURE__ */ new Set());
|
|
1187
1866
|
}, []);
|
|
1188
|
-
const toggleAll = (0,
|
|
1867
|
+
const toggleAll = (0, import_react6.useCallback)(() => {
|
|
1189
1868
|
if (allSelected) {
|
|
1190
1869
|
deselectAll();
|
|
1191
1870
|
} else {
|
|
1192
1871
|
selectAll();
|
|
1193
1872
|
}
|
|
1194
1873
|
}, [allSelected, selectAll, deselectAll]);
|
|
1195
|
-
const isSelected = (0,
|
|
1874
|
+
const isSelected = (0, import_react6.useCallback)(
|
|
1196
1875
|
(index) => {
|
|
1197
1876
|
return selectedRowIndices.has(index);
|
|
1198
1877
|
},
|
|
1199
1878
|
[selectedRowIndices]
|
|
1200
1879
|
);
|
|
1201
|
-
const selectRange = (0,
|
|
1880
|
+
const selectRange = (0, import_react6.useCallback)((startIndex, endIndex) => {
|
|
1202
1881
|
const min = Math.min(startIndex, endIndex);
|
|
1203
1882
|
const max = Math.max(startIndex, endIndex);
|
|
1204
1883
|
setSelectedRowIndices((prev) => {
|
|
@@ -1225,10 +1904,10 @@ function useRowSelection(data) {
|
|
|
1225
1904
|
};
|
|
1226
1905
|
}
|
|
1227
1906
|
function useColumnResize(initialWidths, minWidth = 60, maxWidth = 600) {
|
|
1228
|
-
const [columnWidths, setColumnWidths] = (0,
|
|
1229
|
-
const [isResizing, setIsResizing] = (0,
|
|
1230
|
-
const [resizingColumn, setResizingColumn] = (0,
|
|
1231
|
-
const startResize = (0,
|
|
1907
|
+
const [columnWidths, setColumnWidths] = (0, import_react6.useState)({ ...initialWidths });
|
|
1908
|
+
const [isResizing, setIsResizing] = (0, import_react6.useState)(false);
|
|
1909
|
+
const [resizingColumn, setResizingColumn] = (0, import_react6.useState)(null);
|
|
1910
|
+
const startResize = (0, import_react6.useCallback)(
|
|
1232
1911
|
(columnId, event) => {
|
|
1233
1912
|
setIsResizing(true);
|
|
1234
1913
|
setResizingColumn(columnId);
|
|
@@ -1253,7 +1932,7 @@ function useColumnResize(initialWidths, minWidth = 60, maxWidth = 600) {
|
|
|
1253
1932
|
},
|
|
1254
1933
|
[columnWidths, minWidth, maxWidth]
|
|
1255
1934
|
);
|
|
1256
|
-
const resetColumnWidth = (0,
|
|
1935
|
+
const resetColumnWidth = (0, import_react6.useCallback)(
|
|
1257
1936
|
(columnId) => {
|
|
1258
1937
|
if (initialWidths[columnId]) {
|
|
1259
1938
|
setColumnWidths((prev) => ({
|
|
@@ -1264,7 +1943,7 @@ function useColumnResize(initialWidths, minWidth = 60, maxWidth = 600) {
|
|
|
1264
1943
|
},
|
|
1265
1944
|
[initialWidths]
|
|
1266
1945
|
);
|
|
1267
|
-
const resetAllWidths = (0,
|
|
1946
|
+
const resetAllWidths = (0, import_react6.useCallback)(() => {
|
|
1268
1947
|
setColumnWidths({ ...initialWidths });
|
|
1269
1948
|
}, [initialWidths]);
|
|
1270
1949
|
return {
|
|
@@ -1279,16 +1958,16 @@ function useColumnResize(initialWidths, minWidth = 60, maxWidth = 600) {
|
|
|
1279
1958
|
}
|
|
1280
1959
|
|
|
1281
1960
|
// src/hooks/useLicense.ts
|
|
1282
|
-
var
|
|
1283
|
-
var
|
|
1284
|
-
var globalLicenseInfo = (0,
|
|
1961
|
+
var import_tinypivot_core5 = require("@smallwebco/tinypivot-core");
|
|
1962
|
+
var import_react7 = require("react");
|
|
1963
|
+
var globalLicenseInfo = (0, import_tinypivot_core5.getFreeLicenseInfo)();
|
|
1285
1964
|
var globalDemoMode = false;
|
|
1286
1965
|
var listeners = /* @__PURE__ */ new Set();
|
|
1287
1966
|
function notifyListeners() {
|
|
1288
1967
|
listeners.forEach((listener) => listener());
|
|
1289
1968
|
}
|
|
1290
1969
|
async function setLicenseKey(key) {
|
|
1291
|
-
globalLicenseInfo = await (0,
|
|
1970
|
+
globalLicenseInfo = await (0, import_tinypivot_core5.validateLicenseKey)(key);
|
|
1292
1971
|
if (!globalLicenseInfo.isValid) {
|
|
1293
1972
|
console.warn("[TinyPivot] Invalid or expired license key. Running in free mode.");
|
|
1294
1973
|
} else if (globalLicenseInfo.type !== "free") {
|
|
@@ -1297,7 +1976,7 @@ async function setLicenseKey(key) {
|
|
|
1297
1976
|
notifyListeners();
|
|
1298
1977
|
}
|
|
1299
1978
|
async function enableDemoMode(secret) {
|
|
1300
|
-
const demoLicense = await (0,
|
|
1979
|
+
const demoLicense = await (0, import_tinypivot_core5.getDemoLicenseInfo)(secret);
|
|
1301
1980
|
if (!demoLicense) {
|
|
1302
1981
|
console.warn("[TinyPivot] Demo mode activation failed - invalid secret");
|
|
1303
1982
|
return false;
|
|
@@ -1309,40 +1988,44 @@ async function enableDemoMode(secret) {
|
|
|
1309
1988
|
return true;
|
|
1310
1989
|
}
|
|
1311
1990
|
function configureLicenseSecret(secret) {
|
|
1312
|
-
(0,
|
|
1991
|
+
(0, import_tinypivot_core5.configureLicenseSecret)(secret);
|
|
1313
1992
|
}
|
|
1314
1993
|
function useLicense() {
|
|
1315
|
-
const [, forceUpdate] = (0,
|
|
1316
|
-
(0,
|
|
1994
|
+
const [, forceUpdate] = (0, import_react7.useState)({});
|
|
1995
|
+
(0, import_react7.useState)(() => {
|
|
1317
1996
|
const update = () => forceUpdate({});
|
|
1318
1997
|
listeners.add(update);
|
|
1319
1998
|
return () => listeners.delete(update);
|
|
1320
1999
|
});
|
|
1321
2000
|
const isDemo = globalDemoMode;
|
|
1322
2001
|
const licenseInfo = globalLicenseInfo;
|
|
1323
|
-
const isPro = (0,
|
|
1324
|
-
() => globalDemoMode || (0,
|
|
2002
|
+
const isPro = (0, import_react7.useMemo)(
|
|
2003
|
+
() => globalDemoMode || (0, import_tinypivot_core5.isPro)(licenseInfo),
|
|
1325
2004
|
[licenseInfo]
|
|
1326
2005
|
);
|
|
1327
|
-
const canUsePivot = (0,
|
|
1328
|
-
() => globalDemoMode || (0,
|
|
2006
|
+
const canUsePivot = (0, import_react7.useMemo)(
|
|
2007
|
+
() => globalDemoMode || (0, import_tinypivot_core5.canUsePivot)(licenseInfo),
|
|
1329
2008
|
[licenseInfo]
|
|
1330
2009
|
);
|
|
1331
|
-
const canUseAdvancedAggregations = (0,
|
|
2010
|
+
const canUseAdvancedAggregations = (0, import_react7.useMemo)(
|
|
1332
2011
|
() => globalDemoMode || licenseInfo.features.advancedAggregations,
|
|
1333
2012
|
[licenseInfo]
|
|
1334
2013
|
);
|
|
1335
|
-
const canUsePercentageMode = (0,
|
|
2014
|
+
const canUsePercentageMode = (0, import_react7.useMemo)(
|
|
1336
2015
|
() => globalDemoMode || licenseInfo.features.percentageMode,
|
|
1337
2016
|
[licenseInfo]
|
|
1338
2017
|
);
|
|
1339
|
-
const
|
|
1340
|
-
() => (0,
|
|
2018
|
+
const canUseCharts = (0, import_react7.useMemo)(
|
|
2019
|
+
() => globalDemoMode || (0, import_tinypivot_core5.canUseCharts)(licenseInfo),
|
|
2020
|
+
[licenseInfo]
|
|
2021
|
+
);
|
|
2022
|
+
const showWatermark = (0, import_react7.useMemo)(
|
|
2023
|
+
() => (0, import_tinypivot_core5.shouldShowWatermark)(licenseInfo, globalDemoMode),
|
|
1341
2024
|
[licenseInfo]
|
|
1342
2025
|
);
|
|
1343
|
-
const requirePro = (0,
|
|
2026
|
+
const requirePro = (0, import_react7.useCallback)((feature) => {
|
|
1344
2027
|
if (!isPro) {
|
|
1345
|
-
(0,
|
|
2028
|
+
(0, import_tinypivot_core5.logProRequired)(feature);
|
|
1346
2029
|
return false;
|
|
1347
2030
|
}
|
|
1348
2031
|
return true;
|
|
@@ -1354,31 +2037,32 @@ function useLicense() {
|
|
|
1354
2037
|
canUsePivot,
|
|
1355
2038
|
canUseAdvancedAggregations,
|
|
1356
2039
|
canUsePercentageMode,
|
|
2040
|
+
canUseCharts,
|
|
1357
2041
|
showWatermark,
|
|
1358
2042
|
requirePro
|
|
1359
2043
|
};
|
|
1360
2044
|
}
|
|
1361
2045
|
|
|
1362
2046
|
// src/hooks/usePivotTable.ts
|
|
1363
|
-
var
|
|
1364
|
-
var
|
|
2047
|
+
var import_tinypivot_core6 = require("@smallwebco/tinypivot-core");
|
|
2048
|
+
var import_react8 = require("react");
|
|
1365
2049
|
function usePivotTable(data) {
|
|
1366
2050
|
const { canUsePivot, requirePro } = useLicense();
|
|
1367
|
-
const [rowFields, setRowFieldsState] = (0,
|
|
1368
|
-
const [columnFields, setColumnFieldsState] = (0,
|
|
1369
|
-
const [valueFields, setValueFields] = (0,
|
|
1370
|
-
const [showRowTotals, setShowRowTotals] = (0,
|
|
1371
|
-
const [showColumnTotals, setShowColumnTotals] = (0,
|
|
1372
|
-
const [calculatedFields, setCalculatedFields] = (0,
|
|
1373
|
-
const [currentStorageKey, setCurrentStorageKey] = (0,
|
|
1374
|
-
const availableFields = (0,
|
|
1375
|
-
return (0,
|
|
2051
|
+
const [rowFields, setRowFieldsState] = (0, import_react8.useState)([]);
|
|
2052
|
+
const [columnFields, setColumnFieldsState] = (0, import_react8.useState)([]);
|
|
2053
|
+
const [valueFields, setValueFields] = (0, import_react8.useState)([]);
|
|
2054
|
+
const [showRowTotals, setShowRowTotals] = (0, import_react8.useState)(true);
|
|
2055
|
+
const [showColumnTotals, setShowColumnTotals] = (0, import_react8.useState)(true);
|
|
2056
|
+
const [calculatedFields, setCalculatedFields] = (0, import_react8.useState)(() => (0, import_tinypivot_core6.loadCalculatedFields)());
|
|
2057
|
+
const [currentStorageKey, setCurrentStorageKey] = (0, import_react8.useState)(null);
|
|
2058
|
+
const availableFields = (0, import_react8.useMemo)(() => {
|
|
2059
|
+
return (0, import_tinypivot_core6.computeAvailableFields)(data);
|
|
1376
2060
|
}, [data]);
|
|
1377
|
-
const unassignedFields = (0,
|
|
1378
|
-
return (0,
|
|
2061
|
+
const unassignedFields = (0, import_react8.useMemo)(() => {
|
|
2062
|
+
return (0, import_tinypivot_core6.getUnassignedFields)(availableFields, rowFields, columnFields, valueFields);
|
|
1379
2063
|
}, [availableFields, rowFields, columnFields, valueFields]);
|
|
1380
|
-
const isConfigured = (0,
|
|
1381
|
-
return (0,
|
|
2064
|
+
const isConfigured = (0, import_react8.useMemo)(() => {
|
|
2065
|
+
return (0, import_tinypivot_core6.isPivotConfigured)({
|
|
1382
2066
|
rowFields,
|
|
1383
2067
|
columnFields,
|
|
1384
2068
|
valueFields,
|
|
@@ -1386,12 +2070,12 @@ function usePivotTable(data) {
|
|
|
1386
2070
|
showColumnTotals
|
|
1387
2071
|
});
|
|
1388
2072
|
}, [rowFields, columnFields, valueFields, showRowTotals, showColumnTotals]);
|
|
1389
|
-
const pivotResult = (0,
|
|
2073
|
+
const pivotResult = (0, import_react8.useMemo)(() => {
|
|
1390
2074
|
if (!isConfigured)
|
|
1391
2075
|
return null;
|
|
1392
2076
|
if (!canUsePivot)
|
|
1393
2077
|
return null;
|
|
1394
|
-
return (0,
|
|
2078
|
+
return (0, import_tinypivot_core6.computePivotResult)(data, {
|
|
1395
2079
|
rowFields,
|
|
1396
2080
|
columnFields,
|
|
1397
2081
|
valueFields,
|
|
@@ -1400,15 +2084,15 @@ function usePivotTable(data) {
|
|
|
1400
2084
|
calculatedFields
|
|
1401
2085
|
});
|
|
1402
2086
|
}, [data, isConfigured, canUsePivot, rowFields, columnFields, valueFields, showRowTotals, showColumnTotals, calculatedFields]);
|
|
1403
|
-
(0,
|
|
2087
|
+
(0, import_react8.useEffect)(() => {
|
|
1404
2088
|
if (data.length === 0)
|
|
1405
2089
|
return;
|
|
1406
2090
|
const newKeys = Object.keys(data[0]);
|
|
1407
|
-
const storageKey = (0,
|
|
2091
|
+
const storageKey = (0, import_tinypivot_core6.generateStorageKey)(newKeys);
|
|
1408
2092
|
if (storageKey !== currentStorageKey) {
|
|
1409
2093
|
setCurrentStorageKey(storageKey);
|
|
1410
|
-
const savedConfig = (0,
|
|
1411
|
-
if (savedConfig && (0,
|
|
2094
|
+
const savedConfig = (0, import_tinypivot_core6.loadPivotConfig)(storageKey);
|
|
2095
|
+
if (savedConfig && (0, import_tinypivot_core6.isConfigValidForFields)(savedConfig, newKeys)) {
|
|
1412
2096
|
setRowFieldsState(savedConfig.rowFields);
|
|
1413
2097
|
setColumnFieldsState(savedConfig.columnFields);
|
|
1414
2098
|
setValueFields(savedConfig.valueFields);
|
|
@@ -1425,7 +2109,7 @@ function usePivotTable(data) {
|
|
|
1425
2109
|
showRowTotals,
|
|
1426
2110
|
showColumnTotals
|
|
1427
2111
|
};
|
|
1428
|
-
if (!(0,
|
|
2112
|
+
if (!(0, import_tinypivot_core6.isConfigValidForFields)(currentConfig, newKeys)) {
|
|
1429
2113
|
setRowFieldsState([]);
|
|
1430
2114
|
setColumnFieldsState([]);
|
|
1431
2115
|
setValueFields([]);
|
|
@@ -1433,7 +2117,7 @@ function usePivotTable(data) {
|
|
|
1433
2117
|
}
|
|
1434
2118
|
}
|
|
1435
2119
|
}, [data]);
|
|
1436
|
-
(0,
|
|
2120
|
+
(0, import_react8.useEffect)(() => {
|
|
1437
2121
|
if (!currentStorageKey)
|
|
1438
2122
|
return;
|
|
1439
2123
|
const config = {
|
|
@@ -1444,9 +2128,9 @@ function usePivotTable(data) {
|
|
|
1444
2128
|
showColumnTotals,
|
|
1445
2129
|
calculatedFields
|
|
1446
2130
|
};
|
|
1447
|
-
(0,
|
|
2131
|
+
(0, import_tinypivot_core6.savePivotConfig)(currentStorageKey, config);
|
|
1448
2132
|
}, [currentStorageKey, rowFields, columnFields, valueFields, showRowTotals, showColumnTotals, calculatedFields]);
|
|
1449
|
-
const addRowField = (0,
|
|
2133
|
+
const addRowField = (0, import_react8.useCallback)(
|
|
1450
2134
|
(field) => {
|
|
1451
2135
|
if (!rowFields.includes(field)) {
|
|
1452
2136
|
setRowFieldsState((prev) => [...prev, field]);
|
|
@@ -1454,13 +2138,13 @@ function usePivotTable(data) {
|
|
|
1454
2138
|
},
|
|
1455
2139
|
[rowFields]
|
|
1456
2140
|
);
|
|
1457
|
-
const removeRowField = (0,
|
|
2141
|
+
const removeRowField = (0, import_react8.useCallback)((field) => {
|
|
1458
2142
|
setRowFieldsState((prev) => prev.filter((f) => f !== field));
|
|
1459
2143
|
}, []);
|
|
1460
|
-
const setRowFields = (0,
|
|
2144
|
+
const setRowFields = (0, import_react8.useCallback)((fields) => {
|
|
1461
2145
|
setRowFieldsState(fields);
|
|
1462
2146
|
}, []);
|
|
1463
|
-
const addColumnField = (0,
|
|
2147
|
+
const addColumnField = (0, import_react8.useCallback)(
|
|
1464
2148
|
(field) => {
|
|
1465
2149
|
if (!columnFields.includes(field)) {
|
|
1466
2150
|
setColumnFieldsState((prev) => [...prev, field]);
|
|
@@ -1468,13 +2152,13 @@ function usePivotTable(data) {
|
|
|
1468
2152
|
},
|
|
1469
2153
|
[columnFields]
|
|
1470
2154
|
);
|
|
1471
|
-
const removeColumnField = (0,
|
|
2155
|
+
const removeColumnField = (0, import_react8.useCallback)((field) => {
|
|
1472
2156
|
setColumnFieldsState((prev) => prev.filter((f) => f !== field));
|
|
1473
2157
|
}, []);
|
|
1474
|
-
const setColumnFields = (0,
|
|
2158
|
+
const setColumnFields = (0, import_react8.useCallback)((fields) => {
|
|
1475
2159
|
setColumnFieldsState(fields);
|
|
1476
2160
|
}, []);
|
|
1477
|
-
const addValueField = (0,
|
|
2161
|
+
const addValueField = (0, import_react8.useCallback)(
|
|
1478
2162
|
(field, aggregation = "sum") => {
|
|
1479
2163
|
if (aggregation !== "sum" && !requirePro(`${aggregation} aggregation`)) {
|
|
1480
2164
|
return;
|
|
@@ -1488,7 +2172,7 @@ function usePivotTable(data) {
|
|
|
1488
2172
|
},
|
|
1489
2173
|
[requirePro]
|
|
1490
2174
|
);
|
|
1491
|
-
const removeValueField = (0,
|
|
2175
|
+
const removeValueField = (0, import_react8.useCallback)((field, aggregation) => {
|
|
1492
2176
|
setValueFields((prev) => {
|
|
1493
2177
|
if (aggregation) {
|
|
1494
2178
|
return prev.filter((v) => !(v.field === field && v.aggregation === aggregation));
|
|
@@ -1496,7 +2180,7 @@ function usePivotTable(data) {
|
|
|
1496
2180
|
return prev.filter((v) => v.field !== field);
|
|
1497
2181
|
});
|
|
1498
2182
|
}, []);
|
|
1499
|
-
const updateValueFieldAggregation = (0,
|
|
2183
|
+
const updateValueFieldAggregation = (0, import_react8.useCallback)(
|
|
1500
2184
|
(field, oldAgg, newAgg) => {
|
|
1501
2185
|
setValueFields(
|
|
1502
2186
|
(prev) => prev.map((v) => {
|
|
@@ -1509,12 +2193,12 @@ function usePivotTable(data) {
|
|
|
1509
2193
|
},
|
|
1510
2194
|
[]
|
|
1511
2195
|
);
|
|
1512
|
-
const clearConfig = (0,
|
|
2196
|
+
const clearConfig = (0, import_react8.useCallback)(() => {
|
|
1513
2197
|
setRowFieldsState([]);
|
|
1514
2198
|
setColumnFieldsState([]);
|
|
1515
2199
|
setValueFields([]);
|
|
1516
2200
|
}, []);
|
|
1517
|
-
const autoSuggestConfig = (0,
|
|
2201
|
+
const autoSuggestConfig = (0, import_react8.useCallback)(() => {
|
|
1518
2202
|
if (!requirePro("Pivot Table - Auto Suggest"))
|
|
1519
2203
|
return;
|
|
1520
2204
|
if (availableFields.length === 0)
|
|
@@ -1526,7 +2210,7 @@ function usePivotTable(data) {
|
|
|
1526
2210
|
setValueFields([{ field: numericFields[0].field, aggregation: "sum" }]);
|
|
1527
2211
|
}
|
|
1528
2212
|
}, [availableFields, requirePro]);
|
|
1529
|
-
const addCalculatedField = (0,
|
|
2213
|
+
const addCalculatedField = (0, import_react8.useCallback)((field) => {
|
|
1530
2214
|
setCalculatedFields((prev) => {
|
|
1531
2215
|
const existing = prev.findIndex((f) => f.id === field.id);
|
|
1532
2216
|
let updated;
|
|
@@ -1535,14 +2219,14 @@ function usePivotTable(data) {
|
|
|
1535
2219
|
} else {
|
|
1536
2220
|
updated = [...prev, field];
|
|
1537
2221
|
}
|
|
1538
|
-
(0,
|
|
2222
|
+
(0, import_tinypivot_core6.saveCalculatedFields)(updated);
|
|
1539
2223
|
return updated;
|
|
1540
2224
|
});
|
|
1541
2225
|
}, []);
|
|
1542
|
-
const removeCalculatedField = (0,
|
|
2226
|
+
const removeCalculatedField = (0, import_react8.useCallback)((id) => {
|
|
1543
2227
|
setCalculatedFields((prev) => {
|
|
1544
2228
|
const updated = prev.filter((f) => f.id !== id);
|
|
1545
|
-
(0,
|
|
2229
|
+
(0, import_tinypivot_core6.saveCalculatedFields)(updated);
|
|
1546
2230
|
return updated;
|
|
1547
2231
|
});
|
|
1548
2232
|
setValueFields((prev) => prev.filter((v) => v.field !== `calc:${id}`));
|
|
@@ -1580,9 +2264,9 @@ function usePivotTable(data) {
|
|
|
1580
2264
|
}
|
|
1581
2265
|
|
|
1582
2266
|
// src/components/PivotConfig.tsx
|
|
1583
|
-
var
|
|
1584
|
-
var
|
|
1585
|
-
var
|
|
2267
|
+
var import_tinypivot_core7 = require("@smallwebco/tinypivot-core");
|
|
2268
|
+
var import_react9 = require("react");
|
|
2269
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1586
2270
|
function aggregationRequiresPro(agg) {
|
|
1587
2271
|
return agg !== "sum";
|
|
1588
2272
|
}
|
|
@@ -1623,15 +2307,15 @@ function PivotConfig({
|
|
|
1623
2307
|
onRemoveCalculatedField,
|
|
1624
2308
|
onUpdateCalculatedField
|
|
1625
2309
|
}) {
|
|
1626
|
-
const [fieldSearch, setFieldSearch] = (0,
|
|
1627
|
-
const [showCalcModal, setShowCalcModal] = (0,
|
|
1628
|
-
const [editingCalcField, setEditingCalcField] = (0,
|
|
2310
|
+
const [fieldSearch, setFieldSearch] = (0, import_react9.useState)("");
|
|
2311
|
+
const [showCalcModal, setShowCalcModal] = (0, import_react9.useState)(false);
|
|
2312
|
+
const [editingCalcField, setEditingCalcField] = (0, import_react9.useState)(null);
|
|
1629
2313
|
const { canUseAdvancedAggregations } = useLicense();
|
|
1630
|
-
const isAggregationAvailable = (0,
|
|
2314
|
+
const isAggregationAvailable = (0, import_react9.useCallback)((agg) => {
|
|
1631
2315
|
return !aggregationRequiresPro(agg) || canUseAdvancedAggregations;
|
|
1632
2316
|
}, [canUseAdvancedAggregations]);
|
|
1633
|
-
const numericFieldNames = (0,
|
|
1634
|
-
const calculatedFieldsAsStats = (0,
|
|
2317
|
+
const numericFieldNames = (0, import_react9.useMemo)(() => availableFields.filter((f) => f.isNumeric).map((f) => f.field), [availableFields]);
|
|
2318
|
+
const calculatedFieldsAsStats = (0, import_react9.useMemo)(() => {
|
|
1635
2319
|
if (!calculatedFields)
|
|
1636
2320
|
return [];
|
|
1637
2321
|
return calculatedFields.map((calc) => ({
|
|
@@ -1645,11 +2329,11 @@ function PivotConfig({
|
|
|
1645
2329
|
calcFormula: calc.formula
|
|
1646
2330
|
}));
|
|
1647
2331
|
}, [calculatedFields]);
|
|
1648
|
-
const allAvailableFields = (0,
|
|
2332
|
+
const allAvailableFields = (0, import_react9.useMemo)(() => [
|
|
1649
2333
|
...availableFields.map((f) => ({ ...f, isCalculated: false })),
|
|
1650
2334
|
...calculatedFieldsAsStats
|
|
1651
2335
|
], [availableFields, calculatedFieldsAsStats]);
|
|
1652
|
-
const assignedFields = (0,
|
|
2336
|
+
const assignedFields = (0, import_react9.useMemo)(() => {
|
|
1653
2337
|
const rowSet = new Set(rowFields);
|
|
1654
2338
|
const colSet = new Set(columnFields);
|
|
1655
2339
|
const valueMap = new Map(valueFields.map((v) => [v.field, v]));
|
|
@@ -1659,7 +2343,7 @@ function PivotConfig({
|
|
|
1659
2343
|
valueConfig: valueMap.get(f.field)
|
|
1660
2344
|
}));
|
|
1661
2345
|
}, [allAvailableFields, rowFields, columnFields, valueFields]);
|
|
1662
|
-
const unassignedFields = (0,
|
|
2346
|
+
const unassignedFields = (0, import_react9.useMemo)(() => {
|
|
1663
2347
|
const rowSet = new Set(rowFields);
|
|
1664
2348
|
const colSet = new Set(columnFields);
|
|
1665
2349
|
const valSet = new Set(valueFields.map((v) => v.field));
|
|
@@ -1667,7 +2351,7 @@ function PivotConfig({
|
|
|
1667
2351
|
(f) => !rowSet.has(f.field) && !colSet.has(f.field) && !valSet.has(f.field)
|
|
1668
2352
|
);
|
|
1669
2353
|
}, [allAvailableFields, rowFields, columnFields, valueFields]);
|
|
1670
|
-
const filteredUnassignedFields = (0,
|
|
2354
|
+
const filteredUnassignedFields = (0, import_react9.useMemo)(() => {
|
|
1671
2355
|
if (!fieldSearch.trim())
|
|
1672
2356
|
return unassignedFields;
|
|
1673
2357
|
const search = fieldSearch.toLowerCase().trim();
|
|
@@ -1678,13 +2362,13 @@ function PivotConfig({
|
|
|
1678
2362
|
});
|
|
1679
2363
|
}, [unassignedFields, fieldSearch]);
|
|
1680
2364
|
const assignedCount = assignedFields.length;
|
|
1681
|
-
const getFieldDisplayName = (0,
|
|
2365
|
+
const getFieldDisplayName = (0, import_react9.useCallback)((field) => {
|
|
1682
2366
|
if (field.isCalculated && field.calcName) {
|
|
1683
2367
|
return field.calcName;
|
|
1684
2368
|
}
|
|
1685
2369
|
return field.field;
|
|
1686
2370
|
}, []);
|
|
1687
|
-
const handleDragStart = (0,
|
|
2371
|
+
const handleDragStart = (0, import_react9.useCallback)(
|
|
1688
2372
|
(field, event) => {
|
|
1689
2373
|
event.dataTransfer?.setData("text/plain", field);
|
|
1690
2374
|
event.dataTransfer.effectAllowed = "move";
|
|
@@ -1692,7 +2376,7 @@ function PivotConfig({
|
|
|
1692
2376
|
},
|
|
1693
2377
|
[onDragStart]
|
|
1694
2378
|
);
|
|
1695
|
-
const handleAggregationChange = (0,
|
|
2379
|
+
const handleAggregationChange = (0, import_react9.useCallback)(
|
|
1696
2380
|
(field, currentAgg, newAgg) => {
|
|
1697
2381
|
if (!isAggregationAvailable(newAgg)) {
|
|
1698
2382
|
console.warn(`[TinyPivot] "${newAgg}" aggregation requires a Pro license. Visit https://tiny-pivot.com/#pricing to upgrade.`);
|
|
@@ -1702,7 +2386,7 @@ function PivotConfig({
|
|
|
1702
2386
|
},
|
|
1703
2387
|
[onUpdateAggregation, isAggregationAvailable]
|
|
1704
2388
|
);
|
|
1705
|
-
const toggleRowColumn = (0,
|
|
2389
|
+
const toggleRowColumn = (0, import_react9.useCallback)(
|
|
1706
2390
|
(field, currentAssignment) => {
|
|
1707
2391
|
if (currentAssignment === "row") {
|
|
1708
2392
|
onRemoveRowField(field);
|
|
@@ -1714,7 +2398,7 @@ function PivotConfig({
|
|
|
1714
2398
|
},
|
|
1715
2399
|
[onRemoveRowField, onAddColumnField, onRemoveColumnField, onAddRowField]
|
|
1716
2400
|
);
|
|
1717
|
-
const removeField = (0,
|
|
2401
|
+
const removeField = (0, import_react9.useCallback)(
|
|
1718
2402
|
(field, assignedTo, valueConfig) => {
|
|
1719
2403
|
if (assignedTo === "row") {
|
|
1720
2404
|
onRemoveRowField(field);
|
|
@@ -1726,15 +2410,15 @@ function PivotConfig({
|
|
|
1726
2410
|
},
|
|
1727
2411
|
[onRemoveRowField, onRemoveColumnField, onRemoveValueField]
|
|
1728
2412
|
);
|
|
1729
|
-
const handleTotalsToggle = (0,
|
|
2413
|
+
const handleTotalsToggle = (0, import_react9.useCallback)((checked) => {
|
|
1730
2414
|
onShowRowTotalsChange(checked);
|
|
1731
2415
|
onShowColumnTotalsChange(checked);
|
|
1732
2416
|
}, [onShowRowTotalsChange, onShowColumnTotalsChange]);
|
|
1733
|
-
const openCalcModal = (0,
|
|
2417
|
+
const openCalcModal = (0, import_react9.useCallback)((field) => {
|
|
1734
2418
|
setEditingCalcField(field || null);
|
|
1735
2419
|
setShowCalcModal(true);
|
|
1736
2420
|
}, []);
|
|
1737
|
-
const handleSaveCalcField = (0,
|
|
2421
|
+
const handleSaveCalcField = (0, import_react9.useCallback)((field) => {
|
|
1738
2422
|
if (editingCalcField && onUpdateCalculatedField) {
|
|
1739
2423
|
onUpdateCalculatedField(field);
|
|
1740
2424
|
} else if (onAddCalculatedField) {
|
|
@@ -1743,14 +2427,14 @@ function PivotConfig({
|
|
|
1743
2427
|
setShowCalcModal(false);
|
|
1744
2428
|
setEditingCalcField(null);
|
|
1745
2429
|
}, [editingCalcField, onAddCalculatedField, onUpdateCalculatedField]);
|
|
1746
|
-
const handleCloseCalcModal = (0,
|
|
2430
|
+
const handleCloseCalcModal = (0, import_react9.useCallback)(() => {
|
|
1747
2431
|
setShowCalcModal(false);
|
|
1748
2432
|
setEditingCalcField(null);
|
|
1749
2433
|
}, []);
|
|
1750
|
-
return /* @__PURE__ */ (0,
|
|
1751
|
-
/* @__PURE__ */ (0,
|
|
1752
|
-
/* @__PURE__ */ (0,
|
|
1753
|
-
/* @__PURE__ */ (0,
|
|
2434
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-pivot-config", children: [
|
|
2435
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-config-header", children: [
|
|
2436
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("h3", { className: "vpg-config-title", children: [
|
|
2437
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1754
2438
|
"path",
|
|
1755
2439
|
{
|
|
1756
2440
|
strokeLinecap: "round",
|
|
@@ -1761,13 +2445,13 @@ function PivotConfig({
|
|
|
1761
2445
|
) }),
|
|
1762
2446
|
"Fields"
|
|
1763
2447
|
] }),
|
|
1764
|
-
/* @__PURE__ */ (0,
|
|
2448
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-header-actions", children: assignedCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1765
2449
|
"button",
|
|
1766
2450
|
{
|
|
1767
2451
|
className: "vpg-action-btn vpg-clear-btn",
|
|
1768
2452
|
title: "Clear all",
|
|
1769
2453
|
onClick: onClearConfig,
|
|
1770
|
-
children: /* @__PURE__ */ (0,
|
|
2454
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1771
2455
|
"path",
|
|
1772
2456
|
{
|
|
1773
2457
|
strokeLinecap: "round",
|
|
@@ -1779,9 +2463,9 @@ function PivotConfig({
|
|
|
1779
2463
|
}
|
|
1780
2464
|
) })
|
|
1781
2465
|
] }),
|
|
1782
|
-
assignedCount > 0 && /* @__PURE__ */ (0,
|
|
1783
|
-
/* @__PURE__ */ (0,
|
|
1784
|
-
/* @__PURE__ */ (0,
|
|
2466
|
+
assignedCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-assigned-section", children: [
|
|
2467
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-section-label", children: "Active" }),
|
|
2468
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-assigned-list", children: assignedFields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1785
2469
|
"div",
|
|
1786
2470
|
{
|
|
1787
2471
|
className: `vpg-assigned-item vpg-type-${field.assignedTo}${field.isCalculated ? " vpg-type-calc" : ""}`,
|
|
@@ -1790,12 +2474,12 @@ function PivotConfig({
|
|
|
1790
2474
|
onDragStart: (e) => handleDragStart(field.field, e),
|
|
1791
2475
|
onDragEnd,
|
|
1792
2476
|
children: [
|
|
1793
|
-
/* @__PURE__ */ (0,
|
|
1794
|
-
/* @__PURE__ */ (0,
|
|
1795
|
-
/* @__PURE__ */ (0,
|
|
2477
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-item-main", children: [
|
|
2478
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: `vpg-item-badge ${field.assignedTo}${field.isCalculated ? " calc" : ""}`, children: field.isCalculated ? "\u0192" : field.assignedTo === "row" ? "R" : field.assignedTo === "column" ? "C" : (0, import_tinypivot_core7.getAggregationSymbol)(field.valueConfig?.aggregation || "sum") }),
|
|
2479
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-item-name", children: getFieldDisplayName(field) })
|
|
1796
2480
|
] }),
|
|
1797
|
-
/* @__PURE__ */ (0,
|
|
1798
|
-
(field.assignedTo === "row" || field.assignedTo === "column") && /* @__PURE__ */ (0,
|
|
2481
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-item-actions", children: [
|
|
2482
|
+
(field.assignedTo === "row" || field.assignedTo === "column") && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1799
2483
|
"button",
|
|
1800
2484
|
{
|
|
1801
2485
|
className: "vpg-toggle-btn",
|
|
@@ -1804,14 +2488,14 @@ function PivotConfig({
|
|
|
1804
2488
|
e.stopPropagation();
|
|
1805
2489
|
toggleRowColumn(field.field, field.assignedTo);
|
|
1806
2490
|
},
|
|
1807
|
-
children: /* @__PURE__ */ (0,
|
|
2491
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1808
2492
|
"svg",
|
|
1809
2493
|
{
|
|
1810
2494
|
className: "vpg-icon-xs",
|
|
1811
2495
|
fill: "none",
|
|
1812
2496
|
stroke: "currentColor",
|
|
1813
2497
|
viewBox: "0 0 24 24",
|
|
1814
|
-
children: /* @__PURE__ */ (0,
|
|
2498
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1815
2499
|
"path",
|
|
1816
2500
|
{
|
|
1817
2501
|
strokeLinecap: "round",
|
|
@@ -1824,7 +2508,7 @@ function PivotConfig({
|
|
|
1824
2508
|
)
|
|
1825
2509
|
}
|
|
1826
2510
|
),
|
|
1827
|
-
field.assignedTo === "value" && field.valueConfig && /* @__PURE__ */ (0,
|
|
2511
|
+
field.assignedTo === "value" && field.valueConfig && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1828
2512
|
"select",
|
|
1829
2513
|
{
|
|
1830
2514
|
className: "vpg-agg-select",
|
|
@@ -1838,7 +2522,7 @@ function PivotConfig({
|
|
|
1838
2522
|
);
|
|
1839
2523
|
},
|
|
1840
2524
|
onClick: (e) => e.stopPropagation(),
|
|
1841
|
-
children:
|
|
2525
|
+
children: import_tinypivot_core7.AGGREGATION_OPTIONS.map((agg) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1842
2526
|
"option",
|
|
1843
2527
|
{
|
|
1844
2528
|
value: agg.value,
|
|
@@ -1854,7 +2538,7 @@ function PivotConfig({
|
|
|
1854
2538
|
))
|
|
1855
2539
|
}
|
|
1856
2540
|
),
|
|
1857
|
-
/* @__PURE__ */ (0,
|
|
2541
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1858
2542
|
"button",
|
|
1859
2543
|
{
|
|
1860
2544
|
className: "vpg-remove-btn",
|
|
@@ -1872,14 +2556,14 @@ function PivotConfig({
|
|
|
1872
2556
|
field.field
|
|
1873
2557
|
)) })
|
|
1874
2558
|
] }),
|
|
1875
|
-
/* @__PURE__ */ (0,
|
|
1876
|
-
/* @__PURE__ */ (0,
|
|
2559
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-unassigned-section", children: [
|
|
2560
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-section-header", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-section-label", children: [
|
|
1877
2561
|
"Available",
|
|
1878
2562
|
" ",
|
|
1879
|
-
/* @__PURE__ */ (0,
|
|
2563
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-count", children: unassignedFields.length })
|
|
1880
2564
|
] }) }),
|
|
1881
|
-
/* @__PURE__ */ (0,
|
|
1882
|
-
/* @__PURE__ */ (0,
|
|
2565
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-field-search", children: [
|
|
2566
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "vpg-search-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1883
2567
|
"path",
|
|
1884
2568
|
{
|
|
1885
2569
|
strokeLinecap: "round",
|
|
@@ -1888,7 +2572,7 @@ function PivotConfig({
|
|
|
1888
2572
|
d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
|
|
1889
2573
|
}
|
|
1890
2574
|
) }),
|
|
1891
|
-
/* @__PURE__ */ (0,
|
|
2575
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1892
2576
|
"input",
|
|
1893
2577
|
{
|
|
1894
2578
|
type: "text",
|
|
@@ -1898,7 +2582,7 @@ function PivotConfig({
|
|
|
1898
2582
|
className: "vpg-search-input"
|
|
1899
2583
|
}
|
|
1900
2584
|
),
|
|
1901
|
-
fieldSearch && /* @__PURE__ */ (0,
|
|
2585
|
+
fieldSearch && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "vpg-clear-search", onClick: () => setFieldSearch(""), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1902
2586
|
"path",
|
|
1903
2587
|
{
|
|
1904
2588
|
strokeLinecap: "round",
|
|
@@ -1908,8 +2592,8 @@ function PivotConfig({
|
|
|
1908
2592
|
}
|
|
1909
2593
|
) }) })
|
|
1910
2594
|
] }),
|
|
1911
|
-
/* @__PURE__ */ (0,
|
|
1912
|
-
filteredUnassignedFields.map((field) => /* @__PURE__ */ (0,
|
|
2595
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-field-list", children: [
|
|
2596
|
+
filteredUnassignedFields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1913
2597
|
"div",
|
|
1914
2598
|
{
|
|
1915
2599
|
className: `vpg-field-item${field.isNumeric && !field.isCalculated ? " vpg-is-numeric" : ""}${field.isCalculated ? " vpg-is-calculated" : ""}`,
|
|
@@ -1918,10 +2602,10 @@ function PivotConfig({
|
|
|
1918
2602
|
onDragStart: (e) => handleDragStart(field.field, e),
|
|
1919
2603
|
onDragEnd,
|
|
1920
2604
|
children: [
|
|
1921
|
-
/* @__PURE__ */ (0,
|
|
1922
|
-
/* @__PURE__ */ (0,
|
|
1923
|
-
field.isCalculated ? /* @__PURE__ */ (0,
|
|
1924
|
-
/* @__PURE__ */ (0,
|
|
2605
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: `vpg-field-type-icon${field.isCalculated ? " vpg-calc-type" : ""}`, title: field.type, children: getFieldIcon(field.type, field.isCalculated) }),
|
|
2606
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-field-name", children: getFieldDisplayName(field) }),
|
|
2607
|
+
field.isCalculated ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
2608
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1925
2609
|
"button",
|
|
1926
2610
|
{
|
|
1927
2611
|
className: "vpg-field-edit",
|
|
@@ -1935,7 +2619,7 @@ function PivotConfig({
|
|
|
1935
2619
|
children: "\u270E"
|
|
1936
2620
|
}
|
|
1937
2621
|
),
|
|
1938
|
-
/* @__PURE__ */ (0,
|
|
2622
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1939
2623
|
"button",
|
|
1940
2624
|
{
|
|
1941
2625
|
className: "vpg-field-delete",
|
|
@@ -1949,22 +2633,22 @@ function PivotConfig({
|
|
|
1949
2633
|
children: "\xD7"
|
|
1950
2634
|
}
|
|
1951
2635
|
)
|
|
1952
|
-
] }) : /* @__PURE__ */ (0,
|
|
2636
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-unique-count", children: field.uniqueCount })
|
|
1953
2637
|
]
|
|
1954
2638
|
},
|
|
1955
2639
|
field.field
|
|
1956
2640
|
)),
|
|
1957
|
-
filteredUnassignedFields.length === 0 && fieldSearch && /* @__PURE__ */ (0,
|
|
2641
|
+
filteredUnassignedFields.length === 0 && fieldSearch && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-empty-hint", children: [
|
|
1958
2642
|
'No fields match "',
|
|
1959
2643
|
fieldSearch,
|
|
1960
2644
|
'"'
|
|
1961
2645
|
] }),
|
|
1962
|
-
unassignedFields.length === 0 && /* @__PURE__ */ (0,
|
|
2646
|
+
unassignedFields.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-empty-hint", children: "All fields assigned" })
|
|
1963
2647
|
] })
|
|
1964
2648
|
] }),
|
|
1965
|
-
/* @__PURE__ */ (0,
|
|
1966
|
-
/* @__PURE__ */ (0,
|
|
1967
|
-
/* @__PURE__ */ (0,
|
|
2649
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-options-section", children: [
|
|
2650
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "vpg-option-toggle", children: [
|
|
2651
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1968
2652
|
"input",
|
|
1969
2653
|
{
|
|
1970
2654
|
type: "checkbox",
|
|
@@ -1972,14 +2656,14 @@ function PivotConfig({
|
|
|
1972
2656
|
onChange: (e) => handleTotalsToggle(e.target.checked)
|
|
1973
2657
|
}
|
|
1974
2658
|
),
|
|
1975
|
-
/* @__PURE__ */ (0,
|
|
2659
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Totals" })
|
|
1976
2660
|
] }),
|
|
1977
|
-
/* @__PURE__ */ (0,
|
|
1978
|
-
/* @__PURE__ */ (0,
|
|
1979
|
-
/* @__PURE__ */ (0,
|
|
2661
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { className: "vpg-calc-btn", onClick: () => openCalcModal(), title: "Add calculated field (e.g. Profit Margin %)", children: [
|
|
2662
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-calc-icon", children: "\u0192" }),
|
|
2663
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "+ Calc" })
|
|
1980
2664
|
] })
|
|
1981
2665
|
] }),
|
|
1982
|
-
/* @__PURE__ */ (0,
|
|
2666
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1983
2667
|
CalculatedFieldModal,
|
|
1984
2668
|
{
|
|
1985
2669
|
show: showCalcModal,
|
|
@@ -1993,9 +2677,9 @@ function PivotConfig({
|
|
|
1993
2677
|
}
|
|
1994
2678
|
|
|
1995
2679
|
// src/components/PivotSkeleton.tsx
|
|
1996
|
-
var
|
|
1997
|
-
var
|
|
1998
|
-
var
|
|
2680
|
+
var import_tinypivot_core8 = require("@smallwebco/tinypivot-core");
|
|
2681
|
+
var import_react10 = require("react");
|
|
2682
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1999
2683
|
function PivotSkeleton({
|
|
2000
2684
|
rowFields,
|
|
2001
2685
|
columnFields,
|
|
@@ -2018,7 +2702,7 @@ function PivotSkeleton({
|
|
|
2018
2702
|
onReorderColumnFields
|
|
2019
2703
|
}) {
|
|
2020
2704
|
const { showWatermark, canUsePivot, isDemo } = useLicense();
|
|
2021
|
-
const getValueFieldDisplayName = (0,
|
|
2705
|
+
const getValueFieldDisplayName = (0, import_react10.useCallback)((field) => {
|
|
2022
2706
|
if (field.startsWith("calc:")) {
|
|
2023
2707
|
const calcId = field.replace("calc:", "");
|
|
2024
2708
|
const calcField = calculatedFields?.find((c) => c.id === calcId);
|
|
@@ -2026,15 +2710,15 @@ function PivotSkeleton({
|
|
|
2026
2710
|
}
|
|
2027
2711
|
return field;
|
|
2028
2712
|
}, [calculatedFields]);
|
|
2029
|
-
const isCalculatedField = (0,
|
|
2713
|
+
const isCalculatedField = (0, import_react10.useCallback)((field) => {
|
|
2030
2714
|
return field.startsWith("calc:");
|
|
2031
2715
|
}, []);
|
|
2032
|
-
const [dragOverArea, setDragOverArea] = (0,
|
|
2033
|
-
const [reorderDragSource, setReorderDragSource] = (0,
|
|
2034
|
-
const [reorderDropTarget, setReorderDropTarget] = (0,
|
|
2035
|
-
const [sortDirection, setSortDirection] = (0,
|
|
2036
|
-
const [sortTarget, setSortTarget] = (0,
|
|
2037
|
-
const toggleSort = (0,
|
|
2716
|
+
const [dragOverArea, setDragOverArea] = (0, import_react10.useState)(null);
|
|
2717
|
+
const [reorderDragSource, setReorderDragSource] = (0, import_react10.useState)(null);
|
|
2718
|
+
const [reorderDropTarget, setReorderDropTarget] = (0, import_react10.useState)(null);
|
|
2719
|
+
const [sortDirection, setSortDirection] = (0, import_react10.useState)("asc");
|
|
2720
|
+
const [sortTarget, setSortTarget] = (0, import_react10.useState)("row");
|
|
2721
|
+
const toggleSort = (0, import_react10.useCallback)((target = "row") => {
|
|
2038
2722
|
if (sortTarget === target) {
|
|
2039
2723
|
setSortDirection((prev) => prev === "asc" ? "desc" : "asc");
|
|
2040
2724
|
} else {
|
|
@@ -2042,13 +2726,13 @@ function PivotSkeleton({
|
|
|
2042
2726
|
setSortDirection("asc");
|
|
2043
2727
|
}
|
|
2044
2728
|
}, [sortTarget]);
|
|
2045
|
-
const [selectedCell, setSelectedCell] = (0,
|
|
2046
|
-
const [selectionStart, setSelectionStart] = (0,
|
|
2047
|
-
const [selectionEnd, setSelectionEnd] = (0,
|
|
2048
|
-
const [isSelecting, setIsSelecting] = (0,
|
|
2049
|
-
const [showCopyToast, setShowCopyToast] = (0,
|
|
2050
|
-
const [copyToastMessage, setCopyToastMessage] = (0,
|
|
2051
|
-
const selectionBounds = (0,
|
|
2729
|
+
const [selectedCell, setSelectedCell] = (0, import_react10.useState)(null);
|
|
2730
|
+
const [selectionStart, setSelectionStart] = (0, import_react10.useState)(null);
|
|
2731
|
+
const [selectionEnd, setSelectionEnd] = (0, import_react10.useState)(null);
|
|
2732
|
+
const [isSelecting, setIsSelecting] = (0, import_react10.useState)(false);
|
|
2733
|
+
const [showCopyToast, setShowCopyToast] = (0, import_react10.useState)(false);
|
|
2734
|
+
const [copyToastMessage, setCopyToastMessage] = (0, import_react10.useState)("");
|
|
2735
|
+
const selectionBounds = (0, import_react10.useMemo)(() => {
|
|
2052
2736
|
if (!selectionStart || !selectionEnd)
|
|
2053
2737
|
return null;
|
|
2054
2738
|
return {
|
|
@@ -2058,7 +2742,7 @@ function PivotSkeleton({
|
|
|
2058
2742
|
maxCol: Math.max(selectionStart.col, selectionEnd.col)
|
|
2059
2743
|
};
|
|
2060
2744
|
}, [selectionStart, selectionEnd]);
|
|
2061
|
-
const handleCellMouseDown = (0,
|
|
2745
|
+
const handleCellMouseDown = (0, import_react10.useCallback)(
|
|
2062
2746
|
(rowIndex, colIndex, event) => {
|
|
2063
2747
|
event.preventDefault();
|
|
2064
2748
|
if (event.shiftKey && selectedCell) {
|
|
@@ -2072,7 +2756,7 @@ function PivotSkeleton({
|
|
|
2072
2756
|
},
|
|
2073
2757
|
[selectedCell]
|
|
2074
2758
|
);
|
|
2075
|
-
const handleCellMouseEnter = (0,
|
|
2759
|
+
const handleCellMouseEnter = (0, import_react10.useCallback)(
|
|
2076
2760
|
(rowIndex, colIndex) => {
|
|
2077
2761
|
if (isSelecting) {
|
|
2078
2762
|
setSelectionEnd({ row: rowIndex, col: colIndex });
|
|
@@ -2080,7 +2764,7 @@ function PivotSkeleton({
|
|
|
2080
2764
|
},
|
|
2081
2765
|
[isSelecting]
|
|
2082
2766
|
);
|
|
2083
|
-
const isCellSelected = (0,
|
|
2767
|
+
const isCellSelected = (0, import_react10.useCallback)(
|
|
2084
2768
|
(rowIndex, colIndex) => {
|
|
2085
2769
|
if (!selectionBounds) {
|
|
2086
2770
|
return selectedCell?.row === rowIndex && selectedCell?.col === colIndex;
|
|
@@ -2090,12 +2774,12 @@ function PivotSkeleton({
|
|
|
2090
2774
|
},
|
|
2091
2775
|
[selectionBounds, selectedCell]
|
|
2092
2776
|
);
|
|
2093
|
-
(0,
|
|
2777
|
+
(0, import_react10.useEffect)(() => {
|
|
2094
2778
|
const handleMouseUp = () => setIsSelecting(false);
|
|
2095
2779
|
document.addEventListener("mouseup", handleMouseUp);
|
|
2096
2780
|
return () => document.removeEventListener("mouseup", handleMouseUp);
|
|
2097
2781
|
}, []);
|
|
2098
|
-
const sortedRowIndices = (0,
|
|
2782
|
+
const sortedRowIndices = (0, import_react10.useMemo)(() => {
|
|
2099
2783
|
if (!pivotResult)
|
|
2100
2784
|
return [];
|
|
2101
2785
|
const indices = pivotResult.rowHeaders.map((_, i) => i);
|
|
@@ -2123,7 +2807,7 @@ function PivotSkeleton({
|
|
|
2123
2807
|
});
|
|
2124
2808
|
return indices;
|
|
2125
2809
|
}, [pivotResult, sortTarget, sortDirection]);
|
|
2126
|
-
const copySelectionToClipboard = (0,
|
|
2810
|
+
const copySelectionToClipboard = (0, import_react10.useCallback)(() => {
|
|
2127
2811
|
if (!selectionBounds || !pivotResult)
|
|
2128
2812
|
return;
|
|
2129
2813
|
const { minRow, maxRow, minCol, maxCol } = selectionBounds;
|
|
@@ -2149,7 +2833,7 @@ function PivotSkeleton({
|
|
|
2149
2833
|
console.error("Copy failed:", err);
|
|
2150
2834
|
});
|
|
2151
2835
|
}, [selectionBounds, pivotResult, sortedRowIndices]);
|
|
2152
|
-
(0,
|
|
2836
|
+
(0, import_react10.useEffect)(() => {
|
|
2153
2837
|
const handleKeydown = (event) => {
|
|
2154
2838
|
if (!selectionBounds)
|
|
2155
2839
|
return;
|
|
@@ -2167,7 +2851,7 @@ function PivotSkeleton({
|
|
|
2167
2851
|
document.addEventListener("keydown", handleKeydown);
|
|
2168
2852
|
return () => document.removeEventListener("keydown", handleKeydown);
|
|
2169
2853
|
}, [selectionBounds, copySelectionToClipboard]);
|
|
2170
|
-
const selectionStats = (0,
|
|
2854
|
+
const selectionStats = (0, import_react10.useMemo)(() => {
|
|
2171
2855
|
if (!selectionBounds || !pivotResult)
|
|
2172
2856
|
return null;
|
|
2173
2857
|
const { minRow, maxRow, minCol, maxCol } = selectionBounds;
|
|
@@ -2196,18 +2880,18 @@ function PivotSkeleton({
|
|
|
2196
2880
|
avg
|
|
2197
2881
|
};
|
|
2198
2882
|
}, [selectionBounds, pivotResult, sortedRowIndices]);
|
|
2199
|
-
const formatStatValue = (0,
|
|
2883
|
+
const formatStatValue = (0, import_react10.useCallback)((val) => {
|
|
2200
2884
|
if (Math.abs(val) >= 1e6)
|
|
2201
2885
|
return `${(val / 1e6).toFixed(2)}M`;
|
|
2202
2886
|
if (Math.abs(val) >= 1e3)
|
|
2203
2887
|
return `${(val / 1e3).toFixed(2)}K`;
|
|
2204
2888
|
return val.toFixed(2);
|
|
2205
2889
|
}, []);
|
|
2206
|
-
const columnHeaderCells = (0,
|
|
2890
|
+
const columnHeaderCells = (0, import_react10.useMemo)(() => {
|
|
2207
2891
|
if (!pivotResult || pivotResult.headers.length === 0) {
|
|
2208
2892
|
return [
|
|
2209
2893
|
valueFields.map((vf) => ({
|
|
2210
|
-
label: `${getValueFieldDisplayName(vf.field)} (${(0,
|
|
2894
|
+
label: `${getValueFieldDisplayName(vf.field)} (${(0, import_tinypivot_core8.getAggregationLabel)(vf.aggregation)})`,
|
|
2211
2895
|
colspan: 1
|
|
2212
2896
|
}))
|
|
2213
2897
|
];
|
|
@@ -2231,13 +2915,13 @@ function PivotSkeleton({
|
|
|
2231
2915
|
return result;
|
|
2232
2916
|
}, [pivotResult, valueFields]);
|
|
2233
2917
|
const hasActiveFilters = activeFilters && activeFilters.length > 0;
|
|
2234
|
-
const filterSummary = (0,
|
|
2918
|
+
const filterSummary = (0, import_react10.useMemo)(() => {
|
|
2235
2919
|
if (!activeFilters || activeFilters.length === 0)
|
|
2236
2920
|
return "";
|
|
2237
2921
|
return activeFilters.map((f) => f.column).join(", ");
|
|
2238
2922
|
}, [activeFilters]);
|
|
2239
|
-
const [showFilterTooltip, setShowFilterTooltip] = (0,
|
|
2240
|
-
const filterTooltipDetails = (0,
|
|
2923
|
+
const [showFilterTooltip, setShowFilterTooltip] = (0, import_react10.useState)(false);
|
|
2924
|
+
const filterTooltipDetails = (0, import_react10.useMemo)(() => {
|
|
2241
2925
|
if (!activeFilters || activeFilters.length === 0)
|
|
2242
2926
|
return [];
|
|
2243
2927
|
return activeFilters.map((f) => {
|
|
@@ -2262,7 +2946,7 @@ function PivotSkeleton({
|
|
|
2262
2946
|
};
|
|
2263
2947
|
});
|
|
2264
2948
|
}, [activeFilters]);
|
|
2265
|
-
const handleDragOver = (0,
|
|
2949
|
+
const handleDragOver = (0, import_react10.useCallback)(
|
|
2266
2950
|
(area, event) => {
|
|
2267
2951
|
event.preventDefault();
|
|
2268
2952
|
event.dataTransfer.dropEffect = "move";
|
|
@@ -2270,10 +2954,10 @@ function PivotSkeleton({
|
|
|
2270
2954
|
},
|
|
2271
2955
|
[]
|
|
2272
2956
|
);
|
|
2273
|
-
const handleDragLeave = (0,
|
|
2957
|
+
const handleDragLeave = (0, import_react10.useCallback)(() => {
|
|
2274
2958
|
setDragOverArea(null);
|
|
2275
2959
|
}, []);
|
|
2276
|
-
const handleDrop = (0,
|
|
2960
|
+
const handleDrop = (0, import_react10.useCallback)(
|
|
2277
2961
|
(area, event) => {
|
|
2278
2962
|
event.preventDefault();
|
|
2279
2963
|
const field = event.dataTransfer?.getData("text/plain");
|
|
@@ -2303,7 +2987,7 @@ function PivotSkeleton({
|
|
|
2303
2987
|
},
|
|
2304
2988
|
[rowFields, columnFields, valueFields, onAddRowField, onRemoveRowField, onAddColumnField, onRemoveColumnField, onAddValueField, onRemoveValueField]
|
|
2305
2989
|
);
|
|
2306
|
-
const handleChipDragStart = (0,
|
|
2990
|
+
const handleChipDragStart = (0, import_react10.useCallback)(
|
|
2307
2991
|
(zone, index, event) => {
|
|
2308
2992
|
setReorderDragSource({ zone, index });
|
|
2309
2993
|
event.dataTransfer.effectAllowed = "move";
|
|
@@ -2314,11 +2998,11 @@ function PivotSkeleton({
|
|
|
2314
2998
|
},
|
|
2315
2999
|
[]
|
|
2316
3000
|
);
|
|
2317
|
-
const handleChipDragEnd = (0,
|
|
3001
|
+
const handleChipDragEnd = (0, import_react10.useCallback)(() => {
|
|
2318
3002
|
setReorderDragSource(null);
|
|
2319
3003
|
setReorderDropTarget(null);
|
|
2320
3004
|
}, []);
|
|
2321
|
-
const handleChipDragOver = (0,
|
|
3005
|
+
const handleChipDragOver = (0, import_react10.useCallback)(
|
|
2322
3006
|
(zone, index, event) => {
|
|
2323
3007
|
event.preventDefault();
|
|
2324
3008
|
if (reorderDragSource && reorderDragSource.zone === zone) {
|
|
@@ -2328,10 +3012,10 @@ function PivotSkeleton({
|
|
|
2328
3012
|
},
|
|
2329
3013
|
[reorderDragSource]
|
|
2330
3014
|
);
|
|
2331
|
-
const handleChipDragLeave = (0,
|
|
3015
|
+
const handleChipDragLeave = (0, import_react10.useCallback)(() => {
|
|
2332
3016
|
setReorderDropTarget(null);
|
|
2333
3017
|
}, []);
|
|
2334
|
-
const handleChipDrop = (0,
|
|
3018
|
+
const handleChipDrop = (0, import_react10.useCallback)(
|
|
2335
3019
|
(zone, targetIndex, event) => {
|
|
2336
3020
|
event.preventDefault();
|
|
2337
3021
|
event.stopPropagation();
|
|
@@ -2357,13 +3041,13 @@ function PivotSkeleton({
|
|
|
2357
3041
|
},
|
|
2358
3042
|
[reorderDragSource, rowFields, columnFields, onReorderRowFields, onReorderColumnFields]
|
|
2359
3043
|
);
|
|
2360
|
-
const isChipDragSource = (0,
|
|
3044
|
+
const isChipDragSource = (0, import_react10.useCallback)(
|
|
2361
3045
|
(zone, index) => {
|
|
2362
3046
|
return reorderDragSource?.zone === zone && reorderDragSource?.index === index;
|
|
2363
3047
|
},
|
|
2364
3048
|
[reorderDragSource]
|
|
2365
3049
|
);
|
|
2366
|
-
const isChipDropTarget = (0,
|
|
3050
|
+
const isChipDropTarget = (0, import_react10.useCallback)(
|
|
2367
3051
|
(zone, index) => {
|
|
2368
3052
|
return reorderDropTarget?.zone === zone && reorderDropTarget?.index === index;
|
|
2369
3053
|
},
|
|
@@ -2371,25 +3055,25 @@ function PivotSkeleton({
|
|
|
2371
3055
|
);
|
|
2372
3056
|
const currentFontSize = fontSize;
|
|
2373
3057
|
const rowHeaderWidth = 180;
|
|
2374
|
-
const rowHeaderColWidth = (0,
|
|
3058
|
+
const rowHeaderColWidth = (0, import_react10.useMemo)(() => {
|
|
2375
3059
|
const numCols = Math.max(rowFields.length, 1);
|
|
2376
3060
|
return Math.max(rowHeaderWidth / numCols, 80);
|
|
2377
3061
|
}, [rowFields.length]);
|
|
2378
|
-
const getRowHeaderLeftOffset = (0,
|
|
3062
|
+
const getRowHeaderLeftOffset = (0, import_react10.useCallback)((fieldIdx) => {
|
|
2379
3063
|
return fieldIdx * rowHeaderColWidth;
|
|
2380
3064
|
}, [rowHeaderColWidth]);
|
|
2381
|
-
return /* @__PURE__ */ (0,
|
|
3065
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
2382
3066
|
"div",
|
|
2383
3067
|
{
|
|
2384
3068
|
className: `vpg-pivot-skeleton vpg-font-${currentFontSize} ${draggingField ? "vpg-is-dragging" : ""}`,
|
|
2385
3069
|
children: [
|
|
2386
|
-
showCopyToast && /* @__PURE__ */ (0,
|
|
2387
|
-
/* @__PURE__ */ (0,
|
|
3070
|
+
showCopyToast && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-toast", children: [
|
|
3071
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }),
|
|
2388
3072
|
copyToastMessage
|
|
2389
3073
|
] }),
|
|
2390
|
-
/* @__PURE__ */ (0,
|
|
2391
|
-
/* @__PURE__ */ (0,
|
|
2392
|
-
/* @__PURE__ */ (0,
|
|
3074
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-skeleton-header", children: [
|
|
3075
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-skeleton-title", children: [
|
|
3076
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2393
3077
|
"path",
|
|
2394
3078
|
{
|
|
2395
3079
|
strokeLinecap: "round",
|
|
@@ -2398,24 +3082,24 @@ function PivotSkeleton({
|
|
|
2398
3082
|
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"
|
|
2399
3083
|
}
|
|
2400
3084
|
) }),
|
|
2401
|
-
/* @__PURE__ */ (0,
|
|
3085
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "Pivot Table" })
|
|
2402
3086
|
] }),
|
|
2403
|
-
/* @__PURE__ */ (0,
|
|
2404
|
-
hasActiveFilters && /* @__PURE__ */ (0,
|
|
3087
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-header-right", children: [
|
|
3088
|
+
hasActiveFilters && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
2405
3089
|
"div",
|
|
2406
3090
|
{
|
|
2407
3091
|
className: "vpg-filter-indicator",
|
|
2408
3092
|
onMouseEnter: () => setShowFilterTooltip(true),
|
|
2409
3093
|
onMouseLeave: () => setShowFilterTooltip(false),
|
|
2410
3094
|
children: [
|
|
2411
|
-
/* @__PURE__ */ (0,
|
|
3095
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2412
3096
|
"svg",
|
|
2413
3097
|
{
|
|
2414
3098
|
className: "vpg-filter-icon",
|
|
2415
3099
|
fill: "none",
|
|
2416
3100
|
stroke: "currentColor",
|
|
2417
3101
|
viewBox: "0 0 24 24",
|
|
2418
|
-
children: /* @__PURE__ */ (0,
|
|
3102
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2419
3103
|
"path",
|
|
2420
3104
|
{
|
|
2421
3105
|
strokeLinecap: "round",
|
|
@@ -2426,11 +3110,11 @@ function PivotSkeleton({
|
|
|
2426
3110
|
)
|
|
2427
3111
|
}
|
|
2428
3112
|
),
|
|
2429
|
-
/* @__PURE__ */ (0,
|
|
3113
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "vpg-filter-text", children: [
|
|
2430
3114
|
"Filtered:",
|
|
2431
3115
|
" ",
|
|
2432
|
-
/* @__PURE__ */ (0,
|
|
2433
|
-
filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ (0,
|
|
3116
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: filterSummary }),
|
|
3117
|
+
filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "vpg-filter-count", children: [
|
|
2434
3118
|
"(",
|
|
2435
3119
|
filteredRowCount.toLocaleString(),
|
|
2436
3120
|
" ",
|
|
@@ -2441,13 +3125,13 @@ function PivotSkeleton({
|
|
|
2441
3125
|
"rows)"
|
|
2442
3126
|
] })
|
|
2443
3127
|
] }),
|
|
2444
|
-
showFilterTooltip && /* @__PURE__ */ (0,
|
|
2445
|
-
/* @__PURE__ */ (0,
|
|
2446
|
-
filterTooltipDetails.map((filter) => /* @__PURE__ */ (0,
|
|
2447
|
-
/* @__PURE__ */ (0,
|
|
2448
|
-
/* @__PURE__ */ (0,
|
|
2449
|
-
filter.values.map((val, idx) => /* @__PURE__ */ (0,
|
|
2450
|
-
filter.remaining > 0 && /* @__PURE__ */ (0,
|
|
3128
|
+
showFilterTooltip && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-filter-tooltip", children: [
|
|
3129
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "vpg-tooltip-header", children: "Active Filters" }),
|
|
3130
|
+
filterTooltipDetails.map((filter) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-tooltip-filter", children: [
|
|
3131
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "vpg-tooltip-column", children: filter.column }),
|
|
3132
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "vpg-tooltip-values", children: filter.isRange ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vpg-tooltip-value vpg-range-value", children: filter.displayText }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
3133
|
+
filter.values.map((val, idx) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vpg-tooltip-value", children: val }, idx)),
|
|
3134
|
+
filter.remaining > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "vpg-tooltip-more", children: [
|
|
2451
3135
|
"+",
|
|
2452
3136
|
filter.remaining,
|
|
2453
3137
|
" ",
|
|
@@ -2455,7 +3139,7 @@ function PivotSkeleton({
|
|
|
2455
3139
|
] })
|
|
2456
3140
|
] }) })
|
|
2457
3141
|
] }, filter.column)),
|
|
2458
|
-
filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ (0,
|
|
3142
|
+
filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-tooltip-summary", children: [
|
|
2459
3143
|
"Showing",
|
|
2460
3144
|
" ",
|
|
2461
3145
|
filteredRowCount.toLocaleString(),
|
|
@@ -2470,20 +3154,20 @@ function PivotSkeleton({
|
|
|
2470
3154
|
]
|
|
2471
3155
|
}
|
|
2472
3156
|
),
|
|
2473
|
-
isConfigured && /* @__PURE__ */ (0,
|
|
2474
|
-
/* @__PURE__ */ (0,
|
|
3157
|
+
isConfigured && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-config-summary", children: [
|
|
3158
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "vpg-summary-badge vpg-rows", children: [
|
|
2475
3159
|
rowFields.length,
|
|
2476
3160
|
" ",
|
|
2477
3161
|
"row",
|
|
2478
3162
|
rowFields.length !== 1 ? "s" : ""
|
|
2479
3163
|
] }),
|
|
2480
|
-
/* @__PURE__ */ (0,
|
|
3164
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "vpg-summary-badge vpg-cols", children: [
|
|
2481
3165
|
columnFields.length,
|
|
2482
3166
|
" ",
|
|
2483
3167
|
"col",
|
|
2484
3168
|
columnFields.length !== 1 ? "s" : ""
|
|
2485
3169
|
] }),
|
|
2486
|
-
/* @__PURE__ */ (0,
|
|
3170
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "vpg-summary-badge vpg-vals", children: [
|
|
2487
3171
|
valueFields.length,
|
|
2488
3172
|
" ",
|
|
2489
3173
|
"val",
|
|
@@ -2492,8 +3176,8 @@ function PivotSkeleton({
|
|
|
2492
3176
|
] })
|
|
2493
3177
|
] })
|
|
2494
3178
|
] }),
|
|
2495
|
-
!canUsePivot ? /* @__PURE__ */ (0,
|
|
2496
|
-
/* @__PURE__ */ (0,
|
|
3179
|
+
!canUsePivot ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "vpg-pro-required", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-pro-content", children: [
|
|
3180
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { className: "vpg-pro-icon", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2497
3181
|
"path",
|
|
2498
3182
|
{
|
|
2499
3183
|
strokeLinecap: "round",
|
|
@@ -2502,12 +3186,12 @@ function PivotSkeleton({
|
|
|
2502
3186
|
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"
|
|
2503
3187
|
}
|
|
2504
3188
|
) }),
|
|
2505
|
-
/* @__PURE__ */ (0,
|
|
2506
|
-
/* @__PURE__ */ (0,
|
|
2507
|
-
/* @__PURE__ */ (0,
|
|
2508
|
-
] }) }) : /* @__PURE__ */ (0,
|
|
2509
|
-
/* @__PURE__ */ (0,
|
|
2510
|
-
/* @__PURE__ */ (0,
|
|
3189
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h3", { children: "Pro Feature" }),
|
|
3190
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { children: "Pivot Table functionality requires a Pro license." }),
|
|
3191
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("a", { href: "https://tiny-pivot.com/#pricing", target: "_blank", rel: "noopener noreferrer", className: "vpg-pro-link", children: "Get Pro License \u2192" })
|
|
3192
|
+
] }) }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
3193
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-config-bar", children: [
|
|
3194
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
2511
3195
|
"div",
|
|
2512
3196
|
{
|
|
2513
3197
|
className: `vpg-drop-zone vpg-row-zone ${dragOverArea === "row" ? "vpg-drag-over" : ""}`,
|
|
@@ -2515,12 +3199,12 @@ function PivotSkeleton({
|
|
|
2515
3199
|
onDragLeave: handleDragLeave,
|
|
2516
3200
|
onDrop: (e) => handleDrop("row", e),
|
|
2517
3201
|
children: [
|
|
2518
|
-
/* @__PURE__ */ (0,
|
|
2519
|
-
/* @__PURE__ */ (0,
|
|
2520
|
-
/* @__PURE__ */ (0,
|
|
3202
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-zone-header", children: [
|
|
3203
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vpg-zone-icon vpg-row-icon", children: "\u2193" }),
|
|
3204
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vpg-zone-label", children: "Rows" })
|
|
2521
3205
|
] }),
|
|
2522
|
-
/* @__PURE__ */ (0,
|
|
2523
|
-
rowFields.map((field, idx) => /* @__PURE__ */ (0,
|
|
3206
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-zone-chips", children: [
|
|
3207
|
+
rowFields.map((field, idx) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
2524
3208
|
"div",
|
|
2525
3209
|
{
|
|
2526
3210
|
className: `vpg-mini-chip vpg-row-chip ${isChipDragSource("row", idx) ? "vpg-chip-dragging" : ""} ${isChipDropTarget("row", idx) ? "vpg-chip-drop-target" : ""}`,
|
|
@@ -2531,9 +3215,9 @@ function PivotSkeleton({
|
|
|
2531
3215
|
onDragLeave: handleChipDragLeave,
|
|
2532
3216
|
onDrop: (e) => handleChipDrop("row", idx, e),
|
|
2533
3217
|
children: [
|
|
2534
|
-
/* @__PURE__ */ (0,
|
|
2535
|
-
/* @__PURE__ */ (0,
|
|
2536
|
-
/* @__PURE__ */ (0,
|
|
3218
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vpg-drag-handle", children: "\u22EE\u22EE" }),
|
|
3219
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vpg-mini-name", children: field }),
|
|
3220
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2537
3221
|
"button",
|
|
2538
3222
|
{
|
|
2539
3223
|
className: "vpg-mini-remove",
|
|
@@ -2548,12 +3232,12 @@ function PivotSkeleton({
|
|
|
2548
3232
|
},
|
|
2549
3233
|
field
|
|
2550
3234
|
)),
|
|
2551
|
-
rowFields.length === 0 && /* @__PURE__ */ (0,
|
|
3235
|
+
rowFields.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vpg-zone-hint", children: "Drop here" })
|
|
2552
3236
|
] })
|
|
2553
3237
|
]
|
|
2554
3238
|
}
|
|
2555
3239
|
),
|
|
2556
|
-
/* @__PURE__ */ (0,
|
|
3240
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
2557
3241
|
"div",
|
|
2558
3242
|
{
|
|
2559
3243
|
className: `vpg-drop-zone vpg-column-zone ${dragOverArea === "column" ? "vpg-drag-over" : ""}`,
|
|
@@ -2561,12 +3245,12 @@ function PivotSkeleton({
|
|
|
2561
3245
|
onDragLeave: handleDragLeave,
|
|
2562
3246
|
onDrop: (e) => handleDrop("column", e),
|
|
2563
3247
|
children: [
|
|
2564
|
-
/* @__PURE__ */ (0,
|
|
2565
|
-
/* @__PURE__ */ (0,
|
|
2566
|
-
/* @__PURE__ */ (0,
|
|
3248
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-zone-header", children: [
|
|
3249
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vpg-zone-icon vpg-column-icon", children: "\u2192" }),
|
|
3250
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vpg-zone-label", children: "Columns" })
|
|
2567
3251
|
] }),
|
|
2568
|
-
/* @__PURE__ */ (0,
|
|
2569
|
-
columnFields.map((field, idx) => /* @__PURE__ */ (0,
|
|
3252
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-zone-chips", children: [
|
|
3253
|
+
columnFields.map((field, idx) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
2570
3254
|
"div",
|
|
2571
3255
|
{
|
|
2572
3256
|
className: `vpg-mini-chip vpg-column-chip ${isChipDragSource("column", idx) ? "vpg-chip-dragging" : ""} ${isChipDropTarget("column", idx) ? "vpg-chip-drop-target" : ""}`,
|
|
@@ -2577,9 +3261,9 @@ function PivotSkeleton({
|
|
|
2577
3261
|
onDragLeave: handleChipDragLeave,
|
|
2578
3262
|
onDrop: (e) => handleChipDrop("column", idx, e),
|
|
2579
3263
|
children: [
|
|
2580
|
-
/* @__PURE__ */ (0,
|
|
2581
|
-
/* @__PURE__ */ (0,
|
|
2582
|
-
/* @__PURE__ */ (0,
|
|
3264
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vpg-drag-handle", children: "\u22EE\u22EE" }),
|
|
3265
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vpg-mini-name", children: field }),
|
|
3266
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2583
3267
|
"button",
|
|
2584
3268
|
{
|
|
2585
3269
|
className: "vpg-mini-remove",
|
|
@@ -2594,12 +3278,12 @@ function PivotSkeleton({
|
|
|
2594
3278
|
},
|
|
2595
3279
|
field
|
|
2596
3280
|
)),
|
|
2597
|
-
columnFields.length === 0 && /* @__PURE__ */ (0,
|
|
3281
|
+
columnFields.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vpg-zone-hint", children: "Drop here" })
|
|
2598
3282
|
] })
|
|
2599
3283
|
]
|
|
2600
3284
|
}
|
|
2601
3285
|
),
|
|
2602
|
-
/* @__PURE__ */ (0,
|
|
3286
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
2603
3287
|
"div",
|
|
2604
3288
|
{
|
|
2605
3289
|
className: `vpg-drop-zone vpg-value-zone ${dragOverArea === "value" ? "vpg-drag-over" : ""}`,
|
|
@@ -2607,19 +3291,19 @@ function PivotSkeleton({
|
|
|
2607
3291
|
onDragLeave: handleDragLeave,
|
|
2608
3292
|
onDrop: (e) => handleDrop("value", e),
|
|
2609
3293
|
children: [
|
|
2610
|
-
/* @__PURE__ */ (0,
|
|
2611
|
-
/* @__PURE__ */ (0,
|
|
2612
|
-
/* @__PURE__ */ (0,
|
|
3294
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-zone-header", children: [
|
|
3295
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vpg-zone-icon vpg-value-icon", children: "\u03A3" }),
|
|
3296
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vpg-zone-label", children: "Values" })
|
|
2613
3297
|
] }),
|
|
2614
|
-
/* @__PURE__ */ (0,
|
|
2615
|
-
valueFields.map((vf) => /* @__PURE__ */ (0,
|
|
3298
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-zone-chips", children: [
|
|
3299
|
+
valueFields.map((vf) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
2616
3300
|
"div",
|
|
2617
3301
|
{
|
|
2618
3302
|
className: `vpg-mini-chip vpg-value-chip${isCalculatedField(vf.field) ? " vpg-calc-chip" : ""}`,
|
|
2619
3303
|
children: [
|
|
2620
|
-
/* @__PURE__ */ (0,
|
|
2621
|
-
/* @__PURE__ */ (0,
|
|
2622
|
-
/* @__PURE__ */ (0,
|
|
3304
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vpg-agg-symbol", children: isCalculatedField(vf.field) ? "\u0192" : (0, import_tinypivot_core8.getAggregationSymbol)(vf.aggregation) }),
|
|
3305
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vpg-mini-name", children: getValueFieldDisplayName(vf.field) }),
|
|
3306
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2623
3307
|
"button",
|
|
2624
3308
|
{
|
|
2625
3309
|
className: "vpg-mini-remove",
|
|
@@ -2631,21 +3315,21 @@ function PivotSkeleton({
|
|
|
2631
3315
|
},
|
|
2632
3316
|
`${vf.field}-${vf.aggregation}`
|
|
2633
3317
|
)),
|
|
2634
|
-
valueFields.length === 0 && /* @__PURE__ */ (0,
|
|
3318
|
+
valueFields.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vpg-zone-hint", children: "Drop numeric" })
|
|
2635
3319
|
] })
|
|
2636
3320
|
]
|
|
2637
3321
|
}
|
|
2638
3322
|
)
|
|
2639
3323
|
] }),
|
|
2640
|
-
(!isConfigured || !pivotResult) && /* @__PURE__ */ (0,
|
|
2641
|
-
/* @__PURE__ */ (0,
|
|
3324
|
+
(!isConfigured || !pivotResult) && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "vpg-placeholder", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-placeholder-content", children: [
|
|
3325
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2642
3326
|
"svg",
|
|
2643
3327
|
{
|
|
2644
3328
|
className: "vpg-placeholder-icon",
|
|
2645
3329
|
fill: "none",
|
|
2646
3330
|
viewBox: "0 0 24 24",
|
|
2647
3331
|
stroke: "currentColor",
|
|
2648
|
-
children: /* @__PURE__ */ (0,
|
|
3332
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2649
3333
|
"path",
|
|
2650
3334
|
{
|
|
2651
3335
|
strokeLinecap: "round",
|
|
@@ -2656,58 +3340,58 @@ function PivotSkeleton({
|
|
|
2656
3340
|
)
|
|
2657
3341
|
}
|
|
2658
3342
|
),
|
|
2659
|
-
/* @__PURE__ */ (0,
|
|
3343
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vpg-placeholder-text", children: valueFields.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2660
3344
|
"Add a",
|
|
2661
3345
|
" ",
|
|
2662
|
-
/* @__PURE__ */ (0,
|
|
3346
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "Values" }),
|
|
2663
3347
|
" ",
|
|
2664
3348
|
"field to see your pivot table"
|
|
2665
|
-
] }) : rowFields.length === 0 && columnFields.length === 0 ? /* @__PURE__ */ (0,
|
|
3349
|
+
] }) : rowFields.length === 0 && columnFields.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2666
3350
|
"Add",
|
|
2667
3351
|
" ",
|
|
2668
|
-
/* @__PURE__ */ (0,
|
|
3352
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "Row" }),
|
|
2669
3353
|
" ",
|
|
2670
3354
|
"or",
|
|
2671
3355
|
" ",
|
|
2672
|
-
/* @__PURE__ */ (0,
|
|
3356
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "Column" }),
|
|
2673
3357
|
" ",
|
|
2674
3358
|
"fields to group your data"
|
|
2675
3359
|
] }) : "Your pivot table will appear here" })
|
|
2676
3360
|
] }) }),
|
|
2677
|
-
isConfigured && pivotResult && /* @__PURE__ */ (0,
|
|
2678
|
-
/* @__PURE__ */ (0,
|
|
2679
|
-
levelIdx === 0 && (rowFields.length > 0 ? rowFields : ["Rows"]).map((field, fieldIdx) => /* @__PURE__ */ (0,
|
|
3361
|
+
isConfigured && pivotResult && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "vpg-table-container", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("table", { className: "vpg-pivot-table", children: [
|
|
3362
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("thead", { children: columnHeaderCells.map((headerRow, levelIdx) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("tr", { className: "vpg-column-header-row", children: [
|
|
3363
|
+
levelIdx === 0 && (rowFields.length > 0 ? rowFields : ["Rows"]).map((field, fieldIdx) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2680
3364
|
"th",
|
|
2681
3365
|
{
|
|
2682
3366
|
className: "vpg-row-header-label",
|
|
2683
3367
|
rowSpan: columnHeaderCells.length,
|
|
2684
3368
|
style: { width: `${rowHeaderColWidth}px`, minWidth: "80px", left: `${getRowHeaderLeftOffset(fieldIdx)}px` },
|
|
2685
3369
|
onClick: () => toggleSort("row"),
|
|
2686
|
-
children: /* @__PURE__ */ (0,
|
|
2687
|
-
/* @__PURE__ */ (0,
|
|
2688
|
-
(fieldIdx === rowFields.length - 1 || rowFields.length === 0) && /* @__PURE__ */ (0,
|
|
3370
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-header-content", children: [
|
|
3371
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: field }),
|
|
3372
|
+
(fieldIdx === rowFields.length - 1 || rowFields.length === 0) && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: `vpg-sort-indicator ${sortTarget === "row" ? "active" : ""}`, children: sortTarget === "row" ? sortDirection === "asc" ? "\u2191" : "\u2193" : "\u21C5" })
|
|
2689
3373
|
] })
|
|
2690
3374
|
},
|
|
2691
3375
|
`row-header-${fieldIdx}`
|
|
2692
3376
|
)),
|
|
2693
|
-
headerRow.map((cell, idx) => /* @__PURE__ */ (0,
|
|
3377
|
+
headerRow.map((cell, idx) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2694
3378
|
"th",
|
|
2695
3379
|
{
|
|
2696
3380
|
className: "vpg-column-header-cell",
|
|
2697
3381
|
colSpan: cell.colspan,
|
|
2698
3382
|
onClick: () => levelIdx === columnHeaderCells.length - 1 && toggleSort(idx),
|
|
2699
|
-
children: /* @__PURE__ */ (0,
|
|
2700
|
-
/* @__PURE__ */ (0,
|
|
2701
|
-
levelIdx === columnHeaderCells.length - 1 && /* @__PURE__ */ (0,
|
|
3383
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-header-content", children: [
|
|
3384
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: cell.label }),
|
|
3385
|
+
levelIdx === columnHeaderCells.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: `vpg-sort-indicator ${sortTarget === idx ? "active" : ""}`, children: sortTarget === idx ? sortDirection === "asc" ? "\u2191" : "\u2193" : "\u21C5" })
|
|
2702
3386
|
] })
|
|
2703
3387
|
},
|
|
2704
3388
|
idx
|
|
2705
3389
|
)),
|
|
2706
|
-
pivotResult.rowTotals.length > 0 && levelIdx === 0 && /* @__PURE__ */ (0,
|
|
3390
|
+
pivotResult.rowTotals.length > 0 && levelIdx === 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("th", { className: "vpg-total-header", rowSpan: columnHeaderCells.length, children: "Total" })
|
|
2707
3391
|
] }, `header-${levelIdx}`)) }),
|
|
2708
|
-
/* @__PURE__ */ (0,
|
|
2709
|
-
sortedRowIndices.map((sortedIdx) => /* @__PURE__ */ (0,
|
|
2710
|
-
pivotResult.rowHeaders[sortedIdx].map((val, idx) => /* @__PURE__ */ (0,
|
|
3392
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("tbody", { children: [
|
|
3393
|
+
sortedRowIndices.map((sortedIdx) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("tr", { className: "vpg-data-row", children: [
|
|
3394
|
+
pivotResult.rowHeaders[sortedIdx].map((val, idx) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2711
3395
|
"th",
|
|
2712
3396
|
{
|
|
2713
3397
|
className: "vpg-row-header-cell",
|
|
@@ -2718,7 +3402,7 @@ function PivotSkeleton({
|
|
|
2718
3402
|
)),
|
|
2719
3403
|
pivotResult.data[sortedIdx].map((cell, colIdx) => {
|
|
2720
3404
|
const displayRowIdx = sortedRowIndices.indexOf(sortedIdx);
|
|
2721
|
-
return /* @__PURE__ */ (0,
|
|
3405
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2722
3406
|
"td",
|
|
2723
3407
|
{
|
|
2724
3408
|
className: `vpg-data-cell ${isCellSelected(displayRowIdx, colIdx) ? "selected" : ""} ${cell.value === null ? "vpg-is-null" : ""}`,
|
|
@@ -2729,10 +3413,10 @@ function PivotSkeleton({
|
|
|
2729
3413
|
colIdx
|
|
2730
3414
|
);
|
|
2731
3415
|
}),
|
|
2732
|
-
pivotResult.rowTotals[sortedIdx] && /* @__PURE__ */ (0,
|
|
3416
|
+
pivotResult.rowTotals[sortedIdx] && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("td", { className: "vpg-data-cell vpg-total-cell", children: pivotResult.rowTotals[sortedIdx].formattedValue })
|
|
2733
3417
|
] }, sortedIdx)),
|
|
2734
|
-
pivotResult.columnTotals.length > 0 && /* @__PURE__ */ (0,
|
|
2735
|
-
/* @__PURE__ */ (0,
|
|
3418
|
+
pivotResult.columnTotals.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("tr", { className: "vpg-totals-row", children: [
|
|
3419
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2736
3420
|
"th",
|
|
2737
3421
|
{
|
|
2738
3422
|
className: "vpg-row-header-cell vpg-total-label",
|
|
@@ -2741,13 +3425,13 @@ function PivotSkeleton({
|
|
|
2741
3425
|
children: "Total"
|
|
2742
3426
|
}
|
|
2743
3427
|
),
|
|
2744
|
-
pivotResult.columnTotals.map((cell, colIdx) => /* @__PURE__ */ (0,
|
|
2745
|
-
pivotResult.rowTotals.length > 0 && /* @__PURE__ */ (0,
|
|
3428
|
+
pivotResult.columnTotals.map((cell, colIdx) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("td", { className: "vpg-data-cell vpg-total-cell", children: cell.formattedValue }, colIdx)),
|
|
3429
|
+
pivotResult.rowTotals.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("td", { className: "vpg-data-cell vpg-grand-total-cell", children: pivotResult.grandTotal.formattedValue })
|
|
2746
3430
|
] })
|
|
2747
3431
|
] })
|
|
2748
3432
|
] }) }),
|
|
2749
|
-
isConfigured && pivotResult && /* @__PURE__ */ (0,
|
|
2750
|
-
/* @__PURE__ */ (0,
|
|
3433
|
+
isConfigured && pivotResult && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-skeleton-footer", children: [
|
|
3434
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "vpg-footer-info", children: [
|
|
2751
3435
|
pivotResult.rowHeaders.length,
|
|
2752
3436
|
" ",
|
|
2753
3437
|
"rows \xD7",
|
|
@@ -2755,30 +3439,30 @@ function PivotSkeleton({
|
|
|
2755
3439
|
" ",
|
|
2756
3440
|
"columns"
|
|
2757
3441
|
] }),
|
|
2758
|
-
selectionStats && selectionStats.count > 1 && /* @__PURE__ */ (0,
|
|
2759
|
-
/* @__PURE__ */ (0,
|
|
2760
|
-
/* @__PURE__ */ (0,
|
|
2761
|
-
/* @__PURE__ */ (0,
|
|
3442
|
+
selectionStats && selectionStats.count > 1 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-selection-stats", children: [
|
|
3443
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "vpg-stat", children: [
|
|
3444
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vpg-stat-label", children: "Count:" }),
|
|
3445
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vpg-stat-value", children: selectionStats.count })
|
|
2762
3446
|
] }),
|
|
2763
|
-
selectionStats.numericCount > 0 && /* @__PURE__ */ (0,
|
|
2764
|
-
/* @__PURE__ */ (0,
|
|
2765
|
-
/* @__PURE__ */ (0,
|
|
2766
|
-
/* @__PURE__ */ (0,
|
|
2767
|
-
/* @__PURE__ */ (0,
|
|
3447
|
+
selectionStats.numericCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
3448
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vpg-stat-divider", children: "|" }),
|
|
3449
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "vpg-stat", children: [
|
|
3450
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vpg-stat-label", children: "Sum:" }),
|
|
3451
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.sum) })
|
|
2768
3452
|
] }),
|
|
2769
|
-
/* @__PURE__ */ (0,
|
|
2770
|
-
/* @__PURE__ */ (0,
|
|
2771
|
-
/* @__PURE__ */ (0,
|
|
2772
|
-
/* @__PURE__ */ (0,
|
|
3453
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vpg-stat-divider", children: "|" }),
|
|
3454
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "vpg-stat", children: [
|
|
3455
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vpg-stat-label", children: "Avg:" }),
|
|
3456
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.avg) })
|
|
2773
3457
|
] })
|
|
2774
3458
|
] })
|
|
2775
3459
|
] })
|
|
2776
3460
|
] })
|
|
2777
3461
|
] }),
|
|
2778
|
-
showWatermark && canUsePivot && /* @__PURE__ */ (0,
|
|
2779
|
-
/* @__PURE__ */ (0,
|
|
2780
|
-
/* @__PURE__ */ (0,
|
|
2781
|
-
/* @__PURE__ */ (0,
|
|
3462
|
+
showWatermark && canUsePivot && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: `vpg-watermark ${isDemo ? "vpg-demo-mode" : ""}`, children: isDemo ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
3463
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vpg-demo-badge", children: "DEMO" }),
|
|
3464
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "Pro features unlocked for evaluation" }),
|
|
3465
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2782
3466
|
"a",
|
|
2783
3467
|
{
|
|
2784
3468
|
href: "https://tiny-pivot.com/#pricing",
|
|
@@ -2788,14 +3472,14 @@ function PivotSkeleton({
|
|
|
2788
3472
|
children: "Get Pro License \u2192"
|
|
2789
3473
|
}
|
|
2790
3474
|
)
|
|
2791
|
-
] }) : /* @__PURE__ */ (0,
|
|
3475
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: "Powered by TinyPivot" }) })
|
|
2792
3476
|
]
|
|
2793
3477
|
}
|
|
2794
3478
|
);
|
|
2795
3479
|
}
|
|
2796
3480
|
|
|
2797
3481
|
// src/components/DataGrid.tsx
|
|
2798
|
-
var
|
|
3482
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
2799
3483
|
var MIN_COL_WIDTH = 120;
|
|
2800
3484
|
var MAX_COL_WIDTH = 350;
|
|
2801
3485
|
function DataGrid({
|
|
@@ -2820,38 +3504,42 @@ function DataGrid({
|
|
|
2820
3504
|
onExport,
|
|
2821
3505
|
onCopy
|
|
2822
3506
|
}) {
|
|
2823
|
-
const { showWatermark, canUsePivot, isDemo, isPro } = useLicense();
|
|
2824
|
-
const currentTheme = (0,
|
|
3507
|
+
const { showWatermark, canUsePivot, canUseCharts, isDemo, isPro } = useLicense();
|
|
3508
|
+
const currentTheme = (0, import_react11.useMemo)(() => {
|
|
2825
3509
|
if (theme === "auto") {
|
|
2826
3510
|
return window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
2827
3511
|
}
|
|
2828
3512
|
return theme;
|
|
2829
3513
|
}, [theme]);
|
|
2830
|
-
const [currentFontSize, setCurrentFontSize] = (0,
|
|
2831
|
-
const [globalSearchTerm, setGlobalSearchTerm] = (0,
|
|
2832
|
-
const [showSearchInput, setShowSearchInput] = (0,
|
|
2833
|
-
const [currentPage, setCurrentPage] = (0,
|
|
2834
|
-
const [columnWidths, setColumnWidths] = (0,
|
|
2835
|
-
const [resizingColumnId, setResizingColumnId] = (0,
|
|
2836
|
-
const [resizeStartX, setResizeStartX] = (0,
|
|
2837
|
-
const [resizeStartWidth, setResizeStartWidth] = (0,
|
|
2838
|
-
const [gridHeight, setGridHeight] = (0,
|
|
2839
|
-
const [isResizingVertically, setIsResizingVertically] = (0,
|
|
2840
|
-
const [verticalResizeStartY, setVerticalResizeStartY] = (0,
|
|
2841
|
-
const [verticalResizeStartHeight, setVerticalResizeStartHeight] = (0,
|
|
2842
|
-
const [showCopyToast, setShowCopyToast] = (0,
|
|
2843
|
-
const [copyToastMessage, setCopyToastMessage] = (0,
|
|
2844
|
-
const [viewMode, setViewMode] = (0,
|
|
2845
|
-
const [
|
|
2846
|
-
const
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
const [
|
|
2850
|
-
const [
|
|
2851
|
-
const [
|
|
2852
|
-
const [
|
|
2853
|
-
const
|
|
2854
|
-
const
|
|
3514
|
+
const [currentFontSize, setCurrentFontSize] = (0, import_react11.useState)(initialFontSize);
|
|
3515
|
+
const [globalSearchTerm, setGlobalSearchTerm] = (0, import_react11.useState)("");
|
|
3516
|
+
const [showSearchInput, setShowSearchInput] = (0, import_react11.useState)(false);
|
|
3517
|
+
const [currentPage, setCurrentPage] = (0, import_react11.useState)(1);
|
|
3518
|
+
const [columnWidths, setColumnWidths] = (0, import_react11.useState)({});
|
|
3519
|
+
const [resizingColumnId, setResizingColumnId] = (0, import_react11.useState)(null);
|
|
3520
|
+
const [resizeStartX, setResizeStartX] = (0, import_react11.useState)(0);
|
|
3521
|
+
const [resizeStartWidth, setResizeStartWidth] = (0, import_react11.useState)(0);
|
|
3522
|
+
const [gridHeight, setGridHeight] = (0, import_react11.useState)(initialHeight);
|
|
3523
|
+
const [isResizingVertically, setIsResizingVertically] = (0, import_react11.useState)(false);
|
|
3524
|
+
const [verticalResizeStartY, setVerticalResizeStartY] = (0, import_react11.useState)(0);
|
|
3525
|
+
const [verticalResizeStartHeight, setVerticalResizeStartHeight] = (0, import_react11.useState)(0);
|
|
3526
|
+
const [showCopyToast, setShowCopyToast] = (0, import_react11.useState)(false);
|
|
3527
|
+
const [copyToastMessage, setCopyToastMessage] = (0, import_react11.useState)("");
|
|
3528
|
+
const [viewMode, setViewMode] = (0, import_react11.useState)("grid");
|
|
3529
|
+
const [_chartConfig, setChartConfig] = (0, import_react11.useState)(null);
|
|
3530
|
+
const handleChartConfigChange = (0, import_react11.useCallback)((config) => {
|
|
3531
|
+
setChartConfig(config);
|
|
3532
|
+
}, []);
|
|
3533
|
+
const [showPivotConfig, setShowPivotConfig] = (0, import_react11.useState)(true);
|
|
3534
|
+
const [draggingField, setDraggingField] = (0, import_react11.useState)(null);
|
|
3535
|
+
const [activeFilterColumn, setActiveFilterColumn] = (0, import_react11.useState)(null);
|
|
3536
|
+
const [filterDropdownPosition, setFilterDropdownPosition] = (0, import_react11.useState)({ top: 0, left: 0, maxHeight: 400 });
|
|
3537
|
+
const [selectedCell, setSelectedCell] = (0, import_react11.useState)(null);
|
|
3538
|
+
const [selectionStart, setSelectionStart] = (0, import_react11.useState)(null);
|
|
3539
|
+
const [selectionEnd, setSelectionEnd] = (0, import_react11.useState)(null);
|
|
3540
|
+
const [isSelecting, setIsSelecting] = (0, import_react11.useState)(false);
|
|
3541
|
+
const tableContainerRef = (0, import_react11.useRef)(null);
|
|
3542
|
+
const tableBodyRef = (0, import_react11.useRef)(null);
|
|
2855
3543
|
const fontSizeOptions = [
|
|
2856
3544
|
{ value: "xs", label: "S" },
|
|
2857
3545
|
{ value: "sm", label: "M" },
|
|
@@ -2875,7 +3563,7 @@ function DataGrid({
|
|
|
2875
3563
|
setNumericRangeFilter,
|
|
2876
3564
|
getNumericRangeFilter
|
|
2877
3565
|
} = useExcelGrid({ data, enableSorting: true, enableFiltering: true });
|
|
2878
|
-
const filteredDataForPivot = (0,
|
|
3566
|
+
const filteredDataForPivot = (0, import_react11.useMemo)(() => {
|
|
2879
3567
|
const filteredRows = table.getFilteredRowModel().rows;
|
|
2880
3568
|
return filteredRows.map((row) => row.original);
|
|
2881
3569
|
}, [table, columnFilters]);
|
|
@@ -2905,7 +3593,7 @@ function DataGrid({
|
|
|
2905
3593
|
addCalculatedField,
|
|
2906
3594
|
removeCalculatedField
|
|
2907
3595
|
} = usePivotTable(filteredDataForPivot);
|
|
2908
|
-
const activeFilterInfo = (0,
|
|
3596
|
+
const activeFilterInfo = (0, import_react11.useMemo)(() => {
|
|
2909
3597
|
if (activeFilters.length === 0)
|
|
2910
3598
|
return null;
|
|
2911
3599
|
return activeFilters.map((f) => {
|
|
@@ -2930,8 +3618,8 @@ function DataGrid({
|
|
|
2930
3618
|
};
|
|
2931
3619
|
});
|
|
2932
3620
|
}, [activeFilters]);
|
|
2933
|
-
const rows = (0,
|
|
2934
|
-
const searchFilteredData = (0,
|
|
3621
|
+
const rows = (0, import_react11.useMemo)(() => table.getFilteredRowModel().rows, [table, columnFilters]);
|
|
3622
|
+
const searchFilteredData = (0, import_react11.useMemo)(() => {
|
|
2935
3623
|
if (!globalSearchTerm.trim() || !enableSearch) {
|
|
2936
3624
|
return rows;
|
|
2937
3625
|
}
|
|
@@ -2949,22 +3637,22 @@ function DataGrid({
|
|
|
2949
3637
|
});
|
|
2950
3638
|
}, [rows, globalSearchTerm, enableSearch, columnKeys]);
|
|
2951
3639
|
const totalSearchedRows = searchFilteredData.length;
|
|
2952
|
-
const totalPages = (0,
|
|
3640
|
+
const totalPages = (0, import_react11.useMemo)(() => {
|
|
2953
3641
|
if (!enablePagination)
|
|
2954
3642
|
return 1;
|
|
2955
3643
|
return Math.max(1, Math.ceil(totalSearchedRows / pageSize));
|
|
2956
3644
|
}, [enablePagination, totalSearchedRows, pageSize]);
|
|
2957
|
-
const paginatedRows = (0,
|
|
3645
|
+
const paginatedRows = (0, import_react11.useMemo)(() => {
|
|
2958
3646
|
if (!enablePagination)
|
|
2959
3647
|
return searchFilteredData;
|
|
2960
3648
|
const start = (currentPage - 1) * pageSize;
|
|
2961
3649
|
const end = start + pageSize;
|
|
2962
3650
|
return searchFilteredData.slice(start, end);
|
|
2963
3651
|
}, [enablePagination, searchFilteredData, currentPage, pageSize]);
|
|
2964
|
-
(0,
|
|
3652
|
+
(0, import_react11.useEffect)(() => {
|
|
2965
3653
|
setCurrentPage(1);
|
|
2966
3654
|
}, [columnFilters, globalSearchTerm]);
|
|
2967
|
-
const selectionBounds = (0,
|
|
3655
|
+
const selectionBounds = (0, import_react11.useMemo)(() => {
|
|
2968
3656
|
if (!selectionStart || !selectionEnd)
|
|
2969
3657
|
return null;
|
|
2970
3658
|
return {
|
|
@@ -2974,7 +3662,7 @@ function DataGrid({
|
|
|
2974
3662
|
maxCol: Math.max(selectionStart.col, selectionEnd.col)
|
|
2975
3663
|
};
|
|
2976
3664
|
}, [selectionStart, selectionEnd]);
|
|
2977
|
-
const selectionStats = (0,
|
|
3665
|
+
const selectionStats = (0, import_react11.useMemo)(() => {
|
|
2978
3666
|
if (!selectionBounds)
|
|
2979
3667
|
return null;
|
|
2980
3668
|
const { minRow, maxRow, minCol, maxCol } = selectionBounds;
|
|
@@ -3004,7 +3692,7 @@ function DataGrid({
|
|
|
3004
3692
|
const avg = sum / values.length;
|
|
3005
3693
|
return { count, sum, avg, numericCount: values.length };
|
|
3006
3694
|
}, [selectionBounds, rows, columnKeys]);
|
|
3007
|
-
(0,
|
|
3695
|
+
(0, import_react11.useEffect)(() => {
|
|
3008
3696
|
if (typeof document === "undefined")
|
|
3009
3697
|
return;
|
|
3010
3698
|
if (data.length === 0)
|
|
@@ -3028,7 +3716,7 @@ function DataGrid({
|
|
|
3028
3716
|
}
|
|
3029
3717
|
setColumnWidths(widths);
|
|
3030
3718
|
}, [data, columnKeys]);
|
|
3031
|
-
const startColumnResize = (0,
|
|
3719
|
+
const startColumnResize = (0, import_react11.useCallback)(
|
|
3032
3720
|
(columnId, event) => {
|
|
3033
3721
|
if (!enableColumnResize)
|
|
3034
3722
|
return;
|
|
@@ -3040,7 +3728,7 @@ function DataGrid({
|
|
|
3040
3728
|
},
|
|
3041
3729
|
[enableColumnResize, columnWidths]
|
|
3042
3730
|
);
|
|
3043
|
-
(0,
|
|
3731
|
+
(0, import_react11.useEffect)(() => {
|
|
3044
3732
|
if (!resizingColumnId)
|
|
3045
3733
|
return;
|
|
3046
3734
|
const handleResizeMove = (event) => {
|
|
@@ -3061,7 +3749,7 @@ function DataGrid({
|
|
|
3061
3749
|
document.removeEventListener("mouseup", handleResizeEnd);
|
|
3062
3750
|
};
|
|
3063
3751
|
}, [resizingColumnId, resizeStartX, resizeStartWidth]);
|
|
3064
|
-
const startVerticalResize = (0,
|
|
3752
|
+
const startVerticalResize = (0, import_react11.useCallback)(
|
|
3065
3753
|
(event) => {
|
|
3066
3754
|
if (!enableVerticalResize)
|
|
3067
3755
|
return;
|
|
@@ -3072,7 +3760,7 @@ function DataGrid({
|
|
|
3072
3760
|
},
|
|
3073
3761
|
[enableVerticalResize, gridHeight]
|
|
3074
3762
|
);
|
|
3075
|
-
(0,
|
|
3763
|
+
(0, import_react11.useEffect)(() => {
|
|
3076
3764
|
if (!isResizingVertically)
|
|
3077
3765
|
return;
|
|
3078
3766
|
const handleVerticalResizeMove = (event) => {
|
|
@@ -3090,7 +3778,7 @@ function DataGrid({
|
|
|
3090
3778
|
document.removeEventListener("mouseup", handleVerticalResizeEnd);
|
|
3091
3779
|
};
|
|
3092
3780
|
}, [isResizingVertically, verticalResizeStartY, verticalResizeStartHeight, minHeight, maxHeight]);
|
|
3093
|
-
const handleExport = (0,
|
|
3781
|
+
const handleExport = (0, import_react11.useCallback)(() => {
|
|
3094
3782
|
if (viewMode === "pivot") {
|
|
3095
3783
|
if (!pivotResult)
|
|
3096
3784
|
return;
|
|
@@ -3136,7 +3824,7 @@ function DataGrid({
|
|
|
3136
3824
|
columnKeys,
|
|
3137
3825
|
onExport
|
|
3138
3826
|
]);
|
|
3139
|
-
const copySelectionToClipboard = (0,
|
|
3827
|
+
const copySelectionToClipboard = (0, import_react11.useCallback)(() => {
|
|
3140
3828
|
if (!selectionBounds || !enableClipboard)
|
|
3141
3829
|
return;
|
|
3142
3830
|
const text = formatSelectionForClipboard(
|
|
@@ -3161,7 +3849,7 @@ function DataGrid({
|
|
|
3161
3849
|
}
|
|
3162
3850
|
);
|
|
3163
3851
|
}, [selectionBounds, enableClipboard, rows, columnKeys, onCopy]);
|
|
3164
|
-
const handleMouseDown = (0,
|
|
3852
|
+
const handleMouseDown = (0, import_react11.useCallback)(
|
|
3165
3853
|
(rowIndex, colIndex, event) => {
|
|
3166
3854
|
event.preventDefault();
|
|
3167
3855
|
if (event.shiftKey && selectedCell) {
|
|
@@ -3185,7 +3873,7 @@ function DataGrid({
|
|
|
3185
3873
|
},
|
|
3186
3874
|
[selectedCell, rows, columnKeys, onCellClick]
|
|
3187
3875
|
);
|
|
3188
|
-
const handleMouseEnter = (0,
|
|
3876
|
+
const handleMouseEnter = (0, import_react11.useCallback)(
|
|
3189
3877
|
(rowIndex, colIndex) => {
|
|
3190
3878
|
if (isSelecting) {
|
|
3191
3879
|
setSelectionEnd({ row: rowIndex, col: colIndex });
|
|
@@ -3193,12 +3881,12 @@ function DataGrid({
|
|
|
3193
3881
|
},
|
|
3194
3882
|
[isSelecting]
|
|
3195
3883
|
);
|
|
3196
|
-
(0,
|
|
3884
|
+
(0, import_react11.useEffect)(() => {
|
|
3197
3885
|
const handleMouseUp = () => setIsSelecting(false);
|
|
3198
3886
|
document.addEventListener("mouseup", handleMouseUp);
|
|
3199
3887
|
return () => document.removeEventListener("mouseup", handleMouseUp);
|
|
3200
3888
|
}, []);
|
|
3201
|
-
(0,
|
|
3889
|
+
(0, import_react11.useEffect)(() => {
|
|
3202
3890
|
const handleKeydown = (event) => {
|
|
3203
3891
|
if ((event.ctrlKey || event.metaKey) && event.key === "c" && selectionBounds) {
|
|
3204
3892
|
event.preventDefault();
|
|
@@ -3216,7 +3904,7 @@ function DataGrid({
|
|
|
3216
3904
|
document.addEventListener("keydown", handleKeydown);
|
|
3217
3905
|
return () => document.removeEventListener("keydown", handleKeydown);
|
|
3218
3906
|
}, [selectionBounds, copySelectionToClipboard]);
|
|
3219
|
-
const openFilterDropdown = (0,
|
|
3907
|
+
const openFilterDropdown = (0, import_react11.useCallback)(
|
|
3220
3908
|
(columnId, event) => {
|
|
3221
3909
|
event.stopPropagation();
|
|
3222
3910
|
const target = event.currentTarget;
|
|
@@ -3245,22 +3933,22 @@ function DataGrid({
|
|
|
3245
3933
|
},
|
|
3246
3934
|
[]
|
|
3247
3935
|
);
|
|
3248
|
-
const closeFilterDropdown = (0,
|
|
3936
|
+
const closeFilterDropdown = (0, import_react11.useCallback)(() => {
|
|
3249
3937
|
setActiveFilterColumn(null);
|
|
3250
3938
|
}, []);
|
|
3251
|
-
const handleFilter = (0,
|
|
3939
|
+
const handleFilter = (0, import_react11.useCallback)(
|
|
3252
3940
|
(columnId, values) => {
|
|
3253
3941
|
setColumnFilter(columnId, values);
|
|
3254
3942
|
},
|
|
3255
3943
|
[setColumnFilter]
|
|
3256
3944
|
);
|
|
3257
|
-
const handleRangeFilter = (0,
|
|
3945
|
+
const handleRangeFilter = (0, import_react11.useCallback)(
|
|
3258
3946
|
(columnId, range) => {
|
|
3259
3947
|
setNumericRangeFilter(columnId, range);
|
|
3260
3948
|
},
|
|
3261
3949
|
[setNumericRangeFilter]
|
|
3262
3950
|
);
|
|
3263
|
-
const handleSort = (0,
|
|
3951
|
+
const handleSort = (0, import_react11.useCallback)(
|
|
3264
3952
|
(columnId, direction) => {
|
|
3265
3953
|
if (direction === null) {
|
|
3266
3954
|
const current = getSortDirection(columnId);
|
|
@@ -3284,7 +3972,7 @@ function DataGrid({
|
|
|
3284
3972
|
},
|
|
3285
3973
|
[getSortDirection, toggleSort]
|
|
3286
3974
|
);
|
|
3287
|
-
const isCellSelected = (0,
|
|
3975
|
+
const isCellSelected = (0, import_react11.useCallback)(
|
|
3288
3976
|
(rowIndex, colIndex) => {
|
|
3289
3977
|
if (!selectionBounds) {
|
|
3290
3978
|
return selectedCell?.row === rowIndex && selectedCell?.col === colIndex;
|
|
@@ -3326,30 +4014,30 @@ function DataGrid({
|
|
|
3326
4014
|
}
|
|
3327
4015
|
return String(value);
|
|
3328
4016
|
};
|
|
3329
|
-
const totalTableWidth = (0,
|
|
4017
|
+
const totalTableWidth = (0, import_react11.useMemo)(() => {
|
|
3330
4018
|
return columnKeys.reduce((sum, key) => sum + (columnWidths[key] || MIN_COL_WIDTH), 0);
|
|
3331
4019
|
}, [columnKeys, columnWidths]);
|
|
3332
4020
|
const activeFilterCount = columnFilters.length;
|
|
3333
|
-
return /* @__PURE__ */ (0,
|
|
4021
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
3334
4022
|
"div",
|
|
3335
4023
|
{
|
|
3336
4024
|
className: `vpg-data-grid vpg-font-${currentFontSize} vpg-theme-${currentTheme} ${stripedRows ? "vpg-striped" : ""} ${resizingColumnId ? "vpg-resizing" : ""} ${isResizingVertically ? "vpg-resizing-vertical" : ""}`,
|
|
3337
4025
|
style: { height: `${gridHeight}px` },
|
|
3338
4026
|
children: [
|
|
3339
|
-
showCopyToast && /* @__PURE__ */ (0,
|
|
3340
|
-
/* @__PURE__ */ (0,
|
|
4027
|
+
showCopyToast && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-toast", children: [
|
|
4028
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }),
|
|
3341
4029
|
copyToastMessage
|
|
3342
4030
|
] }),
|
|
3343
|
-
/* @__PURE__ */ (0,
|
|
3344
|
-
/* @__PURE__ */ (0,
|
|
3345
|
-
showPivot && /* @__PURE__ */ (0,
|
|
3346
|
-
/* @__PURE__ */ (0,
|
|
4031
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-toolbar", children: [
|
|
4032
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-toolbar-left", children: [
|
|
4033
|
+
showPivot && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-view-toggle", children: [
|
|
4034
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
3347
4035
|
"button",
|
|
3348
4036
|
{
|
|
3349
4037
|
className: `vpg-view-btn ${viewMode === "grid" ? "active" : ""}`,
|
|
3350
4038
|
onClick: () => setViewMode("grid"),
|
|
3351
4039
|
children: [
|
|
3352
|
-
/* @__PURE__ */ (0,
|
|
4040
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3353
4041
|
"path",
|
|
3354
4042
|
{
|
|
3355
4043
|
strokeLinecap: "round",
|
|
@@ -3362,13 +4050,13 @@ function DataGrid({
|
|
|
3362
4050
|
]
|
|
3363
4051
|
}
|
|
3364
4052
|
),
|
|
3365
|
-
/* @__PURE__ */ (0,
|
|
4053
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
3366
4054
|
"button",
|
|
3367
4055
|
{
|
|
3368
4056
|
className: `vpg-view-btn vpg-pivot-btn ${viewMode === "pivot" ? "active" : ""}`,
|
|
3369
4057
|
onClick: () => setViewMode("pivot"),
|
|
3370
4058
|
children: [
|
|
3371
|
-
/* @__PURE__ */ (0,
|
|
4059
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3372
4060
|
"path",
|
|
3373
4061
|
{
|
|
3374
4062
|
strokeLinecap: "round",
|
|
@@ -3380,16 +4068,37 @@ function DataGrid({
|
|
|
3380
4068
|
"Pivot"
|
|
3381
4069
|
]
|
|
3382
4070
|
}
|
|
4071
|
+
),
|
|
4072
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
4073
|
+
"button",
|
|
4074
|
+
{
|
|
4075
|
+
className: `vpg-view-btn vpg-chart-btn ${viewMode === "chart" ? "active" : ""} ${!canUseCharts ? "vpg-pro-feature" : ""}`,
|
|
4076
|
+
title: canUseCharts ? "Chart Builder" : "Chart Builder (Pro feature)",
|
|
4077
|
+
onClick: () => canUseCharts && setViewMode("chart"),
|
|
4078
|
+
children: [
|
|
4079
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4080
|
+
"path",
|
|
4081
|
+
{
|
|
4082
|
+
strokeLinecap: "round",
|
|
4083
|
+
strokeLinejoin: "round",
|
|
4084
|
+
strokeWidth: 2,
|
|
4085
|
+
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"
|
|
4086
|
+
}
|
|
4087
|
+
) }),
|
|
4088
|
+
"Chart",
|
|
4089
|
+
!canUseCharts && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-pro-badge", children: "Pro" })
|
|
4090
|
+
]
|
|
4091
|
+
}
|
|
3383
4092
|
)
|
|
3384
4093
|
] }),
|
|
3385
|
-
viewMode === "grid" && /* @__PURE__ */ (0,
|
|
3386
|
-
enableSearch && /* @__PURE__ */ (0,
|
|
4094
|
+
viewMode === "grid" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
4095
|
+
enableSearch && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "vpg-search-container", children: !showSearchInput ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3387
4096
|
"button",
|
|
3388
4097
|
{
|
|
3389
4098
|
className: "vpg-icon-btn",
|
|
3390
4099
|
title: "Search (Ctrl+F)",
|
|
3391
4100
|
onClick: () => setShowSearchInput(true),
|
|
3392
|
-
children: /* @__PURE__ */ (0,
|
|
4101
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3393
4102
|
"path",
|
|
3394
4103
|
{
|
|
3395
4104
|
strokeLinecap: "round",
|
|
@@ -3399,15 +4108,15 @@ function DataGrid({
|
|
|
3399
4108
|
}
|
|
3400
4109
|
) })
|
|
3401
4110
|
}
|
|
3402
|
-
) : /* @__PURE__ */ (0,
|
|
3403
|
-
/* @__PURE__ */ (0,
|
|
4111
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-search-box", children: [
|
|
4112
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3404
4113
|
"svg",
|
|
3405
4114
|
{
|
|
3406
4115
|
className: "vpg-search-icon",
|
|
3407
4116
|
fill: "none",
|
|
3408
4117
|
stroke: "currentColor",
|
|
3409
4118
|
viewBox: "0 0 24 24",
|
|
3410
|
-
children: /* @__PURE__ */ (0,
|
|
4119
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3411
4120
|
"path",
|
|
3412
4121
|
{
|
|
3413
4122
|
strokeLinecap: "round",
|
|
@@ -3418,7 +4127,7 @@ function DataGrid({
|
|
|
3418
4127
|
)
|
|
3419
4128
|
}
|
|
3420
4129
|
),
|
|
3421
|
-
/* @__PURE__ */ (0,
|
|
4130
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3422
4131
|
"input",
|
|
3423
4132
|
{
|
|
3424
4133
|
type: "text",
|
|
@@ -3435,14 +4144,14 @@ function DataGrid({
|
|
|
3435
4144
|
autoFocus: true
|
|
3436
4145
|
}
|
|
3437
4146
|
),
|
|
3438
|
-
globalSearchTerm && /* @__PURE__ */ (0,
|
|
4147
|
+
globalSearchTerm && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { className: "vpg-search-clear", onClick: () => setGlobalSearchTerm(""), children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3439
4148
|
"svg",
|
|
3440
4149
|
{
|
|
3441
4150
|
className: "vpg-icon-xs",
|
|
3442
4151
|
fill: "none",
|
|
3443
4152
|
stroke: "currentColor",
|
|
3444
4153
|
viewBox: "0 0 24 24",
|
|
3445
|
-
children: /* @__PURE__ */ (0,
|
|
4154
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3446
4155
|
"path",
|
|
3447
4156
|
{
|
|
3448
4157
|
strokeLinecap: "round",
|
|
@@ -3454,9 +4163,9 @@ function DataGrid({
|
|
|
3454
4163
|
}
|
|
3455
4164
|
) })
|
|
3456
4165
|
] }) }),
|
|
3457
|
-
/* @__PURE__ */ (0,
|
|
3458
|
-
/* @__PURE__ */ (0,
|
|
3459
|
-
/* @__PURE__ */ (0,
|
|
4166
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-font-size-control", children: [
|
|
4167
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-label", children: "Size:" }),
|
|
4168
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "vpg-font-size-toggle", children: fontSizeOptions.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3460
4169
|
"button",
|
|
3461
4170
|
{
|
|
3462
4171
|
className: `vpg-font-size-btn ${currentFontSize === opt.value ? "active" : ""}`,
|
|
@@ -3466,8 +4175,8 @@ function DataGrid({
|
|
|
3466
4175
|
opt.value
|
|
3467
4176
|
)) })
|
|
3468
4177
|
] }),
|
|
3469
|
-
activeFilterCount > 0 && /* @__PURE__ */ (0,
|
|
3470
|
-
/* @__PURE__ */ (0,
|
|
4178
|
+
activeFilterCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-filter-info", children: [
|
|
4179
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3471
4180
|
"path",
|
|
3472
4181
|
{
|
|
3473
4182
|
fillRule: "evenodd",
|
|
@@ -3475,28 +4184,28 @@ function DataGrid({
|
|
|
3475
4184
|
clipRule: "evenodd"
|
|
3476
4185
|
}
|
|
3477
4186
|
) }),
|
|
3478
|
-
/* @__PURE__ */ (0,
|
|
4187
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
|
|
3479
4188
|
activeFilterCount,
|
|
3480
4189
|
" ",
|
|
3481
4190
|
"filter",
|
|
3482
4191
|
activeFilterCount > 1 ? "s" : ""
|
|
3483
4192
|
] })
|
|
3484
4193
|
] }),
|
|
3485
|
-
globalSearchTerm && /* @__PURE__ */ (0,
|
|
4194
|
+
globalSearchTerm && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "vpg-search-info", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
|
|
3486
4195
|
totalSearchedRows,
|
|
3487
4196
|
" ",
|
|
3488
4197
|
"match",
|
|
3489
4198
|
totalSearchedRows !== 1 ? "es" : ""
|
|
3490
4199
|
] }) })
|
|
3491
4200
|
] }),
|
|
3492
|
-
viewMode === "pivot" && canUsePivot && /* @__PURE__ */ (0,
|
|
3493
|
-
/* @__PURE__ */ (0,
|
|
4201
|
+
viewMode === "pivot" && canUsePivot && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
4202
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
3494
4203
|
"button",
|
|
3495
4204
|
{
|
|
3496
4205
|
className: `vpg-config-toggle ${showPivotConfig ? "active" : ""}`,
|
|
3497
4206
|
onClick: () => setShowPivotConfig(!showPivotConfig),
|
|
3498
4207
|
children: [
|
|
3499
|
-
/* @__PURE__ */ (0,
|
|
4208
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3500
4209
|
"path",
|
|
3501
4210
|
{
|
|
3502
4211
|
strokeLinecap: "round",
|
|
@@ -3511,8 +4220,8 @@ function DataGrid({
|
|
|
3511
4220
|
]
|
|
3512
4221
|
}
|
|
3513
4222
|
),
|
|
3514
|
-
pivotIsConfigured && /* @__PURE__ */ (0,
|
|
3515
|
-
/* @__PURE__ */ (0,
|
|
4223
|
+
pivotIsConfigured && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-pivot-status", children: [
|
|
4224
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3516
4225
|
"path",
|
|
3517
4226
|
{
|
|
3518
4227
|
fillRule: "evenodd",
|
|
@@ -3520,13 +4229,13 @@ function DataGrid({
|
|
|
3520
4229
|
clipRule: "evenodd"
|
|
3521
4230
|
}
|
|
3522
4231
|
) }),
|
|
3523
|
-
/* @__PURE__ */ (0,
|
|
4232
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "Pivot configured" })
|
|
3524
4233
|
] })
|
|
3525
4234
|
] })
|
|
3526
4235
|
] }),
|
|
3527
|
-
/* @__PURE__ */ (0,
|
|
3528
|
-
viewMode === "grid" && activeFilterCount > 0 && /* @__PURE__ */ (0,
|
|
3529
|
-
/* @__PURE__ */ (0,
|
|
4236
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-toolbar-right", children: [
|
|
4237
|
+
viewMode === "grid" && activeFilterCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("button", { className: "vpg-clear-filters", onClick: clearAllFilters, children: [
|
|
4238
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3530
4239
|
"path",
|
|
3531
4240
|
{
|
|
3532
4241
|
strokeLinecap: "round",
|
|
@@ -3537,13 +4246,13 @@ function DataGrid({
|
|
|
3537
4246
|
) }),
|
|
3538
4247
|
"Clear Filters"
|
|
3539
4248
|
] }),
|
|
3540
|
-
enableClipboard && selectionBounds && viewMode === "grid" && /* @__PURE__ */ (0,
|
|
4249
|
+
enableClipboard && selectionBounds && viewMode === "grid" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3541
4250
|
"button",
|
|
3542
4251
|
{
|
|
3543
4252
|
className: "vpg-icon-btn",
|
|
3544
4253
|
title: "Copy selection (Ctrl+C)",
|
|
3545
4254
|
onClick: copySelectionToClipboard,
|
|
3546
|
-
children: /* @__PURE__ */ (0,
|
|
4255
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3547
4256
|
"path",
|
|
3548
4257
|
{
|
|
3549
4258
|
strokeLinecap: "round",
|
|
@@ -3554,14 +4263,14 @@ function DataGrid({
|
|
|
3554
4263
|
) })
|
|
3555
4264
|
}
|
|
3556
4265
|
),
|
|
3557
|
-
enableExport && viewMode === "grid" && /* @__PURE__ */ (0,
|
|
4266
|
+
enableExport && viewMode === "grid" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
3558
4267
|
"button",
|
|
3559
4268
|
{
|
|
3560
4269
|
className: "vpg-export-btn",
|
|
3561
4270
|
title: "Export to CSV",
|
|
3562
4271
|
onClick: handleExport,
|
|
3563
4272
|
children: [
|
|
3564
|
-
/* @__PURE__ */ (0,
|
|
4273
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3565
4274
|
"path",
|
|
3566
4275
|
{
|
|
3567
4276
|
strokeLinecap: "round",
|
|
@@ -3574,7 +4283,7 @@ function DataGrid({
|
|
|
3574
4283
|
]
|
|
3575
4284
|
}
|
|
3576
4285
|
),
|
|
3577
|
-
enableExport && viewMode === "pivot" && pivotIsConfigured && /* @__PURE__ */ (0,
|
|
4286
|
+
enableExport && viewMode === "pivot" && pivotIsConfigured && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
3578
4287
|
"button",
|
|
3579
4288
|
{
|
|
3580
4289
|
className: `vpg-export-btn ${!isPro ? "vpg-export-btn-disabled" : ""}`,
|
|
@@ -3582,7 +4291,7 @@ function DataGrid({
|
|
|
3582
4291
|
title: isPro ? "Export Pivot to CSV" : "Export Pivot to CSV (Pro feature)",
|
|
3583
4292
|
onClick: () => isPro && handleExport(),
|
|
3584
4293
|
children: [
|
|
3585
|
-
/* @__PURE__ */ (0,
|
|
4294
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3586
4295
|
"path",
|
|
3587
4296
|
{
|
|
3588
4297
|
strokeLinecap: "round",
|
|
@@ -3598,13 +4307,13 @@ function DataGrid({
|
|
|
3598
4307
|
)
|
|
3599
4308
|
] })
|
|
3600
4309
|
] }),
|
|
3601
|
-
viewMode === "grid" && /* @__PURE__ */ (0,
|
|
3602
|
-
loading && /* @__PURE__ */ (0,
|
|
3603
|
-
/* @__PURE__ */ (0,
|
|
3604
|
-
/* @__PURE__ */ (0,
|
|
4310
|
+
viewMode === "grid" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { ref: tableContainerRef, className: "vpg-grid-container", tabIndex: 0, children: [
|
|
4311
|
+
loading && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-loading", children: [
|
|
4312
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "vpg-spinner" }),
|
|
4313
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "Loading data..." })
|
|
3605
4314
|
] }),
|
|
3606
|
-
!loading && data.length === 0 && /* @__PURE__ */ (0,
|
|
3607
|
-
/* @__PURE__ */ (0,
|
|
4315
|
+
!loading && data.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-empty", children: [
|
|
4316
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "vpg-empty-icon", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { className: "vpg-icon-lg", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3608
4317
|
"path",
|
|
3609
4318
|
{
|
|
3610
4319
|
strokeLinecap: "round",
|
|
@@ -3613,10 +4322,10 @@ function DataGrid({
|
|
|
3613
4322
|
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"
|
|
3614
4323
|
}
|
|
3615
4324
|
) }) }),
|
|
3616
|
-
/* @__PURE__ */ (0,
|
|
4325
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "No data available" })
|
|
3617
4326
|
] }),
|
|
3618
|
-
!loading && data.length > 0 && filteredRowCount === 0 && /* @__PURE__ */ (0,
|
|
3619
|
-
/* @__PURE__ */ (0,
|
|
4327
|
+
!loading && data.length > 0 && filteredRowCount === 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-empty", children: [
|
|
4328
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "vpg-empty-icon vpg-warning", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { className: "vpg-icon-lg", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3620
4329
|
"path",
|
|
3621
4330
|
{
|
|
3622
4331
|
strokeLinecap: "round",
|
|
@@ -3625,11 +4334,11 @@ function DataGrid({
|
|
|
3625
4334
|
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"
|
|
3626
4335
|
}
|
|
3627
4336
|
) }) }),
|
|
3628
|
-
/* @__PURE__ */ (0,
|
|
3629
|
-
/* @__PURE__ */ (0,
|
|
4337
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "No matching records" }),
|
|
4338
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { className: "vpg-clear-link", onClick: clearAllFilters, children: "Clear all filters" })
|
|
3630
4339
|
] }),
|
|
3631
|
-
!loading && filteredRowCount > 0 && /* @__PURE__ */ (0,
|
|
3632
|
-
/* @__PURE__ */ (0,
|
|
4340
|
+
!loading && filteredRowCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "vpg-table-wrapper", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("table", { className: "vpg-table", style: { minWidth: `${totalTableWidth}px` }, children: [
|
|
4341
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("tr", { children: columnKeys.map((colId) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
3633
4342
|
"th",
|
|
3634
4343
|
{
|
|
3635
4344
|
className: `vpg-header-cell ${hasActiveFilter(colId) ? "vpg-has-filter" : ""} ${getSortDirection(colId) !== null ? "vpg-is-sorted" : ""} ${activeFilterColumn === colId ? "vpg-is-active" : ""}`,
|
|
@@ -3644,16 +4353,16 @@ function DataGrid({
|
|
|
3644
4353
|
}
|
|
3645
4354
|
},
|
|
3646
4355
|
children: [
|
|
3647
|
-
/* @__PURE__ */ (0,
|
|
3648
|
-
/* @__PURE__ */ (0,
|
|
3649
|
-
/* @__PURE__ */ (0,
|
|
3650
|
-
getSortDirection(colId) && /* @__PURE__ */ (0,
|
|
4356
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-header-content", children: [
|
|
4357
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-header-text", children: colId }),
|
|
4358
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-header-icons", children: [
|
|
4359
|
+
getSortDirection(colId) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-sort-indicator", children: getSortDirection(colId) === "asc" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3651
4360
|
"svg",
|
|
3652
4361
|
{
|
|
3653
4362
|
className: "vpg-icon-sm",
|
|
3654
4363
|
fill: "currentColor",
|
|
3655
4364
|
viewBox: "0 0 20 20",
|
|
3656
|
-
children: /* @__PURE__ */ (0,
|
|
4365
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3657
4366
|
"path",
|
|
3658
4367
|
{
|
|
3659
4368
|
fillRule: "evenodd",
|
|
@@ -3662,13 +4371,13 @@ function DataGrid({
|
|
|
3662
4371
|
}
|
|
3663
4372
|
)
|
|
3664
4373
|
}
|
|
3665
|
-
) : /* @__PURE__ */ (0,
|
|
4374
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3666
4375
|
"svg",
|
|
3667
4376
|
{
|
|
3668
4377
|
className: "vpg-icon-sm",
|
|
3669
4378
|
fill: "currentColor",
|
|
3670
4379
|
viewBox: "0 0 20 20",
|
|
3671
|
-
children: /* @__PURE__ */ (0,
|
|
4380
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3672
4381
|
"path",
|
|
3673
4382
|
{
|
|
3674
4383
|
fillRule: "evenodd",
|
|
@@ -3678,13 +4387,13 @@ function DataGrid({
|
|
|
3678
4387
|
)
|
|
3679
4388
|
}
|
|
3680
4389
|
) }),
|
|
3681
|
-
hasActiveFilter(colId) && /* @__PURE__ */ (0,
|
|
4390
|
+
hasActiveFilter(colId) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-filter-indicator", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3682
4391
|
"svg",
|
|
3683
4392
|
{
|
|
3684
4393
|
className: "vpg-icon-xs",
|
|
3685
4394
|
fill: "currentColor",
|
|
3686
4395
|
viewBox: "0 0 20 20",
|
|
3687
|
-
children: /* @__PURE__ */ (0,
|
|
4396
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3688
4397
|
"path",
|
|
3689
4398
|
{
|
|
3690
4399
|
fillRule: "evenodd",
|
|
@@ -3694,14 +4403,14 @@ function DataGrid({
|
|
|
3694
4403
|
)
|
|
3695
4404
|
}
|
|
3696
4405
|
) }),
|
|
3697
|
-
/* @__PURE__ */ (0,
|
|
4406
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-dropdown-arrow", title: "Filter & Sort", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3698
4407
|
"svg",
|
|
3699
4408
|
{
|
|
3700
4409
|
className: "vpg-icon-sm",
|
|
3701
4410
|
fill: "none",
|
|
3702
4411
|
stroke: "currentColor",
|
|
3703
4412
|
viewBox: "0 0 24 24",
|
|
3704
|
-
children: /* @__PURE__ */ (0,
|
|
4413
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3705
4414
|
"path",
|
|
3706
4415
|
{
|
|
3707
4416
|
strokeLinecap: "round",
|
|
@@ -3714,7 +4423,7 @@ function DataGrid({
|
|
|
3714
4423
|
) })
|
|
3715
4424
|
] })
|
|
3716
4425
|
] }),
|
|
3717
|
-
enableColumnResize && /* @__PURE__ */ (0,
|
|
4426
|
+
enableColumnResize && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3718
4427
|
"div",
|
|
3719
4428
|
{
|
|
3720
4429
|
className: "vpg-resize-handle",
|
|
@@ -3725,7 +4434,7 @@ function DataGrid({
|
|
|
3725
4434
|
},
|
|
3726
4435
|
colId
|
|
3727
4436
|
)) }) }),
|
|
3728
|
-
/* @__PURE__ */ (0,
|
|
4437
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("tbody", { ref: tableBodyRef, children: paginatedRows.map((row, rowIndex) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("tr", { className: "vpg-row", children: columnKeys.map((colId, colIndex) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3729
4438
|
"td",
|
|
3730
4439
|
{
|
|
3731
4440
|
className: `vpg-cell ${isCellSelected(rowIndex, colIndex) ? "vpg-selected" : ""} ${getColumnStats(colId).type === "number" ? "vpg-is-number" : ""}`,
|
|
@@ -3743,8 +4452,8 @@ function DataGrid({
|
|
|
3743
4452
|
)) }, row.id)) })
|
|
3744
4453
|
] }) })
|
|
3745
4454
|
] }),
|
|
3746
|
-
viewMode === "pivot" && /* @__PURE__ */ (0,
|
|
3747
|
-
showPivotConfig && canUsePivot && /* @__PURE__ */ (0,
|
|
4455
|
+
viewMode === "pivot" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-pivot-container", children: [
|
|
4456
|
+
showPivotConfig && canUsePivot && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "vpg-pivot-config-panel", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3748
4457
|
PivotConfig,
|
|
3749
4458
|
{
|
|
3750
4459
|
availableFields: pivotAvailableFields,
|
|
@@ -3772,7 +4481,7 @@ function DataGrid({
|
|
|
3772
4481
|
onUpdateCalculatedField: addCalculatedField
|
|
3773
4482
|
}
|
|
3774
4483
|
) }),
|
|
3775
|
-
/* @__PURE__ */ (0,
|
|
4484
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: `vpg-pivot-main ${!showPivotConfig ? "vpg-full-width" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3776
4485
|
PivotSkeleton,
|
|
3777
4486
|
{
|
|
3778
4487
|
rowFields: pivotRowFields,
|
|
@@ -3798,47 +4507,78 @@ function DataGrid({
|
|
|
3798
4507
|
}
|
|
3799
4508
|
) })
|
|
3800
4509
|
] }),
|
|
3801
|
-
/* @__PURE__ */ (0,
|
|
3802
|
-
/* @__PURE__ */ (0,
|
|
3803
|
-
/* @__PURE__ */ (0,
|
|
4510
|
+
viewMode === "chart" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-chart-view", children: [
|
|
4511
|
+
activeFilterInfo && activeFilterInfo.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-chart-filter-bar", children: [
|
|
4512
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("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" }) }),
|
|
4513
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
|
|
4514
|
+
"Chart showing",
|
|
4515
|
+
filteredRowCount.toLocaleString(),
|
|
4516
|
+
" ",
|
|
4517
|
+
"of",
|
|
4518
|
+
totalRowCount.toLocaleString(),
|
|
4519
|
+
" ",
|
|
4520
|
+
"records"
|
|
4521
|
+
] }),
|
|
4522
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { className: "vpg-chart-clear-filters", onClick: clearAllFilters, children: "Clear filters" })
|
|
4523
|
+
] }),
|
|
4524
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4525
|
+
ChartBuilder,
|
|
4526
|
+
{
|
|
4527
|
+
data: filteredDataForPivot,
|
|
4528
|
+
theme: currentTheme,
|
|
4529
|
+
onConfigChange: handleChartConfigChange
|
|
4530
|
+
}
|
|
4531
|
+
)
|
|
4532
|
+
] }),
|
|
4533
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-footer", children: [
|
|
4534
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "vpg-footer-left", children: viewMode === "grid" ? enablePagination ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
4535
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
|
|
3804
4536
|
((currentPage - 1) * pageSize + 1).toLocaleString(),
|
|
3805
4537
|
"-",
|
|
3806
4538
|
Math.min(currentPage * pageSize, totalSearchedRows).toLocaleString()
|
|
3807
4539
|
] }),
|
|
3808
|
-
/* @__PURE__ */ (0,
|
|
3809
|
-
/* @__PURE__ */ (0,
|
|
3810
|
-
totalSearchedRows !== totalRowCount && /* @__PURE__ */ (0,
|
|
4540
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-separator", children: "of" }),
|
|
4541
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: totalSearchedRows.toLocaleString() }),
|
|
4542
|
+
totalSearchedRows !== totalRowCount && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "vpg-filtered-note", children: [
|
|
3811
4543
|
"(",
|
|
3812
4544
|
totalRowCount.toLocaleString(),
|
|
3813
4545
|
" ",
|
|
3814
4546
|
"total)"
|
|
3815
4547
|
] })
|
|
3816
|
-
] }) : filteredRowCount === totalRowCount && totalSearchedRows === totalRowCount ? /* @__PURE__ */ (0,
|
|
4548
|
+
] }) : filteredRowCount === totalRowCount && totalSearchedRows === totalRowCount ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
|
|
3817
4549
|
totalRowCount.toLocaleString(),
|
|
3818
4550
|
" ",
|
|
3819
4551
|
"records"
|
|
3820
|
-
] }) : /* @__PURE__ */ (0,
|
|
3821
|
-
/* @__PURE__ */ (0,
|
|
3822
|
-
/* @__PURE__ */ (0,
|
|
3823
|
-
/* @__PURE__ */ (0,
|
|
3824
|
-
/* @__PURE__ */ (0,
|
|
3825
|
-
] }) : /* @__PURE__ */ (0,
|
|
3826
|
-
/* @__PURE__ */ (0,
|
|
3827
|
-
/* @__PURE__ */ (0,
|
|
3828
|
-
/* @__PURE__ */ (0,
|
|
4552
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
4553
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-filtered-count", children: totalSearchedRows.toLocaleString() }),
|
|
4554
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-separator", children: "of" }),
|
|
4555
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: totalRowCount.toLocaleString() }),
|
|
4556
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-separator", children: "records" })
|
|
4557
|
+
] }) : viewMode === "pivot" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
4558
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-pivot-label", children: "Pivot Table" }),
|
|
4559
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-separator", children: "\u2022" }),
|
|
4560
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
|
|
3829
4561
|
totalRowCount.toLocaleString(),
|
|
3830
4562
|
" ",
|
|
3831
4563
|
"source records"
|
|
3832
4564
|
] })
|
|
4565
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
4566
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-chart-label", children: "Chart Builder" }),
|
|
4567
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-separator", children: "\u2022" }),
|
|
4568
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
|
|
4569
|
+
totalRowCount.toLocaleString(),
|
|
4570
|
+
" ",
|
|
4571
|
+
"records"
|
|
4572
|
+
] })
|
|
3833
4573
|
] }) }),
|
|
3834
|
-
enablePagination && viewMode === "grid" && totalPages > 1 && /* @__PURE__ */ (0,
|
|
3835
|
-
/* @__PURE__ */ (0,
|
|
4574
|
+
enablePagination && viewMode === "grid" && totalPages > 1 && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-pagination", children: [
|
|
4575
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3836
4576
|
"button",
|
|
3837
4577
|
{
|
|
3838
4578
|
className: "vpg-page-btn",
|
|
3839
4579
|
disabled: currentPage === 1,
|
|
3840
4580
|
onClick: () => setCurrentPage(1),
|
|
3841
|
-
children: /* @__PURE__ */ (0,
|
|
4581
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3842
4582
|
"path",
|
|
3843
4583
|
{
|
|
3844
4584
|
strokeLinecap: "round",
|
|
@@ -3849,13 +4589,13 @@ function DataGrid({
|
|
|
3849
4589
|
) })
|
|
3850
4590
|
}
|
|
3851
4591
|
),
|
|
3852
|
-
/* @__PURE__ */ (0,
|
|
4592
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3853
4593
|
"button",
|
|
3854
4594
|
{
|
|
3855
4595
|
className: "vpg-page-btn",
|
|
3856
4596
|
disabled: currentPage === 1,
|
|
3857
4597
|
onClick: () => setCurrentPage((p) => Math.max(1, p - 1)),
|
|
3858
|
-
children: /* @__PURE__ */ (0,
|
|
4598
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3859
4599
|
"path",
|
|
3860
4600
|
{
|
|
3861
4601
|
strokeLinecap: "round",
|
|
@@ -3866,7 +4606,7 @@ function DataGrid({
|
|
|
3866
4606
|
) })
|
|
3867
4607
|
}
|
|
3868
4608
|
),
|
|
3869
|
-
/* @__PURE__ */ (0,
|
|
4609
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "vpg-page-info", children: [
|
|
3870
4610
|
"Page",
|
|
3871
4611
|
" ",
|
|
3872
4612
|
currentPage,
|
|
@@ -3875,13 +4615,13 @@ function DataGrid({
|
|
|
3875
4615
|
" ",
|
|
3876
4616
|
totalPages
|
|
3877
4617
|
] }),
|
|
3878
|
-
/* @__PURE__ */ (0,
|
|
4618
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3879
4619
|
"button",
|
|
3880
4620
|
{
|
|
3881
4621
|
className: "vpg-page-btn",
|
|
3882
4622
|
disabled: currentPage === totalPages,
|
|
3883
4623
|
onClick: () => setCurrentPage((p) => Math.min(totalPages, p + 1)),
|
|
3884
|
-
children: /* @__PURE__ */ (0,
|
|
4624
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3885
4625
|
"path",
|
|
3886
4626
|
{
|
|
3887
4627
|
strokeLinecap: "round",
|
|
@@ -3892,13 +4632,13 @@ function DataGrid({
|
|
|
3892
4632
|
) })
|
|
3893
4633
|
}
|
|
3894
4634
|
),
|
|
3895
|
-
/* @__PURE__ */ (0,
|
|
4635
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3896
4636
|
"button",
|
|
3897
4637
|
{
|
|
3898
4638
|
className: "vpg-page-btn",
|
|
3899
4639
|
disabled: currentPage === totalPages,
|
|
3900
4640
|
onClick: () => setCurrentPage(totalPages),
|
|
3901
|
-
children: /* @__PURE__ */ (0,
|
|
4641
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3902
4642
|
"path",
|
|
3903
4643
|
{
|
|
3904
4644
|
strokeLinecap: "round",
|
|
@@ -3910,45 +4650,45 @@ function DataGrid({
|
|
|
3910
4650
|
}
|
|
3911
4651
|
)
|
|
3912
4652
|
] }),
|
|
3913
|
-
viewMode === "grid" && selectionStats && selectionStats.count > 1 && /* @__PURE__ */ (0,
|
|
3914
|
-
/* @__PURE__ */ (0,
|
|
3915
|
-
/* @__PURE__ */ (0,
|
|
3916
|
-
/* @__PURE__ */ (0,
|
|
4653
|
+
viewMode === "grid" && selectionStats && selectionStats.count > 1 && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-selection-stats", children: [
|
|
4654
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "vpg-stat", children: [
|
|
4655
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-stat-label", children: "Count:" }),
|
|
4656
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-stat-value", children: selectionStats.count })
|
|
3917
4657
|
] }),
|
|
3918
|
-
selectionStats.numericCount > 0 && /* @__PURE__ */ (0,
|
|
3919
|
-
/* @__PURE__ */ (0,
|
|
3920
|
-
/* @__PURE__ */ (0,
|
|
3921
|
-
/* @__PURE__ */ (0,
|
|
3922
|
-
/* @__PURE__ */ (0,
|
|
4658
|
+
selectionStats.numericCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
4659
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-stat-divider", children: "|" }),
|
|
4660
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "vpg-stat", children: [
|
|
4661
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-stat-label", children: "Sum:" }),
|
|
4662
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.sum) })
|
|
3923
4663
|
] }),
|
|
3924
|
-
/* @__PURE__ */ (0,
|
|
3925
|
-
/* @__PURE__ */ (0,
|
|
3926
|
-
/* @__PURE__ */ (0,
|
|
3927
|
-
/* @__PURE__ */ (0,
|
|
4664
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-stat-divider", children: "|" }),
|
|
4665
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "vpg-stat", children: [
|
|
4666
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-stat-label", children: "Avg:" }),
|
|
4667
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.avg) })
|
|
3928
4668
|
] })
|
|
3929
4669
|
] })
|
|
3930
4670
|
] }),
|
|
3931
|
-
/* @__PURE__ */ (0,
|
|
3932
|
-
/* @__PURE__ */ (0,
|
|
3933
|
-
/* @__PURE__ */ (0,
|
|
3934
|
-
/* @__PURE__ */ (0,
|
|
3935
|
-
] }) : showWatermark ? /* @__PURE__ */ (0,
|
|
3936
|
-
/* @__PURE__ */ (0,
|
|
3937
|
-
/* @__PURE__ */ (0,
|
|
3938
|
-
/* @__PURE__ */ (0,
|
|
3939
|
-
/* @__PURE__ */ (0,
|
|
3940
|
-
/* @__PURE__ */ (0,
|
|
4671
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "vpg-footer-right", children: isDemo ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-demo-banner", children: [
|
|
4672
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-demo-badge", children: "DEMO" }),
|
|
4673
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "Pro features enabled" }),
|
|
4674
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("a", { href: "https://tiny-pivot.com/#pricing", target: "_blank", rel: "noopener noreferrer", children: "Get License \u2192" })
|
|
4675
|
+
] }) : showWatermark ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-watermark-inline", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: [
|
|
4676
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("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: [
|
|
4677
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("rect", { x: "3", y: "3", width: "7", height: "7" }),
|
|
4678
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("rect", { x: "14", y: "3", width: "7", height: "7" }),
|
|
4679
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("rect", { x: "14", y: "14", width: "7", height: "7" }),
|
|
4680
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("rect", { x: "3", y: "14", width: "7", height: "7" })
|
|
3941
4681
|
] }),
|
|
3942
4682
|
"Powered by TinyPivot"
|
|
3943
4683
|
] }) }) : null })
|
|
3944
4684
|
] }),
|
|
3945
|
-
enableVerticalResize && /* @__PURE__ */ (0,
|
|
3946
|
-
/* @__PURE__ */ (0,
|
|
3947
|
-
/* @__PURE__ */ (0,
|
|
3948
|
-
/* @__PURE__ */ (0,
|
|
4685
|
+
enableVerticalResize && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "vpg-vertical-resize-handle", onMouseDown: startVerticalResize, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-resize-grip", children: [
|
|
4686
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", {}),
|
|
4687
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", {}),
|
|
4688
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", {})
|
|
3949
4689
|
] }) }),
|
|
3950
4690
|
activeFilterColumn && typeof document !== "undefined" && (0, import_react_dom2.createPortal)(
|
|
3951
|
-
/* @__PURE__ */ (0,
|
|
4691
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3952
4692
|
"div",
|
|
3953
4693
|
{
|
|
3954
4694
|
className: "vpg-filter-portal",
|
|
@@ -3959,7 +4699,7 @@ function DataGrid({
|
|
|
3959
4699
|
maxHeight: `${filterDropdownPosition.maxHeight}px`,
|
|
3960
4700
|
zIndex: 9999
|
|
3961
4701
|
},
|
|
3962
|
-
children: /* @__PURE__ */ (0,
|
|
4702
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3963
4703
|
ColumnFilter,
|
|
3964
4704
|
{
|
|
3965
4705
|
columnId: activeFilterColumn,
|