@smallwebco/tinypivot-react 1.0.24 → 1.0.25
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 +679 -373
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -2
- package/dist/index.d.ts +9 -2
- package/dist/index.js +679 -371
- package/dist/index.js.map +1 -1
- package/dist/style.css +292 -14
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -45,8 +45,8 @@ __export(index_exports, {
|
|
|
45
45
|
module.exports = __toCommonJS(index_exports);
|
|
46
46
|
|
|
47
47
|
// src/components/DataGrid.tsx
|
|
48
|
-
var
|
|
49
|
-
var
|
|
48
|
+
var import_react9 = require("react");
|
|
49
|
+
var import_react_dom2 = require("react-dom");
|
|
50
50
|
|
|
51
51
|
// src/hooks/useExcelGrid.ts
|
|
52
52
|
var import_react = require("react");
|
|
@@ -312,6 +312,7 @@ function usePivotTable(data) {
|
|
|
312
312
|
const [valueFields, setValueFields] = (0, import_react3.useState)([]);
|
|
313
313
|
const [showRowTotals, setShowRowTotals] = (0, import_react3.useState)(true);
|
|
314
314
|
const [showColumnTotals, setShowColumnTotals] = (0, import_react3.useState)(true);
|
|
315
|
+
const [calculatedFields, setCalculatedFields] = (0, import_react3.useState)(() => (0, import_tinypivot_core3.loadCalculatedFields)());
|
|
315
316
|
const [currentStorageKey, setCurrentStorageKey] = (0, import_react3.useState)(null);
|
|
316
317
|
const availableFields = (0, import_react3.useMemo)(() => {
|
|
317
318
|
return (0, import_tinypivot_core3.computeAvailableFields)(data);
|
|
@@ -336,9 +337,10 @@ function usePivotTable(data) {
|
|
|
336
337
|
columnFields,
|
|
337
338
|
valueFields,
|
|
338
339
|
showRowTotals,
|
|
339
|
-
showColumnTotals
|
|
340
|
+
showColumnTotals,
|
|
341
|
+
calculatedFields
|
|
340
342
|
});
|
|
341
|
-
}, [data, isConfigured, canUsePivot, rowFields, columnFields, valueFields, showRowTotals, showColumnTotals]);
|
|
343
|
+
}, [data, isConfigured, canUsePivot, rowFields, columnFields, valueFields, showRowTotals, showColumnTotals, calculatedFields]);
|
|
342
344
|
(0, import_react3.useEffect)(() => {
|
|
343
345
|
if (data.length === 0) return;
|
|
344
346
|
const newKeys = Object.keys(data[0]);
|
|
@@ -352,6 +354,9 @@ function usePivotTable(data) {
|
|
|
352
354
|
setValueFields(savedConfig.valueFields);
|
|
353
355
|
setShowRowTotals(savedConfig.showRowTotals);
|
|
354
356
|
setShowColumnTotals(savedConfig.showColumnTotals);
|
|
357
|
+
if (savedConfig.calculatedFields) {
|
|
358
|
+
setCalculatedFields(savedConfig.calculatedFields);
|
|
359
|
+
}
|
|
355
360
|
} else {
|
|
356
361
|
const currentConfig = {
|
|
357
362
|
rowFields,
|
|
@@ -375,10 +380,11 @@ function usePivotTable(data) {
|
|
|
375
380
|
columnFields,
|
|
376
381
|
valueFields,
|
|
377
382
|
showRowTotals,
|
|
378
|
-
showColumnTotals
|
|
383
|
+
showColumnTotals,
|
|
384
|
+
calculatedFields
|
|
379
385
|
};
|
|
380
386
|
(0, import_tinypivot_core3.savePivotConfig)(currentStorageKey, config);
|
|
381
|
-
}, [currentStorageKey, rowFields, columnFields, valueFields, showRowTotals, showColumnTotals]);
|
|
387
|
+
}, [currentStorageKey, rowFields, columnFields, valueFields, showRowTotals, showColumnTotals, calculatedFields]);
|
|
382
388
|
const addRowField = (0, import_react3.useCallback)(
|
|
383
389
|
(field) => {
|
|
384
390
|
if (!requirePro("Pivot Table - Row Fields")) return;
|
|
@@ -457,6 +463,27 @@ function usePivotTable(data) {
|
|
|
457
463
|
setValueFields([{ field: numericFields[0].field, aggregation: "sum" }]);
|
|
458
464
|
}
|
|
459
465
|
}, [availableFields, requirePro]);
|
|
466
|
+
const addCalculatedField = (0, import_react3.useCallback)((field) => {
|
|
467
|
+
setCalculatedFields((prev) => {
|
|
468
|
+
const existing = prev.findIndex((f) => f.id === field.id);
|
|
469
|
+
let updated;
|
|
470
|
+
if (existing >= 0) {
|
|
471
|
+
updated = [...prev.slice(0, existing), field, ...prev.slice(existing + 1)];
|
|
472
|
+
} else {
|
|
473
|
+
updated = [...prev, field];
|
|
474
|
+
}
|
|
475
|
+
(0, import_tinypivot_core3.saveCalculatedFields)(updated);
|
|
476
|
+
return updated;
|
|
477
|
+
});
|
|
478
|
+
}, []);
|
|
479
|
+
const removeCalculatedField = (0, import_react3.useCallback)((id) => {
|
|
480
|
+
setCalculatedFields((prev) => {
|
|
481
|
+
const updated = prev.filter((f) => f.id !== id);
|
|
482
|
+
(0, import_tinypivot_core3.saveCalculatedFields)(updated);
|
|
483
|
+
return updated;
|
|
484
|
+
});
|
|
485
|
+
setValueFields((prev) => prev.filter((v) => v.field !== `calc:${id}`));
|
|
486
|
+
}, []);
|
|
460
487
|
return {
|
|
461
488
|
// State
|
|
462
489
|
rowFields,
|
|
@@ -464,6 +491,7 @@ function usePivotTable(data) {
|
|
|
464
491
|
valueFields,
|
|
465
492
|
showRowTotals,
|
|
466
493
|
showColumnTotals,
|
|
494
|
+
calculatedFields,
|
|
467
495
|
// Computed
|
|
468
496
|
availableFields,
|
|
469
497
|
unassignedFields,
|
|
@@ -482,7 +510,9 @@ function usePivotTable(data) {
|
|
|
482
510
|
setShowColumnTotals,
|
|
483
511
|
autoSuggestConfig,
|
|
484
512
|
setRowFields,
|
|
485
|
-
setColumnFields
|
|
513
|
+
setColumnFields,
|
|
514
|
+
addCalculatedField,
|
|
515
|
+
removeCalculatedField
|
|
486
516
|
};
|
|
487
517
|
}
|
|
488
518
|
|
|
@@ -954,10 +984,197 @@ function ColumnFilter({
|
|
|
954
984
|
}
|
|
955
985
|
|
|
956
986
|
// src/components/PivotConfig.tsx
|
|
987
|
+
var import_react7 = require("react");
|
|
988
|
+
var import_tinypivot_core6 = require("@smallwebco/tinypivot-core");
|
|
989
|
+
|
|
990
|
+
// src/components/CalculatedFieldModal.tsx
|
|
957
991
|
var import_react6 = require("react");
|
|
992
|
+
var import_react_dom = require("react-dom");
|
|
958
993
|
var import_tinypivot_core5 = require("@smallwebco/tinypivot-core");
|
|
959
994
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
960
|
-
function
|
|
995
|
+
function CalculatedFieldModal({
|
|
996
|
+
show,
|
|
997
|
+
availableFields,
|
|
998
|
+
existingField,
|
|
999
|
+
onClose,
|
|
1000
|
+
onSave
|
|
1001
|
+
}) {
|
|
1002
|
+
const [name, setName] = (0, import_react6.useState)("");
|
|
1003
|
+
const [formula, setFormula] = (0, import_react6.useState)("");
|
|
1004
|
+
const [formatAs, setFormatAs] = (0, import_react6.useState)("number");
|
|
1005
|
+
const [decimals, setDecimals] = (0, import_react6.useState)(2);
|
|
1006
|
+
const [error, setError] = (0, import_react6.useState)(null);
|
|
1007
|
+
(0, import_react6.useEffect)(() => {
|
|
1008
|
+
if (show) {
|
|
1009
|
+
if (existingField) {
|
|
1010
|
+
setName(existingField.name);
|
|
1011
|
+
setFormula(existingField.formula);
|
|
1012
|
+
setFormatAs(existingField.formatAs || "number");
|
|
1013
|
+
setDecimals(existingField.decimals ?? 2);
|
|
1014
|
+
} else {
|
|
1015
|
+
setName("");
|
|
1016
|
+
setFormula("");
|
|
1017
|
+
setFormatAs("number");
|
|
1018
|
+
setDecimals(2);
|
|
1019
|
+
}
|
|
1020
|
+
setError(null);
|
|
1021
|
+
}
|
|
1022
|
+
}, [show, existingField]);
|
|
1023
|
+
const validationError = (0, import_react6.useMemo)(() => {
|
|
1024
|
+
if (!formula.trim()) return null;
|
|
1025
|
+
return (0, import_tinypivot_core5.validateSimpleFormula)(formula, availableFields);
|
|
1026
|
+
}, [formula, availableFields]);
|
|
1027
|
+
const insertField = (0, import_react6.useCallback)((field) => {
|
|
1028
|
+
setFormula((prev) => {
|
|
1029
|
+
if (prev.trim() && !prev.endsWith(" ")) {
|
|
1030
|
+
return prev + " " + field;
|
|
1031
|
+
}
|
|
1032
|
+
return prev + field;
|
|
1033
|
+
});
|
|
1034
|
+
}, []);
|
|
1035
|
+
const insertOperator = (0, import_react6.useCallback)((op) => {
|
|
1036
|
+
setFormula((prev) => {
|
|
1037
|
+
if (prev.trim() && !prev.endsWith(" ")) {
|
|
1038
|
+
return prev + " " + op + " ";
|
|
1039
|
+
}
|
|
1040
|
+
return prev + op + " ";
|
|
1041
|
+
});
|
|
1042
|
+
}, []);
|
|
1043
|
+
const handleSave = (0, import_react6.useCallback)(() => {
|
|
1044
|
+
if (!name.trim()) {
|
|
1045
|
+
setError("Name is required");
|
|
1046
|
+
return;
|
|
1047
|
+
}
|
|
1048
|
+
const validationResult = (0, import_tinypivot_core5.validateSimpleFormula)(formula, availableFields);
|
|
1049
|
+
if (validationResult) {
|
|
1050
|
+
setError(validationResult);
|
|
1051
|
+
return;
|
|
1052
|
+
}
|
|
1053
|
+
const field = {
|
|
1054
|
+
id: existingField?.id || `calc_${Date.now()}`,
|
|
1055
|
+
name: name.trim(),
|
|
1056
|
+
formula: formula.trim(),
|
|
1057
|
+
formatAs,
|
|
1058
|
+
decimals
|
|
1059
|
+
};
|
|
1060
|
+
onSave(field);
|
|
1061
|
+
onClose();
|
|
1062
|
+
}, [name, formula, formatAs, decimals, existingField, availableFields, onSave, onClose]);
|
|
1063
|
+
const handleOverlayClick = (0, import_react6.useCallback)((e) => {
|
|
1064
|
+
if (e.target === e.currentTarget) {
|
|
1065
|
+
onClose();
|
|
1066
|
+
}
|
|
1067
|
+
}, [onClose]);
|
|
1068
|
+
if (!show) return null;
|
|
1069
|
+
const modalContent = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "vpg-modal-overlay", onClick: handleOverlayClick, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-modal", children: [
|
|
1070
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-modal-header", children: [
|
|
1071
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("h3", { children: [
|
|
1072
|
+
existingField ? "Edit" : "Create",
|
|
1073
|
+
" Calculated Field"
|
|
1074
|
+
] }),
|
|
1075
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "vpg-modal-close", onClick: onClose, children: "\xD7" })
|
|
1076
|
+
] }),
|
|
1077
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-modal-body", children: [
|
|
1078
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-form-group", children: [
|
|
1079
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { className: "vpg-label", children: "Name" }),
|
|
1080
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1081
|
+
"input",
|
|
1082
|
+
{
|
|
1083
|
+
type: "text",
|
|
1084
|
+
className: "vpg-input",
|
|
1085
|
+
placeholder: "e.g., Profit Margin %",
|
|
1086
|
+
value: name,
|
|
1087
|
+
onChange: (e) => setName(e.target.value)
|
|
1088
|
+
}
|
|
1089
|
+
)
|
|
1090
|
+
] }),
|
|
1091
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-form-group", children: [
|
|
1092
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { className: "vpg-label", children: "Formula" }),
|
|
1093
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1094
|
+
"textarea",
|
|
1095
|
+
{
|
|
1096
|
+
className: "vpg-textarea",
|
|
1097
|
+
placeholder: "e.g., revenue / units",
|
|
1098
|
+
rows: 2,
|
|
1099
|
+
value: formula,
|
|
1100
|
+
onChange: (e) => setFormula(e.target.value)
|
|
1101
|
+
}
|
|
1102
|
+
),
|
|
1103
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "vpg-formula-hint", children: "Use field names with math operators: + - * / ( )" }),
|
|
1104
|
+
validationError && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "vpg-error", children: validationError })
|
|
1105
|
+
] }),
|
|
1106
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-form-group", children: [
|
|
1107
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { className: "vpg-label-small", children: "Operators" }),
|
|
1108
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-button-group", children: [
|
|
1109
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "vpg-insert-btn vpg-op-btn", onClick: () => insertOperator("+"), children: "+" }),
|
|
1110
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "vpg-insert-btn vpg-op-btn", onClick: () => insertOperator("-"), children: "\u2212" }),
|
|
1111
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "vpg-insert-btn vpg-op-btn", onClick: () => insertOperator("*"), children: "\xD7" }),
|
|
1112
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "vpg-insert-btn vpg-op-btn", onClick: () => insertOperator("/"), children: "\xF7" }),
|
|
1113
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "vpg-insert-btn vpg-op-btn", onClick: () => insertOperator("("), children: "(" }),
|
|
1114
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "vpg-insert-btn vpg-op-btn", onClick: () => insertOperator(")"), children: ")" })
|
|
1115
|
+
] })
|
|
1116
|
+
] }),
|
|
1117
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-form-group", children: [
|
|
1118
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { className: "vpg-label-small", children: "Insert Field" }),
|
|
1119
|
+
availableFields.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "vpg-button-group vpg-field-buttons", children: availableFields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1120
|
+
"button",
|
|
1121
|
+
{
|
|
1122
|
+
className: "vpg-insert-btn vpg-field-btn",
|
|
1123
|
+
onClick: () => insertField(field),
|
|
1124
|
+
children: field
|
|
1125
|
+
},
|
|
1126
|
+
field
|
|
1127
|
+
)) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "vpg-no-fields", children: "No numeric fields available" })
|
|
1128
|
+
] }),
|
|
1129
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-form-row", children: [
|
|
1130
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-form-group vpg-form-group-half", children: [
|
|
1131
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { className: "vpg-label", children: "Format As" }),
|
|
1132
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1133
|
+
"select",
|
|
1134
|
+
{
|
|
1135
|
+
className: "vpg-select",
|
|
1136
|
+
value: formatAs,
|
|
1137
|
+
onChange: (e) => setFormatAs(e.target.value),
|
|
1138
|
+
children: [
|
|
1139
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("option", { value: "number", children: "Number" }),
|
|
1140
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("option", { value: "percent", children: "Percentage" }),
|
|
1141
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("option", { value: "currency", children: "Currency ($)" })
|
|
1142
|
+
]
|
|
1143
|
+
}
|
|
1144
|
+
)
|
|
1145
|
+
] }),
|
|
1146
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-form-group vpg-form-group-half", children: [
|
|
1147
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { className: "vpg-label", children: "Decimals" }),
|
|
1148
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1149
|
+
"input",
|
|
1150
|
+
{
|
|
1151
|
+
type: "number",
|
|
1152
|
+
className: "vpg-input",
|
|
1153
|
+
min: 0,
|
|
1154
|
+
max: 6,
|
|
1155
|
+
value: decimals,
|
|
1156
|
+
onChange: (e) => setDecimals(Number(e.target.value))
|
|
1157
|
+
}
|
|
1158
|
+
)
|
|
1159
|
+
] })
|
|
1160
|
+
] }),
|
|
1161
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "vpg-error vpg-error-box", children: error })
|
|
1162
|
+
] }),
|
|
1163
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "vpg-modal-footer", children: [
|
|
1164
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "vpg-btn vpg-btn-secondary", onClick: onClose, children: "Cancel" }),
|
|
1165
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { className: "vpg-btn vpg-btn-primary", onClick: handleSave, children: [
|
|
1166
|
+
existingField ? "Update" : "Add",
|
|
1167
|
+
" Field"
|
|
1168
|
+
] })
|
|
1169
|
+
] })
|
|
1170
|
+
] }) });
|
|
1171
|
+
return (0, import_react_dom.createPortal)(modalContent, document.body);
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
// src/components/PivotConfig.tsx
|
|
1175
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
1176
|
+
function getFieldIcon(type, isCalculated) {
|
|
1177
|
+
if (isCalculated) return "\u0192";
|
|
961
1178
|
switch (type) {
|
|
962
1179
|
case "number":
|
|
963
1180
|
return "#";
|
|
@@ -975,7 +1192,9 @@ function PivotConfig({
|
|
|
975
1192
|
columnFields,
|
|
976
1193
|
valueFields,
|
|
977
1194
|
showRowTotals,
|
|
1195
|
+
calculatedFields,
|
|
978
1196
|
onShowRowTotalsChange,
|
|
1197
|
+
onShowColumnTotalsChange,
|
|
979
1198
|
onClearConfig,
|
|
980
1199
|
onAutoSuggest,
|
|
981
1200
|
onDragStart,
|
|
@@ -985,35 +1204,71 @@ function PivotConfig({
|
|
|
985
1204
|
onRemoveColumnField,
|
|
986
1205
|
onRemoveValueField,
|
|
987
1206
|
onAddRowField,
|
|
988
|
-
onAddColumnField
|
|
1207
|
+
onAddColumnField,
|
|
1208
|
+
onAddCalculatedField,
|
|
1209
|
+
onRemoveCalculatedField,
|
|
1210
|
+
onUpdateCalculatedField
|
|
989
1211
|
}) {
|
|
990
1212
|
const { showWatermark } = useLicense();
|
|
991
|
-
const [fieldSearch, setFieldSearch] = (0,
|
|
992
|
-
const
|
|
1213
|
+
const [fieldSearch, setFieldSearch] = (0, import_react7.useState)("");
|
|
1214
|
+
const [showCalcModal, setShowCalcModal] = (0, import_react7.useState)(false);
|
|
1215
|
+
const [editingCalcField, setEditingCalcField] = (0, import_react7.useState)(null);
|
|
1216
|
+
const numericFieldNames = (0, import_react7.useMemo)(
|
|
1217
|
+
() => availableFields.filter((f) => f.isNumeric).map((f) => f.field),
|
|
1218
|
+
[availableFields]
|
|
1219
|
+
);
|
|
1220
|
+
const calculatedFieldsAsStats = (0, import_react7.useMemo)(() => {
|
|
1221
|
+
if (!calculatedFields) return [];
|
|
1222
|
+
return calculatedFields.map((calc) => ({
|
|
1223
|
+
field: `calc:${calc.id}`,
|
|
1224
|
+
type: "number",
|
|
1225
|
+
uniqueCount: 0,
|
|
1226
|
+
isNumeric: true,
|
|
1227
|
+
isCalculated: true,
|
|
1228
|
+
calcId: calc.id,
|
|
1229
|
+
calcName: calc.name,
|
|
1230
|
+
calcFormula: calc.formula
|
|
1231
|
+
}));
|
|
1232
|
+
}, [calculatedFields]);
|
|
1233
|
+
const allAvailableFields = (0, import_react7.useMemo)(() => [
|
|
1234
|
+
...availableFields.map((f) => ({ ...f, isCalculated: false })),
|
|
1235
|
+
...calculatedFieldsAsStats
|
|
1236
|
+
], [availableFields, calculatedFieldsAsStats]);
|
|
1237
|
+
const assignedFields = (0, import_react7.useMemo)(() => {
|
|
993
1238
|
const rowSet = new Set(rowFields);
|
|
994
1239
|
const colSet = new Set(columnFields);
|
|
995
1240
|
const valueMap = new Map(valueFields.map((v) => [v.field, v]));
|
|
996
|
-
return
|
|
1241
|
+
return allAvailableFields.filter((f) => rowSet.has(f.field) || colSet.has(f.field) || valueMap.has(f.field)).map((f) => ({
|
|
997
1242
|
...f,
|
|
998
1243
|
assignedTo: rowSet.has(f.field) ? "row" : colSet.has(f.field) ? "column" : "value",
|
|
999
1244
|
valueConfig: valueMap.get(f.field)
|
|
1000
1245
|
}));
|
|
1001
|
-
}, [
|
|
1002
|
-
const unassignedFields = (0,
|
|
1246
|
+
}, [allAvailableFields, rowFields, columnFields, valueFields]);
|
|
1247
|
+
const unassignedFields = (0, import_react7.useMemo)(() => {
|
|
1003
1248
|
const rowSet = new Set(rowFields);
|
|
1004
1249
|
const colSet = new Set(columnFields);
|
|
1005
1250
|
const valSet = new Set(valueFields.map((v) => v.field));
|
|
1006
|
-
return
|
|
1251
|
+
return allAvailableFields.filter(
|
|
1007
1252
|
(f) => !rowSet.has(f.field) && !colSet.has(f.field) && !valSet.has(f.field)
|
|
1008
1253
|
);
|
|
1009
|
-
}, [
|
|
1010
|
-
const filteredUnassignedFields = (0,
|
|
1254
|
+
}, [allAvailableFields, rowFields, columnFields, valueFields]);
|
|
1255
|
+
const filteredUnassignedFields = (0, import_react7.useMemo)(() => {
|
|
1011
1256
|
if (!fieldSearch.trim()) return unassignedFields;
|
|
1012
1257
|
const search = fieldSearch.toLowerCase().trim();
|
|
1013
|
-
return unassignedFields.filter((f) =>
|
|
1258
|
+
return unassignedFields.filter((f) => {
|
|
1259
|
+
const fieldName = f.field.toLowerCase();
|
|
1260
|
+
const displayName = f.isCalculated && f.calcName ? f.calcName.toLowerCase() : "";
|
|
1261
|
+
return fieldName.includes(search) || displayName.includes(search);
|
|
1262
|
+
});
|
|
1014
1263
|
}, [unassignedFields, fieldSearch]);
|
|
1015
1264
|
const assignedCount = assignedFields.length;
|
|
1016
|
-
const
|
|
1265
|
+
const getFieldDisplayName = (0, import_react7.useCallback)((field) => {
|
|
1266
|
+
if (field.isCalculated && field.calcName) {
|
|
1267
|
+
return field.calcName;
|
|
1268
|
+
}
|
|
1269
|
+
return field.field;
|
|
1270
|
+
}, []);
|
|
1271
|
+
const handleDragStart = (0, import_react7.useCallback)(
|
|
1017
1272
|
(field, event) => {
|
|
1018
1273
|
event.dataTransfer?.setData("text/plain", field);
|
|
1019
1274
|
event.dataTransfer.effectAllowed = "move";
|
|
@@ -1021,13 +1276,13 @@ function PivotConfig({
|
|
|
1021
1276
|
},
|
|
1022
1277
|
[onDragStart]
|
|
1023
1278
|
);
|
|
1024
|
-
const handleAggregationChange = (0,
|
|
1279
|
+
const handleAggregationChange = (0, import_react7.useCallback)(
|
|
1025
1280
|
(field, currentAgg, newAgg) => {
|
|
1026
1281
|
onUpdateAggregation(field, currentAgg, newAgg);
|
|
1027
1282
|
},
|
|
1028
1283
|
[onUpdateAggregation]
|
|
1029
1284
|
);
|
|
1030
|
-
const toggleRowColumn = (0,
|
|
1285
|
+
const toggleRowColumn = (0, import_react7.useCallback)(
|
|
1031
1286
|
(field, currentAssignment) => {
|
|
1032
1287
|
if (currentAssignment === "row") {
|
|
1033
1288
|
onRemoveRowField(field);
|
|
@@ -1039,7 +1294,7 @@ function PivotConfig({
|
|
|
1039
1294
|
},
|
|
1040
1295
|
[onRemoveRowField, onAddColumnField, onRemoveColumnField, onAddRowField]
|
|
1041
1296
|
);
|
|
1042
|
-
const removeField = (0,
|
|
1297
|
+
const removeField = (0, import_react7.useCallback)(
|
|
1043
1298
|
(field, assignedTo, valueConfig) => {
|
|
1044
1299
|
if (assignedTo === "row") {
|
|
1045
1300
|
onRemoveRowField(field);
|
|
@@ -1051,10 +1306,31 @@ function PivotConfig({
|
|
|
1051
1306
|
},
|
|
1052
1307
|
[onRemoveRowField, onRemoveColumnField, onRemoveValueField]
|
|
1053
1308
|
);
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1309
|
+
const handleTotalsToggle = (0, import_react7.useCallback)((checked) => {
|
|
1310
|
+
onShowRowTotalsChange(checked);
|
|
1311
|
+
onShowColumnTotalsChange(checked);
|
|
1312
|
+
}, [onShowRowTotalsChange, onShowColumnTotalsChange]);
|
|
1313
|
+
const openCalcModal = (0, import_react7.useCallback)((field) => {
|
|
1314
|
+
setEditingCalcField(field || null);
|
|
1315
|
+
setShowCalcModal(true);
|
|
1316
|
+
}, []);
|
|
1317
|
+
const handleSaveCalcField = (0, import_react7.useCallback)((field) => {
|
|
1318
|
+
if (editingCalcField && onUpdateCalculatedField) {
|
|
1319
|
+
onUpdateCalculatedField(field);
|
|
1320
|
+
} else if (onAddCalculatedField) {
|
|
1321
|
+
onAddCalculatedField(field);
|
|
1322
|
+
}
|
|
1323
|
+
setShowCalcModal(false);
|
|
1324
|
+
setEditingCalcField(null);
|
|
1325
|
+
}, [editingCalcField, onAddCalculatedField, onUpdateCalculatedField]);
|
|
1326
|
+
const handleCloseCalcModal = (0, import_react7.useCallback)(() => {
|
|
1327
|
+
setShowCalcModal(false);
|
|
1328
|
+
setEditingCalcField(null);
|
|
1329
|
+
}, []);
|
|
1330
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-pivot-config", children: [
|
|
1331
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-config-header", children: [
|
|
1332
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("h3", { className: "vpg-config-title", children: [
|
|
1333
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1058
1334
|
"path",
|
|
1059
1335
|
{
|
|
1060
1336
|
strokeLinecap: "round",
|
|
@@ -1065,13 +1341,13 @@ function PivotConfig({
|
|
|
1065
1341
|
) }),
|
|
1066
1342
|
"Fields"
|
|
1067
1343
|
] }),
|
|
1068
|
-
/* @__PURE__ */ (0,
|
|
1344
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "vpg-header-actions", children: assignedCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1069
1345
|
"button",
|
|
1070
1346
|
{
|
|
1071
1347
|
className: "vpg-action-btn vpg-clear-btn",
|
|
1072
1348
|
title: "Clear all",
|
|
1073
1349
|
onClick: onClearConfig,
|
|
1074
|
-
children: /* @__PURE__ */ (0,
|
|
1350
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1075
1351
|
"path",
|
|
1076
1352
|
{
|
|
1077
1353
|
strokeLinecap: "round",
|
|
@@ -1083,23 +1359,23 @@ function PivotConfig({
|
|
|
1083
1359
|
}
|
|
1084
1360
|
) })
|
|
1085
1361
|
] }),
|
|
1086
|
-
assignedCount > 0 && /* @__PURE__ */ (0,
|
|
1087
|
-
/* @__PURE__ */ (0,
|
|
1088
|
-
/* @__PURE__ */ (0,
|
|
1362
|
+
assignedCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-assigned-section", children: [
|
|
1363
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "vpg-section-label", children: "Active" }),
|
|
1364
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "vpg-assigned-list", children: assignedFields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1089
1365
|
"div",
|
|
1090
1366
|
{
|
|
1091
|
-
className: `vpg-assigned-item vpg-type-${field.assignedTo}`,
|
|
1092
|
-
title: field.field,
|
|
1367
|
+
className: `vpg-assigned-item vpg-type-${field.assignedTo}${field.isCalculated ? " vpg-type-calc" : ""}`,
|
|
1368
|
+
title: field.isCalculated ? field.calcFormula : field.field,
|
|
1093
1369
|
draggable: true,
|
|
1094
1370
|
onDragStart: (e) => handleDragStart(field.field, e),
|
|
1095
1371
|
onDragEnd,
|
|
1096
1372
|
children: [
|
|
1097
|
-
/* @__PURE__ */ (0,
|
|
1098
|
-
/* @__PURE__ */ (0,
|
|
1099
|
-
/* @__PURE__ */ (0,
|
|
1373
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-item-main", children: [
|
|
1374
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.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_core6.getAggregationSymbol)(field.valueConfig?.aggregation || "sum") }),
|
|
1375
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-item-name", children: getFieldDisplayName(field) })
|
|
1100
1376
|
] }),
|
|
1101
|
-
/* @__PURE__ */ (0,
|
|
1102
|
-
(field.assignedTo === "row" || field.assignedTo === "column") && /* @__PURE__ */ (0,
|
|
1377
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-item-actions", children: [
|
|
1378
|
+
(field.assignedTo === "row" || field.assignedTo === "column") && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1103
1379
|
"button",
|
|
1104
1380
|
{
|
|
1105
1381
|
className: "vpg-toggle-btn",
|
|
@@ -1108,14 +1384,14 @@ function PivotConfig({
|
|
|
1108
1384
|
e.stopPropagation();
|
|
1109
1385
|
toggleRowColumn(field.field, field.assignedTo);
|
|
1110
1386
|
},
|
|
1111
|
-
children: /* @__PURE__ */ (0,
|
|
1387
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1112
1388
|
"svg",
|
|
1113
1389
|
{
|
|
1114
1390
|
className: "vpg-icon-xs",
|
|
1115
1391
|
fill: "none",
|
|
1116
1392
|
stroke: "currentColor",
|
|
1117
1393
|
viewBox: "0 0 24 24",
|
|
1118
|
-
children: /* @__PURE__ */ (0,
|
|
1394
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1119
1395
|
"path",
|
|
1120
1396
|
{
|
|
1121
1397
|
strokeLinecap: "round",
|
|
@@ -1128,7 +1404,7 @@ function PivotConfig({
|
|
|
1128
1404
|
)
|
|
1129
1405
|
}
|
|
1130
1406
|
),
|
|
1131
|
-
field.assignedTo === "value" && field.valueConfig && /* @__PURE__ */ (0,
|
|
1407
|
+
field.assignedTo === "value" && field.valueConfig && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1132
1408
|
"select",
|
|
1133
1409
|
{
|
|
1134
1410
|
className: "vpg-agg-select",
|
|
@@ -1142,14 +1418,14 @@ function PivotConfig({
|
|
|
1142
1418
|
);
|
|
1143
1419
|
},
|
|
1144
1420
|
onClick: (e) => e.stopPropagation(),
|
|
1145
|
-
children:
|
|
1421
|
+
children: import_tinypivot_core6.AGGREGATION_OPTIONS.map((agg) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("option", { value: agg.value, children: [
|
|
1146
1422
|
agg.symbol,
|
|
1147
1423
|
" ",
|
|
1148
1424
|
agg.label
|
|
1149
1425
|
] }, agg.value))
|
|
1150
1426
|
}
|
|
1151
1427
|
),
|
|
1152
|
-
/* @__PURE__ */ (0,
|
|
1428
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1153
1429
|
"button",
|
|
1154
1430
|
{
|
|
1155
1431
|
className: "vpg-remove-btn",
|
|
@@ -1167,13 +1443,13 @@ function PivotConfig({
|
|
|
1167
1443
|
field.field
|
|
1168
1444
|
)) })
|
|
1169
1445
|
] }),
|
|
1170
|
-
/* @__PURE__ */ (0,
|
|
1171
|
-
/* @__PURE__ */ (0,
|
|
1446
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-unassigned-section", children: [
|
|
1447
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "vpg-section-header", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-section-label", children: [
|
|
1172
1448
|
"Available ",
|
|
1173
|
-
/* @__PURE__ */ (0,
|
|
1449
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-count", children: unassignedFields.length })
|
|
1174
1450
|
] }) }),
|
|
1175
|
-
/* @__PURE__ */ (0,
|
|
1176
|
-
/* @__PURE__ */ (0,
|
|
1451
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-field-search", children: [
|
|
1452
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { className: "vpg-search-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1177
1453
|
"path",
|
|
1178
1454
|
{
|
|
1179
1455
|
strokeLinecap: "round",
|
|
@@ -1182,7 +1458,7 @@ function PivotConfig({
|
|
|
1182
1458
|
d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
|
|
1183
1459
|
}
|
|
1184
1460
|
) }),
|
|
1185
|
-
/* @__PURE__ */ (0,
|
|
1461
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1186
1462
|
"input",
|
|
1187
1463
|
{
|
|
1188
1464
|
type: "text",
|
|
@@ -1192,7 +1468,7 @@ function PivotConfig({
|
|
|
1192
1468
|
className: "vpg-search-input"
|
|
1193
1469
|
}
|
|
1194
1470
|
),
|
|
1195
|
-
fieldSearch && /* @__PURE__ */ (0,
|
|
1471
|
+
fieldSearch && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { className: "vpg-clear-search", onClick: () => setFieldSearch(""), children: /* @__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)(
|
|
1196
1472
|
"path",
|
|
1197
1473
|
{
|
|
1198
1474
|
strokeLinecap: "round",
|
|
@@ -1202,64 +1478,94 @@ function PivotConfig({
|
|
|
1202
1478
|
}
|
|
1203
1479
|
) }) })
|
|
1204
1480
|
] }),
|
|
1205
|
-
/* @__PURE__ */ (0,
|
|
1206
|
-
filteredUnassignedFields.map((field) => /* @__PURE__ */ (0,
|
|
1481
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-field-list", children: [
|
|
1482
|
+
filteredUnassignedFields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1207
1483
|
"div",
|
|
1208
1484
|
{
|
|
1209
|
-
className: `vpg-field-item
|
|
1210
|
-
title: field.field,
|
|
1485
|
+
className: `vpg-field-item${field.isNumeric && !field.isCalculated ? " vpg-is-numeric" : ""}${field.isCalculated ? " vpg-is-calculated" : ""}`,
|
|
1486
|
+
title: field.isCalculated ? field.calcFormula : field.field,
|
|
1211
1487
|
draggable: true,
|
|
1212
1488
|
onDragStart: (e) => handleDragStart(field.field, e),
|
|
1213
1489
|
onDragEnd,
|
|
1214
1490
|
children: [
|
|
1215
|
-
/* @__PURE__ */ (0,
|
|
1216
|
-
/* @__PURE__ */ (0,
|
|
1217
|
-
/* @__PURE__ */ (0,
|
|
1491
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: `vpg-field-type-icon${field.isCalculated ? " vpg-calc-type" : ""}`, title: field.type, children: getFieldIcon(field.type, field.isCalculated) }),
|
|
1492
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-field-name", children: getFieldDisplayName(field) }),
|
|
1493
|
+
field.isCalculated ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
1494
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1495
|
+
"button",
|
|
1496
|
+
{
|
|
1497
|
+
className: "vpg-field-edit",
|
|
1498
|
+
title: "Edit calculated field",
|
|
1499
|
+
onClick: (e) => {
|
|
1500
|
+
e.stopPropagation();
|
|
1501
|
+
const calcField = calculatedFields?.find((c) => c.id === field.calcId);
|
|
1502
|
+
if (calcField) openCalcModal(calcField);
|
|
1503
|
+
},
|
|
1504
|
+
children: "\u270E"
|
|
1505
|
+
}
|
|
1506
|
+
),
|
|
1507
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1508
|
+
"button",
|
|
1509
|
+
{
|
|
1510
|
+
className: "vpg-field-delete",
|
|
1511
|
+
title: "Delete calculated field",
|
|
1512
|
+
onClick: (e) => {
|
|
1513
|
+
e.stopPropagation();
|
|
1514
|
+
if (field.calcId && onRemoveCalculatedField) {
|
|
1515
|
+
onRemoveCalculatedField(field.calcId);
|
|
1516
|
+
}
|
|
1517
|
+
},
|
|
1518
|
+
children: "\xD7"
|
|
1519
|
+
}
|
|
1520
|
+
)
|
|
1521
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-unique-count", children: field.uniqueCount })
|
|
1218
1522
|
]
|
|
1219
1523
|
},
|
|
1220
1524
|
field.field
|
|
1221
1525
|
)),
|
|
1222
|
-
filteredUnassignedFields.length === 0 && fieldSearch && /* @__PURE__ */ (0,
|
|
1526
|
+
filteredUnassignedFields.length === 0 && fieldSearch && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-empty-hint", children: [
|
|
1223
1527
|
'No fields match "',
|
|
1224
1528
|
fieldSearch,
|
|
1225
1529
|
'"'
|
|
1226
1530
|
] }),
|
|
1227
|
-
unassignedFields.length === 0 && /* @__PURE__ */ (0,
|
|
1531
|
+
unassignedFields.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "vpg-empty-hint", children: "All fields assigned" })
|
|
1228
1532
|
] })
|
|
1229
1533
|
] }),
|
|
1230
|
-
/* @__PURE__ */ (0,
|
|
1231
|
-
/* @__PURE__ */ (0,
|
|
1232
|
-
/* @__PURE__ */ (0,
|
|
1534
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "vpg-options-section", children: [
|
|
1535
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "vpg-option-toggle", children: [
|
|
1536
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1233
1537
|
"input",
|
|
1234
1538
|
{
|
|
1235
1539
|
type: "checkbox",
|
|
1236
1540
|
checked: showRowTotals,
|
|
1237
|
-
onChange: (e) =>
|
|
1541
|
+
onChange: (e) => handleTotalsToggle(e.target.checked)
|
|
1238
1542
|
}
|
|
1239
1543
|
),
|
|
1240
|
-
/* @__PURE__ */ (0,
|
|
1544
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "Totals" })
|
|
1241
1545
|
] }),
|
|
1242
|
-
/* @__PURE__ */ (0,
|
|
1243
|
-
/* @__PURE__ */ (0,
|
|
1244
|
-
|
|
1245
|
-
{
|
|
1246
|
-
strokeLinecap: "round",
|
|
1247
|
-
strokeLinejoin: "round",
|
|
1248
|
-
strokeWidth: 2,
|
|
1249
|
-
d: "M13 10V3L4 14h7v7l9-11h-7z"
|
|
1250
|
-
}
|
|
1251
|
-
) }),
|
|
1252
|
-
"Auto"
|
|
1546
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("button", { className: "vpg-calc-btn", onClick: () => openCalcModal(), title: "Add calculated field (e.g. Profit Margin %)", children: [
|
|
1547
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "vpg-calc-icon", children: "\u0192" }),
|
|
1548
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "+ Calc" })
|
|
1253
1549
|
] })
|
|
1254
1550
|
] }),
|
|
1255
|
-
showWatermark && /* @__PURE__ */ (0,
|
|
1551
|
+
showWatermark && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "vpg-watermark", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: "TinyPivot" }) }),
|
|
1552
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1553
|
+
CalculatedFieldModal,
|
|
1554
|
+
{
|
|
1555
|
+
show: showCalcModal,
|
|
1556
|
+
availableFields: numericFieldNames,
|
|
1557
|
+
existingField: editingCalcField,
|
|
1558
|
+
onClose: handleCloseCalcModal,
|
|
1559
|
+
onSave: handleSaveCalcField
|
|
1560
|
+
}
|
|
1561
|
+
)
|
|
1256
1562
|
] });
|
|
1257
1563
|
}
|
|
1258
1564
|
|
|
1259
1565
|
// src/components/PivotSkeleton.tsx
|
|
1260
|
-
var
|
|
1261
|
-
var
|
|
1262
|
-
var
|
|
1566
|
+
var import_react8 = require("react");
|
|
1567
|
+
var import_tinypivot_core7 = require("@smallwebco/tinypivot-core");
|
|
1568
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1263
1569
|
function PivotSkeleton({
|
|
1264
1570
|
rowFields,
|
|
1265
1571
|
columnFields,
|
|
@@ -1281,12 +1587,12 @@ function PivotSkeleton({
|
|
|
1281
1587
|
onReorderColumnFields
|
|
1282
1588
|
}) {
|
|
1283
1589
|
const { showWatermark, canUsePivot, isDemo } = useLicense();
|
|
1284
|
-
const [dragOverArea, setDragOverArea] = (0,
|
|
1285
|
-
const [reorderDragSource, setReorderDragSource] = (0,
|
|
1286
|
-
const [reorderDropTarget, setReorderDropTarget] = (0,
|
|
1287
|
-
const [sortDirection, setSortDirection] = (0,
|
|
1288
|
-
const [sortTarget, setSortTarget] = (0,
|
|
1289
|
-
const toggleSort = (0,
|
|
1590
|
+
const [dragOverArea, setDragOverArea] = (0, import_react8.useState)(null);
|
|
1591
|
+
const [reorderDragSource, setReorderDragSource] = (0, import_react8.useState)(null);
|
|
1592
|
+
const [reorderDropTarget, setReorderDropTarget] = (0, import_react8.useState)(null);
|
|
1593
|
+
const [sortDirection, setSortDirection] = (0, import_react8.useState)("asc");
|
|
1594
|
+
const [sortTarget, setSortTarget] = (0, import_react8.useState)("row");
|
|
1595
|
+
const toggleSort = (0, import_react8.useCallback)((target = "row") => {
|
|
1290
1596
|
if (sortTarget === target) {
|
|
1291
1597
|
setSortDirection((prev) => prev === "asc" ? "desc" : "asc");
|
|
1292
1598
|
} else {
|
|
@@ -1294,7 +1600,7 @@ function PivotSkeleton({
|
|
|
1294
1600
|
setSortDirection("asc");
|
|
1295
1601
|
}
|
|
1296
1602
|
}, [sortTarget]);
|
|
1297
|
-
const sortedRowIndices = (0,
|
|
1603
|
+
const sortedRowIndices = (0, import_react8.useMemo)(() => {
|
|
1298
1604
|
if (!pivotResult) return [];
|
|
1299
1605
|
const indices = pivotResult.rowHeaders.map((_, i) => i);
|
|
1300
1606
|
const headers = pivotResult.rowHeaders;
|
|
@@ -1318,11 +1624,11 @@ function PivotSkeleton({
|
|
|
1318
1624
|
});
|
|
1319
1625
|
return indices;
|
|
1320
1626
|
}, [pivotResult, sortTarget, sortDirection]);
|
|
1321
|
-
const columnHeaderCells = (0,
|
|
1627
|
+
const columnHeaderCells = (0, import_react8.useMemo)(() => {
|
|
1322
1628
|
if (!pivotResult || pivotResult.headers.length === 0) {
|
|
1323
1629
|
return [
|
|
1324
1630
|
valueFields.map((vf) => ({
|
|
1325
|
-
label: `${vf.field} (${(0,
|
|
1631
|
+
label: `${vf.field} (${(0, import_tinypivot_core7.getAggregationLabel)(vf.aggregation)})`,
|
|
1326
1632
|
colspan: 1
|
|
1327
1633
|
}))
|
|
1328
1634
|
];
|
|
@@ -1346,12 +1652,12 @@ function PivotSkeleton({
|
|
|
1346
1652
|
return result;
|
|
1347
1653
|
}, [pivotResult, valueFields]);
|
|
1348
1654
|
const hasActiveFilters = activeFilters && activeFilters.length > 0;
|
|
1349
|
-
const filterSummary = (0,
|
|
1655
|
+
const filterSummary = (0, import_react8.useMemo)(() => {
|
|
1350
1656
|
if (!activeFilters || activeFilters.length === 0) return "";
|
|
1351
1657
|
return activeFilters.map((f) => f.column).join(", ");
|
|
1352
1658
|
}, [activeFilters]);
|
|
1353
|
-
const [showFilterTooltip, setShowFilterTooltip] = (0,
|
|
1354
|
-
const filterTooltipDetails = (0,
|
|
1659
|
+
const [showFilterTooltip, setShowFilterTooltip] = (0, import_react8.useState)(false);
|
|
1660
|
+
const filterTooltipDetails = (0, import_react8.useMemo)(() => {
|
|
1355
1661
|
if (!activeFilters || activeFilters.length === 0) return [];
|
|
1356
1662
|
return activeFilters.map((f) => {
|
|
1357
1663
|
const maxDisplay = 5;
|
|
@@ -1364,7 +1670,7 @@ function PivotSkeleton({
|
|
|
1364
1670
|
};
|
|
1365
1671
|
});
|
|
1366
1672
|
}, [activeFilters]);
|
|
1367
|
-
const handleDragOver = (0,
|
|
1673
|
+
const handleDragOver = (0, import_react8.useCallback)(
|
|
1368
1674
|
(area, event) => {
|
|
1369
1675
|
event.preventDefault();
|
|
1370
1676
|
event.dataTransfer.dropEffect = "move";
|
|
@@ -1372,10 +1678,10 @@ function PivotSkeleton({
|
|
|
1372
1678
|
},
|
|
1373
1679
|
[]
|
|
1374
1680
|
);
|
|
1375
|
-
const handleDragLeave = (0,
|
|
1681
|
+
const handleDragLeave = (0, import_react8.useCallback)(() => {
|
|
1376
1682
|
setDragOverArea(null);
|
|
1377
1683
|
}, []);
|
|
1378
|
-
const handleDrop = (0,
|
|
1684
|
+
const handleDrop = (0, import_react8.useCallback)(
|
|
1379
1685
|
(area, event) => {
|
|
1380
1686
|
event.preventDefault();
|
|
1381
1687
|
const field = event.dataTransfer?.getData("text/plain");
|
|
@@ -1402,7 +1708,7 @@ function PivotSkeleton({
|
|
|
1402
1708
|
},
|
|
1403
1709
|
[rowFields, columnFields, valueFields, onAddRowField, onRemoveRowField, onAddColumnField, onRemoveColumnField, onAddValueField, onRemoveValueField]
|
|
1404
1710
|
);
|
|
1405
|
-
const handleChipDragStart = (0,
|
|
1711
|
+
const handleChipDragStart = (0, import_react8.useCallback)(
|
|
1406
1712
|
(zone, index, event) => {
|
|
1407
1713
|
setReorderDragSource({ zone, index });
|
|
1408
1714
|
event.dataTransfer.effectAllowed = "move";
|
|
@@ -1413,11 +1719,11 @@ function PivotSkeleton({
|
|
|
1413
1719
|
},
|
|
1414
1720
|
[]
|
|
1415
1721
|
);
|
|
1416
|
-
const handleChipDragEnd = (0,
|
|
1722
|
+
const handleChipDragEnd = (0, import_react8.useCallback)(() => {
|
|
1417
1723
|
setReorderDragSource(null);
|
|
1418
1724
|
setReorderDropTarget(null);
|
|
1419
1725
|
}, []);
|
|
1420
|
-
const handleChipDragOver = (0,
|
|
1726
|
+
const handleChipDragOver = (0, import_react8.useCallback)(
|
|
1421
1727
|
(zone, index, event) => {
|
|
1422
1728
|
event.preventDefault();
|
|
1423
1729
|
if (reorderDragSource && reorderDragSource.zone === zone) {
|
|
@@ -1427,10 +1733,10 @@ function PivotSkeleton({
|
|
|
1427
1733
|
},
|
|
1428
1734
|
[reorderDragSource]
|
|
1429
1735
|
);
|
|
1430
|
-
const handleChipDragLeave = (0,
|
|
1736
|
+
const handleChipDragLeave = (0, import_react8.useCallback)(() => {
|
|
1431
1737
|
setReorderDropTarget(null);
|
|
1432
1738
|
}, []);
|
|
1433
|
-
const handleChipDrop = (0,
|
|
1739
|
+
const handleChipDrop = (0, import_react8.useCallback)(
|
|
1434
1740
|
(zone, targetIndex, event) => {
|
|
1435
1741
|
event.preventDefault();
|
|
1436
1742
|
event.stopPropagation();
|
|
@@ -1456,27 +1762,27 @@ function PivotSkeleton({
|
|
|
1456
1762
|
},
|
|
1457
1763
|
[reorderDragSource, rowFields, columnFields, onReorderRowFields, onReorderColumnFields]
|
|
1458
1764
|
);
|
|
1459
|
-
const isChipDragSource = (0,
|
|
1765
|
+
const isChipDragSource = (0, import_react8.useCallback)(
|
|
1460
1766
|
(zone, index) => {
|
|
1461
1767
|
return reorderDragSource?.zone === zone && reorderDragSource?.index === index;
|
|
1462
1768
|
},
|
|
1463
1769
|
[reorderDragSource]
|
|
1464
1770
|
);
|
|
1465
|
-
const isChipDropTarget = (0,
|
|
1771
|
+
const isChipDropTarget = (0, import_react8.useCallback)(
|
|
1466
1772
|
(zone, index) => {
|
|
1467
1773
|
return reorderDropTarget?.zone === zone && reorderDropTarget?.index === index;
|
|
1468
1774
|
},
|
|
1469
1775
|
[reorderDropTarget]
|
|
1470
1776
|
);
|
|
1471
1777
|
const currentFontSize = fontSize;
|
|
1472
|
-
return /* @__PURE__ */ (0,
|
|
1778
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1473
1779
|
"div",
|
|
1474
1780
|
{
|
|
1475
1781
|
className: `vpg-pivot-skeleton vpg-font-${currentFontSize} ${draggingField ? "vpg-is-dragging" : ""}`,
|
|
1476
1782
|
children: [
|
|
1477
|
-
/* @__PURE__ */ (0,
|
|
1478
|
-
/* @__PURE__ */ (0,
|
|
1479
|
-
/* @__PURE__ */ (0,
|
|
1783
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-skeleton-header", children: [
|
|
1784
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-skeleton-title", children: [
|
|
1785
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1480
1786
|
"path",
|
|
1481
1787
|
{
|
|
1482
1788
|
strokeLinecap: "round",
|
|
@@ -1485,24 +1791,24 @@ function PivotSkeleton({
|
|
|
1485
1791
|
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"
|
|
1486
1792
|
}
|
|
1487
1793
|
) }),
|
|
1488
|
-
/* @__PURE__ */ (0,
|
|
1794
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Pivot Table" })
|
|
1489
1795
|
] }),
|
|
1490
|
-
/* @__PURE__ */ (0,
|
|
1491
|
-
hasActiveFilters && /* @__PURE__ */ (0,
|
|
1796
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-header-right", children: [
|
|
1797
|
+
hasActiveFilters && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1492
1798
|
"div",
|
|
1493
1799
|
{
|
|
1494
1800
|
className: "vpg-filter-indicator",
|
|
1495
1801
|
onMouseEnter: () => setShowFilterTooltip(true),
|
|
1496
1802
|
onMouseLeave: () => setShowFilterTooltip(false),
|
|
1497
1803
|
children: [
|
|
1498
|
-
/* @__PURE__ */ (0,
|
|
1804
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1499
1805
|
"svg",
|
|
1500
1806
|
{
|
|
1501
1807
|
className: "vpg-filter-icon",
|
|
1502
1808
|
fill: "none",
|
|
1503
1809
|
stroke: "currentColor",
|
|
1504
1810
|
viewBox: "0 0 24 24",
|
|
1505
|
-
children: /* @__PURE__ */ (0,
|
|
1811
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1506
1812
|
"path",
|
|
1507
1813
|
{
|
|
1508
1814
|
strokeLinecap: "round",
|
|
@@ -1513,10 +1819,10 @@ function PivotSkeleton({
|
|
|
1513
1819
|
)
|
|
1514
1820
|
}
|
|
1515
1821
|
),
|
|
1516
|
-
/* @__PURE__ */ (0,
|
|
1822
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "vpg-filter-text", children: [
|
|
1517
1823
|
"Filtered: ",
|
|
1518
|
-
/* @__PURE__ */ (0,
|
|
1519
|
-
filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ (0,
|
|
1824
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { children: filterSummary }),
|
|
1825
|
+
filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "vpg-filter-count", children: [
|
|
1520
1826
|
"(",
|
|
1521
1827
|
filteredRowCount.toLocaleString(),
|
|
1522
1828
|
" of ",
|
|
@@ -1524,20 +1830,20 @@ function PivotSkeleton({
|
|
|
1524
1830
|
" rows)"
|
|
1525
1831
|
] })
|
|
1526
1832
|
] }),
|
|
1527
|
-
showFilterTooltip && /* @__PURE__ */ (0,
|
|
1528
|
-
/* @__PURE__ */ (0,
|
|
1529
|
-
filterTooltipDetails.map((filter) => /* @__PURE__ */ (0,
|
|
1530
|
-
/* @__PURE__ */ (0,
|
|
1531
|
-
/* @__PURE__ */ (0,
|
|
1532
|
-
filter.values.map((val, idx) => /* @__PURE__ */ (0,
|
|
1533
|
-
filter.remaining > 0 && /* @__PURE__ */ (0,
|
|
1833
|
+
showFilterTooltip && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-filter-tooltip", children: [
|
|
1834
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "vpg-tooltip-header", children: "Active Filters" }),
|
|
1835
|
+
filterTooltipDetails.map((filter) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-tooltip-filter", children: [
|
|
1836
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "vpg-tooltip-column", children: filter.column }),
|
|
1837
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-tooltip-values", children: [
|
|
1838
|
+
filter.values.map((val, idx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-tooltip-value", children: val }, idx)),
|
|
1839
|
+
filter.remaining > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "vpg-tooltip-more", children: [
|
|
1534
1840
|
"+",
|
|
1535
1841
|
filter.remaining,
|
|
1536
1842
|
" more"
|
|
1537
1843
|
] })
|
|
1538
1844
|
] })
|
|
1539
1845
|
] }, filter.column)),
|
|
1540
|
-
filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ (0,
|
|
1846
|
+
filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-tooltip-summary", children: [
|
|
1541
1847
|
"Showing ",
|
|
1542
1848
|
filteredRowCount.toLocaleString(),
|
|
1543
1849
|
" of ",
|
|
@@ -1548,18 +1854,18 @@ function PivotSkeleton({
|
|
|
1548
1854
|
]
|
|
1549
1855
|
}
|
|
1550
1856
|
),
|
|
1551
|
-
isConfigured && /* @__PURE__ */ (0,
|
|
1552
|
-
/* @__PURE__ */ (0,
|
|
1857
|
+
isConfigured && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-config-summary", children: [
|
|
1858
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "vpg-summary-badge vpg-rows", children: [
|
|
1553
1859
|
rowFields.length,
|
|
1554
1860
|
" row",
|
|
1555
1861
|
rowFields.length !== 1 ? "s" : ""
|
|
1556
1862
|
] }),
|
|
1557
|
-
/* @__PURE__ */ (0,
|
|
1863
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "vpg-summary-badge vpg-cols", children: [
|
|
1558
1864
|
columnFields.length,
|
|
1559
1865
|
" col",
|
|
1560
1866
|
columnFields.length !== 1 ? "s" : ""
|
|
1561
1867
|
] }),
|
|
1562
|
-
/* @__PURE__ */ (0,
|
|
1868
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "vpg-summary-badge vpg-vals", children: [
|
|
1563
1869
|
valueFields.length,
|
|
1564
1870
|
" val",
|
|
1565
1871
|
valueFields.length !== 1 ? "s" : ""
|
|
@@ -1567,8 +1873,8 @@ function PivotSkeleton({
|
|
|
1567
1873
|
] })
|
|
1568
1874
|
] })
|
|
1569
1875
|
] }),
|
|
1570
|
-
!canUsePivot ? /* @__PURE__ */ (0,
|
|
1571
|
-
/* @__PURE__ */ (0,
|
|
1876
|
+
!canUsePivot ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "vpg-pro-required", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-pro-content", children: [
|
|
1877
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-pro-icon", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1572
1878
|
"path",
|
|
1573
1879
|
{
|
|
1574
1880
|
strokeLinecap: "round",
|
|
@@ -1577,12 +1883,12 @@ function PivotSkeleton({
|
|
|
1577
1883
|
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"
|
|
1578
1884
|
}
|
|
1579
1885
|
) }),
|
|
1580
|
-
/* @__PURE__ */ (0,
|
|
1581
|
-
/* @__PURE__ */ (0,
|
|
1582
|
-
/* @__PURE__ */ (0,
|
|
1583
|
-
] }) }) : /* @__PURE__ */ (0,
|
|
1584
|
-
/* @__PURE__ */ (0,
|
|
1585
|
-
/* @__PURE__ */ (0,
|
|
1886
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { children: "Pro Feature" }),
|
|
1887
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { children: "Pivot Table functionality requires a Pro license." }),
|
|
1888
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("a", { href: "https://tiny-pivot.com/#pricing", target: "_blank", rel: "noopener noreferrer", className: "vpg-pro-link", children: "Get Pro License \u2192" })
|
|
1889
|
+
] }) }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
1890
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-config-bar", children: [
|
|
1891
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1586
1892
|
"div",
|
|
1587
1893
|
{
|
|
1588
1894
|
className: `vpg-drop-zone vpg-row-zone ${dragOverArea === "row" ? "vpg-drag-over" : ""}`,
|
|
@@ -1590,12 +1896,12 @@ function PivotSkeleton({
|
|
|
1590
1896
|
onDragLeave: handleDragLeave,
|
|
1591
1897
|
onDrop: (e) => handleDrop("row", e),
|
|
1592
1898
|
children: [
|
|
1593
|
-
/* @__PURE__ */ (0,
|
|
1594
|
-
/* @__PURE__ */ (0,
|
|
1595
|
-
/* @__PURE__ */ (0,
|
|
1899
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-zone-header", children: [
|
|
1900
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-zone-icon vpg-row-icon", children: "\u2193" }),
|
|
1901
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-zone-label", children: "Rows" })
|
|
1596
1902
|
] }),
|
|
1597
|
-
/* @__PURE__ */ (0,
|
|
1598
|
-
rowFields.map((field, idx) => /* @__PURE__ */ (0,
|
|
1903
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-zone-chips", children: [
|
|
1904
|
+
rowFields.map((field, idx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1599
1905
|
"div",
|
|
1600
1906
|
{
|
|
1601
1907
|
className: `vpg-mini-chip vpg-row-chip ${isChipDragSource("row", idx) ? "vpg-chip-dragging" : ""} ${isChipDropTarget("row", idx) ? "vpg-chip-drop-target" : ""}`,
|
|
@@ -1606,9 +1912,9 @@ function PivotSkeleton({
|
|
|
1606
1912
|
onDragLeave: handleChipDragLeave,
|
|
1607
1913
|
onDrop: (e) => handleChipDrop("row", idx, e),
|
|
1608
1914
|
children: [
|
|
1609
|
-
/* @__PURE__ */ (0,
|
|
1610
|
-
/* @__PURE__ */ (0,
|
|
1611
|
-
/* @__PURE__ */ (0,
|
|
1915
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-drag-handle", children: "\u22EE\u22EE" }),
|
|
1916
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-mini-name", children: field }),
|
|
1917
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1612
1918
|
"button",
|
|
1613
1919
|
{
|
|
1614
1920
|
className: "vpg-mini-remove",
|
|
@@ -1623,12 +1929,12 @@ function PivotSkeleton({
|
|
|
1623
1929
|
},
|
|
1624
1930
|
field
|
|
1625
1931
|
)),
|
|
1626
|
-
rowFields.length === 0 && /* @__PURE__ */ (0,
|
|
1932
|
+
rowFields.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-zone-hint", children: "Drop here" })
|
|
1627
1933
|
] })
|
|
1628
1934
|
]
|
|
1629
1935
|
}
|
|
1630
1936
|
),
|
|
1631
|
-
/* @__PURE__ */ (0,
|
|
1937
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1632
1938
|
"div",
|
|
1633
1939
|
{
|
|
1634
1940
|
className: `vpg-drop-zone vpg-column-zone ${dragOverArea === "column" ? "vpg-drag-over" : ""}`,
|
|
@@ -1636,12 +1942,12 @@ function PivotSkeleton({
|
|
|
1636
1942
|
onDragLeave: handleDragLeave,
|
|
1637
1943
|
onDrop: (e) => handleDrop("column", e),
|
|
1638
1944
|
children: [
|
|
1639
|
-
/* @__PURE__ */ (0,
|
|
1640
|
-
/* @__PURE__ */ (0,
|
|
1641
|
-
/* @__PURE__ */ (0,
|
|
1945
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-zone-header", children: [
|
|
1946
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-zone-icon vpg-column-icon", children: "\u2192" }),
|
|
1947
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-zone-label", children: "Columns" })
|
|
1642
1948
|
] }),
|
|
1643
|
-
/* @__PURE__ */ (0,
|
|
1644
|
-
columnFields.map((field, idx) => /* @__PURE__ */ (0,
|
|
1949
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-zone-chips", children: [
|
|
1950
|
+
columnFields.map((field, idx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1645
1951
|
"div",
|
|
1646
1952
|
{
|
|
1647
1953
|
className: `vpg-mini-chip vpg-column-chip ${isChipDragSource("column", idx) ? "vpg-chip-dragging" : ""} ${isChipDropTarget("column", idx) ? "vpg-chip-drop-target" : ""}`,
|
|
@@ -1652,9 +1958,9 @@ function PivotSkeleton({
|
|
|
1652
1958
|
onDragLeave: handleChipDragLeave,
|
|
1653
1959
|
onDrop: (e) => handleChipDrop("column", idx, e),
|
|
1654
1960
|
children: [
|
|
1655
|
-
/* @__PURE__ */ (0,
|
|
1656
|
-
/* @__PURE__ */ (0,
|
|
1657
|
-
/* @__PURE__ */ (0,
|
|
1961
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-drag-handle", children: "\u22EE\u22EE" }),
|
|
1962
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-mini-name", children: field }),
|
|
1963
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1658
1964
|
"button",
|
|
1659
1965
|
{
|
|
1660
1966
|
className: "vpg-mini-remove",
|
|
@@ -1669,12 +1975,12 @@ function PivotSkeleton({
|
|
|
1669
1975
|
},
|
|
1670
1976
|
field
|
|
1671
1977
|
)),
|
|
1672
|
-
columnFields.length === 0 && /* @__PURE__ */ (0,
|
|
1978
|
+
columnFields.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-zone-hint", children: "Drop here" })
|
|
1673
1979
|
] })
|
|
1674
1980
|
]
|
|
1675
1981
|
}
|
|
1676
1982
|
),
|
|
1677
|
-
/* @__PURE__ */ (0,
|
|
1983
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1678
1984
|
"div",
|
|
1679
1985
|
{
|
|
1680
1986
|
className: `vpg-drop-zone vpg-value-zone ${dragOverArea === "value" ? "vpg-drag-over" : ""}`,
|
|
@@ -1682,19 +1988,19 @@ function PivotSkeleton({
|
|
|
1682
1988
|
onDragLeave: handleDragLeave,
|
|
1683
1989
|
onDrop: (e) => handleDrop("value", e),
|
|
1684
1990
|
children: [
|
|
1685
|
-
/* @__PURE__ */ (0,
|
|
1686
|
-
/* @__PURE__ */ (0,
|
|
1687
|
-
/* @__PURE__ */ (0,
|
|
1991
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-zone-header", children: [
|
|
1992
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-zone-icon vpg-value-icon", children: "\u03A3" }),
|
|
1993
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-zone-label", children: "Values" })
|
|
1688
1994
|
] }),
|
|
1689
|
-
/* @__PURE__ */ (0,
|
|
1690
|
-
valueFields.map((vf) => /* @__PURE__ */ (0,
|
|
1995
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-zone-chips", children: [
|
|
1996
|
+
valueFields.map((vf) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1691
1997
|
"div",
|
|
1692
1998
|
{
|
|
1693
1999
|
className: "vpg-mini-chip vpg-value-chip",
|
|
1694
2000
|
children: [
|
|
1695
|
-
/* @__PURE__ */ (0,
|
|
1696
|
-
/* @__PURE__ */ (0,
|
|
1697
|
-
/* @__PURE__ */ (0,
|
|
2001
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-agg-symbol", children: (0, import_tinypivot_core7.getAggregationSymbol)(vf.aggregation) }),
|
|
2002
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-mini-name", children: vf.field }),
|
|
2003
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1698
2004
|
"button",
|
|
1699
2005
|
{
|
|
1700
2006
|
className: "vpg-mini-remove",
|
|
@@ -1706,21 +2012,21 @@ function PivotSkeleton({
|
|
|
1706
2012
|
},
|
|
1707
2013
|
`${vf.field}-${vf.aggregation}`
|
|
1708
2014
|
)),
|
|
1709
|
-
valueFields.length === 0 && /* @__PURE__ */ (0,
|
|
2015
|
+
valueFields.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-zone-hint", children: "Drop numeric" })
|
|
1710
2016
|
] })
|
|
1711
2017
|
]
|
|
1712
2018
|
}
|
|
1713
2019
|
)
|
|
1714
2020
|
] }),
|
|
1715
|
-
(!isConfigured || !pivotResult) && /* @__PURE__ */ (0,
|
|
1716
|
-
/* @__PURE__ */ (0,
|
|
2021
|
+
(!isConfigured || !pivotResult) && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "vpg-placeholder", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-placeholder-content", children: [
|
|
2022
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1717
2023
|
"svg",
|
|
1718
2024
|
{
|
|
1719
2025
|
className: "vpg-placeholder-icon",
|
|
1720
2026
|
fill: "none",
|
|
1721
2027
|
viewBox: "0 0 24 24",
|
|
1722
2028
|
stroke: "currentColor",
|
|
1723
|
-
children: /* @__PURE__ */ (0,
|
|
2029
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1724
2030
|
"path",
|
|
1725
2031
|
{
|
|
1726
2032
|
strokeLinecap: "round",
|
|
@@ -1731,51 +2037,51 @@ function PivotSkeleton({
|
|
|
1731
2037
|
)
|
|
1732
2038
|
}
|
|
1733
2039
|
),
|
|
1734
|
-
/* @__PURE__ */ (0,
|
|
2040
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-placeholder-text", children: valueFields.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
1735
2041
|
"Add a ",
|
|
1736
|
-
/* @__PURE__ */ (0,
|
|
2042
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { children: "Values" }),
|
|
1737
2043
|
" field to see your pivot table"
|
|
1738
|
-
] }) : rowFields.length === 0 && columnFields.length === 0 ? /* @__PURE__ */ (0,
|
|
2044
|
+
] }) : rowFields.length === 0 && columnFields.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
1739
2045
|
"Add ",
|
|
1740
|
-
/* @__PURE__ */ (0,
|
|
2046
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { children: "Row" }),
|
|
1741
2047
|
" or ",
|
|
1742
|
-
/* @__PURE__ */ (0,
|
|
2048
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { children: "Column" }),
|
|
1743
2049
|
" fields to group your data"
|
|
1744
2050
|
] }) : "Your pivot table will appear here" })
|
|
1745
2051
|
] }) }),
|
|
1746
|
-
isConfigured && pivotResult && /* @__PURE__ */ (0,
|
|
1747
|
-
/* @__PURE__ */ (0,
|
|
1748
|
-
levelIdx === 0 && /* @__PURE__ */ (0,
|
|
2052
|
+
isConfigured && pivotResult && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "vpg-table-container", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("table", { className: "vpg-pivot-table", children: [
|
|
2053
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("thead", { children: columnHeaderCells.map((headerRow, levelIdx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("tr", { className: "vpg-column-header-row", children: [
|
|
2054
|
+
levelIdx === 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1749
2055
|
"th",
|
|
1750
2056
|
{
|
|
1751
2057
|
className: "vpg-row-header-label",
|
|
1752
2058
|
rowSpan: columnHeaderCells.length,
|
|
1753
2059
|
onClick: () => toggleSort("row"),
|
|
1754
|
-
children: /* @__PURE__ */ (0,
|
|
1755
|
-
/* @__PURE__ */ (0,
|
|
1756
|
-
/* @__PURE__ */ (0,
|
|
2060
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-header-content", children: [
|
|
2061
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: rowFields.join(" / ") || "Rows" }),
|
|
2062
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: `vpg-sort-indicator ${sortTarget === "row" ? "active" : ""}`, children: sortTarget === "row" ? sortDirection === "asc" ? "\u2191" : "\u2193" : "\u21C5" })
|
|
1757
2063
|
] })
|
|
1758
2064
|
}
|
|
1759
2065
|
),
|
|
1760
|
-
headerRow.map((cell, idx) => /* @__PURE__ */ (0,
|
|
2066
|
+
headerRow.map((cell, idx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1761
2067
|
"th",
|
|
1762
2068
|
{
|
|
1763
2069
|
className: "vpg-column-header-cell",
|
|
1764
2070
|
colSpan: cell.colspan,
|
|
1765
2071
|
onClick: () => levelIdx === columnHeaderCells.length - 1 && toggleSort(idx),
|
|
1766
|
-
children: /* @__PURE__ */ (0,
|
|
1767
|
-
/* @__PURE__ */ (0,
|
|
1768
|
-
levelIdx === columnHeaderCells.length - 1 && /* @__PURE__ */ (0,
|
|
2072
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-header-content", children: [
|
|
2073
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: cell.label }),
|
|
2074
|
+
levelIdx === columnHeaderCells.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: `vpg-sort-indicator ${sortTarget === idx ? "active" : ""}`, children: sortTarget === idx ? sortDirection === "asc" ? "\u2191" : "\u2193" : "\u21C5" })
|
|
1769
2075
|
] })
|
|
1770
2076
|
},
|
|
1771
2077
|
idx
|
|
1772
2078
|
)),
|
|
1773
|
-
pivotResult.rowTotals.length > 0 && levelIdx === 0 && /* @__PURE__ */ (0,
|
|
2079
|
+
pivotResult.rowTotals.length > 0 && levelIdx === 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("th", { className: "vpg-total-header", rowSpan: columnHeaderCells.length, children: "Total" })
|
|
1774
2080
|
] }, `header-${levelIdx}`)) }),
|
|
1775
|
-
/* @__PURE__ */ (0,
|
|
1776
|
-
sortedRowIndices.map((sortedIdx) => /* @__PURE__ */ (0,
|
|
1777
|
-
/* @__PURE__ */ (0,
|
|
1778
|
-
pivotResult.data[sortedIdx].map((cell, colIdx) => /* @__PURE__ */ (0,
|
|
2081
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("tbody", { children: [
|
|
2082
|
+
sortedRowIndices.map((sortedIdx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("tr", { className: "vpg-data-row", children: [
|
|
2083
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("th", { className: "vpg-row-header-cell", children: pivotResult.rowHeaders[sortedIdx].map((val, idx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-row-value", children: val }, idx)) }),
|
|
2084
|
+
pivotResult.data[sortedIdx].map((cell, colIdx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1779
2085
|
"td",
|
|
1780
2086
|
{
|
|
1781
2087
|
className: `vpg-data-cell ${cell.value === null ? "vpg-is-null" : ""}`,
|
|
@@ -1783,26 +2089,26 @@ function PivotSkeleton({
|
|
|
1783
2089
|
},
|
|
1784
2090
|
colIdx
|
|
1785
2091
|
)),
|
|
1786
|
-
pivotResult.rowTotals[sortedIdx] && /* @__PURE__ */ (0,
|
|
2092
|
+
pivotResult.rowTotals[sortedIdx] && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("td", { className: "vpg-data-cell vpg-total-cell", children: pivotResult.rowTotals[sortedIdx].formattedValue })
|
|
1787
2093
|
] }, sortedIdx)),
|
|
1788
|
-
pivotResult.columnTotals.length > 0 && /* @__PURE__ */ (0,
|
|
1789
|
-
/* @__PURE__ */ (0,
|
|
1790
|
-
pivotResult.columnTotals.map((cell, colIdx) => /* @__PURE__ */ (0,
|
|
1791
|
-
pivotResult.rowTotals.length > 0 && /* @__PURE__ */ (0,
|
|
2094
|
+
pivotResult.columnTotals.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("tr", { className: "vpg-totals-row", children: [
|
|
2095
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("th", { className: "vpg-row-header-cell vpg-total-label", children: "Total" }),
|
|
2096
|
+
pivotResult.columnTotals.map((cell, colIdx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("td", { className: "vpg-data-cell vpg-total-cell", children: cell.formattedValue }, colIdx)),
|
|
2097
|
+
pivotResult.rowTotals.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("td", { className: "vpg-data-cell vpg-grand-total-cell", children: pivotResult.grandTotal.formattedValue })
|
|
1792
2098
|
] })
|
|
1793
2099
|
] })
|
|
1794
2100
|
] }) }),
|
|
1795
|
-
isConfigured && pivotResult && /* @__PURE__ */ (0,
|
|
2101
|
+
isConfigured && pivotResult && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "vpg-skeleton-footer", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { children: [
|
|
1796
2102
|
pivotResult.rowHeaders.length,
|
|
1797
2103
|
" rows \xD7 ",
|
|
1798
2104
|
pivotResult.data[0]?.length || 0,
|
|
1799
2105
|
" columns"
|
|
1800
2106
|
] }) })
|
|
1801
2107
|
] }),
|
|
1802
|
-
showWatermark && canUsePivot && /* @__PURE__ */ (0,
|
|
1803
|
-
/* @__PURE__ */ (0,
|
|
1804
|
-
/* @__PURE__ */ (0,
|
|
1805
|
-
/* @__PURE__ */ (0,
|
|
2108
|
+
showWatermark && canUsePivot && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: `vpg-watermark ${isDemo ? "vpg-demo-mode" : ""}`, children: isDemo ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
2109
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-demo-badge", children: "DEMO" }),
|
|
2110
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Pro features unlocked for evaluation" }),
|
|
2111
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1806
2112
|
"a",
|
|
1807
2113
|
{
|
|
1808
2114
|
href: "https://tiny-pivot.com/#pricing",
|
|
@@ -1812,14 +2118,14 @@ function PivotSkeleton({
|
|
|
1812
2118
|
children: "Get Pro License \u2192"
|
|
1813
2119
|
}
|
|
1814
2120
|
)
|
|
1815
|
-
] }) : /* @__PURE__ */ (0,
|
|
2121
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: "Powered by TinyPivot" }) })
|
|
1816
2122
|
]
|
|
1817
2123
|
}
|
|
1818
2124
|
);
|
|
1819
2125
|
}
|
|
1820
2126
|
|
|
1821
2127
|
// src/components/DataGrid.tsx
|
|
1822
|
-
var
|
|
2128
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1823
2129
|
var MIN_COL_WIDTH = 120;
|
|
1824
2130
|
var MAX_COL_WIDTH = 350;
|
|
1825
2131
|
function DataGrid({
|
|
@@ -1845,37 +2151,37 @@ function DataGrid({
|
|
|
1845
2151
|
onCopy
|
|
1846
2152
|
}) {
|
|
1847
2153
|
const { showWatermark, canUsePivot, isDemo } = useLicense();
|
|
1848
|
-
const currentTheme = (0,
|
|
2154
|
+
const currentTheme = (0, import_react9.useMemo)(() => {
|
|
1849
2155
|
if (theme === "auto") {
|
|
1850
2156
|
return window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
1851
2157
|
}
|
|
1852
2158
|
return theme;
|
|
1853
2159
|
}, [theme]);
|
|
1854
|
-
const [currentFontSize, setCurrentFontSize] = (0,
|
|
1855
|
-
const [globalSearchTerm, setGlobalSearchTerm] = (0,
|
|
1856
|
-
const [showSearchInput, setShowSearchInput] = (0,
|
|
1857
|
-
const [currentPage, setCurrentPage] = (0,
|
|
1858
|
-
const [columnWidths, setColumnWidths] = (0,
|
|
1859
|
-
const [resizingColumnId, setResizingColumnId] = (0,
|
|
1860
|
-
const [resizeStartX, setResizeStartX] = (0,
|
|
1861
|
-
const [resizeStartWidth, setResizeStartWidth] = (0,
|
|
1862
|
-
const [gridHeight, setGridHeight] = (0,
|
|
1863
|
-
const [isResizingVertically, setIsResizingVertically] = (0,
|
|
1864
|
-
const [verticalResizeStartY, setVerticalResizeStartY] = (0,
|
|
1865
|
-
const [verticalResizeStartHeight, setVerticalResizeStartHeight] = (0,
|
|
1866
|
-
const [showCopyToast, setShowCopyToast] = (0,
|
|
1867
|
-
const [copyToastMessage, setCopyToastMessage] = (0,
|
|
1868
|
-
const [viewMode, setViewMode] = (0,
|
|
1869
|
-
const [showPivotConfig, setShowPivotConfig] = (0,
|
|
1870
|
-
const [draggingField, setDraggingField] = (0,
|
|
1871
|
-
const [activeFilterColumn, setActiveFilterColumn] = (0,
|
|
1872
|
-
const [filterDropdownPosition, setFilterDropdownPosition] = (0,
|
|
1873
|
-
const [selectedCell, setSelectedCell] = (0,
|
|
1874
|
-
const [selectionStart, setSelectionStart] = (0,
|
|
1875
|
-
const [selectionEnd, setSelectionEnd] = (0,
|
|
1876
|
-
const [isSelecting, setIsSelecting] = (0,
|
|
1877
|
-
const tableContainerRef = (0,
|
|
1878
|
-
const tableBodyRef = (0,
|
|
2160
|
+
const [currentFontSize, setCurrentFontSize] = (0, import_react9.useState)(initialFontSize);
|
|
2161
|
+
const [globalSearchTerm, setGlobalSearchTerm] = (0, import_react9.useState)("");
|
|
2162
|
+
const [showSearchInput, setShowSearchInput] = (0, import_react9.useState)(false);
|
|
2163
|
+
const [currentPage, setCurrentPage] = (0, import_react9.useState)(1);
|
|
2164
|
+
const [columnWidths, setColumnWidths] = (0, import_react9.useState)({});
|
|
2165
|
+
const [resizingColumnId, setResizingColumnId] = (0, import_react9.useState)(null);
|
|
2166
|
+
const [resizeStartX, setResizeStartX] = (0, import_react9.useState)(0);
|
|
2167
|
+
const [resizeStartWidth, setResizeStartWidth] = (0, import_react9.useState)(0);
|
|
2168
|
+
const [gridHeight, setGridHeight] = (0, import_react9.useState)(initialHeight);
|
|
2169
|
+
const [isResizingVertically, setIsResizingVertically] = (0, import_react9.useState)(false);
|
|
2170
|
+
const [verticalResizeStartY, setVerticalResizeStartY] = (0, import_react9.useState)(0);
|
|
2171
|
+
const [verticalResizeStartHeight, setVerticalResizeStartHeight] = (0, import_react9.useState)(0);
|
|
2172
|
+
const [showCopyToast, setShowCopyToast] = (0, import_react9.useState)(false);
|
|
2173
|
+
const [copyToastMessage, setCopyToastMessage] = (0, import_react9.useState)("");
|
|
2174
|
+
const [viewMode, setViewMode] = (0, import_react9.useState)("grid");
|
|
2175
|
+
const [showPivotConfig, setShowPivotConfig] = (0, import_react9.useState)(true);
|
|
2176
|
+
const [draggingField, setDraggingField] = (0, import_react9.useState)(null);
|
|
2177
|
+
const [activeFilterColumn, setActiveFilterColumn] = (0, import_react9.useState)(null);
|
|
2178
|
+
const [filterDropdownPosition, setFilterDropdownPosition] = (0, import_react9.useState)({ top: 0, left: 0, maxHeight: 400 });
|
|
2179
|
+
const [selectedCell, setSelectedCell] = (0, import_react9.useState)(null);
|
|
2180
|
+
const [selectionStart, setSelectionStart] = (0, import_react9.useState)(null);
|
|
2181
|
+
const [selectionEnd, setSelectionEnd] = (0, import_react9.useState)(null);
|
|
2182
|
+
const [isSelecting, setIsSelecting] = (0, import_react9.useState)(false);
|
|
2183
|
+
const tableContainerRef = (0, import_react9.useRef)(null);
|
|
2184
|
+
const tableBodyRef = (0, import_react9.useRef)(null);
|
|
1879
2185
|
const fontSizeOptions = [
|
|
1880
2186
|
{ value: "xs", label: "S" },
|
|
1881
2187
|
{ value: "sm", label: "M" },
|
|
@@ -1896,7 +2202,7 @@ function DataGrid({
|
|
|
1896
2202
|
columnFilters,
|
|
1897
2203
|
activeFilters
|
|
1898
2204
|
} = useExcelGrid({ data, enableSorting: true, enableFiltering: true });
|
|
1899
|
-
const filteredDataForPivot = (0,
|
|
2205
|
+
const filteredDataForPivot = (0, import_react9.useMemo)(() => {
|
|
1900
2206
|
const filteredRows = table.getFilteredRowModel().rows;
|
|
1901
2207
|
return filteredRows.map((row) => row.original);
|
|
1902
2208
|
}, [table, columnFilters]);
|
|
@@ -1923,7 +2229,7 @@ function DataGrid({
|
|
|
1923
2229
|
setRowFields,
|
|
1924
2230
|
setColumnFields
|
|
1925
2231
|
} = usePivotTable(filteredDataForPivot);
|
|
1926
|
-
const activeFilterInfo = (0,
|
|
2232
|
+
const activeFilterInfo = (0, import_react9.useMemo)(() => {
|
|
1927
2233
|
if (activeFilters.length === 0) return null;
|
|
1928
2234
|
return activeFilters.map((f) => ({
|
|
1929
2235
|
column: f.column,
|
|
@@ -1931,8 +2237,8 @@ function DataGrid({
|
|
|
1931
2237
|
values: f.values || []
|
|
1932
2238
|
}));
|
|
1933
2239
|
}, [activeFilters]);
|
|
1934
|
-
const rows = (0,
|
|
1935
|
-
const searchFilteredData = (0,
|
|
2240
|
+
const rows = (0, import_react9.useMemo)(() => table.getFilteredRowModel().rows, [table, columnFilters]);
|
|
2241
|
+
const searchFilteredData = (0, import_react9.useMemo)(() => {
|
|
1936
2242
|
if (!globalSearchTerm.trim() || !enableSearch) {
|
|
1937
2243
|
return rows;
|
|
1938
2244
|
}
|
|
@@ -1949,20 +2255,20 @@ function DataGrid({
|
|
|
1949
2255
|
});
|
|
1950
2256
|
}, [rows, globalSearchTerm, enableSearch, columnKeys]);
|
|
1951
2257
|
const totalSearchedRows = searchFilteredData.length;
|
|
1952
|
-
const totalPages = (0,
|
|
2258
|
+
const totalPages = (0, import_react9.useMemo)(() => {
|
|
1953
2259
|
if (!enablePagination) return 1;
|
|
1954
2260
|
return Math.max(1, Math.ceil(totalSearchedRows / pageSize));
|
|
1955
2261
|
}, [enablePagination, totalSearchedRows, pageSize]);
|
|
1956
|
-
const paginatedRows = (0,
|
|
2262
|
+
const paginatedRows = (0, import_react9.useMemo)(() => {
|
|
1957
2263
|
if (!enablePagination) return searchFilteredData;
|
|
1958
2264
|
const start = (currentPage - 1) * pageSize;
|
|
1959
2265
|
const end = start + pageSize;
|
|
1960
2266
|
return searchFilteredData.slice(start, end);
|
|
1961
2267
|
}, [enablePagination, searchFilteredData, currentPage, pageSize]);
|
|
1962
|
-
(0,
|
|
2268
|
+
(0, import_react9.useEffect)(() => {
|
|
1963
2269
|
setCurrentPage(1);
|
|
1964
2270
|
}, [columnFilters, globalSearchTerm]);
|
|
1965
|
-
const selectionBounds = (0,
|
|
2271
|
+
const selectionBounds = (0, import_react9.useMemo)(() => {
|
|
1966
2272
|
if (!selectionStart || !selectionEnd) return null;
|
|
1967
2273
|
return {
|
|
1968
2274
|
minRow: Math.min(selectionStart.row, selectionEnd.row),
|
|
@@ -1971,7 +2277,7 @@ function DataGrid({
|
|
|
1971
2277
|
maxCol: Math.max(selectionStart.col, selectionEnd.col)
|
|
1972
2278
|
};
|
|
1973
2279
|
}, [selectionStart, selectionEnd]);
|
|
1974
|
-
const selectionStats = (0,
|
|
2280
|
+
const selectionStats = (0, import_react9.useMemo)(() => {
|
|
1975
2281
|
if (!selectionBounds) return null;
|
|
1976
2282
|
const { minRow, maxRow, minCol, maxCol } = selectionBounds;
|
|
1977
2283
|
const values = [];
|
|
@@ -1997,7 +2303,7 @@ function DataGrid({
|
|
|
1997
2303
|
const avg = sum / values.length;
|
|
1998
2304
|
return { count, sum, avg, numericCount: values.length };
|
|
1999
2305
|
}, [selectionBounds, rows, columnKeys]);
|
|
2000
|
-
(0,
|
|
2306
|
+
(0, import_react9.useEffect)(() => {
|
|
2001
2307
|
if (data.length === 0) return;
|
|
2002
2308
|
const widths = {};
|
|
2003
2309
|
const sampleSize = Math.min(100, data.length);
|
|
@@ -2017,7 +2323,7 @@ function DataGrid({
|
|
|
2017
2323
|
}
|
|
2018
2324
|
setColumnWidths(widths);
|
|
2019
2325
|
}, [data, columnKeys]);
|
|
2020
|
-
const startColumnResize = (0,
|
|
2326
|
+
const startColumnResize = (0, import_react9.useCallback)(
|
|
2021
2327
|
(columnId, event) => {
|
|
2022
2328
|
if (!enableColumnResize) return;
|
|
2023
2329
|
event.preventDefault();
|
|
@@ -2028,7 +2334,7 @@ function DataGrid({
|
|
|
2028
2334
|
},
|
|
2029
2335
|
[enableColumnResize, columnWidths]
|
|
2030
2336
|
);
|
|
2031
|
-
(0,
|
|
2337
|
+
(0, import_react9.useEffect)(() => {
|
|
2032
2338
|
if (!resizingColumnId) return;
|
|
2033
2339
|
const handleResizeMove = (event) => {
|
|
2034
2340
|
const diff = event.clientX - resizeStartX;
|
|
@@ -2048,7 +2354,7 @@ function DataGrid({
|
|
|
2048
2354
|
document.removeEventListener("mouseup", handleResizeEnd);
|
|
2049
2355
|
};
|
|
2050
2356
|
}, [resizingColumnId, resizeStartX, resizeStartWidth]);
|
|
2051
|
-
const startVerticalResize = (0,
|
|
2357
|
+
const startVerticalResize = (0, import_react9.useCallback)(
|
|
2052
2358
|
(event) => {
|
|
2053
2359
|
if (!enableVerticalResize) return;
|
|
2054
2360
|
event.preventDefault();
|
|
@@ -2058,7 +2364,7 @@ function DataGrid({
|
|
|
2058
2364
|
},
|
|
2059
2365
|
[enableVerticalResize, gridHeight]
|
|
2060
2366
|
);
|
|
2061
|
-
(0,
|
|
2367
|
+
(0, import_react9.useEffect)(() => {
|
|
2062
2368
|
if (!isResizingVertically) return;
|
|
2063
2369
|
const handleVerticalResizeMove = (event) => {
|
|
2064
2370
|
const diff = event.clientY - verticalResizeStartY;
|
|
@@ -2075,7 +2381,7 @@ function DataGrid({
|
|
|
2075
2381
|
document.removeEventListener("mouseup", handleVerticalResizeEnd);
|
|
2076
2382
|
};
|
|
2077
2383
|
}, [isResizingVertically, verticalResizeStartY, verticalResizeStartHeight, minHeight, maxHeight]);
|
|
2078
|
-
const handleExport = (0,
|
|
2384
|
+
const handleExport = (0, import_react9.useCallback)(() => {
|
|
2079
2385
|
if (viewMode === "pivot") {
|
|
2080
2386
|
if (!pivotResult) return;
|
|
2081
2387
|
const pivotFilename = exportFilename.replace(".csv", "-pivot.csv");
|
|
@@ -2120,7 +2426,7 @@ function DataGrid({
|
|
|
2120
2426
|
columnKeys,
|
|
2121
2427
|
onExport
|
|
2122
2428
|
]);
|
|
2123
|
-
const copySelectionToClipboard = (0,
|
|
2429
|
+
const copySelectionToClipboard = (0, import_react9.useCallback)(() => {
|
|
2124
2430
|
if (!selectionBounds || !enableClipboard) return;
|
|
2125
2431
|
const text = formatSelectionForClipboard(
|
|
2126
2432
|
rows.map((r) => r.original),
|
|
@@ -2144,7 +2450,7 @@ function DataGrid({
|
|
|
2144
2450
|
}
|
|
2145
2451
|
);
|
|
2146
2452
|
}, [selectionBounds, enableClipboard, rows, columnKeys, onCopy]);
|
|
2147
|
-
const handleMouseDown = (0,
|
|
2453
|
+
const handleMouseDown = (0, import_react9.useCallback)(
|
|
2148
2454
|
(rowIndex, colIndex, event) => {
|
|
2149
2455
|
event.preventDefault();
|
|
2150
2456
|
if (event.shiftKey && selectedCell) {
|
|
@@ -2168,7 +2474,7 @@ function DataGrid({
|
|
|
2168
2474
|
},
|
|
2169
2475
|
[selectedCell, rows, columnKeys, onCellClick]
|
|
2170
2476
|
);
|
|
2171
|
-
const handleMouseEnter = (0,
|
|
2477
|
+
const handleMouseEnter = (0, import_react9.useCallback)(
|
|
2172
2478
|
(rowIndex, colIndex) => {
|
|
2173
2479
|
if (isSelecting) {
|
|
2174
2480
|
setSelectionEnd({ row: rowIndex, col: colIndex });
|
|
@@ -2176,12 +2482,12 @@ function DataGrid({
|
|
|
2176
2482
|
},
|
|
2177
2483
|
[isSelecting]
|
|
2178
2484
|
);
|
|
2179
|
-
(0,
|
|
2485
|
+
(0, import_react9.useEffect)(() => {
|
|
2180
2486
|
const handleMouseUp = () => setIsSelecting(false);
|
|
2181
2487
|
document.addEventListener("mouseup", handleMouseUp);
|
|
2182
2488
|
return () => document.removeEventListener("mouseup", handleMouseUp);
|
|
2183
2489
|
}, []);
|
|
2184
|
-
(0,
|
|
2490
|
+
(0, import_react9.useEffect)(() => {
|
|
2185
2491
|
const handleKeydown = (event) => {
|
|
2186
2492
|
if ((event.ctrlKey || event.metaKey) && event.key === "c" && selectionBounds) {
|
|
2187
2493
|
event.preventDefault();
|
|
@@ -2199,7 +2505,7 @@ function DataGrid({
|
|
|
2199
2505
|
document.addEventListener("keydown", handleKeydown);
|
|
2200
2506
|
return () => document.removeEventListener("keydown", handleKeydown);
|
|
2201
2507
|
}, [selectionBounds, copySelectionToClipboard]);
|
|
2202
|
-
const openFilterDropdown = (0,
|
|
2508
|
+
const openFilterDropdown = (0, import_react9.useCallback)(
|
|
2203
2509
|
(columnId, event) => {
|
|
2204
2510
|
event.stopPropagation();
|
|
2205
2511
|
const target = event.currentTarget;
|
|
@@ -2228,16 +2534,16 @@ function DataGrid({
|
|
|
2228
2534
|
},
|
|
2229
2535
|
[]
|
|
2230
2536
|
);
|
|
2231
|
-
const closeFilterDropdown = (0,
|
|
2537
|
+
const closeFilterDropdown = (0, import_react9.useCallback)(() => {
|
|
2232
2538
|
setActiveFilterColumn(null);
|
|
2233
2539
|
}, []);
|
|
2234
|
-
const handleFilter = (0,
|
|
2540
|
+
const handleFilter = (0, import_react9.useCallback)(
|
|
2235
2541
|
(columnId, values) => {
|
|
2236
2542
|
setColumnFilter(columnId, values);
|
|
2237
2543
|
},
|
|
2238
2544
|
[setColumnFilter]
|
|
2239
2545
|
);
|
|
2240
|
-
const handleSort = (0,
|
|
2546
|
+
const handleSort = (0, import_react9.useCallback)(
|
|
2241
2547
|
(columnId, direction) => {
|
|
2242
2548
|
if (direction === null) {
|
|
2243
2549
|
const current = getSortDirection(columnId);
|
|
@@ -2261,7 +2567,7 @@ function DataGrid({
|
|
|
2261
2567
|
},
|
|
2262
2568
|
[getSortDirection, toggleSort]
|
|
2263
2569
|
);
|
|
2264
|
-
const isCellSelected = (0,
|
|
2570
|
+
const isCellSelected = (0, import_react9.useCallback)(
|
|
2265
2571
|
(rowIndex, colIndex) => {
|
|
2266
2572
|
if (!selectionBounds) {
|
|
2267
2573
|
return selectedCell?.row === rowIndex && selectedCell?.col === colIndex;
|
|
@@ -2299,30 +2605,30 @@ function DataGrid({
|
|
|
2299
2605
|
}
|
|
2300
2606
|
return String(value);
|
|
2301
2607
|
};
|
|
2302
|
-
const totalTableWidth = (0,
|
|
2608
|
+
const totalTableWidth = (0, import_react9.useMemo)(() => {
|
|
2303
2609
|
return columnKeys.reduce((sum, key) => sum + (columnWidths[key] || MIN_COL_WIDTH), 0);
|
|
2304
2610
|
}, [columnKeys, columnWidths]);
|
|
2305
2611
|
const activeFilterCount = columnFilters.length;
|
|
2306
|
-
return /* @__PURE__ */ (0,
|
|
2612
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
2307
2613
|
"div",
|
|
2308
2614
|
{
|
|
2309
2615
|
className: `vpg-data-grid vpg-font-${currentFontSize} vpg-theme-${currentTheme} ${stripedRows ? "vpg-striped" : ""} ${resizingColumnId ? "vpg-resizing" : ""} ${isResizingVertically ? "vpg-resizing-vertical" : ""}`,
|
|
2310
2616
|
style: { height: `${gridHeight}px` },
|
|
2311
2617
|
children: [
|
|
2312
|
-
showCopyToast && /* @__PURE__ */ (0,
|
|
2313
|
-
/* @__PURE__ */ (0,
|
|
2618
|
+
showCopyToast && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-toast", children: [
|
|
2619
|
+
/* @__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)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }),
|
|
2314
2620
|
copyToastMessage
|
|
2315
2621
|
] }),
|
|
2316
|
-
/* @__PURE__ */ (0,
|
|
2317
|
-
/* @__PURE__ */ (0,
|
|
2318
|
-
showPivot && /* @__PURE__ */ (0,
|
|
2319
|
-
/* @__PURE__ */ (0,
|
|
2622
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-toolbar", children: [
|
|
2623
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-toolbar-left", children: [
|
|
2624
|
+
showPivot && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-view-toggle", children: [
|
|
2625
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
2320
2626
|
"button",
|
|
2321
2627
|
{
|
|
2322
2628
|
className: `vpg-view-btn ${viewMode === "grid" ? "active" : ""}`,
|
|
2323
2629
|
onClick: () => setViewMode("grid"),
|
|
2324
2630
|
children: [
|
|
2325
|
-
/* @__PURE__ */ (0,
|
|
2631
|
+
/* @__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)(
|
|
2326
2632
|
"path",
|
|
2327
2633
|
{
|
|
2328
2634
|
strokeLinecap: "round",
|
|
@@ -2335,13 +2641,13 @@ function DataGrid({
|
|
|
2335
2641
|
]
|
|
2336
2642
|
}
|
|
2337
2643
|
),
|
|
2338
|
-
/* @__PURE__ */ (0,
|
|
2644
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
2339
2645
|
"button",
|
|
2340
2646
|
{
|
|
2341
2647
|
className: `vpg-view-btn vpg-pivot-btn ${viewMode === "pivot" ? "active" : ""}`,
|
|
2342
2648
|
onClick: () => setViewMode("pivot"),
|
|
2343
2649
|
children: [
|
|
2344
|
-
/* @__PURE__ */ (0,
|
|
2650
|
+
/* @__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)(
|
|
2345
2651
|
"path",
|
|
2346
2652
|
{
|
|
2347
2653
|
strokeLinecap: "round",
|
|
@@ -2355,14 +2661,14 @@ function DataGrid({
|
|
|
2355
2661
|
}
|
|
2356
2662
|
)
|
|
2357
2663
|
] }),
|
|
2358
|
-
viewMode === "grid" && /* @__PURE__ */ (0,
|
|
2359
|
-
enableSearch && /* @__PURE__ */ (0,
|
|
2664
|
+
viewMode === "grid" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
2665
|
+
enableSearch && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-search-container", children: !showSearchInput ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2360
2666
|
"button",
|
|
2361
2667
|
{
|
|
2362
2668
|
className: "vpg-icon-btn",
|
|
2363
2669
|
title: "Search (Ctrl+F)",
|
|
2364
2670
|
onClick: () => setShowSearchInput(true),
|
|
2365
|
-
children: /* @__PURE__ */ (0,
|
|
2671
|
+
children: /* @__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)(
|
|
2366
2672
|
"path",
|
|
2367
2673
|
{
|
|
2368
2674
|
strokeLinecap: "round",
|
|
@@ -2372,15 +2678,15 @@ function DataGrid({
|
|
|
2372
2678
|
}
|
|
2373
2679
|
) })
|
|
2374
2680
|
}
|
|
2375
|
-
) : /* @__PURE__ */ (0,
|
|
2376
|
-
/* @__PURE__ */ (0,
|
|
2681
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-search-box", children: [
|
|
2682
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2377
2683
|
"svg",
|
|
2378
2684
|
{
|
|
2379
2685
|
className: "vpg-search-icon",
|
|
2380
2686
|
fill: "none",
|
|
2381
2687
|
stroke: "currentColor",
|
|
2382
2688
|
viewBox: "0 0 24 24",
|
|
2383
|
-
children: /* @__PURE__ */ (0,
|
|
2689
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2384
2690
|
"path",
|
|
2385
2691
|
{
|
|
2386
2692
|
strokeLinecap: "round",
|
|
@@ -2391,7 +2697,7 @@ function DataGrid({
|
|
|
2391
2697
|
)
|
|
2392
2698
|
}
|
|
2393
2699
|
),
|
|
2394
|
-
/* @__PURE__ */ (0,
|
|
2700
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2395
2701
|
"input",
|
|
2396
2702
|
{
|
|
2397
2703
|
type: "text",
|
|
@@ -2408,14 +2714,14 @@ function DataGrid({
|
|
|
2408
2714
|
autoFocus: true
|
|
2409
2715
|
}
|
|
2410
2716
|
),
|
|
2411
|
-
globalSearchTerm && /* @__PURE__ */ (0,
|
|
2717
|
+
globalSearchTerm && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "vpg-search-clear", onClick: () => setGlobalSearchTerm(""), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2412
2718
|
"svg",
|
|
2413
2719
|
{
|
|
2414
2720
|
className: "vpg-icon-xs",
|
|
2415
2721
|
fill: "none",
|
|
2416
2722
|
stroke: "currentColor",
|
|
2417
2723
|
viewBox: "0 0 24 24",
|
|
2418
|
-
children: /* @__PURE__ */ (0,
|
|
2724
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2419
2725
|
"path",
|
|
2420
2726
|
{
|
|
2421
2727
|
strokeLinecap: "round",
|
|
@@ -2427,9 +2733,9 @@ function DataGrid({
|
|
|
2427
2733
|
}
|
|
2428
2734
|
) })
|
|
2429
2735
|
] }) }),
|
|
2430
|
-
/* @__PURE__ */ (0,
|
|
2431
|
-
/* @__PURE__ */ (0,
|
|
2432
|
-
/* @__PURE__ */ (0,
|
|
2736
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-font-size-control", children: [
|
|
2737
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-label", children: "Size:" }),
|
|
2738
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-font-size-toggle", children: fontSizeOptions.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2433
2739
|
"button",
|
|
2434
2740
|
{
|
|
2435
2741
|
className: `vpg-font-size-btn ${currentFontSize === opt.value ? "active" : ""}`,
|
|
@@ -2439,8 +2745,8 @@ function DataGrid({
|
|
|
2439
2745
|
opt.value
|
|
2440
2746
|
)) })
|
|
2441
2747
|
] }),
|
|
2442
|
-
activeFilterCount > 0 && /* @__PURE__ */ (0,
|
|
2443
|
-
/* @__PURE__ */ (0,
|
|
2748
|
+
activeFilterCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-filter-info", children: [
|
|
2749
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2444
2750
|
"path",
|
|
2445
2751
|
{
|
|
2446
2752
|
fillRule: "evenodd",
|
|
@@ -2448,26 +2754,26 @@ function DataGrid({
|
|
|
2448
2754
|
clipRule: "evenodd"
|
|
2449
2755
|
}
|
|
2450
2756
|
) }),
|
|
2451
|
-
/* @__PURE__ */ (0,
|
|
2757
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
|
|
2452
2758
|
activeFilterCount,
|
|
2453
2759
|
" filter",
|
|
2454
2760
|
activeFilterCount > 1 ? "s" : ""
|
|
2455
2761
|
] })
|
|
2456
2762
|
] }),
|
|
2457
|
-
globalSearchTerm && /* @__PURE__ */ (0,
|
|
2763
|
+
globalSearchTerm && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-search-info", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
|
|
2458
2764
|
totalSearchedRows,
|
|
2459
2765
|
" match",
|
|
2460
2766
|
totalSearchedRows !== 1 ? "es" : ""
|
|
2461
2767
|
] }) })
|
|
2462
2768
|
] }),
|
|
2463
|
-
viewMode === "pivot" && canUsePivot && /* @__PURE__ */ (0,
|
|
2464
|
-
/* @__PURE__ */ (0,
|
|
2769
|
+
viewMode === "pivot" && canUsePivot && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
2770
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
2465
2771
|
"button",
|
|
2466
2772
|
{
|
|
2467
2773
|
className: `vpg-config-toggle ${showPivotConfig ? "active" : ""}`,
|
|
2468
2774
|
onClick: () => setShowPivotConfig(!showPivotConfig),
|
|
2469
2775
|
children: [
|
|
2470
|
-
/* @__PURE__ */ (0,
|
|
2776
|
+
/* @__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)(
|
|
2471
2777
|
"path",
|
|
2472
2778
|
{
|
|
2473
2779
|
strokeLinecap: "round",
|
|
@@ -2481,8 +2787,8 @@ function DataGrid({
|
|
|
2481
2787
|
]
|
|
2482
2788
|
}
|
|
2483
2789
|
),
|
|
2484
|
-
pivotIsConfigured && /* @__PURE__ */ (0,
|
|
2485
|
-
/* @__PURE__ */ (0,
|
|
2790
|
+
pivotIsConfigured && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-pivot-status", children: [
|
|
2791
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2486
2792
|
"path",
|
|
2487
2793
|
{
|
|
2488
2794
|
fillRule: "evenodd",
|
|
@@ -2490,13 +2796,13 @@ function DataGrid({
|
|
|
2490
2796
|
clipRule: "evenodd"
|
|
2491
2797
|
}
|
|
2492
2798
|
) }),
|
|
2493
|
-
/* @__PURE__ */ (0,
|
|
2799
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Pivot configured" })
|
|
2494
2800
|
] })
|
|
2495
2801
|
] })
|
|
2496
2802
|
] }),
|
|
2497
|
-
/* @__PURE__ */ (0,
|
|
2498
|
-
viewMode === "grid" && activeFilterCount > 0 && /* @__PURE__ */ (0,
|
|
2499
|
-
/* @__PURE__ */ (0,
|
|
2803
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-toolbar-right", children: [
|
|
2804
|
+
viewMode === "grid" && activeFilterCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { className: "vpg-clear-filters", onClick: clearAllFilters, children: [
|
|
2805
|
+
/* @__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)(
|
|
2500
2806
|
"path",
|
|
2501
2807
|
{
|
|
2502
2808
|
strokeLinecap: "round",
|
|
@@ -2507,13 +2813,13 @@ function DataGrid({
|
|
|
2507
2813
|
) }),
|
|
2508
2814
|
"Clear Filters"
|
|
2509
2815
|
] }),
|
|
2510
|
-
enableClipboard && selectionBounds && viewMode === "grid" && /* @__PURE__ */ (0,
|
|
2816
|
+
enableClipboard && selectionBounds && viewMode === "grid" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2511
2817
|
"button",
|
|
2512
2818
|
{
|
|
2513
2819
|
className: "vpg-icon-btn",
|
|
2514
2820
|
title: "Copy selection (Ctrl+C)",
|
|
2515
2821
|
onClick: copySelectionToClipboard,
|
|
2516
|
-
children: /* @__PURE__ */ (0,
|
|
2822
|
+
children: /* @__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)(
|
|
2517
2823
|
"path",
|
|
2518
2824
|
{
|
|
2519
2825
|
strokeLinecap: "round",
|
|
@@ -2524,14 +2830,14 @@ function DataGrid({
|
|
|
2524
2830
|
) })
|
|
2525
2831
|
}
|
|
2526
2832
|
),
|
|
2527
|
-
enableExport && (viewMode === "grid" || viewMode === "pivot" && pivotIsConfigured) && /* @__PURE__ */ (0,
|
|
2833
|
+
enableExport && (viewMode === "grid" || viewMode === "pivot" && pivotIsConfigured) && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
2528
2834
|
"button",
|
|
2529
2835
|
{
|
|
2530
2836
|
className: "vpg-export-btn",
|
|
2531
2837
|
title: viewMode === "pivot" ? "Export Pivot to CSV" : "Export to CSV",
|
|
2532
2838
|
onClick: handleExport,
|
|
2533
2839
|
children: [
|
|
2534
|
-
/* @__PURE__ */ (0,
|
|
2840
|
+
/* @__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)(
|
|
2535
2841
|
"path",
|
|
2536
2842
|
{
|
|
2537
2843
|
strokeLinecap: "round",
|
|
@@ -2547,13 +2853,13 @@ function DataGrid({
|
|
|
2547
2853
|
)
|
|
2548
2854
|
] })
|
|
2549
2855
|
] }),
|
|
2550
|
-
viewMode === "grid" && /* @__PURE__ */ (0,
|
|
2551
|
-
loading && /* @__PURE__ */ (0,
|
|
2552
|
-
/* @__PURE__ */ (0,
|
|
2553
|
-
/* @__PURE__ */ (0,
|
|
2856
|
+
viewMode === "grid" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { ref: tableContainerRef, className: "vpg-grid-container", tabIndex: 0, children: [
|
|
2857
|
+
loading && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-loading", children: [
|
|
2858
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-spinner" }),
|
|
2859
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Loading data..." })
|
|
2554
2860
|
] }),
|
|
2555
|
-
!loading && data.length === 0 && /* @__PURE__ */ (0,
|
|
2556
|
-
/* @__PURE__ */ (0,
|
|
2861
|
+
!loading && data.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-empty", children: [
|
|
2862
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-empty-icon", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "vpg-icon-lg", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2557
2863
|
"path",
|
|
2558
2864
|
{
|
|
2559
2865
|
strokeLinecap: "round",
|
|
@@ -2562,10 +2868,10 @@ function DataGrid({
|
|
|
2562
2868
|
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"
|
|
2563
2869
|
}
|
|
2564
2870
|
) }) }),
|
|
2565
|
-
/* @__PURE__ */ (0,
|
|
2871
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "No data available" })
|
|
2566
2872
|
] }),
|
|
2567
|
-
!loading && data.length > 0 && filteredRowCount === 0 && /* @__PURE__ */ (0,
|
|
2568
|
-
/* @__PURE__ */ (0,
|
|
2873
|
+
!loading && data.length > 0 && filteredRowCount === 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-empty", children: [
|
|
2874
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-empty-icon vpg-warning", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "vpg-icon-lg", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2569
2875
|
"path",
|
|
2570
2876
|
{
|
|
2571
2877
|
strokeLinecap: "round",
|
|
@@ -2574,11 +2880,11 @@ function DataGrid({
|
|
|
2574
2880
|
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"
|
|
2575
2881
|
}
|
|
2576
2882
|
) }) }),
|
|
2577
|
-
/* @__PURE__ */ (0,
|
|
2578
|
-
/* @__PURE__ */ (0,
|
|
2883
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "No matching records" }),
|
|
2884
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "vpg-clear-link", onClick: clearAllFilters, children: "Clear all filters" })
|
|
2579
2885
|
] }),
|
|
2580
|
-
!loading && filteredRowCount > 0 && /* @__PURE__ */ (0,
|
|
2581
|
-
/* @__PURE__ */ (0,
|
|
2886
|
+
!loading && filteredRowCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-table-wrapper", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("table", { className: "vpg-table", style: { minWidth: `${totalTableWidth}px` }, children: [
|
|
2887
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("tr", { children: columnKeys.map((colId, colIndex) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
2582
2888
|
"th",
|
|
2583
2889
|
{
|
|
2584
2890
|
className: `vpg-header-cell ${hasActiveFilter(colId) ? "vpg-has-filter" : ""} ${getSortDirection(colId) !== null ? "vpg-is-sorted" : ""} ${activeFilterColumn === colId ? "vpg-is-active" : ""}`,
|
|
@@ -2593,16 +2899,16 @@ function DataGrid({
|
|
|
2593
2899
|
}
|
|
2594
2900
|
},
|
|
2595
2901
|
children: [
|
|
2596
|
-
/* @__PURE__ */ (0,
|
|
2597
|
-
/* @__PURE__ */ (0,
|
|
2598
|
-
/* @__PURE__ */ (0,
|
|
2599
|
-
getSortDirection(colId) && /* @__PURE__ */ (0,
|
|
2902
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-header-content", children: [
|
|
2903
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-header-text", children: colId }),
|
|
2904
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-header-icons", children: [
|
|
2905
|
+
getSortDirection(colId) && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-sort-indicator", children: getSortDirection(colId) === "asc" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2600
2906
|
"svg",
|
|
2601
2907
|
{
|
|
2602
2908
|
className: "vpg-icon-sm",
|
|
2603
2909
|
fill: "currentColor",
|
|
2604
2910
|
viewBox: "0 0 20 20",
|
|
2605
|
-
children: /* @__PURE__ */ (0,
|
|
2911
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2606
2912
|
"path",
|
|
2607
2913
|
{
|
|
2608
2914
|
fillRule: "evenodd",
|
|
@@ -2611,13 +2917,13 @@ function DataGrid({
|
|
|
2611
2917
|
}
|
|
2612
2918
|
)
|
|
2613
2919
|
}
|
|
2614
|
-
) : /* @__PURE__ */ (0,
|
|
2920
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2615
2921
|
"svg",
|
|
2616
2922
|
{
|
|
2617
2923
|
className: "vpg-icon-sm",
|
|
2618
2924
|
fill: "currentColor",
|
|
2619
2925
|
viewBox: "0 0 20 20",
|
|
2620
|
-
children: /* @__PURE__ */ (0,
|
|
2926
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2621
2927
|
"path",
|
|
2622
2928
|
{
|
|
2623
2929
|
fillRule: "evenodd",
|
|
@@ -2627,13 +2933,13 @@ function DataGrid({
|
|
|
2627
2933
|
)
|
|
2628
2934
|
}
|
|
2629
2935
|
) }),
|
|
2630
|
-
hasActiveFilter(colId) && /* @__PURE__ */ (0,
|
|
2936
|
+
hasActiveFilter(colId) && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-filter-indicator", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2631
2937
|
"svg",
|
|
2632
2938
|
{
|
|
2633
2939
|
className: "vpg-icon-xs",
|
|
2634
2940
|
fill: "currentColor",
|
|
2635
2941
|
viewBox: "0 0 20 20",
|
|
2636
|
-
children: /* @__PURE__ */ (0,
|
|
2942
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2637
2943
|
"path",
|
|
2638
2944
|
{
|
|
2639
2945
|
fillRule: "evenodd",
|
|
@@ -2643,14 +2949,14 @@ function DataGrid({
|
|
|
2643
2949
|
)
|
|
2644
2950
|
}
|
|
2645
2951
|
) }),
|
|
2646
|
-
/* @__PURE__ */ (0,
|
|
2952
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-dropdown-arrow", title: "Filter & Sort", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2647
2953
|
"svg",
|
|
2648
2954
|
{
|
|
2649
2955
|
className: "vpg-icon-sm",
|
|
2650
2956
|
fill: "none",
|
|
2651
2957
|
stroke: "currentColor",
|
|
2652
2958
|
viewBox: "0 0 24 24",
|
|
2653
|
-
children: /* @__PURE__ */ (0,
|
|
2959
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2654
2960
|
"path",
|
|
2655
2961
|
{
|
|
2656
2962
|
strokeLinecap: "round",
|
|
@@ -2663,7 +2969,7 @@ function DataGrid({
|
|
|
2663
2969
|
) })
|
|
2664
2970
|
] })
|
|
2665
2971
|
] }),
|
|
2666
|
-
enableColumnResize && /* @__PURE__ */ (0,
|
|
2972
|
+
enableColumnResize && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2667
2973
|
"div",
|
|
2668
2974
|
{
|
|
2669
2975
|
className: "vpg-resize-handle",
|
|
@@ -2674,7 +2980,7 @@ function DataGrid({
|
|
|
2674
2980
|
},
|
|
2675
2981
|
colId
|
|
2676
2982
|
)) }) }),
|
|
2677
|
-
/* @__PURE__ */ (0,
|
|
2983
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("tbody", { ref: tableBodyRef, children: paginatedRows.map((row, rowIndex) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("tr", { className: "vpg-row", children: columnKeys.map((colId, colIndex) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2678
2984
|
"td",
|
|
2679
2985
|
{
|
|
2680
2986
|
className: `vpg-cell ${isCellSelected(rowIndex, colIndex) ? "vpg-selected" : ""} ${getColumnStats(colId).type === "number" ? "vpg-is-number" : ""}`,
|
|
@@ -2692,8 +2998,8 @@ function DataGrid({
|
|
|
2692
2998
|
)) }, row.id)) })
|
|
2693
2999
|
] }) })
|
|
2694
3000
|
] }),
|
|
2695
|
-
viewMode === "pivot" && /* @__PURE__ */ (0,
|
|
2696
|
-
showPivotConfig && canUsePivot && /* @__PURE__ */ (0,
|
|
3001
|
+
viewMode === "pivot" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-pivot-container", children: [
|
|
3002
|
+
showPivotConfig && canUsePivot && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-pivot-config-panel", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2697
3003
|
PivotConfig,
|
|
2698
3004
|
{
|
|
2699
3005
|
availableFields: pivotAvailableFields,
|
|
@@ -2717,7 +3023,7 @@ function DataGrid({
|
|
|
2717
3023
|
onRemoveValueField: removeValueField
|
|
2718
3024
|
}
|
|
2719
3025
|
) }),
|
|
2720
|
-
/* @__PURE__ */ (0,
|
|
3026
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: `vpg-pivot-main ${!showPivotConfig ? "vpg-full-width" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2721
3027
|
PivotSkeleton,
|
|
2722
3028
|
{
|
|
2723
3029
|
rowFields: pivotRowFields,
|
|
@@ -2742,44 +3048,44 @@ function DataGrid({
|
|
|
2742
3048
|
}
|
|
2743
3049
|
) })
|
|
2744
3050
|
] }),
|
|
2745
|
-
/* @__PURE__ */ (0,
|
|
2746
|
-
/* @__PURE__ */ (0,
|
|
2747
|
-
/* @__PURE__ */ (0,
|
|
3051
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-footer", children: [
|
|
3052
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-footer-left", children: viewMode === "grid" ? enablePagination ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
3053
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
|
|
2748
3054
|
((currentPage - 1) * pageSize + 1).toLocaleString(),
|
|
2749
3055
|
"-",
|
|
2750
3056
|
Math.min(currentPage * pageSize, totalSearchedRows).toLocaleString()
|
|
2751
3057
|
] }),
|
|
2752
|
-
/* @__PURE__ */ (0,
|
|
2753
|
-
/* @__PURE__ */ (0,
|
|
2754
|
-
totalSearchedRows !== totalRowCount && /* @__PURE__ */ (0,
|
|
3058
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-separator", children: "of" }),
|
|
3059
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: totalSearchedRows.toLocaleString() }),
|
|
3060
|
+
totalSearchedRows !== totalRowCount && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "vpg-filtered-note", children: [
|
|
2755
3061
|
"(",
|
|
2756
3062
|
totalRowCount.toLocaleString(),
|
|
2757
3063
|
" total)"
|
|
2758
3064
|
] })
|
|
2759
|
-
] }) : filteredRowCount === totalRowCount && totalSearchedRows === totalRowCount ? /* @__PURE__ */ (0,
|
|
3065
|
+
] }) : filteredRowCount === totalRowCount && totalSearchedRows === totalRowCount ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
|
|
2760
3066
|
totalRowCount.toLocaleString(),
|
|
2761
3067
|
" records"
|
|
2762
|
-
] }) : /* @__PURE__ */ (0,
|
|
2763
|
-
/* @__PURE__ */ (0,
|
|
2764
|
-
/* @__PURE__ */ (0,
|
|
2765
|
-
/* @__PURE__ */ (0,
|
|
2766
|
-
/* @__PURE__ */ (0,
|
|
2767
|
-
] }) : /* @__PURE__ */ (0,
|
|
2768
|
-
/* @__PURE__ */ (0,
|
|
2769
|
-
/* @__PURE__ */ (0,
|
|
2770
|
-
/* @__PURE__ */ (0,
|
|
3068
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
3069
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-filtered-count", children: totalSearchedRows.toLocaleString() }),
|
|
3070
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-separator", children: "of" }),
|
|
3071
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: totalRowCount.toLocaleString() }),
|
|
3072
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-separator", children: "records" })
|
|
3073
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
3074
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-pivot-label", children: "Pivot Table" }),
|
|
3075
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-separator", children: "\u2022" }),
|
|
3076
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
|
|
2771
3077
|
totalRowCount.toLocaleString(),
|
|
2772
3078
|
" source records"
|
|
2773
3079
|
] })
|
|
2774
3080
|
] }) }),
|
|
2775
|
-
enablePagination && viewMode === "grid" && totalPages > 1 && /* @__PURE__ */ (0,
|
|
2776
|
-
/* @__PURE__ */ (0,
|
|
3081
|
+
enablePagination && viewMode === "grid" && totalPages > 1 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-pagination", children: [
|
|
3082
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2777
3083
|
"button",
|
|
2778
3084
|
{
|
|
2779
3085
|
className: "vpg-page-btn",
|
|
2780
3086
|
disabled: currentPage === 1,
|
|
2781
3087
|
onClick: () => setCurrentPage(1),
|
|
2782
|
-
children: /* @__PURE__ */ (0,
|
|
3088
|
+
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)(
|
|
2783
3089
|
"path",
|
|
2784
3090
|
{
|
|
2785
3091
|
strokeLinecap: "round",
|
|
@@ -2790,13 +3096,13 @@ function DataGrid({
|
|
|
2790
3096
|
) })
|
|
2791
3097
|
}
|
|
2792
3098
|
),
|
|
2793
|
-
/* @__PURE__ */ (0,
|
|
3099
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2794
3100
|
"button",
|
|
2795
3101
|
{
|
|
2796
3102
|
className: "vpg-page-btn",
|
|
2797
3103
|
disabled: currentPage === 1,
|
|
2798
3104
|
onClick: () => setCurrentPage((p) => Math.max(1, p - 1)),
|
|
2799
|
-
children: /* @__PURE__ */ (0,
|
|
3105
|
+
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)(
|
|
2800
3106
|
"path",
|
|
2801
3107
|
{
|
|
2802
3108
|
strokeLinecap: "round",
|
|
@@ -2807,19 +3113,19 @@ function DataGrid({
|
|
|
2807
3113
|
) })
|
|
2808
3114
|
}
|
|
2809
3115
|
),
|
|
2810
|
-
/* @__PURE__ */ (0,
|
|
3116
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "vpg-page-info", children: [
|
|
2811
3117
|
"Page ",
|
|
2812
3118
|
currentPage,
|
|
2813
3119
|
" of ",
|
|
2814
3120
|
totalPages
|
|
2815
3121
|
] }),
|
|
2816
|
-
/* @__PURE__ */ (0,
|
|
3122
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2817
3123
|
"button",
|
|
2818
3124
|
{
|
|
2819
3125
|
className: "vpg-page-btn",
|
|
2820
3126
|
disabled: currentPage === totalPages,
|
|
2821
3127
|
onClick: () => setCurrentPage((p) => Math.min(totalPages, p + 1)),
|
|
2822
|
-
children: /* @__PURE__ */ (0,
|
|
3128
|
+
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)(
|
|
2823
3129
|
"path",
|
|
2824
3130
|
{
|
|
2825
3131
|
strokeLinecap: "round",
|
|
@@ -2830,13 +3136,13 @@ function DataGrid({
|
|
|
2830
3136
|
) })
|
|
2831
3137
|
}
|
|
2832
3138
|
),
|
|
2833
|
-
/* @__PURE__ */ (0,
|
|
3139
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2834
3140
|
"button",
|
|
2835
3141
|
{
|
|
2836
3142
|
className: "vpg-page-btn",
|
|
2837
3143
|
disabled: currentPage === totalPages,
|
|
2838
3144
|
onClick: () => setCurrentPage(totalPages),
|
|
2839
|
-
children: /* @__PURE__ */ (0,
|
|
3145
|
+
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)(
|
|
2840
3146
|
"path",
|
|
2841
3147
|
{
|
|
2842
3148
|
strokeLinecap: "round",
|
|
@@ -2848,45 +3154,45 @@ function DataGrid({
|
|
|
2848
3154
|
}
|
|
2849
3155
|
)
|
|
2850
3156
|
] }),
|
|
2851
|
-
viewMode === "grid" && selectionStats && selectionStats.count > 1 && /* @__PURE__ */ (0,
|
|
2852
|
-
/* @__PURE__ */ (0,
|
|
2853
|
-
/* @__PURE__ */ (0,
|
|
2854
|
-
/* @__PURE__ */ (0,
|
|
3157
|
+
viewMode === "grid" && selectionStats && selectionStats.count > 1 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-selection-stats", children: [
|
|
3158
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "vpg-stat", children: [
|
|
3159
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-stat-label", children: "Count:" }),
|
|
3160
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-stat-value", children: selectionStats.count })
|
|
2855
3161
|
] }),
|
|
2856
|
-
selectionStats.numericCount > 0 && /* @__PURE__ */ (0,
|
|
2857
|
-
/* @__PURE__ */ (0,
|
|
2858
|
-
/* @__PURE__ */ (0,
|
|
2859
|
-
/* @__PURE__ */ (0,
|
|
2860
|
-
/* @__PURE__ */ (0,
|
|
3162
|
+
selectionStats.numericCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
3163
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-stat-divider", children: "|" }),
|
|
3164
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "vpg-stat", children: [
|
|
3165
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-stat-label", children: "Sum:" }),
|
|
3166
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.sum) })
|
|
2861
3167
|
] }),
|
|
2862
|
-
/* @__PURE__ */ (0,
|
|
2863
|
-
/* @__PURE__ */ (0,
|
|
2864
|
-
/* @__PURE__ */ (0,
|
|
2865
|
-
/* @__PURE__ */ (0,
|
|
3168
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-stat-divider", children: "|" }),
|
|
3169
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "vpg-stat", children: [
|
|
3170
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-stat-label", children: "Avg:" }),
|
|
3171
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.avg) })
|
|
2866
3172
|
] })
|
|
2867
3173
|
] })
|
|
2868
3174
|
] }),
|
|
2869
|
-
/* @__PURE__ */ (0,
|
|
2870
|
-
/* @__PURE__ */ (0,
|
|
2871
|
-
/* @__PURE__ */ (0,
|
|
2872
|
-
/* @__PURE__ */ (0,
|
|
2873
|
-
] }) : showWatermark ? /* @__PURE__ */ (0,
|
|
2874
|
-
/* @__PURE__ */ (0,
|
|
2875
|
-
/* @__PURE__ */ (0,
|
|
2876
|
-
/* @__PURE__ */ (0,
|
|
2877
|
-
/* @__PURE__ */ (0,
|
|
2878
|
-
/* @__PURE__ */ (0,
|
|
3175
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-footer-right", children: isDemo ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-demo-banner", children: [
|
|
3176
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-demo-badge", children: "DEMO" }),
|
|
3177
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Pro features enabled" }),
|
|
3178
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("a", { href: "https://tiny-pivot.com/#pricing", target: "_blank", rel: "noopener noreferrer", children: "Get License \u2192" })
|
|
3179
|
+
] }) : showWatermark ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-watermark-inline", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: [
|
|
3180
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.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: [
|
|
3181
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("rect", { x: "3", y: "3", width: "7", height: "7" }),
|
|
3182
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("rect", { x: "14", y: "3", width: "7", height: "7" }),
|
|
3183
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("rect", { x: "14", y: "14", width: "7", height: "7" }),
|
|
3184
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("rect", { x: "3", y: "14", width: "7", height: "7" })
|
|
2879
3185
|
] }),
|
|
2880
3186
|
"Powered by TinyPivot"
|
|
2881
3187
|
] }) }) : null })
|
|
2882
3188
|
] }),
|
|
2883
|
-
enableVerticalResize && /* @__PURE__ */ (0,
|
|
2884
|
-
/* @__PURE__ */ (0,
|
|
2885
|
-
/* @__PURE__ */ (0,
|
|
2886
|
-
/* @__PURE__ */ (0,
|
|
3189
|
+
enableVerticalResize && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-vertical-resize-handle", onMouseDown: startVerticalResize, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-resize-grip", children: [
|
|
3190
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", {}),
|
|
3191
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", {}),
|
|
3192
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", {})
|
|
2887
3193
|
] }) }),
|
|
2888
|
-
activeFilterColumn && (0,
|
|
2889
|
-
/* @__PURE__ */ (0,
|
|
3194
|
+
activeFilterColumn && (0, import_react_dom2.createPortal)(
|
|
3195
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2890
3196
|
"div",
|
|
2891
3197
|
{
|
|
2892
3198
|
className: "vpg-filter-portal",
|
|
@@ -2897,7 +3203,7 @@ function DataGrid({
|
|
|
2897
3203
|
maxHeight: `${filterDropdownPosition.maxHeight}px`,
|
|
2898
3204
|
zIndex: 9999
|
|
2899
3205
|
},
|
|
2900
|
-
children: /* @__PURE__ */ (0,
|
|
3206
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2901
3207
|
ColumnFilter,
|
|
2902
3208
|
{
|
|
2903
3209
|
columnId: activeFilterColumn,
|