@smallwebco/tinypivot-react 1.0.67 → 1.0.69
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/README.md +2 -0
- package/dist/index.cjs +980 -693
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -3
- package/dist/index.d.ts +25 -3
- package/dist/index.js +935 -648
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -40,10 +40,10 @@ __export(index_exports, {
|
|
|
40
40
|
enableDemoMode: () => enableDemoMode,
|
|
41
41
|
exportPivotToCSV: () => exportPivotToCSV,
|
|
42
42
|
exportToCSV: () => exportToCSV,
|
|
43
|
-
formatCellValue: () =>
|
|
43
|
+
formatCellValue: () => import_tinypivot_core7.formatCellValue,
|
|
44
44
|
formatSelectionForClipboard: () => formatSelectionForClipboard,
|
|
45
|
-
getAggregationLabel: () =>
|
|
46
|
-
getColumnUniqueValues: () =>
|
|
45
|
+
getAggregationLabel: () => import_tinypivot_core10.getAggregationLabel,
|
|
46
|
+
getColumnUniqueValues: () => import_tinypivot_core7.getColumnUniqueValues,
|
|
47
47
|
setLicenseKey: () => setLicenseKey,
|
|
48
48
|
useAIAnalyst: () => useAIAnalyst,
|
|
49
49
|
useColumnResize: () => useColumnResize,
|
|
@@ -2165,20 +2165,178 @@ function ChartBuilder({
|
|
|
2165
2165
|
}
|
|
2166
2166
|
|
|
2167
2167
|
// src/components/ColumnFilter.tsx
|
|
2168
|
-
var
|
|
2168
|
+
var import_react7 = require("react");
|
|
2169
2169
|
|
|
2170
|
-
// src/components/
|
|
2170
|
+
// src/components/DateRangeFilter.tsx
|
|
2171
|
+
var import_tinypivot_core5 = require("@smallwebco/tinypivot-core");
|
|
2171
2172
|
var import_react5 = require("react");
|
|
2172
2173
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
2174
|
+
function DateRangeFilter({
|
|
2175
|
+
dataMin,
|
|
2176
|
+
dataMax,
|
|
2177
|
+
currentRange,
|
|
2178
|
+
onChange,
|
|
2179
|
+
dateFormat = "iso"
|
|
2180
|
+
}) {
|
|
2181
|
+
const [localMinText, setLocalMinText] = (0, import_react5.useState)("");
|
|
2182
|
+
const [localMaxText, setLocalMaxText] = (0, import_react5.useState)("");
|
|
2183
|
+
const [minError, setMinError] = (0, import_react5.useState)(false);
|
|
2184
|
+
const [maxError, setMaxError] = (0, import_react5.useState)(false);
|
|
2185
|
+
const formattedMin = (0, import_react5.useMemo)(() => (0, import_tinypivot_core5.formatDate)(dataMin, dateFormat), [dataMin, dateFormat]);
|
|
2186
|
+
const formattedMax = (0, import_react5.useMemo)(() => (0, import_tinypivot_core5.formatDate)(dataMax, dateFormat), [dataMax, dateFormat]);
|
|
2187
|
+
const isFilterActive = localMinText !== "" || localMaxText !== "";
|
|
2188
|
+
const emitChange = (0, import_react5.useCallback)(() => {
|
|
2189
|
+
const min = localMinText ? (0, import_tinypivot_core5.parseDateInput)(localMinText, dateFormat) : null;
|
|
2190
|
+
const max = localMaxText ? (0, import_tinypivot_core5.parseDateInput)(localMaxText, dateFormat) : null;
|
|
2191
|
+
if (min === null && max === null) {
|
|
2192
|
+
onChange(null);
|
|
2193
|
+
} else {
|
|
2194
|
+
onChange({ min, max });
|
|
2195
|
+
}
|
|
2196
|
+
}, [localMinText, localMaxText, dateFormat, onChange]);
|
|
2197
|
+
const handleMinBlur = (0, import_react5.useCallback)(() => {
|
|
2198
|
+
if (localMinText === "") {
|
|
2199
|
+
setMinError(false);
|
|
2200
|
+
emitChange();
|
|
2201
|
+
return;
|
|
2202
|
+
}
|
|
2203
|
+
const parsed = (0, import_tinypivot_core5.parseDateInput)(localMinText, dateFormat);
|
|
2204
|
+
setMinError(parsed === null);
|
|
2205
|
+
if (parsed !== null)
|
|
2206
|
+
emitChange();
|
|
2207
|
+
}, [localMinText, dateFormat, emitChange]);
|
|
2208
|
+
const handleMaxBlur = (0, import_react5.useCallback)(() => {
|
|
2209
|
+
if (localMaxText === "") {
|
|
2210
|
+
setMaxError(false);
|
|
2211
|
+
emitChange();
|
|
2212
|
+
return;
|
|
2213
|
+
}
|
|
2214
|
+
const parsed = (0, import_tinypivot_core5.parseDateInput)(localMaxText, dateFormat);
|
|
2215
|
+
setMaxError(parsed === null);
|
|
2216
|
+
if (parsed !== null)
|
|
2217
|
+
emitChange();
|
|
2218
|
+
}, [localMaxText, dateFormat, emitChange]);
|
|
2219
|
+
const clearFilter = (0, import_react5.useCallback)(() => {
|
|
2220
|
+
setLocalMinText("");
|
|
2221
|
+
setLocalMaxText("");
|
|
2222
|
+
setMinError(false);
|
|
2223
|
+
setMaxError(false);
|
|
2224
|
+
onChange(null);
|
|
2225
|
+
}, [onChange]);
|
|
2226
|
+
const setFullRange = (0, import_react5.useCallback)(() => {
|
|
2227
|
+
setLocalMinText((0, import_tinypivot_core5.formatDate)(dataMin, dateFormat));
|
|
2228
|
+
setLocalMaxText((0, import_tinypivot_core5.formatDate)(dataMax, dateFormat));
|
|
2229
|
+
setMinError(false);
|
|
2230
|
+
setMaxError(false);
|
|
2231
|
+
onChange({ min: dataMin, max: dataMax });
|
|
2232
|
+
}, [dataMin, dataMax, dateFormat, onChange]);
|
|
2233
|
+
(0, import_react5.useEffect)(() => {
|
|
2234
|
+
if (currentRange?.min) {
|
|
2235
|
+
setLocalMinText((0, import_tinypivot_core5.formatDate)(currentRange.min, dateFormat));
|
|
2236
|
+
} else {
|
|
2237
|
+
setLocalMinText("");
|
|
2238
|
+
}
|
|
2239
|
+
if (currentRange?.max) {
|
|
2240
|
+
setLocalMaxText((0, import_tinypivot_core5.formatDate)(currentRange.max, dateFormat));
|
|
2241
|
+
} else {
|
|
2242
|
+
setLocalMaxText("");
|
|
2243
|
+
}
|
|
2244
|
+
setMinError(false);
|
|
2245
|
+
setMaxError(false);
|
|
2246
|
+
}, [currentRange, dateFormat]);
|
|
2247
|
+
const handleKeyDown = (0, import_react5.useCallback)((e, handler) => {
|
|
2248
|
+
if (e.key === "Enter")
|
|
2249
|
+
handler();
|
|
2250
|
+
}, []);
|
|
2251
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-range-filter", children: [
|
|
2252
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-range-info", children: [
|
|
2253
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-range-label", children: "Data range:" }),
|
|
2254
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "vpg-range-bounds", children: [
|
|
2255
|
+
formattedMin,
|
|
2256
|
+
" ",
|
|
2257
|
+
"\u2013",
|
|
2258
|
+
" ",
|
|
2259
|
+
formattedMax
|
|
2260
|
+
] })
|
|
2261
|
+
] }),
|
|
2262
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-range-inputs", children: [
|
|
2263
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-input-group", children: [
|
|
2264
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("label", { className: "vpg-input-label", children: "From" }),
|
|
2265
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2266
|
+
"input",
|
|
2267
|
+
{
|
|
2268
|
+
type: "text",
|
|
2269
|
+
className: `vpg-range-input ${minError ? "vpg-input-error" : ""}`,
|
|
2270
|
+
placeholder: (0, import_tinypivot_core5.getDatePlaceholder)(dateFormat),
|
|
2271
|
+
value: localMinText,
|
|
2272
|
+
onChange: (e) => setLocalMinText(e.target.value),
|
|
2273
|
+
onBlur: handleMinBlur,
|
|
2274
|
+
onKeyDown: (e) => handleKeyDown(e, handleMinBlur)
|
|
2275
|
+
}
|
|
2276
|
+
)
|
|
2277
|
+
] }),
|
|
2278
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "vpg-input-separator", children: "to" }),
|
|
2279
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-input-group", children: [
|
|
2280
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("label", { className: "vpg-input-label", children: "To" }),
|
|
2281
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
2282
|
+
"input",
|
|
2283
|
+
{
|
|
2284
|
+
type: "text",
|
|
2285
|
+
className: `vpg-range-input ${maxError ? "vpg-input-error" : ""}`,
|
|
2286
|
+
placeholder: (0, import_tinypivot_core5.getDatePlaceholder)(dateFormat),
|
|
2287
|
+
value: localMaxText,
|
|
2288
|
+
onChange: (e) => setLocalMaxText(e.target.value),
|
|
2289
|
+
onBlur: handleMaxBlur,
|
|
2290
|
+
onKeyDown: (e) => handleKeyDown(e, handleMaxBlur)
|
|
2291
|
+
}
|
|
2292
|
+
)
|
|
2293
|
+
] })
|
|
2294
|
+
] }),
|
|
2295
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-range-actions", children: [
|
|
2296
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("button", { className: "vpg-range-btn", disabled: !isFilterActive, onClick: clearFilter, children: [
|
|
2297
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }),
|
|
2298
|
+
"Clear"
|
|
2299
|
+
] }),
|
|
2300
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("button", { className: "vpg-range-btn", onClick: setFullRange, children: [
|
|
2301
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4" }) }),
|
|
2302
|
+
"Full Range"
|
|
2303
|
+
] })
|
|
2304
|
+
] }),
|
|
2305
|
+
isFilterActive && !minError && !maxError && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "vpg-filter-summary", children: [
|
|
2306
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, 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" }) }),
|
|
2307
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { children: [
|
|
2308
|
+
"Showing dates",
|
|
2309
|
+
localMinText && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("strong", { children: [
|
|
2310
|
+
" ",
|
|
2311
|
+
"from",
|
|
2312
|
+
" ",
|
|
2313
|
+
localMinText
|
|
2314
|
+
] }),
|
|
2315
|
+
localMinText && localMaxText && " ",
|
|
2316
|
+
localMaxText && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("strong", { children: [
|
|
2317
|
+
"to",
|
|
2318
|
+
" ",
|
|
2319
|
+
localMaxText
|
|
2320
|
+
] })
|
|
2321
|
+
] })
|
|
2322
|
+
] })
|
|
2323
|
+
] });
|
|
2324
|
+
}
|
|
2325
|
+
|
|
2326
|
+
// src/components/NumericRangeFilter.tsx
|
|
2327
|
+
var import_tinypivot_core6 = require("@smallwebco/tinypivot-core");
|
|
2328
|
+
var import_react6 = require("react");
|
|
2329
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
2173
2330
|
function NumericRangeFilter({
|
|
2174
2331
|
dataMin,
|
|
2175
2332
|
dataMax,
|
|
2176
2333
|
currentRange,
|
|
2177
|
-
onChange
|
|
2334
|
+
onChange,
|
|
2335
|
+
numberFormat = "us"
|
|
2178
2336
|
}) {
|
|
2179
|
-
const [localMin, setLocalMin] = (0,
|
|
2180
|
-
const [localMax, setLocalMax] = (0,
|
|
2181
|
-
const step = (0,
|
|
2337
|
+
const [localMin, setLocalMin] = (0, import_react6.useState)(currentRange?.min ?? null);
|
|
2338
|
+
const [localMax, setLocalMax] = (0, import_react6.useState)(currentRange?.max ?? null);
|
|
2339
|
+
const step = (0, import_react6.useMemo)(() => {
|
|
2182
2340
|
const range = dataMax - dataMin;
|
|
2183
2341
|
if (range === 0)
|
|
2184
2342
|
return 1;
|
|
@@ -2192,25 +2350,23 @@ function NumericRangeFilter({
|
|
|
2192
2350
|
return 10;
|
|
2193
2351
|
return 10 ** (Math.floor(Math.log10(range)) - 2);
|
|
2194
2352
|
}, [dataMin, dataMax]);
|
|
2195
|
-
const formatValue = (0,
|
|
2353
|
+
const formatValue = (0, import_react6.useCallback)((val) => {
|
|
2196
2354
|
if (val === null)
|
|
2197
2355
|
return "";
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
return val.toLocaleString(void 0, { maximumFractionDigits: 2 });
|
|
2201
|
-
}, []);
|
|
2356
|
+
return (0, import_tinypivot_core6.formatNumber)(val, numberFormat);
|
|
2357
|
+
}, [numberFormat]);
|
|
2202
2358
|
const isFilterActive = localMin !== null || localMax !== null;
|
|
2203
|
-
const minPercent = (0,
|
|
2359
|
+
const minPercent = (0, import_react6.useMemo)(() => {
|
|
2204
2360
|
if (localMin === null || dataMax === dataMin)
|
|
2205
2361
|
return 0;
|
|
2206
2362
|
return (localMin - dataMin) / (dataMax - dataMin) * 100;
|
|
2207
2363
|
}, [localMin, dataMin, dataMax]);
|
|
2208
|
-
const maxPercent = (0,
|
|
2364
|
+
const maxPercent = (0, import_react6.useMemo)(() => {
|
|
2209
2365
|
if (localMax === null || dataMax === dataMin)
|
|
2210
2366
|
return 100;
|
|
2211
2367
|
return (localMax - dataMin) / (dataMax - dataMin) * 100;
|
|
2212
2368
|
}, [localMax, dataMin, dataMax]);
|
|
2213
|
-
const handleMinSlider = (0,
|
|
2369
|
+
const handleMinSlider = (0, import_react6.useCallback)((event) => {
|
|
2214
2370
|
const value = Number.parseFloat(event.target.value);
|
|
2215
2371
|
setLocalMin(() => {
|
|
2216
2372
|
if (localMax !== null && value > localMax) {
|
|
@@ -2219,7 +2375,7 @@ function NumericRangeFilter({
|
|
|
2219
2375
|
return value;
|
|
2220
2376
|
});
|
|
2221
2377
|
}, [localMax]);
|
|
2222
|
-
const handleMaxSlider = (0,
|
|
2378
|
+
const handleMaxSlider = (0, import_react6.useCallback)((event) => {
|
|
2223
2379
|
const value = Number.parseFloat(event.target.value);
|
|
2224
2380
|
setLocalMax(() => {
|
|
2225
2381
|
if (localMin !== null && value < localMin) {
|
|
@@ -2228,14 +2384,14 @@ function NumericRangeFilter({
|
|
|
2228
2384
|
return value;
|
|
2229
2385
|
});
|
|
2230
2386
|
}, [localMin]);
|
|
2231
|
-
const handleSliderChange = (0,
|
|
2387
|
+
const handleSliderChange = (0, import_react6.useCallback)(() => {
|
|
2232
2388
|
if (localMin === null && localMax === null) {
|
|
2233
2389
|
onChange(null);
|
|
2234
2390
|
} else {
|
|
2235
2391
|
onChange({ min: localMin, max: localMax });
|
|
2236
2392
|
}
|
|
2237
2393
|
}, [localMin, localMax, onChange]);
|
|
2238
|
-
const handleMinInput = (0,
|
|
2394
|
+
const handleMinInput = (0, import_react6.useCallback)((event) => {
|
|
2239
2395
|
const value = event.target.value === "" ? null : Number.parseFloat(event.target.value);
|
|
2240
2396
|
if (value !== null && !Number.isNaN(value)) {
|
|
2241
2397
|
setLocalMin(Math.max(dataMin, Math.min(value, localMax ?? dataMax)));
|
|
@@ -2243,7 +2399,7 @@ function NumericRangeFilter({
|
|
|
2243
2399
|
setLocalMin(null);
|
|
2244
2400
|
}
|
|
2245
2401
|
}, [dataMin, dataMax, localMax]);
|
|
2246
|
-
const handleMaxInput = (0,
|
|
2402
|
+
const handleMaxInput = (0, import_react6.useCallback)((event) => {
|
|
2247
2403
|
const value = event.target.value === "" ? null : Number.parseFloat(event.target.value);
|
|
2248
2404
|
if (value !== null && !Number.isNaN(value)) {
|
|
2249
2405
|
setLocalMax(Math.min(dataMax, Math.max(value, localMin ?? dataMin)));
|
|
@@ -2251,39 +2407,39 @@ function NumericRangeFilter({
|
|
|
2251
2407
|
setLocalMax(null);
|
|
2252
2408
|
}
|
|
2253
2409
|
}, [dataMin, dataMax, localMin]);
|
|
2254
|
-
const handleInputBlur = (0,
|
|
2410
|
+
const handleInputBlur = (0, import_react6.useCallback)(() => {
|
|
2255
2411
|
if (localMin === null && localMax === null) {
|
|
2256
2412
|
onChange(null);
|
|
2257
2413
|
} else {
|
|
2258
2414
|
onChange({ min: localMin, max: localMax });
|
|
2259
2415
|
}
|
|
2260
2416
|
}, [localMin, localMax, onChange]);
|
|
2261
|
-
const clearFilter = (0,
|
|
2417
|
+
const clearFilter = (0, import_react6.useCallback)(() => {
|
|
2262
2418
|
setLocalMin(null);
|
|
2263
2419
|
setLocalMax(null);
|
|
2264
2420
|
onChange(null);
|
|
2265
2421
|
}, [onChange]);
|
|
2266
|
-
const setFullRange = (0,
|
|
2422
|
+
const setFullRange = (0, import_react6.useCallback)(() => {
|
|
2267
2423
|
setLocalMin(dataMin);
|
|
2268
2424
|
setLocalMax(dataMax);
|
|
2269
2425
|
onChange({ min: dataMin, max: dataMax });
|
|
2270
2426
|
}, [dataMin, dataMax, onChange]);
|
|
2271
|
-
(0,
|
|
2427
|
+
(0, import_react6.useEffect)(() => {
|
|
2272
2428
|
setLocalMin(currentRange?.min ?? null);
|
|
2273
2429
|
setLocalMax(currentRange?.max ?? null);
|
|
2274
2430
|
}, [currentRange]);
|
|
2275
|
-
return /* @__PURE__ */ (0,
|
|
2276
|
-
/* @__PURE__ */ (0,
|
|
2277
|
-
/* @__PURE__ */ (0,
|
|
2278
|
-
/* @__PURE__ */ (0,
|
|
2431
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-range-filter", children: [
|
|
2432
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-range-info", children: [
|
|
2433
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-range-label", children: "Data range:" }),
|
|
2434
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "vpg-range-bounds", children: [
|
|
2279
2435
|
formatValue(dataMin),
|
|
2280
2436
|
" ",
|
|
2281
2437
|
"\u2013",
|
|
2282
2438
|
formatValue(dataMax)
|
|
2283
2439
|
] })
|
|
2284
2440
|
] }),
|
|
2285
|
-
/* @__PURE__ */ (0,
|
|
2286
|
-
/* @__PURE__ */ (0,
|
|
2441
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-slider-container", children: [
|
|
2442
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "vpg-slider-track", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2287
2443
|
"div",
|
|
2288
2444
|
{
|
|
2289
2445
|
className: "vpg-slider-fill",
|
|
@@ -2293,7 +2449,7 @@ function NumericRangeFilter({
|
|
|
2293
2449
|
}
|
|
2294
2450
|
}
|
|
2295
2451
|
) }),
|
|
2296
|
-
/* @__PURE__ */ (0,
|
|
2452
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2297
2453
|
"input",
|
|
2298
2454
|
{
|
|
2299
2455
|
type: "range",
|
|
@@ -2307,7 +2463,7 @@ function NumericRangeFilter({
|
|
|
2307
2463
|
onTouchEnd: handleSliderChange
|
|
2308
2464
|
}
|
|
2309
2465
|
),
|
|
2310
|
-
/* @__PURE__ */ (0,
|
|
2466
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2311
2467
|
"input",
|
|
2312
2468
|
{
|
|
2313
2469
|
type: "range",
|
|
@@ -2322,10 +2478,10 @@ function NumericRangeFilter({
|
|
|
2322
2478
|
}
|
|
2323
2479
|
)
|
|
2324
2480
|
] }),
|
|
2325
|
-
/* @__PURE__ */ (0,
|
|
2326
|
-
/* @__PURE__ */ (0,
|
|
2327
|
-
/* @__PURE__ */ (0,
|
|
2328
|
-
/* @__PURE__ */ (0,
|
|
2481
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-range-inputs", children: [
|
|
2482
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-input-group", children: [
|
|
2483
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("label", { className: "vpg-input-label", children: "Min" }),
|
|
2484
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2329
2485
|
"input",
|
|
2330
2486
|
{
|
|
2331
2487
|
type: "number",
|
|
@@ -2338,10 +2494,10 @@ function NumericRangeFilter({
|
|
|
2338
2494
|
}
|
|
2339
2495
|
)
|
|
2340
2496
|
] }),
|
|
2341
|
-
/* @__PURE__ */ (0,
|
|
2342
|
-
/* @__PURE__ */ (0,
|
|
2343
|
-
/* @__PURE__ */ (0,
|
|
2344
|
-
/* @__PURE__ */ (0,
|
|
2497
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "vpg-input-separator", children: "to" }),
|
|
2498
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-input-group", children: [
|
|
2499
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("label", { className: "vpg-input-label", children: "Max" }),
|
|
2500
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2345
2501
|
"input",
|
|
2346
2502
|
{
|
|
2347
2503
|
type: "number",
|
|
@@ -2355,15 +2511,15 @@ function NumericRangeFilter({
|
|
|
2355
2511
|
)
|
|
2356
2512
|
] })
|
|
2357
2513
|
] }),
|
|
2358
|
-
/* @__PURE__ */ (0,
|
|
2359
|
-
/* @__PURE__ */ (0,
|
|
2514
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-range-actions", children: [
|
|
2515
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
2360
2516
|
"button",
|
|
2361
2517
|
{
|
|
2362
2518
|
className: "vpg-range-btn",
|
|
2363
2519
|
disabled: !isFilterActive,
|
|
2364
2520
|
onClick: clearFilter,
|
|
2365
2521
|
children: [
|
|
2366
|
-
/* @__PURE__ */ (0,
|
|
2522
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2367
2523
|
"path",
|
|
2368
2524
|
{
|
|
2369
2525
|
strokeLinecap: "round",
|
|
@@ -2376,8 +2532,8 @@ function NumericRangeFilter({
|
|
|
2376
2532
|
]
|
|
2377
2533
|
}
|
|
2378
2534
|
),
|
|
2379
|
-
/* @__PURE__ */ (0,
|
|
2380
|
-
/* @__PURE__ */ (0,
|
|
2535
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { className: "vpg-range-btn", onClick: setFullRange, children: [
|
|
2536
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2381
2537
|
"path",
|
|
2382
2538
|
{
|
|
2383
2539
|
strokeLinecap: "round",
|
|
@@ -2389,8 +2545,8 @@ function NumericRangeFilter({
|
|
|
2389
2545
|
"Full Range"
|
|
2390
2546
|
] })
|
|
2391
2547
|
] }),
|
|
2392
|
-
isFilterActive && /* @__PURE__ */ (0,
|
|
2393
|
-
/* @__PURE__ */ (0,
|
|
2548
|
+
isFilterActive && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "vpg-filter-summary", children: [
|
|
2549
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2394
2550
|
"path",
|
|
2395
2551
|
{
|
|
2396
2552
|
strokeLinecap: "round",
|
|
@@ -2399,15 +2555,15 @@ function NumericRangeFilter({
|
|
|
2399
2555
|
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"
|
|
2400
2556
|
}
|
|
2401
2557
|
) }),
|
|
2402
|
-
/* @__PURE__ */ (0,
|
|
2558
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
|
|
2403
2559
|
"Showing values",
|
|
2404
2560
|
" ",
|
|
2405
|
-
localMin !== null && /* @__PURE__ */ (0,
|
|
2561
|
+
localMin !== null && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("strong", { children: [
|
|
2406
2562
|
"\u2265",
|
|
2407
2563
|
formatValue(localMin)
|
|
2408
2564
|
] }),
|
|
2409
2565
|
localMin !== null && localMax !== null && " and ",
|
|
2410
|
-
localMax !== null && /* @__PURE__ */ (0,
|
|
2566
|
+
localMax !== null && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("strong", { children: [
|
|
2411
2567
|
"\u2264",
|
|
2412
2568
|
formatValue(localMax)
|
|
2413
2569
|
] })
|
|
@@ -2417,45 +2573,53 @@ function NumericRangeFilter({
|
|
|
2417
2573
|
}
|
|
2418
2574
|
|
|
2419
2575
|
// src/components/ColumnFilter.tsx
|
|
2420
|
-
var
|
|
2576
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
2421
2577
|
function ColumnFilter({
|
|
2422
2578
|
columnName,
|
|
2423
2579
|
stats,
|
|
2424
2580
|
selectedValues,
|
|
2425
2581
|
sortDirection,
|
|
2426
2582
|
numericRange,
|
|
2583
|
+
dateRange,
|
|
2584
|
+
numberFormat,
|
|
2585
|
+
dateFormat,
|
|
2427
2586
|
onFilter,
|
|
2428
2587
|
onSort,
|
|
2429
2588
|
onClose,
|
|
2430
|
-
onRangeFilter
|
|
2589
|
+
onRangeFilter,
|
|
2590
|
+
onDateRangeFilter
|
|
2431
2591
|
}) {
|
|
2432
|
-
const [searchQuery, setSearchQuery] = (0,
|
|
2433
|
-
const [localSelected, setLocalSelected] = (0,
|
|
2434
|
-
const dropdownRef = (0,
|
|
2435
|
-
const searchInputRef = (0,
|
|
2592
|
+
const [searchQuery, setSearchQuery] = (0, import_react7.useState)("");
|
|
2593
|
+
const [localSelected, setLocalSelected] = (0, import_react7.useState)(new Set(selectedValues));
|
|
2594
|
+
const dropdownRef = (0, import_react7.useRef)(null);
|
|
2595
|
+
const searchInputRef = (0, import_react7.useRef)(null);
|
|
2436
2596
|
const isNumericColumn = stats.type === "number" && stats.numericMin !== void 0 && stats.numericMax !== void 0;
|
|
2437
|
-
const
|
|
2438
|
-
const [
|
|
2597
|
+
const isDateColumn = stats.type === "date" && stats.dateMin !== void 0 && stats.dateMax !== void 0;
|
|
2598
|
+
const [filterMode, setFilterMode] = (0, import_react7.useState)(
|
|
2599
|
+
numericRange || dateRange ? "range" : "values"
|
|
2600
|
+
);
|
|
2601
|
+
const [localRange, setLocalRange] = (0, import_react7.useState)(numericRange ?? null);
|
|
2602
|
+
const [localDateRange, setLocalDateRange] = (0, import_react7.useState)(dateRange ?? null);
|
|
2439
2603
|
const hasBlankValues = stats.nullCount > 0;
|
|
2440
|
-
const filteredValues = (0,
|
|
2604
|
+
const filteredValues = (0, import_react7.useMemo)(() => {
|
|
2441
2605
|
const values = stats.uniqueValues;
|
|
2442
2606
|
if (!searchQuery)
|
|
2443
2607
|
return values;
|
|
2444
2608
|
const query = searchQuery.toLowerCase();
|
|
2445
2609
|
return values.filter((v) => v.toLowerCase().includes(query));
|
|
2446
2610
|
}, [stats.uniqueValues, searchQuery]);
|
|
2447
|
-
const allValues = (0,
|
|
2611
|
+
const allValues = (0, import_react7.useMemo)(() => {
|
|
2448
2612
|
const values = [...filteredValues];
|
|
2449
2613
|
if (hasBlankValues && (!searchQuery || "(blank)".includes(searchQuery.toLowerCase()))) {
|
|
2450
2614
|
values.unshift("(blank)");
|
|
2451
2615
|
}
|
|
2452
2616
|
return values;
|
|
2453
2617
|
}, [filteredValues, hasBlankValues, searchQuery]);
|
|
2454
|
-
const _isAllSelected = (0,
|
|
2618
|
+
const _isAllSelected = (0, import_react7.useMemo)(
|
|
2455
2619
|
() => allValues.every((v) => localSelected.has(v)),
|
|
2456
2620
|
[allValues, localSelected]
|
|
2457
2621
|
);
|
|
2458
|
-
const toggleValue = (0,
|
|
2622
|
+
const toggleValue = (0, import_react7.useCallback)((value) => {
|
|
2459
2623
|
setLocalSelected((prev) => {
|
|
2460
2624
|
const next = new Set(prev);
|
|
2461
2625
|
if (next.has(value)) {
|
|
@@ -2466,7 +2630,7 @@ function ColumnFilter({
|
|
|
2466
2630
|
return next;
|
|
2467
2631
|
});
|
|
2468
2632
|
}, []);
|
|
2469
|
-
const selectAll = (0,
|
|
2633
|
+
const selectAll = (0, import_react7.useCallback)(() => {
|
|
2470
2634
|
setLocalSelected((prev) => {
|
|
2471
2635
|
const next = new Set(prev);
|
|
2472
2636
|
for (const value of allValues) {
|
|
@@ -2475,10 +2639,10 @@ function ColumnFilter({
|
|
|
2475
2639
|
return next;
|
|
2476
2640
|
});
|
|
2477
2641
|
}, [allValues]);
|
|
2478
|
-
const clearAll = (0,
|
|
2642
|
+
const clearAll = (0, import_react7.useCallback)(() => {
|
|
2479
2643
|
setLocalSelected(/* @__PURE__ */ new Set());
|
|
2480
2644
|
}, []);
|
|
2481
|
-
const applyFilter = (0,
|
|
2645
|
+
const applyFilter = (0, import_react7.useCallback)(() => {
|
|
2482
2646
|
if (localSelected.size === 0) {
|
|
2483
2647
|
onFilter([]);
|
|
2484
2648
|
} else {
|
|
@@ -2486,30 +2650,42 @@ function ColumnFilter({
|
|
|
2486
2650
|
}
|
|
2487
2651
|
onClose();
|
|
2488
2652
|
}, [localSelected, onFilter, onClose]);
|
|
2489
|
-
const sortAscending = (0,
|
|
2653
|
+
const sortAscending = (0, import_react7.useCallback)(() => {
|
|
2490
2654
|
onSort(sortDirection === "asc" ? null : "asc");
|
|
2491
2655
|
}, [sortDirection, onSort]);
|
|
2492
|
-
const sortDescending = (0,
|
|
2656
|
+
const sortDescending = (0, import_react7.useCallback)(() => {
|
|
2493
2657
|
onSort(sortDirection === "desc" ? null : "desc");
|
|
2494
2658
|
}, [sortDirection, onSort]);
|
|
2495
|
-
const clearFilter = (0,
|
|
2659
|
+
const clearFilter = (0, import_react7.useCallback)(() => {
|
|
2496
2660
|
setLocalSelected(/* @__PURE__ */ new Set());
|
|
2497
2661
|
onFilter([]);
|
|
2498
2662
|
onClose();
|
|
2499
2663
|
}, [onFilter, onClose]);
|
|
2500
|
-
const handleRangeChange = (0,
|
|
2664
|
+
const handleRangeChange = (0, import_react7.useCallback)((range) => {
|
|
2501
2665
|
setLocalRange(range);
|
|
2502
2666
|
}, []);
|
|
2503
|
-
const applyRangeFilter = (0,
|
|
2667
|
+
const applyRangeFilter = (0, import_react7.useCallback)(() => {
|
|
2504
2668
|
onRangeFilter?.(localRange);
|
|
2505
2669
|
onClose();
|
|
2506
2670
|
}, [localRange, onRangeFilter, onClose]);
|
|
2507
|
-
const clearRangeFilter = (0,
|
|
2671
|
+
const clearRangeFilter = (0, import_react7.useCallback)(() => {
|
|
2508
2672
|
setLocalRange(null);
|
|
2509
2673
|
onRangeFilter?.(null);
|
|
2510
2674
|
onClose();
|
|
2511
2675
|
}, [onRangeFilter, onClose]);
|
|
2512
|
-
(0,
|
|
2676
|
+
const handleDateRangeChange = (0, import_react7.useCallback)((range) => {
|
|
2677
|
+
setLocalDateRange(range);
|
|
2678
|
+
}, []);
|
|
2679
|
+
const applyDateRangeFilter = (0, import_react7.useCallback)(() => {
|
|
2680
|
+
onDateRangeFilter?.(localDateRange);
|
|
2681
|
+
onClose();
|
|
2682
|
+
}, [localDateRange, onDateRangeFilter, onClose]);
|
|
2683
|
+
const clearDateRangeFilter = (0, import_react7.useCallback)(() => {
|
|
2684
|
+
setLocalDateRange(null);
|
|
2685
|
+
onDateRangeFilter?.(null);
|
|
2686
|
+
onClose();
|
|
2687
|
+
}, [onDateRangeFilter, onClose]);
|
|
2688
|
+
(0, import_react7.useEffect)(() => {
|
|
2513
2689
|
const handleClickOutside = (event) => {
|
|
2514
2690
|
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
|
2515
2691
|
onClose();
|
|
@@ -2518,7 +2694,7 @@ function ColumnFilter({
|
|
|
2518
2694
|
document.addEventListener("mousedown", handleClickOutside);
|
|
2519
2695
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
2520
2696
|
}, [onClose]);
|
|
2521
|
-
(0,
|
|
2697
|
+
(0, import_react7.useEffect)(() => {
|
|
2522
2698
|
const handleKeydown = (event) => {
|
|
2523
2699
|
if (event.key === "Escape") {
|
|
2524
2700
|
onClose();
|
|
@@ -2529,36 +2705,42 @@ function ColumnFilter({
|
|
|
2529
2705
|
document.addEventListener("keydown", handleKeydown);
|
|
2530
2706
|
return () => document.removeEventListener("keydown", handleKeydown);
|
|
2531
2707
|
}, [onClose, applyFilter]);
|
|
2532
|
-
(0,
|
|
2708
|
+
(0, import_react7.useEffect)(() => {
|
|
2533
2709
|
searchInputRef.current?.focus();
|
|
2534
2710
|
}, []);
|
|
2535
|
-
(0,
|
|
2711
|
+
(0, import_react7.useEffect)(() => {
|
|
2536
2712
|
setLocalSelected(new Set(selectedValues));
|
|
2537
2713
|
}, [selectedValues]);
|
|
2538
|
-
(0,
|
|
2714
|
+
(0, import_react7.useEffect)(() => {
|
|
2539
2715
|
setLocalRange(numericRange ?? null);
|
|
2540
2716
|
if (numericRange) {
|
|
2541
2717
|
setFilterMode("range");
|
|
2542
2718
|
}
|
|
2543
2719
|
}, [numericRange]);
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2720
|
+
(0, import_react7.useEffect)(() => {
|
|
2721
|
+
setLocalDateRange(dateRange ?? null);
|
|
2722
|
+
if (dateRange) {
|
|
2723
|
+
setFilterMode("range");
|
|
2724
|
+
}
|
|
2725
|
+
}, [dateRange]);
|
|
2726
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { ref: dropdownRef, className: "vpg-filter-dropdown", children: [
|
|
2727
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-filter-header", children: [
|
|
2728
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vpg-filter-title", children: columnName }),
|
|
2729
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "vpg-filter-count", children: [
|
|
2548
2730
|
stats.uniqueValues.length.toLocaleString(),
|
|
2549
2731
|
" ",
|
|
2550
2732
|
"unique"
|
|
2551
2733
|
] })
|
|
2552
2734
|
] }),
|
|
2553
|
-
/* @__PURE__ */ (0,
|
|
2554
|
-
/* @__PURE__ */ (0,
|
|
2735
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-sort-controls", children: [
|
|
2736
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
2555
2737
|
"button",
|
|
2556
2738
|
{
|
|
2557
2739
|
className: `vpg-sort-btn ${sortDirection === "asc" ? "active" : ""}`,
|
|
2558
|
-
title: isNumericColumn ? "Sort Low to High" : "Sort A to Z",
|
|
2740
|
+
title: isDateColumn ? "Sort Old to New" : isNumericColumn ? "Sort Low to High" : "Sort A to Z",
|
|
2559
2741
|
onClick: sortAscending,
|
|
2560
2742
|
children: [
|
|
2561
|
-
/* @__PURE__ */ (0,
|
|
2743
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2562
2744
|
"path",
|
|
2563
2745
|
{
|
|
2564
2746
|
strokeLinecap: "round",
|
|
@@ -2567,18 +2749,18 @@ function ColumnFilter({
|
|
|
2567
2749
|
d: "M3 4h13M3 8h9m-9 4h6m4 0l4-4m0 0l4 4m-4-4v12"
|
|
2568
2750
|
}
|
|
2569
2751
|
) }),
|
|
2570
|
-
/* @__PURE__ */ (0,
|
|
2752
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: isDateColumn ? "Old\u2192New" : isNumericColumn ? "1\u21929" : "A\u2192Z" })
|
|
2571
2753
|
]
|
|
2572
2754
|
}
|
|
2573
2755
|
),
|
|
2574
|
-
/* @__PURE__ */ (0,
|
|
2756
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
2575
2757
|
"button",
|
|
2576
2758
|
{
|
|
2577
2759
|
className: `vpg-sort-btn ${sortDirection === "desc" ? "active" : ""}`,
|
|
2578
|
-
title: isNumericColumn ? "Sort High to Low" : "Sort Z to A",
|
|
2760
|
+
title: isDateColumn ? "Sort New to Old" : isNumericColumn ? "Sort High to Low" : "Sort Z to A",
|
|
2579
2761
|
onClick: sortDescending,
|
|
2580
2762
|
children: [
|
|
2581
|
-
/* @__PURE__ */ (0,
|
|
2763
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2582
2764
|
"path",
|
|
2583
2765
|
{
|
|
2584
2766
|
strokeLinecap: "round",
|
|
@@ -2587,20 +2769,20 @@ function ColumnFilter({
|
|
|
2587
2769
|
d: "M3 4h13M3 8h9m-9 4h9m5-4v12m0 0l-4-4m4 4l4-4"
|
|
2588
2770
|
}
|
|
2589
2771
|
) }),
|
|
2590
|
-
/* @__PURE__ */ (0,
|
|
2772
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: isDateColumn ? "New\u2192Old" : isNumericColumn ? "9\u21921" : "Z\u2192A" })
|
|
2591
2773
|
]
|
|
2592
2774
|
}
|
|
2593
2775
|
)
|
|
2594
2776
|
] }),
|
|
2595
|
-
/* @__PURE__ */ (0,
|
|
2596
|
-
isNumericColumn && /* @__PURE__ */ (0,
|
|
2597
|
-
/* @__PURE__ */ (0,
|
|
2777
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "vpg-divider" }),
|
|
2778
|
+
(isNumericColumn || isDateColumn) && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-filter-tabs", children: [
|
|
2779
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
2598
2780
|
"button",
|
|
2599
2781
|
{
|
|
2600
2782
|
className: `vpg-tab-btn ${filterMode === "values" ? "active" : ""}`,
|
|
2601
2783
|
onClick: () => setFilterMode("values"),
|
|
2602
2784
|
children: [
|
|
2603
|
-
/* @__PURE__ */ (0,
|
|
2785
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2604
2786
|
"path",
|
|
2605
2787
|
{
|
|
2606
2788
|
strokeLinecap: "round",
|
|
@@ -2613,13 +2795,13 @@ function ColumnFilter({
|
|
|
2613
2795
|
]
|
|
2614
2796
|
}
|
|
2615
2797
|
),
|
|
2616
|
-
/* @__PURE__ */ (0,
|
|
2798
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
2617
2799
|
"button",
|
|
2618
2800
|
{
|
|
2619
2801
|
className: `vpg-tab-btn ${filterMode === "range" ? "active" : ""}`,
|
|
2620
2802
|
onClick: () => setFilterMode("range"),
|
|
2621
2803
|
children: [
|
|
2622
|
-
/* @__PURE__ */ (0,
|
|
2804
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2623
2805
|
"path",
|
|
2624
2806
|
{
|
|
2625
2807
|
strokeLinecap: "round",
|
|
@@ -2633,9 +2815,9 @@ function ColumnFilter({
|
|
|
2633
2815
|
}
|
|
2634
2816
|
)
|
|
2635
2817
|
] }),
|
|
2636
|
-
(!isNumericColumn || filterMode === "values") && /* @__PURE__ */ (0,
|
|
2637
|
-
/* @__PURE__ */ (0,
|
|
2638
|
-
/* @__PURE__ */ (0,
|
|
2818
|
+
(!isNumericColumn && !isDateColumn || filterMode === "values") && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2819
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-search-container", children: [
|
|
2820
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { className: "vpg-search-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2639
2821
|
"path",
|
|
2640
2822
|
{
|
|
2641
2823
|
strokeLinecap: "round",
|
|
@@ -2644,7 +2826,7 @@ function ColumnFilter({
|
|
|
2644
2826
|
d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
|
|
2645
2827
|
}
|
|
2646
2828
|
) }),
|
|
2647
|
-
/* @__PURE__ */ (0,
|
|
2829
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2648
2830
|
"input",
|
|
2649
2831
|
{
|
|
2650
2832
|
ref: searchInputRef,
|
|
@@ -2655,11 +2837,11 @@ function ColumnFilter({
|
|
|
2655
2837
|
className: "vpg-search-input"
|
|
2656
2838
|
}
|
|
2657
2839
|
),
|
|
2658
|
-
searchQuery && /* @__PURE__ */ (0,
|
|
2840
|
+
searchQuery && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "vpg-clear-search", onClick: () => setSearchQuery(""), children: "\xD7" })
|
|
2659
2841
|
] }),
|
|
2660
|
-
/* @__PURE__ */ (0,
|
|
2661
|
-
/* @__PURE__ */ (0,
|
|
2662
|
-
/* @__PURE__ */ (0,
|
|
2842
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-bulk-actions", children: [
|
|
2843
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { className: "vpg-bulk-btn", onClick: selectAll, children: [
|
|
2844
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2663
2845
|
"path",
|
|
2664
2846
|
{
|
|
2665
2847
|
strokeLinecap: "round",
|
|
@@ -2670,8 +2852,8 @@ function ColumnFilter({
|
|
|
2670
2852
|
) }),
|
|
2671
2853
|
"Select All"
|
|
2672
2854
|
] }),
|
|
2673
|
-
/* @__PURE__ */ (0,
|
|
2674
|
-
/* @__PURE__ */ (0,
|
|
2855
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { className: "vpg-bulk-btn", onClick: clearAll, children: [
|
|
2856
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2675
2857
|
"path",
|
|
2676
2858
|
{
|
|
2677
2859
|
strokeLinecap: "round",
|
|
@@ -2683,13 +2865,13 @@ function ColumnFilter({
|
|
|
2683
2865
|
"Clear All"
|
|
2684
2866
|
] })
|
|
2685
2867
|
] }),
|
|
2686
|
-
/* @__PURE__ */ (0,
|
|
2687
|
-
allValues.map((value) => /* @__PURE__ */ (0,
|
|
2868
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-values-list", children: [
|
|
2869
|
+
allValues.map((value) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
2688
2870
|
"label",
|
|
2689
2871
|
{
|
|
2690
2872
|
className: `vpg-value-item ${localSelected.has(value) ? "selected" : ""}`,
|
|
2691
2873
|
children: [
|
|
2692
|
-
/* @__PURE__ */ (0,
|
|
2874
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2693
2875
|
"input",
|
|
2694
2876
|
{
|
|
2695
2877
|
type: "checkbox",
|
|
@@ -2698,48 +2880,66 @@ function ColumnFilter({
|
|
|
2698
2880
|
className: "vpg-value-checkbox"
|
|
2699
2881
|
}
|
|
2700
2882
|
),
|
|
2701
|
-
/* @__PURE__ */ (0,
|
|
2883
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: `vpg-value-text ${value === "(blank)" ? "vpg-blank" : ""}`, children: value })
|
|
2702
2884
|
]
|
|
2703
2885
|
},
|
|
2704
2886
|
value
|
|
2705
2887
|
)),
|
|
2706
|
-
allValues.length === 0 && /* @__PURE__ */ (0,
|
|
2888
|
+
allValues.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "vpg-no-results", children: "No matching values" })
|
|
2707
2889
|
] }),
|
|
2708
|
-
/* @__PURE__ */ (0,
|
|
2709
|
-
/* @__PURE__ */ (0,
|
|
2710
|
-
/* @__PURE__ */ (0,
|
|
2890
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-filter-footer", children: [
|
|
2891
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "vpg-btn-clear", onClick: clearFilter, children: "Clear Filter" }),
|
|
2892
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "vpg-btn-apply", onClick: applyFilter, children: "Apply" })
|
|
2711
2893
|
] })
|
|
2712
2894
|
] }),
|
|
2713
|
-
isNumericColumn && filterMode === "range" && /* @__PURE__ */ (0,
|
|
2714
|
-
/* @__PURE__ */ (0,
|
|
2895
|
+
isNumericColumn && filterMode === "range" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2896
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2715
2897
|
NumericRangeFilter,
|
|
2716
2898
|
{
|
|
2717
2899
|
dataMin: stats.numericMin,
|
|
2718
2900
|
dataMax: stats.numericMax,
|
|
2719
2901
|
currentRange: localRange,
|
|
2720
|
-
onChange: handleRangeChange
|
|
2902
|
+
onChange: handleRangeChange,
|
|
2903
|
+
numberFormat
|
|
2721
2904
|
}
|
|
2722
2905
|
),
|
|
2723
|
-
/* @__PURE__ */ (0,
|
|
2724
|
-
/* @__PURE__ */ (0,
|
|
2725
|
-
/* @__PURE__ */ (0,
|
|
2906
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-filter-footer", children: [
|
|
2907
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "vpg-btn-clear", onClick: clearRangeFilter, children: "Clear Filter" }),
|
|
2908
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "vpg-btn-apply", onClick: applyRangeFilter, children: "Apply" })
|
|
2909
|
+
] })
|
|
2910
|
+
] }),
|
|
2911
|
+
isDateColumn && filterMode === "range" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2912
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2913
|
+
DateRangeFilter,
|
|
2914
|
+
{
|
|
2915
|
+
dataMin: stats.dateMin,
|
|
2916
|
+
dataMax: stats.dateMax,
|
|
2917
|
+
currentRange: localDateRange,
|
|
2918
|
+
onChange: handleDateRangeChange,
|
|
2919
|
+
dateFormat
|
|
2920
|
+
}
|
|
2921
|
+
),
|
|
2922
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vpg-filter-footer", children: [
|
|
2923
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "vpg-btn-clear", onClick: clearDateRangeFilter, children: "Clear Filter" }),
|
|
2924
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "vpg-btn-apply", onClick: applyDateRangeFilter, children: "Apply" })
|
|
2726
2925
|
] })
|
|
2727
2926
|
] })
|
|
2728
2927
|
] });
|
|
2729
2928
|
}
|
|
2730
2929
|
|
|
2731
2930
|
// src/components/DataGrid.tsx
|
|
2732
|
-
var
|
|
2931
|
+
var import_tinypivot_core13 = require("@smallwebco/tinypivot-core");
|
|
2932
|
+
var import_react14 = require("react");
|
|
2733
2933
|
var import_react_dom2 = require("react-dom");
|
|
2734
2934
|
|
|
2735
2935
|
// src/hooks/useExcelGrid.ts
|
|
2736
|
-
var
|
|
2936
|
+
var import_tinypivot_core7 = require("@smallwebco/tinypivot-core");
|
|
2737
2937
|
var import_react_table = require("@tanstack/react-table");
|
|
2738
|
-
var
|
|
2938
|
+
var import_react8 = require("react");
|
|
2739
2939
|
var multiSelectFilter = (row, columnId, filterValue) => {
|
|
2740
2940
|
if (!filterValue)
|
|
2741
2941
|
return true;
|
|
2742
|
-
if ((0,
|
|
2942
|
+
if ((0, import_tinypivot_core7.isNumericRange)(filterValue)) {
|
|
2743
2943
|
const cellValue = row.getValue(columnId);
|
|
2744
2944
|
if (cellValue === null || cellValue === void 0 || cellValue === "") {
|
|
2745
2945
|
return false;
|
|
@@ -2754,6 +2954,22 @@ var multiSelectFilter = (row, columnId, filterValue) => {
|
|
|
2754
2954
|
return false;
|
|
2755
2955
|
return true;
|
|
2756
2956
|
}
|
|
2957
|
+
if ((0, import_tinypivot_core7.isDateRange)(filterValue)) {
|
|
2958
|
+
const cellValue = row.getValue(columnId);
|
|
2959
|
+
if (cellValue === null || cellValue === void 0 || cellValue === "") {
|
|
2960
|
+
return false;
|
|
2961
|
+
}
|
|
2962
|
+
const dateObj = cellValue instanceof Date ? cellValue : new Date(String(cellValue));
|
|
2963
|
+
if (Number.isNaN(dateObj.getTime()))
|
|
2964
|
+
return false;
|
|
2965
|
+
const dateStr = dateObj.toISOString().split("T")[0];
|
|
2966
|
+
const { min, max } = filterValue;
|
|
2967
|
+
if (min !== null && dateStr < min)
|
|
2968
|
+
return false;
|
|
2969
|
+
if (max !== null && dateStr > max)
|
|
2970
|
+
return false;
|
|
2971
|
+
return true;
|
|
2972
|
+
}
|
|
2757
2973
|
if (Array.isArray(filterValue) && filterValue.length > 0) {
|
|
2758
2974
|
const cellValue = row.getValue(columnId);
|
|
2759
2975
|
const cellString = cellValue === null || cellValue === void 0 || cellValue === "" ? "(blank)" : String(cellValue);
|
|
@@ -2763,25 +2979,25 @@ var multiSelectFilter = (row, columnId, filterValue) => {
|
|
|
2763
2979
|
};
|
|
2764
2980
|
function useExcelGrid(options) {
|
|
2765
2981
|
const { data, enableSorting = true, enableFiltering = true } = options;
|
|
2766
|
-
const [sorting, setSorting] = (0,
|
|
2767
|
-
const [columnFilters, setColumnFilters] = (0,
|
|
2768
|
-
const [columnVisibility, setColumnVisibility] = (0,
|
|
2769
|
-
const [globalFilter, setGlobalFilter] = (0,
|
|
2770
|
-
const [columnStatsCache, setColumnStatsCache] = (0,
|
|
2771
|
-
const dataSignature = (0,
|
|
2982
|
+
const [sorting, setSorting] = (0, import_react8.useState)([]);
|
|
2983
|
+
const [columnFilters, setColumnFilters] = (0, import_react8.useState)([]);
|
|
2984
|
+
const [columnVisibility, setColumnVisibility] = (0, import_react8.useState)({});
|
|
2985
|
+
const [globalFilter, setGlobalFilter] = (0, import_react8.useState)("");
|
|
2986
|
+
const [columnStatsCache, setColumnStatsCache] = (0, import_react8.useState)({});
|
|
2987
|
+
const dataSignature = (0, import_react8.useMemo)(
|
|
2772
2988
|
() => `${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
|
2773
2989
|
[data]
|
|
2774
2990
|
);
|
|
2775
|
-
const columnKeys = (0,
|
|
2991
|
+
const columnKeys = (0, import_react8.useMemo)(() => {
|
|
2776
2992
|
if (data.length === 0)
|
|
2777
2993
|
return [];
|
|
2778
2994
|
return Object.keys(data[0]);
|
|
2779
2995
|
}, [data]);
|
|
2780
|
-
const getColumnStats = (0,
|
|
2996
|
+
const getColumnStats = (0, import_react8.useCallback)(
|
|
2781
2997
|
(columnKey) => {
|
|
2782
2998
|
const cacheKey = `${columnKey}-${dataSignature}`;
|
|
2783
2999
|
if (!columnStatsCache[cacheKey]) {
|
|
2784
|
-
const stats = (0,
|
|
3000
|
+
const stats = (0, import_tinypivot_core7.getColumnUniqueValues)(data, columnKey);
|
|
2785
3001
|
setColumnStatsCache((prev) => ({ ...prev, [cacheKey]: stats }));
|
|
2786
3002
|
return stats;
|
|
2787
3003
|
}
|
|
@@ -2789,20 +3005,20 @@ function useExcelGrid(options) {
|
|
|
2789
3005
|
},
|
|
2790
3006
|
[data, columnStatsCache, dataSignature]
|
|
2791
3007
|
);
|
|
2792
|
-
const clearStatsCache = (0,
|
|
3008
|
+
const clearStatsCache = (0, import_react8.useCallback)(() => {
|
|
2793
3009
|
setColumnStatsCache({});
|
|
2794
3010
|
}, []);
|
|
2795
|
-
(0,
|
|
3011
|
+
(0, import_react8.useEffect)(() => {
|
|
2796
3012
|
clearStatsCache();
|
|
2797
3013
|
}, [dataSignature, clearStatsCache]);
|
|
2798
|
-
const columnDefs = (0,
|
|
3014
|
+
const columnDefs = (0, import_react8.useMemo)(() => {
|
|
2799
3015
|
return columnKeys.map((key) => {
|
|
2800
3016
|
const stats = getColumnStats(key);
|
|
2801
3017
|
return {
|
|
2802
3018
|
id: key,
|
|
2803
3019
|
accessorKey: key,
|
|
2804
3020
|
header: key,
|
|
2805
|
-
cell: (info) => (0,
|
|
3021
|
+
cell: (info) => (0, import_tinypivot_core7.formatCellValue)(info.getValue(), stats.type),
|
|
2806
3022
|
filterFn: multiSelectFilter,
|
|
2807
3023
|
meta: {
|
|
2808
3024
|
type: stats.type,
|
|
@@ -2835,14 +3051,24 @@ function useExcelGrid(options) {
|
|
|
2835
3051
|
});
|
|
2836
3052
|
const filteredRowCount = table.getFilteredRowModel().rows.length;
|
|
2837
3053
|
const totalRowCount = data.length;
|
|
2838
|
-
const activeFilters = (0,
|
|
3054
|
+
const activeFilters = (0, import_react8.useMemo)(() => {
|
|
2839
3055
|
return columnFilters.map((f) => {
|
|
2840
3056
|
const filterValue = f.value;
|
|
2841
|
-
if (filterValue && (0,
|
|
3057
|
+
if (filterValue && (0, import_tinypivot_core7.isNumericRange)(filterValue)) {
|
|
2842
3058
|
return {
|
|
2843
3059
|
column: f.id,
|
|
2844
3060
|
type: "range",
|
|
2845
3061
|
range: filterValue,
|
|
3062
|
+
dateRange: null,
|
|
3063
|
+
values: []
|
|
3064
|
+
};
|
|
3065
|
+
}
|
|
3066
|
+
if (filterValue && (0, import_tinypivot_core7.isDateRange)(filterValue)) {
|
|
3067
|
+
return {
|
|
3068
|
+
column: f.id,
|
|
3069
|
+
type: "dateRange",
|
|
3070
|
+
range: null,
|
|
3071
|
+
dateRange: filterValue,
|
|
2846
3072
|
values: []
|
|
2847
3073
|
};
|
|
2848
3074
|
}
|
|
@@ -2850,11 +3076,12 @@ function useExcelGrid(options) {
|
|
|
2850
3076
|
column: f.id,
|
|
2851
3077
|
type: "values",
|
|
2852
3078
|
values: Array.isArray(filterValue) ? filterValue : [],
|
|
2853
|
-
range: null
|
|
3079
|
+
range: null,
|
|
3080
|
+
dateRange: null
|
|
2854
3081
|
};
|
|
2855
3082
|
});
|
|
2856
3083
|
}, [columnFilters]);
|
|
2857
|
-
const hasActiveFilter = (0,
|
|
3084
|
+
const hasActiveFilter = (0, import_react8.useCallback)(
|
|
2858
3085
|
(columnId) => {
|
|
2859
3086
|
const column = table.getColumn(columnId);
|
|
2860
3087
|
if (!column)
|
|
@@ -2862,14 +3089,17 @@ function useExcelGrid(options) {
|
|
|
2862
3089
|
const filterValue = column.getFilterValue();
|
|
2863
3090
|
if (!filterValue)
|
|
2864
3091
|
return false;
|
|
2865
|
-
if ((0,
|
|
3092
|
+
if ((0, import_tinypivot_core7.isNumericRange)(filterValue)) {
|
|
3093
|
+
return filterValue.min !== null || filterValue.max !== null;
|
|
3094
|
+
}
|
|
3095
|
+
if ((0, import_tinypivot_core7.isDateRange)(filterValue)) {
|
|
2866
3096
|
return filterValue.min !== null || filterValue.max !== null;
|
|
2867
3097
|
}
|
|
2868
3098
|
return Array.isArray(filterValue) && filterValue.length > 0;
|
|
2869
3099
|
},
|
|
2870
3100
|
[table]
|
|
2871
3101
|
);
|
|
2872
|
-
const setColumnFilter = (0,
|
|
3102
|
+
const setColumnFilter = (0, import_react8.useCallback)(
|
|
2873
3103
|
(columnId, values) => {
|
|
2874
3104
|
const column = table.getColumn(columnId);
|
|
2875
3105
|
if (column) {
|
|
@@ -2878,7 +3108,7 @@ function useExcelGrid(options) {
|
|
|
2878
3108
|
},
|
|
2879
3109
|
[table]
|
|
2880
3110
|
);
|
|
2881
|
-
const setNumericRangeFilter = (0,
|
|
3111
|
+
const setNumericRangeFilter = (0, import_react8.useCallback)(
|
|
2882
3112
|
(columnId, range) => {
|
|
2883
3113
|
const column = table.getColumn(columnId);
|
|
2884
3114
|
if (column) {
|
|
@@ -2891,25 +3121,51 @@ function useExcelGrid(options) {
|
|
|
2891
3121
|
},
|
|
2892
3122
|
[table]
|
|
2893
3123
|
);
|
|
2894
|
-
const getNumericRangeFilter = (0,
|
|
3124
|
+
const getNumericRangeFilter = (0, import_react8.useCallback)(
|
|
2895
3125
|
(columnId) => {
|
|
2896
3126
|
const column = table.getColumn(columnId);
|
|
2897
3127
|
if (!column)
|
|
2898
3128
|
return null;
|
|
2899
3129
|
const filterValue = column.getFilterValue();
|
|
2900
|
-
if (filterValue && (0,
|
|
3130
|
+
if (filterValue && (0, import_tinypivot_core7.isNumericRange)(filterValue)) {
|
|
2901
3131
|
return filterValue;
|
|
2902
3132
|
}
|
|
2903
3133
|
return null;
|
|
2904
3134
|
},
|
|
2905
3135
|
[table]
|
|
2906
3136
|
);
|
|
2907
|
-
const
|
|
3137
|
+
const setDateRangeFilter = (0, import_react8.useCallback)(
|
|
3138
|
+
(columnId, range) => {
|
|
3139
|
+
const column = table.getColumn(columnId);
|
|
3140
|
+
if (column) {
|
|
3141
|
+
if (!range || range.min === null && range.max === null) {
|
|
3142
|
+
column.setFilterValue(void 0);
|
|
3143
|
+
} else {
|
|
3144
|
+
column.setFilterValue(range);
|
|
3145
|
+
}
|
|
3146
|
+
}
|
|
3147
|
+
},
|
|
3148
|
+
[table]
|
|
3149
|
+
);
|
|
3150
|
+
const getDateRangeFilter = (0, import_react8.useCallback)(
|
|
3151
|
+
(columnId) => {
|
|
3152
|
+
const column = table.getColumn(columnId);
|
|
3153
|
+
if (!column)
|
|
3154
|
+
return null;
|
|
3155
|
+
const filterValue = column.getFilterValue();
|
|
3156
|
+
if (filterValue && (0, import_tinypivot_core7.isDateRange)(filterValue)) {
|
|
3157
|
+
return filterValue;
|
|
3158
|
+
}
|
|
3159
|
+
return null;
|
|
3160
|
+
},
|
|
3161
|
+
[table]
|
|
3162
|
+
);
|
|
3163
|
+
const clearAllFilters = (0, import_react8.useCallback)(() => {
|
|
2908
3164
|
table.resetColumnFilters();
|
|
2909
3165
|
setGlobalFilter("");
|
|
2910
3166
|
setColumnFilters([]);
|
|
2911
3167
|
}, [table]);
|
|
2912
|
-
const getColumnFilterValues = (0,
|
|
3168
|
+
const getColumnFilterValues = (0, import_react8.useCallback)(
|
|
2913
3169
|
(columnId) => {
|
|
2914
3170
|
const column = table.getColumn(columnId);
|
|
2915
3171
|
if (!column)
|
|
@@ -2919,7 +3175,7 @@ function useExcelGrid(options) {
|
|
|
2919
3175
|
},
|
|
2920
3176
|
[table]
|
|
2921
3177
|
);
|
|
2922
|
-
const toggleSort = (0,
|
|
3178
|
+
const toggleSort = (0, import_react8.useCallback)((columnId) => {
|
|
2923
3179
|
setSorting((prev) => {
|
|
2924
3180
|
const current = prev.find((s) => s.id === columnId);
|
|
2925
3181
|
if (!current) {
|
|
@@ -2931,7 +3187,7 @@ function useExcelGrid(options) {
|
|
|
2931
3187
|
}
|
|
2932
3188
|
});
|
|
2933
3189
|
}, []);
|
|
2934
|
-
const getSortDirection = (0,
|
|
3190
|
+
const getSortDirection = (0, import_react8.useCallback)(
|
|
2935
3191
|
(columnId) => {
|
|
2936
3192
|
const sort = sorting.find((s) => s.id === columnId);
|
|
2937
3193
|
if (!sort)
|
|
@@ -2967,65 +3223,68 @@ function useExcelGrid(options) {
|
|
|
2967
3223
|
getSortDirection,
|
|
2968
3224
|
// Numeric range filters
|
|
2969
3225
|
setNumericRangeFilter,
|
|
2970
|
-
getNumericRangeFilter
|
|
3226
|
+
getNumericRangeFilter,
|
|
3227
|
+
// Date range filters
|
|
3228
|
+
setDateRangeFilter,
|
|
3229
|
+
getDateRangeFilter
|
|
2971
3230
|
};
|
|
2972
3231
|
}
|
|
2973
3232
|
|
|
2974
3233
|
// src/hooks/useGridFeatures.ts
|
|
2975
|
-
var
|
|
2976
|
-
var
|
|
3234
|
+
var import_tinypivot_core8 = require("@smallwebco/tinypivot-core");
|
|
3235
|
+
var import_react9 = require("react");
|
|
2977
3236
|
function exportToCSV(data, columns, options) {
|
|
2978
|
-
(0,
|
|
3237
|
+
(0, import_tinypivot_core8.exportToCSV)(data, columns, options);
|
|
2979
3238
|
}
|
|
2980
3239
|
function exportPivotToCSV(pivotData, rowFields, columnFields, valueFields, options) {
|
|
2981
|
-
(0,
|
|
3240
|
+
(0, import_tinypivot_core8.exportPivotToCSV)(pivotData, rowFields, columnFields, valueFields, options);
|
|
2982
3241
|
}
|
|
2983
3242
|
function copyToClipboard(text, onSuccess, onError) {
|
|
2984
|
-
(0,
|
|
3243
|
+
(0, import_tinypivot_core8.copyToClipboard)(text, onSuccess, onError);
|
|
2985
3244
|
}
|
|
2986
3245
|
function formatSelectionForClipboard(rows, columns, selectionBounds) {
|
|
2987
|
-
return (0,
|
|
3246
|
+
return (0, import_tinypivot_core8.formatSelectionForClipboard)(rows, columns, selectionBounds);
|
|
2988
3247
|
}
|
|
2989
3248
|
function usePagination(data, options = {}) {
|
|
2990
|
-
const [pageSize, setPageSize] = (0,
|
|
2991
|
-
const [currentPage, setCurrentPage] = (0,
|
|
2992
|
-
const totalPages = (0,
|
|
3249
|
+
const [pageSize, setPageSize] = (0, import_react9.useState)(options.pageSize ?? 50);
|
|
3250
|
+
const [currentPage, setCurrentPage] = (0, import_react9.useState)(options.currentPage ?? 1);
|
|
3251
|
+
const totalPages = (0, import_react9.useMemo)(
|
|
2993
3252
|
() => Math.max(1, Math.ceil(data.length / pageSize)),
|
|
2994
3253
|
[data.length, pageSize]
|
|
2995
3254
|
);
|
|
2996
|
-
const paginatedData = (0,
|
|
3255
|
+
const paginatedData = (0, import_react9.useMemo)(() => {
|
|
2997
3256
|
const start = (currentPage - 1) * pageSize;
|
|
2998
3257
|
const end = start + pageSize;
|
|
2999
3258
|
return data.slice(start, end);
|
|
3000
3259
|
}, [data, currentPage, pageSize]);
|
|
3001
|
-
const startIndex = (0,
|
|
3002
|
-
const endIndex = (0,
|
|
3260
|
+
const startIndex = (0, import_react9.useMemo)(() => (currentPage - 1) * pageSize + 1, [currentPage, pageSize]);
|
|
3261
|
+
const endIndex = (0, import_react9.useMemo)(
|
|
3003
3262
|
() => Math.min(currentPage * pageSize, data.length),
|
|
3004
3263
|
[currentPage, pageSize, data.length]
|
|
3005
3264
|
);
|
|
3006
|
-
const goToPage = (0,
|
|
3265
|
+
const goToPage = (0, import_react9.useCallback)(
|
|
3007
3266
|
(page) => {
|
|
3008
3267
|
setCurrentPage(Math.max(1, Math.min(page, totalPages)));
|
|
3009
3268
|
},
|
|
3010
3269
|
[totalPages]
|
|
3011
3270
|
);
|
|
3012
|
-
const nextPage = (0,
|
|
3271
|
+
const nextPage = (0, import_react9.useCallback)(() => {
|
|
3013
3272
|
if (currentPage < totalPages) {
|
|
3014
3273
|
setCurrentPage((prev) => prev + 1);
|
|
3015
3274
|
}
|
|
3016
3275
|
}, [currentPage, totalPages]);
|
|
3017
|
-
const prevPage = (0,
|
|
3276
|
+
const prevPage = (0, import_react9.useCallback)(() => {
|
|
3018
3277
|
if (currentPage > 1) {
|
|
3019
3278
|
setCurrentPage((prev) => prev - 1);
|
|
3020
3279
|
}
|
|
3021
3280
|
}, [currentPage]);
|
|
3022
|
-
const firstPage = (0,
|
|
3281
|
+
const firstPage = (0, import_react9.useCallback)(() => {
|
|
3023
3282
|
setCurrentPage(1);
|
|
3024
3283
|
}, []);
|
|
3025
|
-
const lastPage = (0,
|
|
3284
|
+
const lastPage = (0, import_react9.useCallback)(() => {
|
|
3026
3285
|
setCurrentPage(totalPages);
|
|
3027
3286
|
}, [totalPages]);
|
|
3028
|
-
const updatePageSize = (0,
|
|
3287
|
+
const updatePageSize = (0, import_react9.useCallback)((size) => {
|
|
3029
3288
|
setPageSize(size);
|
|
3030
3289
|
setCurrentPage(1);
|
|
3031
3290
|
}, []);
|
|
@@ -3045,9 +3304,9 @@ function usePagination(data, options = {}) {
|
|
|
3045
3304
|
};
|
|
3046
3305
|
}
|
|
3047
3306
|
function useGlobalSearch(data, columns) {
|
|
3048
|
-
const [searchTerm, setSearchTerm] = (0,
|
|
3049
|
-
const [caseSensitive, setCaseSensitive] = (0,
|
|
3050
|
-
const filteredData = (0,
|
|
3307
|
+
const [searchTerm, setSearchTerm] = (0, import_react9.useState)("");
|
|
3308
|
+
const [caseSensitive, setCaseSensitive] = (0, import_react9.useState)(false);
|
|
3309
|
+
const filteredData = (0, import_react9.useMemo)(() => {
|
|
3051
3310
|
if (!searchTerm.trim()) {
|
|
3052
3311
|
return data;
|
|
3053
3312
|
}
|
|
@@ -3065,7 +3324,7 @@ function useGlobalSearch(data, columns) {
|
|
|
3065
3324
|
return false;
|
|
3066
3325
|
});
|
|
3067
3326
|
}, [data, columns, searchTerm, caseSensitive]);
|
|
3068
|
-
const clearSearch = (0,
|
|
3327
|
+
const clearSearch = (0, import_react9.useCallback)(() => {
|
|
3069
3328
|
setSearchTerm("");
|
|
3070
3329
|
}, []);
|
|
3071
3330
|
return {
|
|
@@ -3078,17 +3337,17 @@ function useGlobalSearch(data, columns) {
|
|
|
3078
3337
|
};
|
|
3079
3338
|
}
|
|
3080
3339
|
function useRowSelection(data) {
|
|
3081
|
-
const [selectedRowIndices, setSelectedRowIndices] = (0,
|
|
3082
|
-
const selectedRows = (0,
|
|
3340
|
+
const [selectedRowIndices, setSelectedRowIndices] = (0, import_react9.useState)(/* @__PURE__ */ new Set());
|
|
3341
|
+
const selectedRows = (0, import_react9.useMemo)(() => {
|
|
3083
3342
|
return Array.from(selectedRowIndices).sort((a, b) => a - b).map((idx) => data[idx]).filter(Boolean);
|
|
3084
3343
|
}, [data, selectedRowIndices]);
|
|
3085
|
-
const allSelected = (0,
|
|
3344
|
+
const allSelected = (0, import_react9.useMemo)(() => {
|
|
3086
3345
|
return data.length > 0 && selectedRowIndices.size === data.length;
|
|
3087
3346
|
}, [data.length, selectedRowIndices.size]);
|
|
3088
|
-
const someSelected = (0,
|
|
3347
|
+
const someSelected = (0, import_react9.useMemo)(() => {
|
|
3089
3348
|
return selectedRowIndices.size > 0 && selectedRowIndices.size < data.length;
|
|
3090
3349
|
}, [data.length, selectedRowIndices.size]);
|
|
3091
|
-
const toggleRow = (0,
|
|
3350
|
+
const toggleRow = (0, import_react9.useCallback)((index) => {
|
|
3092
3351
|
setSelectedRowIndices((prev) => {
|
|
3093
3352
|
const next = new Set(prev);
|
|
3094
3353
|
if (next.has(index)) {
|
|
@@ -3099,36 +3358,36 @@ function useRowSelection(data) {
|
|
|
3099
3358
|
return next;
|
|
3100
3359
|
});
|
|
3101
3360
|
}, []);
|
|
3102
|
-
const selectRow = (0,
|
|
3361
|
+
const selectRow = (0, import_react9.useCallback)((index) => {
|
|
3103
3362
|
setSelectedRowIndices((prev) => /* @__PURE__ */ new Set([...prev, index]));
|
|
3104
3363
|
}, []);
|
|
3105
|
-
const deselectRow = (0,
|
|
3364
|
+
const deselectRow = (0, import_react9.useCallback)((index) => {
|
|
3106
3365
|
setSelectedRowIndices((prev) => {
|
|
3107
3366
|
const next = new Set(prev);
|
|
3108
3367
|
next.delete(index);
|
|
3109
3368
|
return next;
|
|
3110
3369
|
});
|
|
3111
3370
|
}, []);
|
|
3112
|
-
const selectAll = (0,
|
|
3371
|
+
const selectAll = (0, import_react9.useCallback)(() => {
|
|
3113
3372
|
setSelectedRowIndices(new Set(data.map((_, idx) => idx)));
|
|
3114
3373
|
}, [data]);
|
|
3115
|
-
const deselectAll = (0,
|
|
3374
|
+
const deselectAll = (0, import_react9.useCallback)(() => {
|
|
3116
3375
|
setSelectedRowIndices(/* @__PURE__ */ new Set());
|
|
3117
3376
|
}, []);
|
|
3118
|
-
const toggleAll = (0,
|
|
3377
|
+
const toggleAll = (0, import_react9.useCallback)(() => {
|
|
3119
3378
|
if (allSelected) {
|
|
3120
3379
|
deselectAll();
|
|
3121
3380
|
} else {
|
|
3122
3381
|
selectAll();
|
|
3123
3382
|
}
|
|
3124
3383
|
}, [allSelected, selectAll, deselectAll]);
|
|
3125
|
-
const isSelected = (0,
|
|
3384
|
+
const isSelected = (0, import_react9.useCallback)(
|
|
3126
3385
|
(index) => {
|
|
3127
3386
|
return selectedRowIndices.has(index);
|
|
3128
3387
|
},
|
|
3129
3388
|
[selectedRowIndices]
|
|
3130
3389
|
);
|
|
3131
|
-
const selectRange = (0,
|
|
3390
|
+
const selectRange = (0, import_react9.useCallback)((startIndex, endIndex) => {
|
|
3132
3391
|
const min = Math.min(startIndex, endIndex);
|
|
3133
3392
|
const max = Math.max(startIndex, endIndex);
|
|
3134
3393
|
setSelectedRowIndices((prev) => {
|
|
@@ -3155,10 +3414,10 @@ function useRowSelection(data) {
|
|
|
3155
3414
|
};
|
|
3156
3415
|
}
|
|
3157
3416
|
function useColumnResize(initialWidths, minWidth = 60, maxWidth = 600) {
|
|
3158
|
-
const [columnWidths, setColumnWidths] = (0,
|
|
3159
|
-
const [isResizing, setIsResizing] = (0,
|
|
3160
|
-
const [resizingColumn, setResizingColumn] = (0,
|
|
3161
|
-
const startResize = (0,
|
|
3417
|
+
const [columnWidths, setColumnWidths] = (0, import_react9.useState)({ ...initialWidths });
|
|
3418
|
+
const [isResizing, setIsResizing] = (0, import_react9.useState)(false);
|
|
3419
|
+
const [resizingColumn, setResizingColumn] = (0, import_react9.useState)(null);
|
|
3420
|
+
const startResize = (0, import_react9.useCallback)(
|
|
3162
3421
|
(columnId, event) => {
|
|
3163
3422
|
setIsResizing(true);
|
|
3164
3423
|
setResizingColumn(columnId);
|
|
@@ -3183,7 +3442,7 @@ function useColumnResize(initialWidths, minWidth = 60, maxWidth = 600) {
|
|
|
3183
3442
|
},
|
|
3184
3443
|
[columnWidths, minWidth, maxWidth]
|
|
3185
3444
|
);
|
|
3186
|
-
const resetColumnWidth = (0,
|
|
3445
|
+
const resetColumnWidth = (0, import_react9.useCallback)(
|
|
3187
3446
|
(columnId) => {
|
|
3188
3447
|
if (initialWidths[columnId]) {
|
|
3189
3448
|
setColumnWidths((prev) => ({
|
|
@@ -3194,7 +3453,7 @@ function useColumnResize(initialWidths, minWidth = 60, maxWidth = 600) {
|
|
|
3194
3453
|
},
|
|
3195
3454
|
[initialWidths]
|
|
3196
3455
|
);
|
|
3197
|
-
const resetAllWidths = (0,
|
|
3456
|
+
const resetAllWidths = (0, import_react9.useCallback)(() => {
|
|
3198
3457
|
setColumnWidths({ ...initialWidths });
|
|
3199
3458
|
}, [initialWidths]);
|
|
3200
3459
|
return {
|
|
@@ -3209,16 +3468,16 @@ function useColumnResize(initialWidths, minWidth = 60, maxWidth = 600) {
|
|
|
3209
3468
|
}
|
|
3210
3469
|
|
|
3211
3470
|
// src/hooks/useLicense.ts
|
|
3212
|
-
var
|
|
3213
|
-
var
|
|
3214
|
-
var globalLicenseInfo = (0,
|
|
3471
|
+
var import_tinypivot_core9 = require("@smallwebco/tinypivot-core");
|
|
3472
|
+
var import_react10 = require("react");
|
|
3473
|
+
var globalLicenseInfo = (0, import_tinypivot_core9.getFreeLicenseInfo)();
|
|
3215
3474
|
var globalDemoMode = false;
|
|
3216
3475
|
var listeners = /* @__PURE__ */ new Set();
|
|
3217
3476
|
function notifyListeners() {
|
|
3218
3477
|
listeners.forEach((listener) => listener());
|
|
3219
3478
|
}
|
|
3220
3479
|
async function setLicenseKey(key) {
|
|
3221
|
-
globalLicenseInfo = await (0,
|
|
3480
|
+
globalLicenseInfo = await (0, import_tinypivot_core9.validateLicenseKey)(key);
|
|
3222
3481
|
if (!globalLicenseInfo.isValid) {
|
|
3223
3482
|
console.warn("[TinyPivot] License validation failed. Check the console for environment details. Running in free mode.");
|
|
3224
3483
|
} else if (globalLicenseInfo.type !== "free") {
|
|
@@ -3227,7 +3486,7 @@ async function setLicenseKey(key) {
|
|
|
3227
3486
|
notifyListeners();
|
|
3228
3487
|
}
|
|
3229
3488
|
async function enableDemoMode(secret) {
|
|
3230
|
-
const demoLicense = await (0,
|
|
3489
|
+
const demoLicense = await (0, import_tinypivot_core9.getDemoLicenseInfo)(secret);
|
|
3231
3490
|
if (!demoLicense) {
|
|
3232
3491
|
console.warn("[TinyPivot] Demo mode activation failed - invalid secret");
|
|
3233
3492
|
return false;
|
|
@@ -3239,48 +3498,48 @@ async function enableDemoMode(secret) {
|
|
|
3239
3498
|
return true;
|
|
3240
3499
|
}
|
|
3241
3500
|
function configureLicenseSecret(secret) {
|
|
3242
|
-
(0,
|
|
3501
|
+
(0, import_tinypivot_core9.configureLicenseSecret)(secret);
|
|
3243
3502
|
}
|
|
3244
3503
|
function useLicense() {
|
|
3245
|
-
const [, forceUpdate] = (0,
|
|
3246
|
-
(0,
|
|
3504
|
+
const [, forceUpdate] = (0, import_react10.useState)({});
|
|
3505
|
+
(0, import_react10.useState)(() => {
|
|
3247
3506
|
const update = () => forceUpdate({});
|
|
3248
3507
|
listeners.add(update);
|
|
3249
3508
|
return () => listeners.delete(update);
|
|
3250
3509
|
});
|
|
3251
3510
|
const isDemo = globalDemoMode;
|
|
3252
3511
|
const licenseInfo = globalLicenseInfo;
|
|
3253
|
-
const isPro = (0,
|
|
3254
|
-
() => globalDemoMode || (0,
|
|
3512
|
+
const isPro = (0, import_react10.useMemo)(
|
|
3513
|
+
() => globalDemoMode || (0, import_tinypivot_core9.isPro)(licenseInfo),
|
|
3255
3514
|
[licenseInfo]
|
|
3256
3515
|
);
|
|
3257
|
-
const canUsePivot = (0,
|
|
3258
|
-
() => globalDemoMode || (0,
|
|
3516
|
+
const canUsePivot = (0, import_react10.useMemo)(
|
|
3517
|
+
() => globalDemoMode || (0, import_tinypivot_core9.canUsePivot)(licenseInfo),
|
|
3259
3518
|
[licenseInfo]
|
|
3260
3519
|
);
|
|
3261
|
-
const canUseAdvancedAggregations = (0,
|
|
3520
|
+
const canUseAdvancedAggregations = (0, import_react10.useMemo)(
|
|
3262
3521
|
() => globalDemoMode || licenseInfo.features.advancedAggregations,
|
|
3263
3522
|
[licenseInfo]
|
|
3264
3523
|
);
|
|
3265
|
-
const canUsePercentageMode = (0,
|
|
3524
|
+
const canUsePercentageMode = (0, import_react10.useMemo)(
|
|
3266
3525
|
() => globalDemoMode || licenseInfo.features.percentageMode,
|
|
3267
3526
|
[licenseInfo]
|
|
3268
3527
|
);
|
|
3269
|
-
const canUseCharts = (0,
|
|
3270
|
-
() => globalDemoMode || (0,
|
|
3528
|
+
const canUseCharts = (0, import_react10.useMemo)(
|
|
3529
|
+
() => globalDemoMode || (0, import_tinypivot_core9.canUseCharts)(licenseInfo),
|
|
3271
3530
|
[licenseInfo]
|
|
3272
3531
|
);
|
|
3273
|
-
const canUseAIAnalyst = (0,
|
|
3274
|
-
() => globalDemoMode || (0,
|
|
3532
|
+
const canUseAIAnalyst = (0, import_react10.useMemo)(
|
|
3533
|
+
() => globalDemoMode || (0, import_tinypivot_core9.canUseAIAnalyst)(licenseInfo),
|
|
3275
3534
|
[licenseInfo]
|
|
3276
3535
|
);
|
|
3277
|
-
const showWatermark = (0,
|
|
3278
|
-
() => (0,
|
|
3536
|
+
const showWatermark = (0, import_react10.useMemo)(
|
|
3537
|
+
() => (0, import_tinypivot_core9.shouldShowWatermark)(licenseInfo, globalDemoMode),
|
|
3279
3538
|
[licenseInfo]
|
|
3280
3539
|
);
|
|
3281
|
-
const requirePro = (0,
|
|
3540
|
+
const requirePro = (0, import_react10.useCallback)((feature) => {
|
|
3282
3541
|
if (!isPro) {
|
|
3283
|
-
(0,
|
|
3542
|
+
(0, import_tinypivot_core9.logProRequired)(feature);
|
|
3284
3543
|
return false;
|
|
3285
3544
|
}
|
|
3286
3545
|
return true;
|
|
@@ -3300,25 +3559,25 @@ function useLicense() {
|
|
|
3300
3559
|
}
|
|
3301
3560
|
|
|
3302
3561
|
// src/hooks/usePivotTable.ts
|
|
3303
|
-
var
|
|
3304
|
-
var
|
|
3562
|
+
var import_tinypivot_core10 = require("@smallwebco/tinypivot-core");
|
|
3563
|
+
var import_react11 = require("react");
|
|
3305
3564
|
function usePivotTable(data) {
|
|
3306
3565
|
const { canUsePivot, requirePro } = useLicense();
|
|
3307
|
-
const [rowFields, setRowFieldsState] = (0,
|
|
3308
|
-
const [columnFields, setColumnFieldsState] = (0,
|
|
3309
|
-
const [valueFields, setValueFields] = (0,
|
|
3310
|
-
const [showRowTotals, setShowRowTotals] = (0,
|
|
3311
|
-
const [showColumnTotals, setShowColumnTotals] = (0,
|
|
3312
|
-
const [calculatedFields, setCalculatedFields] = (0,
|
|
3313
|
-
const [currentStorageKey, setCurrentStorageKey] = (0,
|
|
3314
|
-
const availableFields = (0,
|
|
3315
|
-
return (0,
|
|
3566
|
+
const [rowFields, setRowFieldsState] = (0, import_react11.useState)([]);
|
|
3567
|
+
const [columnFields, setColumnFieldsState] = (0, import_react11.useState)([]);
|
|
3568
|
+
const [valueFields, setValueFields] = (0, import_react11.useState)([]);
|
|
3569
|
+
const [showRowTotals, setShowRowTotals] = (0, import_react11.useState)(true);
|
|
3570
|
+
const [showColumnTotals, setShowColumnTotals] = (0, import_react11.useState)(true);
|
|
3571
|
+
const [calculatedFields, setCalculatedFields] = (0, import_react11.useState)(() => (0, import_tinypivot_core10.loadCalculatedFields)());
|
|
3572
|
+
const [currentStorageKey, setCurrentStorageKey] = (0, import_react11.useState)(null);
|
|
3573
|
+
const availableFields = (0, import_react11.useMemo)(() => {
|
|
3574
|
+
return (0, import_tinypivot_core10.computeAvailableFields)(data);
|
|
3316
3575
|
}, [data]);
|
|
3317
|
-
const unassignedFields = (0,
|
|
3318
|
-
return (0,
|
|
3576
|
+
const unassignedFields = (0, import_react11.useMemo)(() => {
|
|
3577
|
+
return (0, import_tinypivot_core10.getUnassignedFields)(availableFields, rowFields, columnFields, valueFields);
|
|
3319
3578
|
}, [availableFields, rowFields, columnFields, valueFields]);
|
|
3320
|
-
const isConfigured = (0,
|
|
3321
|
-
return (0,
|
|
3579
|
+
const isConfigured = (0, import_react11.useMemo)(() => {
|
|
3580
|
+
return (0, import_tinypivot_core10.isPivotConfigured)({
|
|
3322
3581
|
rowFields,
|
|
3323
3582
|
columnFields,
|
|
3324
3583
|
valueFields,
|
|
@@ -3326,12 +3585,12 @@ function usePivotTable(data) {
|
|
|
3326
3585
|
showColumnTotals
|
|
3327
3586
|
});
|
|
3328
3587
|
}, [rowFields, columnFields, valueFields, showRowTotals, showColumnTotals]);
|
|
3329
|
-
const pivotResult = (0,
|
|
3588
|
+
const pivotResult = (0, import_react11.useMemo)(() => {
|
|
3330
3589
|
if (!isConfigured)
|
|
3331
3590
|
return null;
|
|
3332
3591
|
if (!canUsePivot)
|
|
3333
3592
|
return null;
|
|
3334
|
-
return (0,
|
|
3593
|
+
return (0, import_tinypivot_core10.computePivotResult)(data, {
|
|
3335
3594
|
rowFields,
|
|
3336
3595
|
columnFields,
|
|
3337
3596
|
valueFields,
|
|
@@ -3340,15 +3599,15 @@ function usePivotTable(data) {
|
|
|
3340
3599
|
calculatedFields
|
|
3341
3600
|
});
|
|
3342
3601
|
}, [data, isConfigured, canUsePivot, rowFields, columnFields, valueFields, showRowTotals, showColumnTotals, calculatedFields]);
|
|
3343
|
-
(0,
|
|
3602
|
+
(0, import_react11.useEffect)(() => {
|
|
3344
3603
|
if (data.length === 0)
|
|
3345
3604
|
return;
|
|
3346
3605
|
const newKeys = Object.keys(data[0]);
|
|
3347
|
-
const storageKey = (0,
|
|
3606
|
+
const storageKey = (0, import_tinypivot_core10.generateStorageKey)(newKeys);
|
|
3348
3607
|
if (storageKey !== currentStorageKey) {
|
|
3349
3608
|
setCurrentStorageKey(storageKey);
|
|
3350
|
-
const savedConfig = (0,
|
|
3351
|
-
if (savedConfig && (0,
|
|
3609
|
+
const savedConfig = (0, import_tinypivot_core10.loadPivotConfig)(storageKey);
|
|
3610
|
+
if (savedConfig && (0, import_tinypivot_core10.isConfigValidForFields)(savedConfig, newKeys)) {
|
|
3352
3611
|
setRowFieldsState(savedConfig.rowFields);
|
|
3353
3612
|
setColumnFieldsState(savedConfig.columnFields);
|
|
3354
3613
|
setValueFields(savedConfig.valueFields);
|
|
@@ -3365,7 +3624,7 @@ function usePivotTable(data) {
|
|
|
3365
3624
|
showRowTotals,
|
|
3366
3625
|
showColumnTotals
|
|
3367
3626
|
};
|
|
3368
|
-
if (!(0,
|
|
3627
|
+
if (!(0, import_tinypivot_core10.isConfigValidForFields)(currentConfig, newKeys)) {
|
|
3369
3628
|
setRowFieldsState([]);
|
|
3370
3629
|
setColumnFieldsState([]);
|
|
3371
3630
|
setValueFields([]);
|
|
@@ -3373,7 +3632,7 @@ function usePivotTable(data) {
|
|
|
3373
3632
|
}
|
|
3374
3633
|
}
|
|
3375
3634
|
}, [data]);
|
|
3376
|
-
(0,
|
|
3635
|
+
(0, import_react11.useEffect)(() => {
|
|
3377
3636
|
if (!currentStorageKey)
|
|
3378
3637
|
return;
|
|
3379
3638
|
const config = {
|
|
@@ -3384,9 +3643,9 @@ function usePivotTable(data) {
|
|
|
3384
3643
|
showColumnTotals,
|
|
3385
3644
|
calculatedFields
|
|
3386
3645
|
};
|
|
3387
|
-
(0,
|
|
3646
|
+
(0, import_tinypivot_core10.savePivotConfig)(currentStorageKey, config);
|
|
3388
3647
|
}, [currentStorageKey, rowFields, columnFields, valueFields, showRowTotals, showColumnTotals, calculatedFields]);
|
|
3389
|
-
const addRowField = (0,
|
|
3648
|
+
const addRowField = (0, import_react11.useCallback)(
|
|
3390
3649
|
(field) => {
|
|
3391
3650
|
if (!rowFields.includes(field)) {
|
|
3392
3651
|
setRowFieldsState((prev) => [...prev, field]);
|
|
@@ -3394,13 +3653,13 @@ function usePivotTable(data) {
|
|
|
3394
3653
|
},
|
|
3395
3654
|
[rowFields]
|
|
3396
3655
|
);
|
|
3397
|
-
const removeRowField = (0,
|
|
3656
|
+
const removeRowField = (0, import_react11.useCallback)((field) => {
|
|
3398
3657
|
setRowFieldsState((prev) => prev.filter((f) => f !== field));
|
|
3399
3658
|
}, []);
|
|
3400
|
-
const setRowFields = (0,
|
|
3659
|
+
const setRowFields = (0, import_react11.useCallback)((fields) => {
|
|
3401
3660
|
setRowFieldsState(fields);
|
|
3402
3661
|
}, []);
|
|
3403
|
-
const addColumnField = (0,
|
|
3662
|
+
const addColumnField = (0, import_react11.useCallback)(
|
|
3404
3663
|
(field) => {
|
|
3405
3664
|
if (!columnFields.includes(field)) {
|
|
3406
3665
|
setColumnFieldsState((prev) => [...prev, field]);
|
|
@@ -3408,13 +3667,13 @@ function usePivotTable(data) {
|
|
|
3408
3667
|
},
|
|
3409
3668
|
[columnFields]
|
|
3410
3669
|
);
|
|
3411
|
-
const removeColumnField = (0,
|
|
3670
|
+
const removeColumnField = (0, import_react11.useCallback)((field) => {
|
|
3412
3671
|
setColumnFieldsState((prev) => prev.filter((f) => f !== field));
|
|
3413
3672
|
}, []);
|
|
3414
|
-
const setColumnFields = (0,
|
|
3673
|
+
const setColumnFields = (0, import_react11.useCallback)((fields) => {
|
|
3415
3674
|
setColumnFieldsState(fields);
|
|
3416
3675
|
}, []);
|
|
3417
|
-
const addValueField = (0,
|
|
3676
|
+
const addValueField = (0, import_react11.useCallback)(
|
|
3418
3677
|
(field, aggregation = "sum") => {
|
|
3419
3678
|
if (aggregation !== "sum" && !requirePro(`${aggregation} aggregation`)) {
|
|
3420
3679
|
return;
|
|
@@ -3428,7 +3687,7 @@ function usePivotTable(data) {
|
|
|
3428
3687
|
},
|
|
3429
3688
|
[requirePro]
|
|
3430
3689
|
);
|
|
3431
|
-
const removeValueField = (0,
|
|
3690
|
+
const removeValueField = (0, import_react11.useCallback)((field, aggregation) => {
|
|
3432
3691
|
setValueFields((prev) => {
|
|
3433
3692
|
if (aggregation) {
|
|
3434
3693
|
return prev.filter((v) => !(v.field === field && v.aggregation === aggregation));
|
|
@@ -3436,7 +3695,7 @@ function usePivotTable(data) {
|
|
|
3436
3695
|
return prev.filter((v) => v.field !== field);
|
|
3437
3696
|
});
|
|
3438
3697
|
}, []);
|
|
3439
|
-
const updateValueFieldAggregation = (0,
|
|
3698
|
+
const updateValueFieldAggregation = (0, import_react11.useCallback)(
|
|
3440
3699
|
(field, oldAgg, newAgg) => {
|
|
3441
3700
|
setValueFields(
|
|
3442
3701
|
(prev) => prev.map((v) => {
|
|
@@ -3449,12 +3708,12 @@ function usePivotTable(data) {
|
|
|
3449
3708
|
},
|
|
3450
3709
|
[]
|
|
3451
3710
|
);
|
|
3452
|
-
const clearConfig = (0,
|
|
3711
|
+
const clearConfig = (0, import_react11.useCallback)(() => {
|
|
3453
3712
|
setRowFieldsState([]);
|
|
3454
3713
|
setColumnFieldsState([]);
|
|
3455
3714
|
setValueFields([]);
|
|
3456
3715
|
}, []);
|
|
3457
|
-
const autoSuggestConfig = (0,
|
|
3716
|
+
const autoSuggestConfig = (0, import_react11.useCallback)(() => {
|
|
3458
3717
|
if (!requirePro("Pivot Table - Auto Suggest"))
|
|
3459
3718
|
return;
|
|
3460
3719
|
if (availableFields.length === 0)
|
|
@@ -3466,7 +3725,7 @@ function usePivotTable(data) {
|
|
|
3466
3725
|
setValueFields([{ field: numericFields[0].field, aggregation: "sum" }]);
|
|
3467
3726
|
}
|
|
3468
3727
|
}, [availableFields, requirePro]);
|
|
3469
|
-
const addCalculatedField = (0,
|
|
3728
|
+
const addCalculatedField = (0, import_react11.useCallback)((field) => {
|
|
3470
3729
|
setCalculatedFields((prev) => {
|
|
3471
3730
|
const existing = prev.findIndex((f) => f.id === field.id);
|
|
3472
3731
|
let updated;
|
|
@@ -3475,14 +3734,14 @@ function usePivotTable(data) {
|
|
|
3475
3734
|
} else {
|
|
3476
3735
|
updated = [...prev, field];
|
|
3477
3736
|
}
|
|
3478
|
-
(0,
|
|
3737
|
+
(0, import_tinypivot_core10.saveCalculatedFields)(updated);
|
|
3479
3738
|
return updated;
|
|
3480
3739
|
});
|
|
3481
3740
|
}, []);
|
|
3482
|
-
const removeCalculatedField = (0,
|
|
3741
|
+
const removeCalculatedField = (0, import_react11.useCallback)((id) => {
|
|
3483
3742
|
setCalculatedFields((prev) => {
|
|
3484
3743
|
const updated = prev.filter((f) => f.id !== id);
|
|
3485
|
-
(0,
|
|
3744
|
+
(0, import_tinypivot_core10.saveCalculatedFields)(updated);
|
|
3486
3745
|
return updated;
|
|
3487
3746
|
});
|
|
3488
3747
|
setValueFields((prev) => prev.filter((v) => v.field !== `calc:${id}`));
|
|
@@ -3520,9 +3779,9 @@ function usePivotTable(data) {
|
|
|
3520
3779
|
}
|
|
3521
3780
|
|
|
3522
3781
|
// src/components/PivotConfig.tsx
|
|
3523
|
-
var
|
|
3524
|
-
var
|
|
3525
|
-
var
|
|
3782
|
+
var import_tinypivot_core11 = require("@smallwebco/tinypivot-core");
|
|
3783
|
+
var import_react12 = require("react");
|
|
3784
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
3526
3785
|
function aggregationRequiresPro(agg) {
|
|
3527
3786
|
return agg !== "sum";
|
|
3528
3787
|
}
|
|
@@ -3563,15 +3822,15 @@ function PivotConfig({
|
|
|
3563
3822
|
onRemoveCalculatedField,
|
|
3564
3823
|
onUpdateCalculatedField
|
|
3565
3824
|
}) {
|
|
3566
|
-
const [fieldSearch, setFieldSearch] = (0,
|
|
3567
|
-
const [showCalcModal, setShowCalcModal] = (0,
|
|
3568
|
-
const [editingCalcField, setEditingCalcField] = (0,
|
|
3825
|
+
const [fieldSearch, setFieldSearch] = (0, import_react12.useState)("");
|
|
3826
|
+
const [showCalcModal, setShowCalcModal] = (0, import_react12.useState)(false);
|
|
3827
|
+
const [editingCalcField, setEditingCalcField] = (0, import_react12.useState)(null);
|
|
3569
3828
|
const { canUseAdvancedAggregations } = useLicense();
|
|
3570
|
-
const isAggregationAvailable = (0,
|
|
3829
|
+
const isAggregationAvailable = (0, import_react12.useCallback)((agg) => {
|
|
3571
3830
|
return !aggregationRequiresPro(agg) || canUseAdvancedAggregations;
|
|
3572
3831
|
}, [canUseAdvancedAggregations]);
|
|
3573
|
-
const numericFieldNames = (0,
|
|
3574
|
-
const calculatedFieldsAsStats = (0,
|
|
3832
|
+
const numericFieldNames = (0, import_react12.useMemo)(() => availableFields.filter((f) => f.isNumeric).map((f) => f.field), [availableFields]);
|
|
3833
|
+
const calculatedFieldsAsStats = (0, import_react12.useMemo)(() => {
|
|
3575
3834
|
if (!calculatedFields)
|
|
3576
3835
|
return [];
|
|
3577
3836
|
return calculatedFields.map((calc) => ({
|
|
@@ -3585,11 +3844,11 @@ function PivotConfig({
|
|
|
3585
3844
|
calcFormula: calc.formula
|
|
3586
3845
|
}));
|
|
3587
3846
|
}, [calculatedFields]);
|
|
3588
|
-
const allAvailableFields = (0,
|
|
3847
|
+
const allAvailableFields = (0, import_react12.useMemo)(() => [
|
|
3589
3848
|
...availableFields.map((f) => ({ ...f, isCalculated: false })),
|
|
3590
3849
|
...calculatedFieldsAsStats
|
|
3591
3850
|
], [availableFields, calculatedFieldsAsStats]);
|
|
3592
|
-
const assignedFields = (0,
|
|
3851
|
+
const assignedFields = (0, import_react12.useMemo)(() => {
|
|
3593
3852
|
const rowSet = new Set(rowFields);
|
|
3594
3853
|
const colSet = new Set(columnFields);
|
|
3595
3854
|
const valueMap = new Map(valueFields.map((v) => [v.field, v]));
|
|
@@ -3599,7 +3858,7 @@ function PivotConfig({
|
|
|
3599
3858
|
valueConfig: valueMap.get(f.field)
|
|
3600
3859
|
}));
|
|
3601
3860
|
}, [allAvailableFields, rowFields, columnFields, valueFields]);
|
|
3602
|
-
const unassignedFields = (0,
|
|
3861
|
+
const unassignedFields = (0, import_react12.useMemo)(() => {
|
|
3603
3862
|
const rowSet = new Set(rowFields);
|
|
3604
3863
|
const colSet = new Set(columnFields);
|
|
3605
3864
|
const valSet = new Set(valueFields.map((v) => v.field));
|
|
@@ -3607,7 +3866,7 @@ function PivotConfig({
|
|
|
3607
3866
|
(f) => !rowSet.has(f.field) && !colSet.has(f.field) && !valSet.has(f.field)
|
|
3608
3867
|
);
|
|
3609
3868
|
}, [allAvailableFields, rowFields, columnFields, valueFields]);
|
|
3610
|
-
const filteredUnassignedFields = (0,
|
|
3869
|
+
const filteredUnassignedFields = (0, import_react12.useMemo)(() => {
|
|
3611
3870
|
if (!fieldSearch.trim())
|
|
3612
3871
|
return unassignedFields;
|
|
3613
3872
|
const search = fieldSearch.toLowerCase().trim();
|
|
@@ -3618,13 +3877,13 @@ function PivotConfig({
|
|
|
3618
3877
|
});
|
|
3619
3878
|
}, [unassignedFields, fieldSearch]);
|
|
3620
3879
|
const assignedCount = assignedFields.length;
|
|
3621
|
-
const getFieldDisplayName = (0,
|
|
3880
|
+
const getFieldDisplayName = (0, import_react12.useCallback)((field) => {
|
|
3622
3881
|
if (field.isCalculated && field.calcName) {
|
|
3623
3882
|
return field.calcName;
|
|
3624
3883
|
}
|
|
3625
3884
|
return field.field;
|
|
3626
3885
|
}, []);
|
|
3627
|
-
const handleDragStart = (0,
|
|
3886
|
+
const handleDragStart = (0, import_react12.useCallback)(
|
|
3628
3887
|
(field, event) => {
|
|
3629
3888
|
event.dataTransfer?.setData("text/plain", field);
|
|
3630
3889
|
event.dataTransfer.effectAllowed = "move";
|
|
@@ -3632,7 +3891,7 @@ function PivotConfig({
|
|
|
3632
3891
|
},
|
|
3633
3892
|
[onDragStart]
|
|
3634
3893
|
);
|
|
3635
|
-
const handleAggregationChange = (0,
|
|
3894
|
+
const handleAggregationChange = (0, import_react12.useCallback)(
|
|
3636
3895
|
(field, currentAgg, newAgg) => {
|
|
3637
3896
|
if (!isAggregationAvailable(newAgg)) {
|
|
3638
3897
|
console.warn(`[TinyPivot] "${newAgg}" aggregation requires a Pro license. Visit https://tiny-pivot.com/#pricing to upgrade.`);
|
|
@@ -3642,7 +3901,7 @@ function PivotConfig({
|
|
|
3642
3901
|
},
|
|
3643
3902
|
[onUpdateAggregation, isAggregationAvailable]
|
|
3644
3903
|
);
|
|
3645
|
-
const toggleRowColumn = (0,
|
|
3904
|
+
const toggleRowColumn = (0, import_react12.useCallback)(
|
|
3646
3905
|
(field, currentAssignment) => {
|
|
3647
3906
|
if (currentAssignment === "row") {
|
|
3648
3907
|
onRemoveRowField(field);
|
|
@@ -3654,7 +3913,7 @@ function PivotConfig({
|
|
|
3654
3913
|
},
|
|
3655
3914
|
[onRemoveRowField, onAddColumnField, onRemoveColumnField, onAddRowField]
|
|
3656
3915
|
);
|
|
3657
|
-
const removeField = (0,
|
|
3916
|
+
const removeField = (0, import_react12.useCallback)(
|
|
3658
3917
|
(field, assignedTo, valueConfig) => {
|
|
3659
3918
|
if (assignedTo === "row") {
|
|
3660
3919
|
onRemoveRowField(field);
|
|
@@ -3666,15 +3925,15 @@ function PivotConfig({
|
|
|
3666
3925
|
},
|
|
3667
3926
|
[onRemoveRowField, onRemoveColumnField, onRemoveValueField]
|
|
3668
3927
|
);
|
|
3669
|
-
const handleTotalsToggle = (0,
|
|
3928
|
+
const handleTotalsToggle = (0, import_react12.useCallback)((checked) => {
|
|
3670
3929
|
onShowRowTotalsChange(checked);
|
|
3671
3930
|
onShowColumnTotalsChange(checked);
|
|
3672
3931
|
}, [onShowRowTotalsChange, onShowColumnTotalsChange]);
|
|
3673
|
-
const openCalcModal = (0,
|
|
3932
|
+
const openCalcModal = (0, import_react12.useCallback)((field) => {
|
|
3674
3933
|
setEditingCalcField(field || null);
|
|
3675
3934
|
setShowCalcModal(true);
|
|
3676
3935
|
}, []);
|
|
3677
|
-
const handleSaveCalcField = (0,
|
|
3936
|
+
const handleSaveCalcField = (0, import_react12.useCallback)((field) => {
|
|
3678
3937
|
if (editingCalcField && onUpdateCalculatedField) {
|
|
3679
3938
|
onUpdateCalculatedField(field);
|
|
3680
3939
|
} else if (onAddCalculatedField) {
|
|
@@ -3683,14 +3942,14 @@ function PivotConfig({
|
|
|
3683
3942
|
setShowCalcModal(false);
|
|
3684
3943
|
setEditingCalcField(null);
|
|
3685
3944
|
}, [editingCalcField, onAddCalculatedField, onUpdateCalculatedField]);
|
|
3686
|
-
const handleCloseCalcModal = (0,
|
|
3945
|
+
const handleCloseCalcModal = (0, import_react12.useCallback)(() => {
|
|
3687
3946
|
setShowCalcModal(false);
|
|
3688
3947
|
setEditingCalcField(null);
|
|
3689
3948
|
}, []);
|
|
3690
|
-
return /* @__PURE__ */ (0,
|
|
3691
|
-
/* @__PURE__ */ (0,
|
|
3692
|
-
/* @__PURE__ */ (0,
|
|
3693
|
-
/* @__PURE__ */ (0,
|
|
3949
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-pivot-config", children: [
|
|
3950
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-config-header", children: [
|
|
3951
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("h3", { className: "vpg-config-title", children: [
|
|
3952
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3694
3953
|
"path",
|
|
3695
3954
|
{
|
|
3696
3955
|
strokeLinecap: "round",
|
|
@@ -3701,13 +3960,13 @@ function PivotConfig({
|
|
|
3701
3960
|
) }),
|
|
3702
3961
|
"Fields"
|
|
3703
3962
|
] }),
|
|
3704
|
-
/* @__PURE__ */ (0,
|
|
3963
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "vpg-header-actions", children: assignedCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3705
3964
|
"button",
|
|
3706
3965
|
{
|
|
3707
3966
|
className: "vpg-action-btn vpg-clear-btn",
|
|
3708
3967
|
title: "Clear all",
|
|
3709
3968
|
onClick: onClearConfig,
|
|
3710
|
-
children: /* @__PURE__ */ (0,
|
|
3969
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3711
3970
|
"path",
|
|
3712
3971
|
{
|
|
3713
3972
|
strokeLinecap: "round",
|
|
@@ -3719,9 +3978,9 @@ function PivotConfig({
|
|
|
3719
3978
|
}
|
|
3720
3979
|
) })
|
|
3721
3980
|
] }),
|
|
3722
|
-
assignedCount > 0 && /* @__PURE__ */ (0,
|
|
3723
|
-
/* @__PURE__ */ (0,
|
|
3724
|
-
/* @__PURE__ */ (0,
|
|
3981
|
+
assignedCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-assigned-section", children: [
|
|
3982
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "vpg-section-label", children: "Active" }),
|
|
3983
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "vpg-assigned-list", children: assignedFields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
3725
3984
|
"div",
|
|
3726
3985
|
{
|
|
3727
3986
|
className: `vpg-assigned-item vpg-type-${field.assignedTo}${field.isCalculated ? " vpg-type-calc" : ""}`,
|
|
@@ -3730,12 +3989,12 @@ function PivotConfig({
|
|
|
3730
3989
|
onDragStart: (e) => handleDragStart(field.field, e),
|
|
3731
3990
|
onDragEnd,
|
|
3732
3991
|
children: [
|
|
3733
|
-
/* @__PURE__ */ (0,
|
|
3734
|
-
/* @__PURE__ */ (0,
|
|
3735
|
-
/* @__PURE__ */ (0,
|
|
3992
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-item-main", children: [
|
|
3993
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.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_core11.getAggregationSymbol)(field.valueConfig?.aggregation || "sum") }),
|
|
3994
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-item-name", children: getFieldDisplayName(field) })
|
|
3736
3995
|
] }),
|
|
3737
|
-
/* @__PURE__ */ (0,
|
|
3738
|
-
(field.assignedTo === "row" || field.assignedTo === "column") && /* @__PURE__ */ (0,
|
|
3996
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-item-actions", children: [
|
|
3997
|
+
(field.assignedTo === "row" || field.assignedTo === "column") && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3739
3998
|
"button",
|
|
3740
3999
|
{
|
|
3741
4000
|
className: "vpg-toggle-btn",
|
|
@@ -3744,14 +4003,14 @@ function PivotConfig({
|
|
|
3744
4003
|
e.stopPropagation();
|
|
3745
4004
|
toggleRowColumn(field.field, field.assignedTo);
|
|
3746
4005
|
},
|
|
3747
|
-
children: /* @__PURE__ */ (0,
|
|
4006
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3748
4007
|
"svg",
|
|
3749
4008
|
{
|
|
3750
4009
|
className: "vpg-icon-xs",
|
|
3751
4010
|
fill: "none",
|
|
3752
4011
|
stroke: "currentColor",
|
|
3753
4012
|
viewBox: "0 0 24 24",
|
|
3754
|
-
children: /* @__PURE__ */ (0,
|
|
4013
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3755
4014
|
"path",
|
|
3756
4015
|
{
|
|
3757
4016
|
strokeLinecap: "round",
|
|
@@ -3764,7 +4023,7 @@ function PivotConfig({
|
|
|
3764
4023
|
)
|
|
3765
4024
|
}
|
|
3766
4025
|
),
|
|
3767
|
-
field.assignedTo === "value" && field.valueConfig && /* @__PURE__ */ (0,
|
|
4026
|
+
field.assignedTo === "value" && field.valueConfig && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3768
4027
|
"select",
|
|
3769
4028
|
{
|
|
3770
4029
|
className: "vpg-agg-select",
|
|
@@ -3778,7 +4037,7 @@ function PivotConfig({
|
|
|
3778
4037
|
);
|
|
3779
4038
|
},
|
|
3780
4039
|
onClick: (e) => e.stopPropagation(),
|
|
3781
|
-
children:
|
|
4040
|
+
children: import_tinypivot_core11.AGGREGATION_OPTIONS.map((agg) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
3782
4041
|
"option",
|
|
3783
4042
|
{
|
|
3784
4043
|
value: agg.value,
|
|
@@ -3794,7 +4053,7 @@ function PivotConfig({
|
|
|
3794
4053
|
))
|
|
3795
4054
|
}
|
|
3796
4055
|
),
|
|
3797
|
-
/* @__PURE__ */ (0,
|
|
4056
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3798
4057
|
"button",
|
|
3799
4058
|
{
|
|
3800
4059
|
className: "vpg-remove-btn",
|
|
@@ -3812,14 +4071,14 @@ function PivotConfig({
|
|
|
3812
4071
|
field.field
|
|
3813
4072
|
)) })
|
|
3814
4073
|
] }),
|
|
3815
|
-
/* @__PURE__ */ (0,
|
|
3816
|
-
/* @__PURE__ */ (0,
|
|
4074
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-unassigned-section", children: [
|
|
4075
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "vpg-section-header", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-section-label", children: [
|
|
3817
4076
|
"Available",
|
|
3818
4077
|
" ",
|
|
3819
|
-
/* @__PURE__ */ (0,
|
|
4078
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-count", children: unassignedFields.length })
|
|
3820
4079
|
] }) }),
|
|
3821
|
-
/* @__PURE__ */ (0,
|
|
3822
|
-
/* @__PURE__ */ (0,
|
|
4080
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-field-search", children: [
|
|
4081
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { className: "vpg-search-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3823
4082
|
"path",
|
|
3824
4083
|
{
|
|
3825
4084
|
strokeLinecap: "round",
|
|
@@ -3828,7 +4087,7 @@ function PivotConfig({
|
|
|
3828
4087
|
d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
|
|
3829
4088
|
}
|
|
3830
4089
|
) }),
|
|
3831
|
-
/* @__PURE__ */ (0,
|
|
4090
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3832
4091
|
"input",
|
|
3833
4092
|
{
|
|
3834
4093
|
type: "text",
|
|
@@ -3838,7 +4097,7 @@ function PivotConfig({
|
|
|
3838
4097
|
className: "vpg-search-input"
|
|
3839
4098
|
}
|
|
3840
4099
|
),
|
|
3841
|
-
fieldSearch && /* @__PURE__ */ (0,
|
|
4100
|
+
fieldSearch && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { className: "vpg-clear-search", onClick: () => setFieldSearch(""), children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { className: "vpg-icon-xs", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3842
4101
|
"path",
|
|
3843
4102
|
{
|
|
3844
4103
|
strokeLinecap: "round",
|
|
@@ -3848,8 +4107,8 @@ function PivotConfig({
|
|
|
3848
4107
|
}
|
|
3849
4108
|
) }) })
|
|
3850
4109
|
] }),
|
|
3851
|
-
/* @__PURE__ */ (0,
|
|
3852
|
-
filteredUnassignedFields.map((field) => /* @__PURE__ */ (0,
|
|
4110
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-field-list", children: [
|
|
4111
|
+
filteredUnassignedFields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
3853
4112
|
"div",
|
|
3854
4113
|
{
|
|
3855
4114
|
className: `vpg-field-item${field.isNumeric && !field.isCalculated ? " vpg-is-numeric" : ""}${field.isCalculated ? " vpg-is-calculated" : ""}`,
|
|
@@ -3858,10 +4117,10 @@ function PivotConfig({
|
|
|
3858
4117
|
onDragStart: (e) => handleDragStart(field.field, e),
|
|
3859
4118
|
onDragEnd,
|
|
3860
4119
|
children: [
|
|
3861
|
-
/* @__PURE__ */ (0,
|
|
3862
|
-
/* @__PURE__ */ (0,
|
|
3863
|
-
field.isCalculated ? /* @__PURE__ */ (0,
|
|
3864
|
-
/* @__PURE__ */ (0,
|
|
4120
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: `vpg-field-type-icon${field.isCalculated ? " vpg-calc-type" : ""}`, title: field.type, children: getFieldIcon(field.type, field.isCalculated) }),
|
|
4121
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-field-name", children: getFieldDisplayName(field) }),
|
|
4122
|
+
field.isCalculated ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
4123
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3865
4124
|
"button",
|
|
3866
4125
|
{
|
|
3867
4126
|
className: "vpg-field-edit",
|
|
@@ -3875,7 +4134,7 @@ function PivotConfig({
|
|
|
3875
4134
|
children: "\u270E"
|
|
3876
4135
|
}
|
|
3877
4136
|
),
|
|
3878
|
-
/* @__PURE__ */ (0,
|
|
4137
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3879
4138
|
"button",
|
|
3880
4139
|
{
|
|
3881
4140
|
className: "vpg-field-delete",
|
|
@@ -3889,22 +4148,22 @@ function PivotConfig({
|
|
|
3889
4148
|
children: "\xD7"
|
|
3890
4149
|
}
|
|
3891
4150
|
)
|
|
3892
|
-
] }) : /* @__PURE__ */ (0,
|
|
4151
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-unique-count", children: field.uniqueCount })
|
|
3893
4152
|
]
|
|
3894
4153
|
},
|
|
3895
4154
|
field.field
|
|
3896
4155
|
)),
|
|
3897
|
-
filteredUnassignedFields.length === 0 && fieldSearch && /* @__PURE__ */ (0,
|
|
4156
|
+
filteredUnassignedFields.length === 0 && fieldSearch && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-empty-hint", children: [
|
|
3898
4157
|
'No fields match "',
|
|
3899
4158
|
fieldSearch,
|
|
3900
4159
|
'"'
|
|
3901
4160
|
] }),
|
|
3902
|
-
unassignedFields.length === 0 && /* @__PURE__ */ (0,
|
|
4161
|
+
unassignedFields.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "vpg-empty-hint", children: "All fields assigned" })
|
|
3903
4162
|
] })
|
|
3904
4163
|
] }),
|
|
3905
|
-
/* @__PURE__ */ (0,
|
|
3906
|
-
/* @__PURE__ */ (0,
|
|
3907
|
-
/* @__PURE__ */ (0,
|
|
4164
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "vpg-options-section", children: [
|
|
4165
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "vpg-option-toggle", children: [
|
|
4166
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3908
4167
|
"input",
|
|
3909
4168
|
{
|
|
3910
4169
|
type: "checkbox",
|
|
@@ -3912,14 +4171,14 @@ function PivotConfig({
|
|
|
3912
4171
|
onChange: (e) => handleTotalsToggle(e.target.checked)
|
|
3913
4172
|
}
|
|
3914
4173
|
),
|
|
3915
|
-
/* @__PURE__ */ (0,
|
|
4174
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "Totals" })
|
|
3916
4175
|
] }),
|
|
3917
|
-
/* @__PURE__ */ (0,
|
|
3918
|
-
/* @__PURE__ */ (0,
|
|
3919
|
-
/* @__PURE__ */ (0,
|
|
4176
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("button", { className: "vpg-calc-btn", onClick: () => openCalcModal(), title: "Add calculated field (e.g. Profit Margin %)", children: [
|
|
4177
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "vpg-calc-icon", children: "\u0192" }),
|
|
4178
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "+ Calc" })
|
|
3920
4179
|
] })
|
|
3921
4180
|
] }),
|
|
3922
|
-
/* @__PURE__ */ (0,
|
|
4181
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3923
4182
|
CalculatedFieldModal,
|
|
3924
4183
|
{
|
|
3925
4184
|
show: showCalcModal,
|
|
@@ -3933,9 +4192,9 @@ function PivotConfig({
|
|
|
3933
4192
|
}
|
|
3934
4193
|
|
|
3935
4194
|
// src/components/PivotSkeleton.tsx
|
|
3936
|
-
var
|
|
3937
|
-
var
|
|
3938
|
-
var
|
|
4195
|
+
var import_tinypivot_core12 = require("@smallwebco/tinypivot-core");
|
|
4196
|
+
var import_react13 = require("react");
|
|
4197
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
3939
4198
|
function PivotSkeleton({
|
|
3940
4199
|
rowFields,
|
|
3941
4200
|
columnFields,
|
|
@@ -3958,7 +4217,7 @@ function PivotSkeleton({
|
|
|
3958
4217
|
onReorderColumnFields
|
|
3959
4218
|
}) {
|
|
3960
4219
|
const { showWatermark, canUsePivot, isDemo } = useLicense();
|
|
3961
|
-
const getValueFieldDisplayName = (0,
|
|
4220
|
+
const getValueFieldDisplayName = (0, import_react13.useCallback)((field) => {
|
|
3962
4221
|
if (field.startsWith("calc:")) {
|
|
3963
4222
|
const calcId = field.replace("calc:", "");
|
|
3964
4223
|
const calcField = calculatedFields?.find((c) => c.id === calcId);
|
|
@@ -3966,15 +4225,15 @@ function PivotSkeleton({
|
|
|
3966
4225
|
}
|
|
3967
4226
|
return field;
|
|
3968
4227
|
}, [calculatedFields]);
|
|
3969
|
-
const isCalculatedField = (0,
|
|
4228
|
+
const isCalculatedField = (0, import_react13.useCallback)((field) => {
|
|
3970
4229
|
return field.startsWith("calc:");
|
|
3971
4230
|
}, []);
|
|
3972
|
-
const [dragOverArea, setDragOverArea] = (0,
|
|
3973
|
-
const [reorderDragSource, setReorderDragSource] = (0,
|
|
3974
|
-
const [reorderDropTarget, setReorderDropTarget] = (0,
|
|
3975
|
-
const [sortDirection, setSortDirection] = (0,
|
|
3976
|
-
const [sortTarget, setSortTarget] = (0,
|
|
3977
|
-
const toggleSort = (0,
|
|
4231
|
+
const [dragOverArea, setDragOverArea] = (0, import_react13.useState)(null);
|
|
4232
|
+
const [reorderDragSource, setReorderDragSource] = (0, import_react13.useState)(null);
|
|
4233
|
+
const [reorderDropTarget, setReorderDropTarget] = (0, import_react13.useState)(null);
|
|
4234
|
+
const [sortDirection, setSortDirection] = (0, import_react13.useState)("asc");
|
|
4235
|
+
const [sortTarget, setSortTarget] = (0, import_react13.useState)("row");
|
|
4236
|
+
const toggleSort = (0, import_react13.useCallback)((target = "row") => {
|
|
3978
4237
|
if (sortTarget === target) {
|
|
3979
4238
|
setSortDirection((prev) => prev === "asc" ? "desc" : "asc");
|
|
3980
4239
|
} else {
|
|
@@ -3982,13 +4241,13 @@ function PivotSkeleton({
|
|
|
3982
4241
|
setSortDirection("asc");
|
|
3983
4242
|
}
|
|
3984
4243
|
}, [sortTarget]);
|
|
3985
|
-
const [selectedCell, setSelectedCell] = (0,
|
|
3986
|
-
const [selectionStart, setSelectionStart] = (0,
|
|
3987
|
-
const [selectionEnd, setSelectionEnd] = (0,
|
|
3988
|
-
const [isSelecting, setIsSelecting] = (0,
|
|
3989
|
-
const [showCopyToast, setShowCopyToast] = (0,
|
|
3990
|
-
const [copyToastMessage, setCopyToastMessage] = (0,
|
|
3991
|
-
const selectionBounds = (0,
|
|
4244
|
+
const [selectedCell, setSelectedCell] = (0, import_react13.useState)(null);
|
|
4245
|
+
const [selectionStart, setSelectionStart] = (0, import_react13.useState)(null);
|
|
4246
|
+
const [selectionEnd, setSelectionEnd] = (0, import_react13.useState)(null);
|
|
4247
|
+
const [isSelecting, setIsSelecting] = (0, import_react13.useState)(false);
|
|
4248
|
+
const [showCopyToast, setShowCopyToast] = (0, import_react13.useState)(false);
|
|
4249
|
+
const [copyToastMessage, setCopyToastMessage] = (0, import_react13.useState)("");
|
|
4250
|
+
const selectionBounds = (0, import_react13.useMemo)(() => {
|
|
3992
4251
|
if (!selectionStart || !selectionEnd)
|
|
3993
4252
|
return null;
|
|
3994
4253
|
return {
|
|
@@ -3998,7 +4257,7 @@ function PivotSkeleton({
|
|
|
3998
4257
|
maxCol: Math.max(selectionStart.col, selectionEnd.col)
|
|
3999
4258
|
};
|
|
4000
4259
|
}, [selectionStart, selectionEnd]);
|
|
4001
|
-
const handleCellMouseDown = (0,
|
|
4260
|
+
const handleCellMouseDown = (0, import_react13.useCallback)(
|
|
4002
4261
|
(rowIndex, colIndex, event) => {
|
|
4003
4262
|
event.preventDefault();
|
|
4004
4263
|
if (event.shiftKey && selectedCell) {
|
|
@@ -4012,7 +4271,7 @@ function PivotSkeleton({
|
|
|
4012
4271
|
},
|
|
4013
4272
|
[selectedCell]
|
|
4014
4273
|
);
|
|
4015
|
-
const handleCellMouseEnter = (0,
|
|
4274
|
+
const handleCellMouseEnter = (0, import_react13.useCallback)(
|
|
4016
4275
|
(rowIndex, colIndex) => {
|
|
4017
4276
|
if (isSelecting) {
|
|
4018
4277
|
setSelectionEnd({ row: rowIndex, col: colIndex });
|
|
@@ -4020,7 +4279,7 @@ function PivotSkeleton({
|
|
|
4020
4279
|
},
|
|
4021
4280
|
[isSelecting]
|
|
4022
4281
|
);
|
|
4023
|
-
const isCellSelected = (0,
|
|
4282
|
+
const isCellSelected = (0, import_react13.useCallback)(
|
|
4024
4283
|
(rowIndex, colIndex) => {
|
|
4025
4284
|
if (!selectionBounds) {
|
|
4026
4285
|
return selectedCell?.row === rowIndex && selectedCell?.col === colIndex;
|
|
@@ -4030,12 +4289,12 @@ function PivotSkeleton({
|
|
|
4030
4289
|
},
|
|
4031
4290
|
[selectionBounds, selectedCell]
|
|
4032
4291
|
);
|
|
4033
|
-
(0,
|
|
4292
|
+
(0, import_react13.useEffect)(() => {
|
|
4034
4293
|
const handleMouseUp = () => setIsSelecting(false);
|
|
4035
4294
|
document.addEventListener("mouseup", handleMouseUp);
|
|
4036
4295
|
return () => document.removeEventListener("mouseup", handleMouseUp);
|
|
4037
4296
|
}, []);
|
|
4038
|
-
const sortedRowIndices = (0,
|
|
4297
|
+
const sortedRowIndices = (0, import_react13.useMemo)(() => {
|
|
4039
4298
|
if (!pivotResult)
|
|
4040
4299
|
return [];
|
|
4041
4300
|
const indices = pivotResult.rowHeaders.map((_, i) => i);
|
|
@@ -4063,7 +4322,7 @@ function PivotSkeleton({
|
|
|
4063
4322
|
});
|
|
4064
4323
|
return indices;
|
|
4065
4324
|
}, [pivotResult, sortTarget, sortDirection]);
|
|
4066
|
-
const copySelectionToClipboard = (0,
|
|
4325
|
+
const copySelectionToClipboard = (0, import_react13.useCallback)(() => {
|
|
4067
4326
|
if (!selectionBounds || !pivotResult)
|
|
4068
4327
|
return;
|
|
4069
4328
|
const { minRow, maxRow, minCol, maxCol } = selectionBounds;
|
|
@@ -4089,7 +4348,7 @@ function PivotSkeleton({
|
|
|
4089
4348
|
console.error("Copy failed:", err);
|
|
4090
4349
|
});
|
|
4091
4350
|
}, [selectionBounds, pivotResult, sortedRowIndices]);
|
|
4092
|
-
(0,
|
|
4351
|
+
(0, import_react13.useEffect)(() => {
|
|
4093
4352
|
const handleKeydown = (event) => {
|
|
4094
4353
|
if (!selectionBounds)
|
|
4095
4354
|
return;
|
|
@@ -4107,7 +4366,7 @@ function PivotSkeleton({
|
|
|
4107
4366
|
document.addEventListener("keydown", handleKeydown);
|
|
4108
4367
|
return () => document.removeEventListener("keydown", handleKeydown);
|
|
4109
4368
|
}, [selectionBounds, copySelectionToClipboard]);
|
|
4110
|
-
const selectionStats = (0,
|
|
4369
|
+
const selectionStats = (0, import_react13.useMemo)(() => {
|
|
4111
4370
|
if (!selectionBounds || !pivotResult)
|
|
4112
4371
|
return null;
|
|
4113
4372
|
const { minRow, maxRow, minCol, maxCol } = selectionBounds;
|
|
@@ -4136,18 +4395,18 @@ function PivotSkeleton({
|
|
|
4136
4395
|
avg
|
|
4137
4396
|
};
|
|
4138
4397
|
}, [selectionBounds, pivotResult, sortedRowIndices]);
|
|
4139
|
-
const formatStatValue = (0,
|
|
4398
|
+
const formatStatValue = (0, import_react13.useCallback)((val) => {
|
|
4140
4399
|
if (Math.abs(val) >= 1e6)
|
|
4141
4400
|
return `${(val / 1e6).toFixed(2)}M`;
|
|
4142
4401
|
if (Math.abs(val) >= 1e3)
|
|
4143
4402
|
return `${(val / 1e3).toFixed(2)}K`;
|
|
4144
4403
|
return val.toFixed(2);
|
|
4145
4404
|
}, []);
|
|
4146
|
-
const columnHeaderCells = (0,
|
|
4405
|
+
const columnHeaderCells = (0, import_react13.useMemo)(() => {
|
|
4147
4406
|
if (!pivotResult || pivotResult.headers.length === 0) {
|
|
4148
4407
|
return [
|
|
4149
4408
|
valueFields.map((vf) => ({
|
|
4150
|
-
label: `${getValueFieldDisplayName(vf.field)} (${(0,
|
|
4409
|
+
label: `${getValueFieldDisplayName(vf.field)} (${(0, import_tinypivot_core12.getAggregationLabel)(vf.aggregation)})`,
|
|
4151
4410
|
colspan: 1
|
|
4152
4411
|
}))
|
|
4153
4412
|
];
|
|
@@ -4171,13 +4430,13 @@ function PivotSkeleton({
|
|
|
4171
4430
|
return result;
|
|
4172
4431
|
}, [pivotResult, valueFields]);
|
|
4173
4432
|
const hasActiveFilters = activeFilters && activeFilters.length > 0;
|
|
4174
|
-
const filterSummary = (0,
|
|
4433
|
+
const filterSummary = (0, import_react13.useMemo)(() => {
|
|
4175
4434
|
if (!activeFilters || activeFilters.length === 0)
|
|
4176
4435
|
return "";
|
|
4177
4436
|
return activeFilters.map((f) => f.column).join(", ");
|
|
4178
4437
|
}, [activeFilters]);
|
|
4179
|
-
const [showFilterTooltip, setShowFilterTooltip] = (0,
|
|
4180
|
-
const filterTooltipDetails = (0,
|
|
4438
|
+
const [showFilterTooltip, setShowFilterTooltip] = (0, import_react13.useState)(false);
|
|
4439
|
+
const filterTooltipDetails = (0, import_react13.useMemo)(() => {
|
|
4181
4440
|
if (!activeFilters || activeFilters.length === 0)
|
|
4182
4441
|
return [];
|
|
4183
4442
|
return activeFilters.map((f) => {
|
|
@@ -4202,7 +4461,7 @@ function PivotSkeleton({
|
|
|
4202
4461
|
};
|
|
4203
4462
|
});
|
|
4204
4463
|
}, [activeFilters]);
|
|
4205
|
-
const handleDragOver = (0,
|
|
4464
|
+
const handleDragOver = (0, import_react13.useCallback)(
|
|
4206
4465
|
(area, event) => {
|
|
4207
4466
|
event.preventDefault();
|
|
4208
4467
|
event.dataTransfer.dropEffect = "move";
|
|
@@ -4210,10 +4469,10 @@ function PivotSkeleton({
|
|
|
4210
4469
|
},
|
|
4211
4470
|
[]
|
|
4212
4471
|
);
|
|
4213
|
-
const handleDragLeave = (0,
|
|
4472
|
+
const handleDragLeave = (0, import_react13.useCallback)(() => {
|
|
4214
4473
|
setDragOverArea(null);
|
|
4215
4474
|
}, []);
|
|
4216
|
-
const handleDrop = (0,
|
|
4475
|
+
const handleDrop = (0, import_react13.useCallback)(
|
|
4217
4476
|
(area, event) => {
|
|
4218
4477
|
event.preventDefault();
|
|
4219
4478
|
const field = event.dataTransfer?.getData("text/plain");
|
|
@@ -4243,7 +4502,7 @@ function PivotSkeleton({
|
|
|
4243
4502
|
},
|
|
4244
4503
|
[rowFields, columnFields, valueFields, onAddRowField, onRemoveRowField, onAddColumnField, onRemoveColumnField, onAddValueField, onRemoveValueField]
|
|
4245
4504
|
);
|
|
4246
|
-
const handleChipDragStart = (0,
|
|
4505
|
+
const handleChipDragStart = (0, import_react13.useCallback)(
|
|
4247
4506
|
(zone, index, event) => {
|
|
4248
4507
|
setReorderDragSource({ zone, index });
|
|
4249
4508
|
event.dataTransfer.effectAllowed = "move";
|
|
@@ -4254,11 +4513,11 @@ function PivotSkeleton({
|
|
|
4254
4513
|
},
|
|
4255
4514
|
[]
|
|
4256
4515
|
);
|
|
4257
|
-
const handleChipDragEnd = (0,
|
|
4516
|
+
const handleChipDragEnd = (0, import_react13.useCallback)(() => {
|
|
4258
4517
|
setReorderDragSource(null);
|
|
4259
4518
|
setReorderDropTarget(null);
|
|
4260
4519
|
}, []);
|
|
4261
|
-
const handleChipDragOver = (0,
|
|
4520
|
+
const handleChipDragOver = (0, import_react13.useCallback)(
|
|
4262
4521
|
(zone, index, event) => {
|
|
4263
4522
|
event.preventDefault();
|
|
4264
4523
|
if (reorderDragSource && reorderDragSource.zone === zone) {
|
|
@@ -4268,10 +4527,10 @@ function PivotSkeleton({
|
|
|
4268
4527
|
},
|
|
4269
4528
|
[reorderDragSource]
|
|
4270
4529
|
);
|
|
4271
|
-
const handleChipDragLeave = (0,
|
|
4530
|
+
const handleChipDragLeave = (0, import_react13.useCallback)(() => {
|
|
4272
4531
|
setReorderDropTarget(null);
|
|
4273
4532
|
}, []);
|
|
4274
|
-
const handleChipDrop = (0,
|
|
4533
|
+
const handleChipDrop = (0, import_react13.useCallback)(
|
|
4275
4534
|
(zone, targetIndex, event) => {
|
|
4276
4535
|
event.preventDefault();
|
|
4277
4536
|
event.stopPropagation();
|
|
@@ -4297,13 +4556,13 @@ function PivotSkeleton({
|
|
|
4297
4556
|
},
|
|
4298
4557
|
[reorderDragSource, rowFields, columnFields, onReorderRowFields, onReorderColumnFields]
|
|
4299
4558
|
);
|
|
4300
|
-
const isChipDragSource = (0,
|
|
4559
|
+
const isChipDragSource = (0, import_react13.useCallback)(
|
|
4301
4560
|
(zone, index) => {
|
|
4302
4561
|
return reorderDragSource?.zone === zone && reorderDragSource?.index === index;
|
|
4303
4562
|
},
|
|
4304
4563
|
[reorderDragSource]
|
|
4305
4564
|
);
|
|
4306
|
-
const isChipDropTarget = (0,
|
|
4565
|
+
const isChipDropTarget = (0, import_react13.useCallback)(
|
|
4307
4566
|
(zone, index) => {
|
|
4308
4567
|
return reorderDropTarget?.zone === zone && reorderDropTarget?.index === index;
|
|
4309
4568
|
},
|
|
@@ -4311,25 +4570,25 @@ function PivotSkeleton({
|
|
|
4311
4570
|
);
|
|
4312
4571
|
const currentFontSize = fontSize;
|
|
4313
4572
|
const rowHeaderWidth = 180;
|
|
4314
|
-
const rowHeaderColWidth = (0,
|
|
4573
|
+
const rowHeaderColWidth = (0, import_react13.useMemo)(() => {
|
|
4315
4574
|
const numCols = Math.max(rowFields.length, 1);
|
|
4316
4575
|
return Math.max(rowHeaderWidth / numCols, 80);
|
|
4317
4576
|
}, [rowFields.length]);
|
|
4318
|
-
const getRowHeaderLeftOffset = (0,
|
|
4577
|
+
const getRowHeaderLeftOffset = (0, import_react13.useCallback)((fieldIdx) => {
|
|
4319
4578
|
return fieldIdx * rowHeaderColWidth;
|
|
4320
4579
|
}, [rowHeaderColWidth]);
|
|
4321
|
-
return /* @__PURE__ */ (0,
|
|
4580
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
4322
4581
|
"div",
|
|
4323
4582
|
{
|
|
4324
4583
|
className: `vpg-pivot-skeleton vpg-font-${currentFontSize} ${draggingField ? "vpg-is-dragging" : ""}`,
|
|
4325
4584
|
children: [
|
|
4326
|
-
showCopyToast && /* @__PURE__ */ (0,
|
|
4327
|
-
/* @__PURE__ */ (0,
|
|
4585
|
+
showCopyToast && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "vpg-toast", children: [
|
|
4586
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }),
|
|
4328
4587
|
copyToastMessage
|
|
4329
4588
|
] }),
|
|
4330
|
-
/* @__PURE__ */ (0,
|
|
4331
|
-
/* @__PURE__ */ (0,
|
|
4332
|
-
/* @__PURE__ */ (0,
|
|
4589
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "vpg-skeleton-header", children: [
|
|
4590
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "vpg-skeleton-title", children: [
|
|
4591
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4333
4592
|
"path",
|
|
4334
4593
|
{
|
|
4335
4594
|
strokeLinecap: "round",
|
|
@@ -4338,24 +4597,24 @@ function PivotSkeleton({
|
|
|
4338
4597
|
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"
|
|
4339
4598
|
}
|
|
4340
4599
|
) }),
|
|
4341
|
-
/* @__PURE__ */ (0,
|
|
4600
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "Pivot Table" })
|
|
4342
4601
|
] }),
|
|
4343
|
-
/* @__PURE__ */ (0,
|
|
4344
|
-
hasActiveFilters && /* @__PURE__ */ (0,
|
|
4602
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "vpg-header-right", children: [
|
|
4603
|
+
hasActiveFilters && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
4345
4604
|
"div",
|
|
4346
4605
|
{
|
|
4347
4606
|
className: "vpg-filter-indicator",
|
|
4348
4607
|
onMouseEnter: () => setShowFilterTooltip(true),
|
|
4349
4608
|
onMouseLeave: () => setShowFilterTooltip(false),
|
|
4350
4609
|
children: [
|
|
4351
|
-
/* @__PURE__ */ (0,
|
|
4610
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4352
4611
|
"svg",
|
|
4353
4612
|
{
|
|
4354
4613
|
className: "vpg-filter-icon",
|
|
4355
4614
|
fill: "none",
|
|
4356
4615
|
stroke: "currentColor",
|
|
4357
4616
|
viewBox: "0 0 24 24",
|
|
4358
|
-
children: /* @__PURE__ */ (0,
|
|
4617
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4359
4618
|
"path",
|
|
4360
4619
|
{
|
|
4361
4620
|
strokeLinecap: "round",
|
|
@@ -4366,11 +4625,11 @@ function PivotSkeleton({
|
|
|
4366
4625
|
)
|
|
4367
4626
|
}
|
|
4368
4627
|
),
|
|
4369
|
-
/* @__PURE__ */ (0,
|
|
4628
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "vpg-filter-text", children: [
|
|
4370
4629
|
"Filtered:",
|
|
4371
4630
|
" ",
|
|
4372
|
-
/* @__PURE__ */ (0,
|
|
4373
|
-
filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ (0,
|
|
4631
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { children: filterSummary }),
|
|
4632
|
+
filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "vpg-filter-count", children: [
|
|
4374
4633
|
"(",
|
|
4375
4634
|
filteredRowCount.toLocaleString(),
|
|
4376
4635
|
" ",
|
|
@@ -4381,13 +4640,13 @@ function PivotSkeleton({
|
|
|
4381
4640
|
"rows)"
|
|
4382
4641
|
] })
|
|
4383
4642
|
] }),
|
|
4384
|
-
showFilterTooltip && /* @__PURE__ */ (0,
|
|
4385
|
-
/* @__PURE__ */ (0,
|
|
4386
|
-
filterTooltipDetails.map((filter) => /* @__PURE__ */ (0,
|
|
4387
|
-
/* @__PURE__ */ (0,
|
|
4388
|
-
/* @__PURE__ */ (0,
|
|
4389
|
-
filter.values.map((val, idx) => /* @__PURE__ */ (0,
|
|
4390
|
-
filter.remaining > 0 && /* @__PURE__ */ (0,
|
|
4643
|
+
showFilterTooltip && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "vpg-filter-tooltip", children: [
|
|
4644
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "vpg-tooltip-header", children: "Active Filters" }),
|
|
4645
|
+
filterTooltipDetails.map((filter) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "vpg-tooltip-filter", children: [
|
|
4646
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "vpg-tooltip-column", children: filter.column }),
|
|
4647
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "vpg-tooltip-values", children: filter.isRange ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "vpg-tooltip-value vpg-range-value", children: filter.displayText }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
4648
|
+
filter.values.map((val, idx) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "vpg-tooltip-value", children: val }, idx)),
|
|
4649
|
+
filter.remaining > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "vpg-tooltip-more", children: [
|
|
4391
4650
|
"+",
|
|
4392
4651
|
filter.remaining,
|
|
4393
4652
|
" ",
|
|
@@ -4395,7 +4654,7 @@ function PivotSkeleton({
|
|
|
4395
4654
|
] })
|
|
4396
4655
|
] }) })
|
|
4397
4656
|
] }, filter.column)),
|
|
4398
|
-
filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ (0,
|
|
4657
|
+
filteredRowCount !== void 0 && totalRowCount !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "vpg-tooltip-summary", children: [
|
|
4399
4658
|
"Showing",
|
|
4400
4659
|
" ",
|
|
4401
4660
|
filteredRowCount.toLocaleString(),
|
|
@@ -4410,20 +4669,20 @@ function PivotSkeleton({
|
|
|
4410
4669
|
]
|
|
4411
4670
|
}
|
|
4412
4671
|
),
|
|
4413
|
-
isConfigured && /* @__PURE__ */ (0,
|
|
4414
|
-
/* @__PURE__ */ (0,
|
|
4672
|
+
isConfigured && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "vpg-config-summary", children: [
|
|
4673
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "vpg-summary-badge vpg-rows", children: [
|
|
4415
4674
|
rowFields.length,
|
|
4416
4675
|
" ",
|
|
4417
4676
|
"row",
|
|
4418
4677
|
rowFields.length !== 1 ? "s" : ""
|
|
4419
4678
|
] }),
|
|
4420
|
-
/* @__PURE__ */ (0,
|
|
4679
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "vpg-summary-badge vpg-cols", children: [
|
|
4421
4680
|
columnFields.length,
|
|
4422
4681
|
" ",
|
|
4423
4682
|
"col",
|
|
4424
4683
|
columnFields.length !== 1 ? "s" : ""
|
|
4425
4684
|
] }),
|
|
4426
|
-
/* @__PURE__ */ (0,
|
|
4685
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "vpg-summary-badge vpg-vals", children: [
|
|
4427
4686
|
valueFields.length,
|
|
4428
4687
|
" ",
|
|
4429
4688
|
"val",
|
|
@@ -4432,8 +4691,8 @@ function PivotSkeleton({
|
|
|
4432
4691
|
] })
|
|
4433
4692
|
] })
|
|
4434
4693
|
] }),
|
|
4435
|
-
!canUsePivot ? /* @__PURE__ */ (0,
|
|
4436
|
-
/* @__PURE__ */ (0,
|
|
4694
|
+
!canUsePivot ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "vpg-pro-required", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "vpg-pro-content", children: [
|
|
4695
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("svg", { className: "vpg-pro-icon", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4437
4696
|
"path",
|
|
4438
4697
|
{
|
|
4439
4698
|
strokeLinecap: "round",
|
|
@@ -4442,12 +4701,12 @@ function PivotSkeleton({
|
|
|
4442
4701
|
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"
|
|
4443
4702
|
}
|
|
4444
4703
|
) }),
|
|
4445
|
-
/* @__PURE__ */ (0,
|
|
4446
|
-
/* @__PURE__ */ (0,
|
|
4447
|
-
/* @__PURE__ */ (0,
|
|
4448
|
-
] }) }) : /* @__PURE__ */ (0,
|
|
4449
|
-
/* @__PURE__ */ (0,
|
|
4450
|
-
/* @__PURE__ */ (0,
|
|
4704
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { children: "Pro Feature" }),
|
|
4705
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: "Pivot Table functionality requires a Pro license." }),
|
|
4706
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("a", { href: "https://tiny-pivot.com/#pricing", target: "_blank", rel: "noopener noreferrer", className: "vpg-pro-link", children: "Get Pro License \u2192" })
|
|
4707
|
+
] }) }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
4708
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "vpg-config-bar", children: [
|
|
4709
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
4451
4710
|
"div",
|
|
4452
4711
|
{
|
|
4453
4712
|
className: `vpg-drop-zone vpg-row-zone ${dragOverArea === "row" ? "vpg-drag-over" : ""}`,
|
|
@@ -4455,12 +4714,12 @@ function PivotSkeleton({
|
|
|
4455
4714
|
onDragLeave: handleDragLeave,
|
|
4456
4715
|
onDrop: (e) => handleDrop("row", e),
|
|
4457
4716
|
children: [
|
|
4458
|
-
/* @__PURE__ */ (0,
|
|
4459
|
-
/* @__PURE__ */ (0,
|
|
4460
|
-
/* @__PURE__ */ (0,
|
|
4717
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "vpg-zone-header", children: [
|
|
4718
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "vpg-zone-icon vpg-row-icon", children: "\u2193" }),
|
|
4719
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "vpg-zone-label", children: "Rows" })
|
|
4461
4720
|
] }),
|
|
4462
|
-
/* @__PURE__ */ (0,
|
|
4463
|
-
rowFields.map((field, idx) => /* @__PURE__ */ (0,
|
|
4721
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "vpg-zone-chips", children: [
|
|
4722
|
+
rowFields.map((field, idx) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
4464
4723
|
"div",
|
|
4465
4724
|
{
|
|
4466
4725
|
className: `vpg-mini-chip vpg-row-chip ${isChipDragSource("row", idx) ? "vpg-chip-dragging" : ""} ${isChipDropTarget("row", idx) ? "vpg-chip-drop-target" : ""}`,
|
|
@@ -4471,9 +4730,9 @@ function PivotSkeleton({
|
|
|
4471
4730
|
onDragLeave: handleChipDragLeave,
|
|
4472
4731
|
onDrop: (e) => handleChipDrop("row", idx, e),
|
|
4473
4732
|
children: [
|
|
4474
|
-
/* @__PURE__ */ (0,
|
|
4475
|
-
/* @__PURE__ */ (0,
|
|
4476
|
-
/* @__PURE__ */ (0,
|
|
4733
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "vpg-drag-handle", children: "\u22EE\u22EE" }),
|
|
4734
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "vpg-mini-name", children: field }),
|
|
4735
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4477
4736
|
"button",
|
|
4478
4737
|
{
|
|
4479
4738
|
className: "vpg-mini-remove",
|
|
@@ -4488,12 +4747,12 @@ function PivotSkeleton({
|
|
|
4488
4747
|
},
|
|
4489
4748
|
field
|
|
4490
4749
|
)),
|
|
4491
|
-
rowFields.length === 0 && /* @__PURE__ */ (0,
|
|
4750
|
+
rowFields.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "vpg-zone-hint", children: "Drop here" })
|
|
4492
4751
|
] })
|
|
4493
4752
|
]
|
|
4494
4753
|
}
|
|
4495
4754
|
),
|
|
4496
|
-
/* @__PURE__ */ (0,
|
|
4755
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
4497
4756
|
"div",
|
|
4498
4757
|
{
|
|
4499
4758
|
className: `vpg-drop-zone vpg-column-zone ${dragOverArea === "column" ? "vpg-drag-over" : ""}`,
|
|
@@ -4501,12 +4760,12 @@ function PivotSkeleton({
|
|
|
4501
4760
|
onDragLeave: handleDragLeave,
|
|
4502
4761
|
onDrop: (e) => handleDrop("column", e),
|
|
4503
4762
|
children: [
|
|
4504
|
-
/* @__PURE__ */ (0,
|
|
4505
|
-
/* @__PURE__ */ (0,
|
|
4506
|
-
/* @__PURE__ */ (0,
|
|
4763
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "vpg-zone-header", children: [
|
|
4764
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "vpg-zone-icon vpg-column-icon", children: "\u2192" }),
|
|
4765
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "vpg-zone-label", children: "Columns" })
|
|
4507
4766
|
] }),
|
|
4508
|
-
/* @__PURE__ */ (0,
|
|
4509
|
-
columnFields.map((field, idx) => /* @__PURE__ */ (0,
|
|
4767
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "vpg-zone-chips", children: [
|
|
4768
|
+
columnFields.map((field, idx) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
4510
4769
|
"div",
|
|
4511
4770
|
{
|
|
4512
4771
|
className: `vpg-mini-chip vpg-column-chip ${isChipDragSource("column", idx) ? "vpg-chip-dragging" : ""} ${isChipDropTarget("column", idx) ? "vpg-chip-drop-target" : ""}`,
|
|
@@ -4517,9 +4776,9 @@ function PivotSkeleton({
|
|
|
4517
4776
|
onDragLeave: handleChipDragLeave,
|
|
4518
4777
|
onDrop: (e) => handleChipDrop("column", idx, e),
|
|
4519
4778
|
children: [
|
|
4520
|
-
/* @__PURE__ */ (0,
|
|
4521
|
-
/* @__PURE__ */ (0,
|
|
4522
|
-
/* @__PURE__ */ (0,
|
|
4779
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "vpg-drag-handle", children: "\u22EE\u22EE" }),
|
|
4780
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "vpg-mini-name", children: field }),
|
|
4781
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4523
4782
|
"button",
|
|
4524
4783
|
{
|
|
4525
4784
|
className: "vpg-mini-remove",
|
|
@@ -4534,12 +4793,12 @@ function PivotSkeleton({
|
|
|
4534
4793
|
},
|
|
4535
4794
|
field
|
|
4536
4795
|
)),
|
|
4537
|
-
columnFields.length === 0 && /* @__PURE__ */ (0,
|
|
4796
|
+
columnFields.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "vpg-zone-hint", children: "Drop here" })
|
|
4538
4797
|
] })
|
|
4539
4798
|
]
|
|
4540
4799
|
}
|
|
4541
4800
|
),
|
|
4542
|
-
/* @__PURE__ */ (0,
|
|
4801
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
4543
4802
|
"div",
|
|
4544
4803
|
{
|
|
4545
4804
|
className: `vpg-drop-zone vpg-value-zone ${dragOverArea === "value" ? "vpg-drag-over" : ""}`,
|
|
@@ -4547,19 +4806,19 @@ function PivotSkeleton({
|
|
|
4547
4806
|
onDragLeave: handleDragLeave,
|
|
4548
4807
|
onDrop: (e) => handleDrop("value", e),
|
|
4549
4808
|
children: [
|
|
4550
|
-
/* @__PURE__ */ (0,
|
|
4551
|
-
/* @__PURE__ */ (0,
|
|
4552
|
-
/* @__PURE__ */ (0,
|
|
4809
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "vpg-zone-header", children: [
|
|
4810
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "vpg-zone-icon vpg-value-icon", children: "\u03A3" }),
|
|
4811
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "vpg-zone-label", children: "Values" })
|
|
4553
4812
|
] }),
|
|
4554
|
-
/* @__PURE__ */ (0,
|
|
4555
|
-
valueFields.map((vf) => /* @__PURE__ */ (0,
|
|
4813
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "vpg-zone-chips", children: [
|
|
4814
|
+
valueFields.map((vf) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
4556
4815
|
"div",
|
|
4557
4816
|
{
|
|
4558
4817
|
className: `vpg-mini-chip vpg-value-chip${isCalculatedField(vf.field) ? " vpg-calc-chip" : ""}`,
|
|
4559
4818
|
children: [
|
|
4560
|
-
/* @__PURE__ */ (0,
|
|
4561
|
-
/* @__PURE__ */ (0,
|
|
4562
|
-
/* @__PURE__ */ (0,
|
|
4819
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "vpg-agg-symbol", children: isCalculatedField(vf.field) ? "\u0192" : (0, import_tinypivot_core12.getAggregationSymbol)(vf.aggregation) }),
|
|
4820
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "vpg-mini-name", children: getValueFieldDisplayName(vf.field) }),
|
|
4821
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4563
4822
|
"button",
|
|
4564
4823
|
{
|
|
4565
4824
|
className: "vpg-mini-remove",
|
|
@@ -4571,21 +4830,21 @@ function PivotSkeleton({
|
|
|
4571
4830
|
},
|
|
4572
4831
|
`${vf.field}-${vf.aggregation}`
|
|
4573
4832
|
)),
|
|
4574
|
-
valueFields.length === 0 && /* @__PURE__ */ (0,
|
|
4833
|
+
valueFields.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "vpg-zone-hint", children: "Drop numeric" })
|
|
4575
4834
|
] })
|
|
4576
4835
|
]
|
|
4577
4836
|
}
|
|
4578
4837
|
)
|
|
4579
4838
|
] }),
|
|
4580
|
-
(!isConfigured || !pivotResult) && /* @__PURE__ */ (0,
|
|
4581
|
-
/* @__PURE__ */ (0,
|
|
4839
|
+
(!isConfigured || !pivotResult) && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "vpg-placeholder", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "vpg-placeholder-content", children: [
|
|
4840
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4582
4841
|
"svg",
|
|
4583
4842
|
{
|
|
4584
4843
|
className: "vpg-placeholder-icon",
|
|
4585
4844
|
fill: "none",
|
|
4586
4845
|
viewBox: "0 0 24 24",
|
|
4587
4846
|
stroke: "currentColor",
|
|
4588
|
-
children: /* @__PURE__ */ (0,
|
|
4847
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4589
4848
|
"path",
|
|
4590
4849
|
{
|
|
4591
4850
|
strokeLinecap: "round",
|
|
@@ -4596,58 +4855,58 @@ function PivotSkeleton({
|
|
|
4596
4855
|
)
|
|
4597
4856
|
}
|
|
4598
4857
|
),
|
|
4599
|
-
/* @__PURE__ */ (0,
|
|
4858
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "vpg-placeholder-text", children: valueFields.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
4600
4859
|
"Add a",
|
|
4601
4860
|
" ",
|
|
4602
|
-
/* @__PURE__ */ (0,
|
|
4861
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { children: "Values" }),
|
|
4603
4862
|
" ",
|
|
4604
4863
|
"field to see your pivot table"
|
|
4605
|
-
] }) : rowFields.length === 0 && columnFields.length === 0 ? /* @__PURE__ */ (0,
|
|
4864
|
+
] }) : rowFields.length === 0 && columnFields.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
4606
4865
|
"Add",
|
|
4607
4866
|
" ",
|
|
4608
|
-
/* @__PURE__ */ (0,
|
|
4867
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { children: "Row" }),
|
|
4609
4868
|
" ",
|
|
4610
4869
|
"or",
|
|
4611
4870
|
" ",
|
|
4612
|
-
/* @__PURE__ */ (0,
|
|
4871
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { children: "Column" }),
|
|
4613
4872
|
" ",
|
|
4614
4873
|
"fields to group your data"
|
|
4615
4874
|
] }) : "Your pivot table will appear here" })
|
|
4616
4875
|
] }) }),
|
|
4617
|
-
isConfigured && pivotResult && /* @__PURE__ */ (0,
|
|
4618
|
-
/* @__PURE__ */ (0,
|
|
4619
|
-
levelIdx === 0 && (rowFields.length > 0 ? rowFields : ["Rows"]).map((field, fieldIdx) => /* @__PURE__ */ (0,
|
|
4876
|
+
isConfigured && pivotResult && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "vpg-table-container", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("table", { className: "vpg-pivot-table", children: [
|
|
4877
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("thead", { children: columnHeaderCells.map((headerRow, levelIdx) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("tr", { className: "vpg-column-header-row", children: [
|
|
4878
|
+
levelIdx === 0 && (rowFields.length > 0 ? rowFields : ["Rows"]).map((field, fieldIdx) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4620
4879
|
"th",
|
|
4621
4880
|
{
|
|
4622
4881
|
className: "vpg-row-header-label",
|
|
4623
4882
|
rowSpan: columnHeaderCells.length,
|
|
4624
4883
|
style: { width: `${rowHeaderColWidth}px`, minWidth: "80px", left: `${getRowHeaderLeftOffset(fieldIdx)}px` },
|
|
4625
4884
|
onClick: () => toggleSort("row"),
|
|
4626
|
-
children: /* @__PURE__ */ (0,
|
|
4627
|
-
/* @__PURE__ */ (0,
|
|
4628
|
-
(fieldIdx === rowFields.length - 1 || rowFields.length === 0) && /* @__PURE__ */ (0,
|
|
4885
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "vpg-header-content", children: [
|
|
4886
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: field }),
|
|
4887
|
+
(fieldIdx === rowFields.length - 1 || rowFields.length === 0) && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: `vpg-sort-indicator ${sortTarget === "row" ? "active" : ""}`, children: sortTarget === "row" ? sortDirection === "asc" ? "\u2191" : "\u2193" : "\u21C5" })
|
|
4629
4888
|
] })
|
|
4630
4889
|
},
|
|
4631
4890
|
`row-header-${fieldIdx}`
|
|
4632
4891
|
)),
|
|
4633
|
-
headerRow.map((cell, idx) => /* @__PURE__ */ (0,
|
|
4892
|
+
headerRow.map((cell, idx) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4634
4893
|
"th",
|
|
4635
4894
|
{
|
|
4636
4895
|
className: "vpg-column-header-cell",
|
|
4637
4896
|
colSpan: cell.colspan,
|
|
4638
4897
|
onClick: () => levelIdx === columnHeaderCells.length - 1 && toggleSort(idx),
|
|
4639
|
-
children: /* @__PURE__ */ (0,
|
|
4640
|
-
/* @__PURE__ */ (0,
|
|
4641
|
-
levelIdx === columnHeaderCells.length - 1 && /* @__PURE__ */ (0,
|
|
4898
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "vpg-header-content", children: [
|
|
4899
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: cell.label }),
|
|
4900
|
+
levelIdx === columnHeaderCells.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: `vpg-sort-indicator ${sortTarget === idx ? "active" : ""}`, children: sortTarget === idx ? sortDirection === "asc" ? "\u2191" : "\u2193" : "\u21C5" })
|
|
4642
4901
|
] })
|
|
4643
4902
|
},
|
|
4644
4903
|
idx
|
|
4645
4904
|
)),
|
|
4646
|
-
pivotResult.rowTotals.length > 0 && levelIdx === 0 && /* @__PURE__ */ (0,
|
|
4905
|
+
pivotResult.rowTotals.length > 0 && levelIdx === 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("th", { className: "vpg-total-header", rowSpan: columnHeaderCells.length, children: "Total" })
|
|
4647
4906
|
] }, `header-${levelIdx}`)) }),
|
|
4648
|
-
/* @__PURE__ */ (0,
|
|
4649
|
-
sortedRowIndices.map((sortedIdx) => /* @__PURE__ */ (0,
|
|
4650
|
-
pivotResult.rowHeaders[sortedIdx].map((val, idx) => /* @__PURE__ */ (0,
|
|
4907
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("tbody", { children: [
|
|
4908
|
+
sortedRowIndices.map((sortedIdx) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("tr", { className: "vpg-data-row", children: [
|
|
4909
|
+
pivotResult.rowHeaders[sortedIdx].map((val, idx) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4651
4910
|
"th",
|
|
4652
4911
|
{
|
|
4653
4912
|
className: "vpg-row-header-cell",
|
|
@@ -4658,7 +4917,7 @@ function PivotSkeleton({
|
|
|
4658
4917
|
)),
|
|
4659
4918
|
pivotResult.data[sortedIdx].map((cell, colIdx) => {
|
|
4660
4919
|
const displayRowIdx = sortedRowIndices.indexOf(sortedIdx);
|
|
4661
|
-
return /* @__PURE__ */ (0,
|
|
4920
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4662
4921
|
"td",
|
|
4663
4922
|
{
|
|
4664
4923
|
className: `vpg-data-cell ${isCellSelected(displayRowIdx, colIdx) ? "selected" : ""} ${cell.value === null ? "vpg-is-null" : ""}`,
|
|
@@ -4669,10 +4928,10 @@ function PivotSkeleton({
|
|
|
4669
4928
|
colIdx
|
|
4670
4929
|
);
|
|
4671
4930
|
}),
|
|
4672
|
-
pivotResult.rowTotals[sortedIdx] && /* @__PURE__ */ (0,
|
|
4931
|
+
pivotResult.rowTotals[sortedIdx] && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("td", { className: "vpg-data-cell vpg-total-cell", children: pivotResult.rowTotals[sortedIdx].formattedValue })
|
|
4673
4932
|
] }, sortedIdx)),
|
|
4674
|
-
pivotResult.columnTotals.length > 0 && /* @__PURE__ */ (0,
|
|
4675
|
-
/* @__PURE__ */ (0,
|
|
4933
|
+
pivotResult.columnTotals.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("tr", { className: "vpg-totals-row", children: [
|
|
4934
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4676
4935
|
"th",
|
|
4677
4936
|
{
|
|
4678
4937
|
className: "vpg-row-header-cell vpg-total-label",
|
|
@@ -4681,13 +4940,13 @@ function PivotSkeleton({
|
|
|
4681
4940
|
children: "Total"
|
|
4682
4941
|
}
|
|
4683
4942
|
),
|
|
4684
|
-
pivotResult.columnTotals.map((cell, colIdx) => /* @__PURE__ */ (0,
|
|
4685
|
-
pivotResult.rowTotals.length > 0 && /* @__PURE__ */ (0,
|
|
4943
|
+
pivotResult.columnTotals.map((cell, colIdx) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("td", { className: "vpg-data-cell vpg-total-cell", children: cell.formattedValue }, colIdx)),
|
|
4944
|
+
pivotResult.rowTotals.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("td", { className: "vpg-data-cell vpg-grand-total-cell", children: pivotResult.grandTotal.formattedValue })
|
|
4686
4945
|
] })
|
|
4687
4946
|
] })
|
|
4688
4947
|
] }) }),
|
|
4689
|
-
isConfigured && pivotResult && /* @__PURE__ */ (0,
|
|
4690
|
-
/* @__PURE__ */ (0,
|
|
4948
|
+
isConfigured && pivotResult && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "vpg-skeleton-footer", children: [
|
|
4949
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "vpg-footer-info", children: [
|
|
4691
4950
|
pivotResult.rowHeaders.length,
|
|
4692
4951
|
" ",
|
|
4693
4952
|
"rows \xD7",
|
|
@@ -4695,30 +4954,30 @@ function PivotSkeleton({
|
|
|
4695
4954
|
" ",
|
|
4696
4955
|
"columns"
|
|
4697
4956
|
] }),
|
|
4698
|
-
selectionStats && selectionStats.count > 1 && /* @__PURE__ */ (0,
|
|
4699
|
-
/* @__PURE__ */ (0,
|
|
4700
|
-
/* @__PURE__ */ (0,
|
|
4701
|
-
/* @__PURE__ */ (0,
|
|
4957
|
+
selectionStats && selectionStats.count > 1 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "vpg-selection-stats", children: [
|
|
4958
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "vpg-stat", children: [
|
|
4959
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "vpg-stat-label", children: "Count:" }),
|
|
4960
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "vpg-stat-value", children: selectionStats.count })
|
|
4702
4961
|
] }),
|
|
4703
|
-
selectionStats.numericCount > 0 && /* @__PURE__ */ (0,
|
|
4704
|
-
/* @__PURE__ */ (0,
|
|
4705
|
-
/* @__PURE__ */ (0,
|
|
4706
|
-
/* @__PURE__ */ (0,
|
|
4707
|
-
/* @__PURE__ */ (0,
|
|
4962
|
+
selectionStats.numericCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
4963
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "vpg-stat-divider", children: "|" }),
|
|
4964
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "vpg-stat", children: [
|
|
4965
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "vpg-stat-label", children: "Sum:" }),
|
|
4966
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.sum) })
|
|
4708
4967
|
] }),
|
|
4709
|
-
/* @__PURE__ */ (0,
|
|
4710
|
-
/* @__PURE__ */ (0,
|
|
4711
|
-
/* @__PURE__ */ (0,
|
|
4712
|
-
/* @__PURE__ */ (0,
|
|
4968
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "vpg-stat-divider", children: "|" }),
|
|
4969
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "vpg-stat", children: [
|
|
4970
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "vpg-stat-label", children: "Avg:" }),
|
|
4971
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.avg) })
|
|
4713
4972
|
] })
|
|
4714
4973
|
] })
|
|
4715
4974
|
] })
|
|
4716
4975
|
] })
|
|
4717
4976
|
] }),
|
|
4718
|
-
showWatermark && canUsePivot && /* @__PURE__ */ (0,
|
|
4719
|
-
/* @__PURE__ */ (0,
|
|
4720
|
-
/* @__PURE__ */ (0,
|
|
4721
|
-
/* @__PURE__ */ (0,
|
|
4977
|
+
showWatermark && canUsePivot && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: `vpg-watermark ${isDemo ? "vpg-demo-mode" : ""}`, children: isDemo ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
4978
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "vpg-demo-badge", children: "DEMO" }),
|
|
4979
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "Pro features unlocked for evaluation" }),
|
|
4980
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4722
4981
|
"a",
|
|
4723
4982
|
{
|
|
4724
4983
|
href: "https://tiny-pivot.com/#pricing",
|
|
@@ -4728,14 +4987,14 @@ function PivotSkeleton({
|
|
|
4728
4987
|
children: "Get Pro License \u2192"
|
|
4729
4988
|
}
|
|
4730
4989
|
)
|
|
4731
|
-
] }) : /* @__PURE__ */ (0,
|
|
4990
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: "Powered by TinyPivot" }) })
|
|
4732
4991
|
]
|
|
4733
4992
|
}
|
|
4734
4993
|
);
|
|
4735
4994
|
}
|
|
4736
4995
|
|
|
4737
4996
|
// src/components/DataGrid.tsx
|
|
4738
|
-
var
|
|
4997
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
4739
4998
|
var MIN_COL_WIDTH = 120;
|
|
4740
4999
|
var MAX_COL_WIDTH = 350;
|
|
4741
5000
|
function DataGrid({
|
|
@@ -4756,6 +5015,8 @@ function DataGrid({
|
|
|
4756
5015
|
initialHeight = 600,
|
|
4757
5016
|
minHeight = 300,
|
|
4758
5017
|
maxHeight = 1200,
|
|
5018
|
+
numberFormat = "us",
|
|
5019
|
+
dateFormat = "iso",
|
|
4759
5020
|
aiAnalyst,
|
|
4760
5021
|
onCellClick,
|
|
4761
5022
|
onExport,
|
|
@@ -4767,45 +5028,45 @@ function DataGrid({
|
|
|
4767
5028
|
}) {
|
|
4768
5029
|
const { showWatermark, canUsePivot, canUseCharts, canUseAIAnalyst, isDemo, isPro } = useLicense();
|
|
4769
5030
|
const showAIAnalyst = aiAnalyst?.enabled && canUseAIAnalyst;
|
|
4770
|
-
const currentTheme = (0,
|
|
5031
|
+
const currentTheme = (0, import_react14.useMemo)(() => {
|
|
4771
5032
|
if (theme === "auto") {
|
|
4772
5033
|
return window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
4773
5034
|
}
|
|
4774
5035
|
return theme;
|
|
4775
5036
|
}, [theme]);
|
|
4776
|
-
const [currentFontSize, setCurrentFontSize] = (0,
|
|
4777
|
-
const [globalSearchTerm, setGlobalSearchTerm] = (0,
|
|
4778
|
-
const [showSearchInput, setShowSearchInput] = (0,
|
|
4779
|
-
const [currentPage, setCurrentPage] = (0,
|
|
4780
|
-
const [columnWidths, setColumnWidths] = (0,
|
|
4781
|
-
const [resizingColumnId, setResizingColumnId] = (0,
|
|
4782
|
-
const [resizeStartX, setResizeStartX] = (0,
|
|
4783
|
-
const [resizeStartWidth, setResizeStartWidth] = (0,
|
|
4784
|
-
const [gridHeight, setGridHeight] = (0,
|
|
4785
|
-
const [isResizingVertically, setIsResizingVertically] = (0,
|
|
4786
|
-
const [verticalResizeStartY, setVerticalResizeStartY] = (0,
|
|
4787
|
-
const [verticalResizeStartHeight, setVerticalResizeStartHeight] = (0,
|
|
4788
|
-
const [showCopyToast, setShowCopyToast] = (0,
|
|
4789
|
-
const [copyToastMessage, setCopyToastMessage] = (0,
|
|
4790
|
-
const [viewMode, setViewMode] = (0,
|
|
4791
|
-
const aiAnalystRef = (0,
|
|
4792
|
-
const [aiLoadedData, setAiLoadedData] = (0,
|
|
4793
|
-
const [isLoadingFullData, setIsLoadingFullData] = (0,
|
|
4794
|
-
const displayData = (0,
|
|
4795
|
-
const [_chartConfig, setChartConfig] = (0,
|
|
4796
|
-
const handleChartConfigChange = (0,
|
|
5037
|
+
const [currentFontSize, setCurrentFontSize] = (0, import_react14.useState)(initialFontSize);
|
|
5038
|
+
const [globalSearchTerm, setGlobalSearchTerm] = (0, import_react14.useState)("");
|
|
5039
|
+
const [showSearchInput, setShowSearchInput] = (0, import_react14.useState)(false);
|
|
5040
|
+
const [currentPage, setCurrentPage] = (0, import_react14.useState)(1);
|
|
5041
|
+
const [columnWidths, setColumnWidths] = (0, import_react14.useState)({});
|
|
5042
|
+
const [resizingColumnId, setResizingColumnId] = (0, import_react14.useState)(null);
|
|
5043
|
+
const [resizeStartX, setResizeStartX] = (0, import_react14.useState)(0);
|
|
5044
|
+
const [resizeStartWidth, setResizeStartWidth] = (0, import_react14.useState)(0);
|
|
5045
|
+
const [gridHeight, setGridHeight] = (0, import_react14.useState)(initialHeight);
|
|
5046
|
+
const [isResizingVertically, setIsResizingVertically] = (0, import_react14.useState)(false);
|
|
5047
|
+
const [verticalResizeStartY, setVerticalResizeStartY] = (0, import_react14.useState)(0);
|
|
5048
|
+
const [verticalResizeStartHeight, setVerticalResizeStartHeight] = (0, import_react14.useState)(0);
|
|
5049
|
+
const [showCopyToast, setShowCopyToast] = (0, import_react14.useState)(false);
|
|
5050
|
+
const [copyToastMessage, setCopyToastMessage] = (0, import_react14.useState)("");
|
|
5051
|
+
const [viewMode, setViewMode] = (0, import_react14.useState)("grid");
|
|
5052
|
+
const aiAnalystRef = (0, import_react14.useRef)(null);
|
|
5053
|
+
const [aiLoadedData, setAiLoadedData] = (0, import_react14.useState)(null);
|
|
5054
|
+
const [isLoadingFullData, setIsLoadingFullData] = (0, import_react14.useState)(false);
|
|
5055
|
+
const displayData = (0, import_react14.useMemo)(() => aiLoadedData || data, [aiLoadedData, data]);
|
|
5056
|
+
const [_chartConfig, setChartConfig] = (0, import_react14.useState)(null);
|
|
5057
|
+
const handleChartConfigChange = (0, import_react14.useCallback)((config) => {
|
|
4797
5058
|
setChartConfig(config);
|
|
4798
5059
|
}, []);
|
|
4799
|
-
const [showPivotConfig, setShowPivotConfig] = (0,
|
|
4800
|
-
const [draggingField, setDraggingField] = (0,
|
|
4801
|
-
const [activeFilterColumn, setActiveFilterColumn] = (0,
|
|
4802
|
-
const [filterDropdownPosition, setFilterDropdownPosition] = (0,
|
|
4803
|
-
const [selectedCell, setSelectedCell] = (0,
|
|
4804
|
-
const [selectionStart, setSelectionStart] = (0,
|
|
4805
|
-
const [selectionEnd, setSelectionEnd] = (0,
|
|
4806
|
-
const [isSelecting, setIsSelecting] = (0,
|
|
4807
|
-
const tableContainerRef = (0,
|
|
4808
|
-
const tableBodyRef = (0,
|
|
5060
|
+
const [showPivotConfig, setShowPivotConfig] = (0, import_react14.useState)(true);
|
|
5061
|
+
const [draggingField, setDraggingField] = (0, import_react14.useState)(null);
|
|
5062
|
+
const [activeFilterColumn, setActiveFilterColumn] = (0, import_react14.useState)(null);
|
|
5063
|
+
const [filterDropdownPosition, setFilterDropdownPosition] = (0, import_react14.useState)({ top: 0, left: 0, maxHeight: 400 });
|
|
5064
|
+
const [selectedCell, setSelectedCell] = (0, import_react14.useState)(null);
|
|
5065
|
+
const [selectionStart, setSelectionStart] = (0, import_react14.useState)(null);
|
|
5066
|
+
const [selectionEnd, setSelectionEnd] = (0, import_react14.useState)(null);
|
|
5067
|
+
const [isSelecting, setIsSelecting] = (0, import_react14.useState)(false);
|
|
5068
|
+
const tableContainerRef = (0, import_react14.useRef)(null);
|
|
5069
|
+
const tableBodyRef = (0, import_react14.useRef)(null);
|
|
4809
5070
|
const fontSizeOptions = [
|
|
4810
5071
|
{ value: "xs", label: "S" },
|
|
4811
5072
|
{ value: "sm", label: "M" },
|
|
@@ -4827,9 +5088,12 @@ function DataGrid({
|
|
|
4827
5088
|
activeFilters,
|
|
4828
5089
|
// Numeric range filters
|
|
4829
5090
|
setNumericRangeFilter,
|
|
4830
|
-
getNumericRangeFilter
|
|
5091
|
+
getNumericRangeFilter,
|
|
5092
|
+
// Date range filters
|
|
5093
|
+
setDateRangeFilter,
|
|
5094
|
+
getDateRangeFilter
|
|
4831
5095
|
} = useExcelGrid({ data: displayData, enableSorting: true, enableFiltering: true });
|
|
4832
|
-
const filteredDataForPivot = (0,
|
|
5096
|
+
const filteredDataForPivot = (0, import_react14.useMemo)(() => {
|
|
4833
5097
|
const filteredRows = table.getFilteredRowModel().rows;
|
|
4834
5098
|
return filteredRows.map((row) => row.original);
|
|
4835
5099
|
}, [table, columnFilters]);
|
|
@@ -4859,7 +5123,7 @@ function DataGrid({
|
|
|
4859
5123
|
addCalculatedField,
|
|
4860
5124
|
removeCalculatedField
|
|
4861
5125
|
} = usePivotTable(filteredDataForPivot);
|
|
4862
|
-
const activeFilterInfo = (0,
|
|
5126
|
+
const activeFilterInfo = (0, import_react14.useMemo)(() => {
|
|
4863
5127
|
if (activeFilters.length === 0)
|
|
4864
5128
|
return null;
|
|
4865
5129
|
return activeFilters.map((f) => {
|
|
@@ -4876,6 +5140,19 @@ function DataGrid({
|
|
|
4876
5140
|
isRange: true
|
|
4877
5141
|
};
|
|
4878
5142
|
}
|
|
5143
|
+
if (f.type === "dateRange" && f.dateRange) {
|
|
5144
|
+
const parts = [];
|
|
5145
|
+
if (f.dateRange.min !== null)
|
|
5146
|
+
parts.push(`from ${(0, import_tinypivot_core13.formatDate)(f.dateRange.min, dateFormat)}`);
|
|
5147
|
+
if (f.dateRange.max !== null)
|
|
5148
|
+
parts.push(`to ${(0, import_tinypivot_core13.formatDate)(f.dateRange.max, dateFormat)}`);
|
|
5149
|
+
return {
|
|
5150
|
+
column: f.column,
|
|
5151
|
+
valueCount: 1,
|
|
5152
|
+
displayText: parts.join(" "),
|
|
5153
|
+
isRange: true
|
|
5154
|
+
};
|
|
5155
|
+
}
|
|
4879
5156
|
return {
|
|
4880
5157
|
column: f.column,
|
|
4881
5158
|
valueCount: f.values?.length || 0,
|
|
@@ -4883,9 +5160,9 @@ function DataGrid({
|
|
|
4883
5160
|
isRange: false
|
|
4884
5161
|
};
|
|
4885
5162
|
});
|
|
4886
|
-
}, [activeFilters]);
|
|
4887
|
-
const rows = (0,
|
|
4888
|
-
const searchFilteredData = (0,
|
|
5163
|
+
}, [activeFilters, dateFormat]);
|
|
5164
|
+
const rows = (0, import_react14.useMemo)(() => table.getFilteredRowModel().rows, [table, columnFilters]);
|
|
5165
|
+
const searchFilteredData = (0, import_react14.useMemo)(() => {
|
|
4889
5166
|
if (!globalSearchTerm.trim() || !enableSearch) {
|
|
4890
5167
|
return rows;
|
|
4891
5168
|
}
|
|
@@ -4903,22 +5180,22 @@ function DataGrid({
|
|
|
4903
5180
|
});
|
|
4904
5181
|
}, [rows, globalSearchTerm, enableSearch, columnKeys]);
|
|
4905
5182
|
const totalSearchedRows = searchFilteredData.length;
|
|
4906
|
-
const totalPages = (0,
|
|
5183
|
+
const totalPages = (0, import_react14.useMemo)(() => {
|
|
4907
5184
|
if (!enablePagination)
|
|
4908
5185
|
return 1;
|
|
4909
5186
|
return Math.max(1, Math.ceil(totalSearchedRows / pageSize));
|
|
4910
5187
|
}, [enablePagination, totalSearchedRows, pageSize]);
|
|
4911
|
-
const paginatedRows = (0,
|
|
5188
|
+
const paginatedRows = (0, import_react14.useMemo)(() => {
|
|
4912
5189
|
if (!enablePagination)
|
|
4913
5190
|
return searchFilteredData;
|
|
4914
5191
|
const start = (currentPage - 1) * pageSize;
|
|
4915
5192
|
const end = start + pageSize;
|
|
4916
5193
|
return searchFilteredData.slice(start, end);
|
|
4917
5194
|
}, [enablePagination, searchFilteredData, currentPage, pageSize]);
|
|
4918
|
-
(0,
|
|
5195
|
+
(0, import_react14.useEffect)(() => {
|
|
4919
5196
|
setCurrentPage(1);
|
|
4920
5197
|
}, [columnFilters, globalSearchTerm]);
|
|
4921
|
-
const selectionBounds = (0,
|
|
5198
|
+
const selectionBounds = (0, import_react14.useMemo)(() => {
|
|
4922
5199
|
if (!selectionStart || !selectionEnd)
|
|
4923
5200
|
return null;
|
|
4924
5201
|
return {
|
|
@@ -4928,7 +5205,7 @@ function DataGrid({
|
|
|
4928
5205
|
maxCol: Math.max(selectionStart.col, selectionEnd.col)
|
|
4929
5206
|
};
|
|
4930
5207
|
}, [selectionStart, selectionEnd]);
|
|
4931
|
-
const selectionStats = (0,
|
|
5208
|
+
const selectionStats = (0, import_react14.useMemo)(() => {
|
|
4932
5209
|
if (!selectionBounds)
|
|
4933
5210
|
return null;
|
|
4934
5211
|
const { minRow, maxRow, minCol, maxCol } = selectionBounds;
|
|
@@ -4958,7 +5235,7 @@ function DataGrid({
|
|
|
4958
5235
|
const avg = sum / values.length;
|
|
4959
5236
|
return { count, sum, avg, numericCount: values.length };
|
|
4960
5237
|
}, [selectionBounds, rows, columnKeys]);
|
|
4961
|
-
(0,
|
|
5238
|
+
(0, import_react14.useEffect)(() => {
|
|
4962
5239
|
if (typeof document === "undefined")
|
|
4963
5240
|
return;
|
|
4964
5241
|
if (displayData.length === 0)
|
|
@@ -4982,7 +5259,7 @@ function DataGrid({
|
|
|
4982
5259
|
}
|
|
4983
5260
|
setColumnWidths(widths);
|
|
4984
5261
|
}, [displayData, columnKeys]);
|
|
4985
|
-
const startColumnResize = (0,
|
|
5262
|
+
const startColumnResize = (0, import_react14.useCallback)(
|
|
4986
5263
|
(columnId, event) => {
|
|
4987
5264
|
if (!enableColumnResize)
|
|
4988
5265
|
return;
|
|
@@ -4994,7 +5271,7 @@ function DataGrid({
|
|
|
4994
5271
|
},
|
|
4995
5272
|
[enableColumnResize, columnWidths]
|
|
4996
5273
|
);
|
|
4997
|
-
(0,
|
|
5274
|
+
(0, import_react14.useEffect)(() => {
|
|
4998
5275
|
if (!resizingColumnId)
|
|
4999
5276
|
return;
|
|
5000
5277
|
const handleResizeMove = (event) => {
|
|
@@ -5015,7 +5292,7 @@ function DataGrid({
|
|
|
5015
5292
|
document.removeEventListener("mouseup", handleResizeEnd);
|
|
5016
5293
|
};
|
|
5017
5294
|
}, [resizingColumnId, resizeStartX, resizeStartWidth]);
|
|
5018
|
-
const startVerticalResize = (0,
|
|
5295
|
+
const startVerticalResize = (0, import_react14.useCallback)(
|
|
5019
5296
|
(event) => {
|
|
5020
5297
|
if (!enableVerticalResize)
|
|
5021
5298
|
return;
|
|
@@ -5026,7 +5303,7 @@ function DataGrid({
|
|
|
5026
5303
|
},
|
|
5027
5304
|
[enableVerticalResize, gridHeight]
|
|
5028
5305
|
);
|
|
5029
|
-
(0,
|
|
5306
|
+
(0, import_react14.useEffect)(() => {
|
|
5030
5307
|
if (!isResizingVertically)
|
|
5031
5308
|
return;
|
|
5032
5309
|
const handleVerticalResizeMove = (event) => {
|
|
@@ -5044,7 +5321,7 @@ function DataGrid({
|
|
|
5044
5321
|
document.removeEventListener("mouseup", handleVerticalResizeEnd);
|
|
5045
5322
|
};
|
|
5046
5323
|
}, [isResizingVertically, verticalResizeStartY, verticalResizeStartHeight, minHeight, maxHeight]);
|
|
5047
|
-
const handleExport = (0,
|
|
5324
|
+
const handleExport = (0, import_react14.useCallback)(() => {
|
|
5048
5325
|
if (viewMode === "pivot") {
|
|
5049
5326
|
if (!pivotResult)
|
|
5050
5327
|
return;
|
|
@@ -5090,7 +5367,7 @@ function DataGrid({
|
|
|
5090
5367
|
columnKeys,
|
|
5091
5368
|
onExport
|
|
5092
5369
|
]);
|
|
5093
|
-
const copySelectionToClipboard = (0,
|
|
5370
|
+
const copySelectionToClipboard = (0, import_react14.useCallback)(() => {
|
|
5094
5371
|
if (!selectionBounds || !enableClipboard)
|
|
5095
5372
|
return;
|
|
5096
5373
|
const text = formatSelectionForClipboard(
|
|
@@ -5115,7 +5392,7 @@ function DataGrid({
|
|
|
5115
5392
|
}
|
|
5116
5393
|
);
|
|
5117
5394
|
}, [selectionBounds, enableClipboard, rows, columnKeys, onCopy]);
|
|
5118
|
-
const handleMouseDown = (0,
|
|
5395
|
+
const handleMouseDown = (0, import_react14.useCallback)(
|
|
5119
5396
|
(rowIndex, colIndex, event) => {
|
|
5120
5397
|
event.preventDefault();
|
|
5121
5398
|
if (event.shiftKey && selectedCell) {
|
|
@@ -5139,7 +5416,7 @@ function DataGrid({
|
|
|
5139
5416
|
},
|
|
5140
5417
|
[selectedCell, rows, columnKeys, onCellClick]
|
|
5141
5418
|
);
|
|
5142
|
-
const handleMouseEnter = (0,
|
|
5419
|
+
const handleMouseEnter = (0, import_react14.useCallback)(
|
|
5143
5420
|
(rowIndex, colIndex) => {
|
|
5144
5421
|
if (isSelecting) {
|
|
5145
5422
|
setSelectionEnd({ row: rowIndex, col: colIndex });
|
|
@@ -5148,7 +5425,7 @@ function DataGrid({
|
|
|
5148
5425
|
[isSelecting]
|
|
5149
5426
|
);
|
|
5150
5427
|
const isShowingAIData = aiLoadedData !== null;
|
|
5151
|
-
const resetToFullData = (0,
|
|
5428
|
+
const resetToFullData = (0, import_react14.useCallback)(async () => {
|
|
5152
5429
|
if (aiAnalystRef.current?.selectedDataSource) {
|
|
5153
5430
|
setIsLoadingFullData(true);
|
|
5154
5431
|
try {
|
|
@@ -5169,37 +5446,37 @@ function DataGrid({
|
|
|
5169
5446
|
}
|
|
5170
5447
|
clearAllFilters();
|
|
5171
5448
|
}, [clearAllFilters]);
|
|
5172
|
-
const handleAIDataLoaded = (0,
|
|
5449
|
+
const handleAIDataLoaded = (0, import_react14.useCallback)(
|
|
5173
5450
|
(payload) => {
|
|
5174
5451
|
setAiLoadedData(payload.data);
|
|
5175
5452
|
onAIDataLoaded?.(payload);
|
|
5176
5453
|
},
|
|
5177
5454
|
[onAIDataLoaded]
|
|
5178
5455
|
);
|
|
5179
|
-
const handleAIConversationUpdate = (0,
|
|
5456
|
+
const handleAIConversationUpdate = (0, import_react14.useCallback)(
|
|
5180
5457
|
(payload) => {
|
|
5181
5458
|
onAIConversationUpdate?.(payload);
|
|
5182
5459
|
},
|
|
5183
5460
|
[onAIConversationUpdate]
|
|
5184
5461
|
);
|
|
5185
|
-
const handleAIQueryExecuted = (0,
|
|
5462
|
+
const handleAIQueryExecuted = (0, import_react14.useCallback)(
|
|
5186
5463
|
(payload) => {
|
|
5187
5464
|
onAIQueryExecuted?.(payload);
|
|
5188
5465
|
},
|
|
5189
5466
|
[onAIQueryExecuted]
|
|
5190
5467
|
);
|
|
5191
|
-
const handleAIError = (0,
|
|
5468
|
+
const handleAIError = (0, import_react14.useCallback)(
|
|
5192
5469
|
(payload) => {
|
|
5193
5470
|
onAIError?.(payload);
|
|
5194
5471
|
},
|
|
5195
5472
|
[onAIError]
|
|
5196
5473
|
);
|
|
5197
|
-
(0,
|
|
5474
|
+
(0, import_react14.useEffect)(() => {
|
|
5198
5475
|
const handleMouseUp = () => setIsSelecting(false);
|
|
5199
5476
|
document.addEventListener("mouseup", handleMouseUp);
|
|
5200
5477
|
return () => document.removeEventListener("mouseup", handleMouseUp);
|
|
5201
5478
|
}, []);
|
|
5202
|
-
(0,
|
|
5479
|
+
(0, import_react14.useEffect)(() => {
|
|
5203
5480
|
const handleKeydown = (event) => {
|
|
5204
5481
|
if ((event.ctrlKey || event.metaKey) && event.key === "c" && selectionBounds) {
|
|
5205
5482
|
event.preventDefault();
|
|
@@ -5217,7 +5494,7 @@ function DataGrid({
|
|
|
5217
5494
|
document.addEventListener("keydown", handleKeydown);
|
|
5218
5495
|
return () => document.removeEventListener("keydown", handleKeydown);
|
|
5219
5496
|
}, [selectionBounds, copySelectionToClipboard]);
|
|
5220
|
-
const openFilterDropdown = (0,
|
|
5497
|
+
const openFilterDropdown = (0, import_react14.useCallback)(
|
|
5221
5498
|
(columnId, event) => {
|
|
5222
5499
|
event.stopPropagation();
|
|
5223
5500
|
const target = event.currentTarget;
|
|
@@ -5246,22 +5523,28 @@ function DataGrid({
|
|
|
5246
5523
|
},
|
|
5247
5524
|
[]
|
|
5248
5525
|
);
|
|
5249
|
-
const closeFilterDropdown = (0,
|
|
5526
|
+
const closeFilterDropdown = (0, import_react14.useCallback)(() => {
|
|
5250
5527
|
setActiveFilterColumn(null);
|
|
5251
5528
|
}, []);
|
|
5252
|
-
const handleFilter = (0,
|
|
5529
|
+
const handleFilter = (0, import_react14.useCallback)(
|
|
5253
5530
|
(columnId, values) => {
|
|
5254
5531
|
setColumnFilter(columnId, values);
|
|
5255
5532
|
},
|
|
5256
5533
|
[setColumnFilter]
|
|
5257
5534
|
);
|
|
5258
|
-
const handleRangeFilter = (0,
|
|
5535
|
+
const handleRangeFilter = (0, import_react14.useCallback)(
|
|
5259
5536
|
(columnId, range) => {
|
|
5260
5537
|
setNumericRangeFilter(columnId, range);
|
|
5261
5538
|
},
|
|
5262
5539
|
[setNumericRangeFilter]
|
|
5263
5540
|
);
|
|
5264
|
-
const
|
|
5541
|
+
const handleDateRangeFilter = (0, import_react14.useCallback)(
|
|
5542
|
+
(columnId, range) => {
|
|
5543
|
+
setDateRangeFilter(columnId, range);
|
|
5544
|
+
},
|
|
5545
|
+
[setDateRangeFilter]
|
|
5546
|
+
);
|
|
5547
|
+
const handleSort = (0, import_react14.useCallback)(
|
|
5265
5548
|
(columnId, direction) => {
|
|
5266
5549
|
if (direction === null) {
|
|
5267
5550
|
const current = getSortDirection(columnId);
|
|
@@ -5285,7 +5568,7 @@ function DataGrid({
|
|
|
5285
5568
|
},
|
|
5286
5569
|
[getSortDirection, toggleSort]
|
|
5287
5570
|
);
|
|
5288
|
-
const isCellSelected = (0,
|
|
5571
|
+
const isCellSelected = (0, import_react14.useCallback)(
|
|
5289
5572
|
(rowIndex, colIndex) => {
|
|
5290
5573
|
if (!selectionBounds) {
|
|
5291
5574
|
return selectedCell?.row === rowIndex && selectedCell?.col === colIndex;
|
|
@@ -5298,10 +5581,7 @@ function DataGrid({
|
|
|
5298
5581
|
const formatStatValue = (value) => {
|
|
5299
5582
|
if (value === null)
|
|
5300
5583
|
return "-";
|
|
5301
|
-
|
|
5302
|
-
return value.toLocaleString("en-US", { maximumFractionDigits: 2 });
|
|
5303
|
-
}
|
|
5304
|
-
return value.toLocaleString("en-US", { maximumFractionDigits: 4 });
|
|
5584
|
+
return (0, import_tinypivot_core13.formatNumber)(value, numberFormat);
|
|
5305
5585
|
};
|
|
5306
5586
|
const noFormatPatterns = /^(?:.*_)?(?:id|code|year|month|quarter|day|week|date|zip|phone|fax|ssn|ein|npi|ndc|gpi|hcpcs|icd|cpt|rx|bin|pcn|group|member|claim|rx_number|script|fill)(?:_.*)?$/i;
|
|
5307
5587
|
const shouldFormatNumber = (columnId) => {
|
|
@@ -5313,68 +5593,71 @@ function DataGrid({
|
|
|
5313
5593
|
if (value === "")
|
|
5314
5594
|
return "";
|
|
5315
5595
|
const stats = getColumnStats(columnId);
|
|
5596
|
+
if (stats.type === "date") {
|
|
5597
|
+
return (0, import_tinypivot_core13.formatDate)(value, dateFormat);
|
|
5598
|
+
}
|
|
5316
5599
|
if (stats.type === "number") {
|
|
5317
5600
|
const num = typeof value === "number" ? value : Number.parseFloat(String(value));
|
|
5318
5601
|
if (Number.isNaN(num))
|
|
5319
5602
|
return String(value);
|
|
5320
5603
|
if (shouldFormatNumber(columnId) && Math.abs(num) >= 1e3) {
|
|
5321
|
-
return
|
|
5604
|
+
return (0, import_tinypivot_core13.formatNumber)(num, numberFormat);
|
|
5322
5605
|
}
|
|
5323
5606
|
if (Number.isInteger(num)) {
|
|
5324
5607
|
return String(num);
|
|
5325
5608
|
}
|
|
5326
|
-
return
|
|
5609
|
+
return (0, import_tinypivot_core13.formatNumber)(num, numberFormat, { maximumFractionDigits: 4 });
|
|
5327
5610
|
}
|
|
5328
5611
|
return String(value);
|
|
5329
5612
|
};
|
|
5330
|
-
const totalTableWidth = (0,
|
|
5613
|
+
const totalTableWidth = (0, import_react14.useMemo)(() => {
|
|
5331
5614
|
return columnKeys.reduce((sum, key) => sum + (columnWidths[key] || MIN_COL_WIDTH), 0);
|
|
5332
5615
|
}, [columnKeys, columnWidths]);
|
|
5333
5616
|
const activeFilterCount = columnFilters.length;
|
|
5334
|
-
return /* @__PURE__ */ (0,
|
|
5617
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
5335
5618
|
"div",
|
|
5336
5619
|
{
|
|
5337
5620
|
className: `vpg-data-grid vpg-font-${currentFontSize} vpg-theme-${currentTheme} ${stripedRows ? "vpg-striped" : ""} ${resizingColumnId ? "vpg-resizing" : ""} ${isResizingVertically ? "vpg-resizing-vertical" : ""}`,
|
|
5338
5621
|
style: { height: `${gridHeight}px` },
|
|
5339
5622
|
children: [
|
|
5340
|
-
showCopyToast && /* @__PURE__ */ (0,
|
|
5341
|
-
/* @__PURE__ */ (0,
|
|
5623
|
+
showCopyToast && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "vpg-toast", children: [
|
|
5624
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }),
|
|
5342
5625
|
copyToastMessage
|
|
5343
5626
|
] }),
|
|
5344
|
-
/* @__PURE__ */ (0,
|
|
5345
|
-
/* @__PURE__ */ (0,
|
|
5346
|
-
showPivot && /* @__PURE__ */ (0,
|
|
5347
|
-
showAIAnalyst && /* @__PURE__ */ (0,
|
|
5627
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "vpg-toolbar", children: [
|
|
5628
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "vpg-toolbar-left", children: [
|
|
5629
|
+
showPivot && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "vpg-view-toggle", children: [
|
|
5630
|
+
showAIAnalyst && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
5348
5631
|
"button",
|
|
5349
5632
|
{
|
|
5350
5633
|
className: `vpg-view-btn vpg-ai-btn ${viewMode === "ai" ? "active" : ""}`,
|
|
5351
5634
|
onClick: () => setViewMode("ai"),
|
|
5352
5635
|
children: [
|
|
5353
|
-
/* @__PURE__ */ (0,
|
|
5636
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 2a2 2 0 0 1 2 2c0 .74-.4 1.39-1 1.73V7h1a7 7 0 0 1 7 7h1a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1h-1v1a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-1H2a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1h1a7 7 0 0 1 7-7h1V5.73c-.6-.34-1-.99-1-1.73a2 2 0 0 1 2-2z" }) }),
|
|
5354
5637
|
"AI Analyst"
|
|
5355
5638
|
]
|
|
5356
5639
|
}
|
|
5357
5640
|
),
|
|
5358
|
-
aiAnalyst?.enabled && !canUseAIAnalyst && /* @__PURE__ */ (0,
|
|
5641
|
+
aiAnalyst?.enabled && !canUseAIAnalyst && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
5359
5642
|
"button",
|
|
5360
5643
|
{
|
|
5361
5644
|
className: "vpg-view-btn vpg-ai-btn vpg-pro-feature",
|
|
5362
5645
|
title: "AI Analyst (Pro feature)",
|
|
5363
5646
|
onClick: (e) => e.preventDefault(),
|
|
5364
5647
|
children: [
|
|
5365
|
-
/* @__PURE__ */ (0,
|
|
5648
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 2a2 2 0 0 1 2 2c0 .74-.4 1.39-1 1.73V7h1a7 7 0 0 1 7 7h1a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1h-1v1a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-1H2a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1h1a7 7 0 0 1 7-7h1V5.73c-.6-.34-1-.99-1-1.73a2 2 0 0 1 2-2z" }) }),
|
|
5366
5649
|
"AI Analyst",
|
|
5367
|
-
/* @__PURE__ */ (0,
|
|
5650
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "vpg-pro-badge", children: "Pro" })
|
|
5368
5651
|
]
|
|
5369
5652
|
}
|
|
5370
5653
|
),
|
|
5371
|
-
/* @__PURE__ */ (0,
|
|
5654
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
5372
5655
|
"button",
|
|
5373
5656
|
{
|
|
5374
5657
|
className: `vpg-view-btn ${viewMode === "grid" ? "active" : ""}`,
|
|
5375
5658
|
onClick: () => setViewMode("grid"),
|
|
5376
5659
|
children: [
|
|
5377
|
-
/* @__PURE__ */ (0,
|
|
5660
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5378
5661
|
"path",
|
|
5379
5662
|
{
|
|
5380
5663
|
strokeLinecap: "round",
|
|
@@ -5387,13 +5670,13 @@ function DataGrid({
|
|
|
5387
5670
|
]
|
|
5388
5671
|
}
|
|
5389
5672
|
),
|
|
5390
|
-
/* @__PURE__ */ (0,
|
|
5673
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
5391
5674
|
"button",
|
|
5392
5675
|
{
|
|
5393
5676
|
className: `vpg-view-btn vpg-pivot-btn ${viewMode === "pivot" ? "active" : ""}`,
|
|
5394
5677
|
onClick: () => setViewMode("pivot"),
|
|
5395
5678
|
children: [
|
|
5396
|
-
/* @__PURE__ */ (0,
|
|
5679
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5397
5680
|
"path",
|
|
5398
5681
|
{
|
|
5399
5682
|
strokeLinecap: "round",
|
|
@@ -5406,14 +5689,14 @@ function DataGrid({
|
|
|
5406
5689
|
]
|
|
5407
5690
|
}
|
|
5408
5691
|
),
|
|
5409
|
-
/* @__PURE__ */ (0,
|
|
5692
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
5410
5693
|
"button",
|
|
5411
5694
|
{
|
|
5412
5695
|
className: `vpg-view-btn vpg-chart-btn ${viewMode === "chart" ? "active" : ""} ${!canUseCharts ? "vpg-pro-feature" : ""}`,
|
|
5413
5696
|
title: canUseCharts ? "Chart Builder" : "Chart Builder (Pro feature)",
|
|
5414
5697
|
onClick: () => canUseCharts && setViewMode("chart"),
|
|
5415
5698
|
children: [
|
|
5416
|
-
/* @__PURE__ */ (0,
|
|
5699
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5417
5700
|
"path",
|
|
5418
5701
|
{
|
|
5419
5702
|
strokeLinecap: "round",
|
|
@@ -5423,19 +5706,19 @@ function DataGrid({
|
|
|
5423
5706
|
}
|
|
5424
5707
|
) }),
|
|
5425
5708
|
"Chart",
|
|
5426
|
-
!canUseCharts && /* @__PURE__ */ (0,
|
|
5709
|
+
!canUseCharts && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "vpg-pro-badge", children: "Pro" })
|
|
5427
5710
|
]
|
|
5428
5711
|
}
|
|
5429
5712
|
)
|
|
5430
5713
|
] }),
|
|
5431
|
-
viewMode === "grid" && /* @__PURE__ */ (0,
|
|
5432
|
-
enableSearch && /* @__PURE__ */ (0,
|
|
5714
|
+
viewMode === "grid" && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
5715
|
+
enableSearch && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "vpg-search-container", children: !showSearchInput ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5433
5716
|
"button",
|
|
5434
5717
|
{
|
|
5435
5718
|
className: "vpg-icon-btn",
|
|
5436
5719
|
title: "Search (Ctrl+F)",
|
|
5437
5720
|
onClick: () => setShowSearchInput(true),
|
|
5438
|
-
children: /* @__PURE__ */ (0,
|
|
5721
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5439
5722
|
"path",
|
|
5440
5723
|
{
|
|
5441
5724
|
strokeLinecap: "round",
|
|
@@ -5445,15 +5728,15 @@ function DataGrid({
|
|
|
5445
5728
|
}
|
|
5446
5729
|
) })
|
|
5447
5730
|
}
|
|
5448
|
-
) : /* @__PURE__ */ (0,
|
|
5449
|
-
/* @__PURE__ */ (0,
|
|
5731
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "vpg-search-box", children: [
|
|
5732
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5450
5733
|
"svg",
|
|
5451
5734
|
{
|
|
5452
5735
|
className: "vpg-search-icon",
|
|
5453
5736
|
fill: "none",
|
|
5454
5737
|
stroke: "currentColor",
|
|
5455
5738
|
viewBox: "0 0 24 24",
|
|
5456
|
-
children: /* @__PURE__ */ (0,
|
|
5739
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5457
5740
|
"path",
|
|
5458
5741
|
{
|
|
5459
5742
|
strokeLinecap: "round",
|
|
@@ -5464,7 +5747,7 @@ function DataGrid({
|
|
|
5464
5747
|
)
|
|
5465
5748
|
}
|
|
5466
5749
|
),
|
|
5467
|
-
/* @__PURE__ */ (0,
|
|
5750
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5468
5751
|
"input",
|
|
5469
5752
|
{
|
|
5470
5753
|
type: "text",
|
|
@@ -5481,14 +5764,14 @@ function DataGrid({
|
|
|
5481
5764
|
autoFocus: true
|
|
5482
5765
|
}
|
|
5483
5766
|
),
|
|
5484
|
-
globalSearchTerm && /* @__PURE__ */ (0,
|
|
5767
|
+
globalSearchTerm && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { className: "vpg-search-clear", onClick: () => setGlobalSearchTerm(""), children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5485
5768
|
"svg",
|
|
5486
5769
|
{
|
|
5487
5770
|
className: "vpg-icon-xs",
|
|
5488
5771
|
fill: "none",
|
|
5489
5772
|
stroke: "currentColor",
|
|
5490
5773
|
viewBox: "0 0 24 24",
|
|
5491
|
-
children: /* @__PURE__ */ (0,
|
|
5774
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5492
5775
|
"path",
|
|
5493
5776
|
{
|
|
5494
5777
|
strokeLinecap: "round",
|
|
@@ -5500,9 +5783,9 @@ function DataGrid({
|
|
|
5500
5783
|
}
|
|
5501
5784
|
) })
|
|
5502
5785
|
] }) }),
|
|
5503
|
-
/* @__PURE__ */ (0,
|
|
5504
|
-
/* @__PURE__ */ (0,
|
|
5505
|
-
/* @__PURE__ */ (0,
|
|
5786
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "vpg-font-size-control", children: [
|
|
5787
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "vpg-label", children: "Size:" }),
|
|
5788
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "vpg-font-size-toggle", children: fontSizeOptions.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5506
5789
|
"button",
|
|
5507
5790
|
{
|
|
5508
5791
|
className: `vpg-font-size-btn ${currentFontSize === opt.value ? "active" : ""}`,
|
|
@@ -5512,8 +5795,8 @@ function DataGrid({
|
|
|
5512
5795
|
opt.value
|
|
5513
5796
|
)) })
|
|
5514
5797
|
] }),
|
|
5515
|
-
activeFilterCount > 0 && /* @__PURE__ */ (0,
|
|
5516
|
-
/* @__PURE__ */ (0,
|
|
5798
|
+
activeFilterCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "vpg-filter-info", children: [
|
|
5799
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5517
5800
|
"path",
|
|
5518
5801
|
{
|
|
5519
5802
|
fillRule: "evenodd",
|
|
@@ -5521,28 +5804,28 @@ function DataGrid({
|
|
|
5521
5804
|
clipRule: "evenodd"
|
|
5522
5805
|
}
|
|
5523
5806
|
) }),
|
|
5524
|
-
/* @__PURE__ */ (0,
|
|
5807
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
|
|
5525
5808
|
activeFilterCount,
|
|
5526
5809
|
" ",
|
|
5527
5810
|
"filter",
|
|
5528
5811
|
activeFilterCount > 1 ? "s" : ""
|
|
5529
5812
|
] })
|
|
5530
5813
|
] }),
|
|
5531
|
-
globalSearchTerm && /* @__PURE__ */ (0,
|
|
5814
|
+
globalSearchTerm && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "vpg-search-info", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
|
|
5532
5815
|
totalSearchedRows,
|
|
5533
5816
|
" ",
|
|
5534
5817
|
"match",
|
|
5535
5818
|
totalSearchedRows !== 1 ? "es" : ""
|
|
5536
5819
|
] }) })
|
|
5537
5820
|
] }),
|
|
5538
|
-
viewMode === "pivot" && canUsePivot && /* @__PURE__ */ (0,
|
|
5539
|
-
/* @__PURE__ */ (0,
|
|
5821
|
+
viewMode === "pivot" && canUsePivot && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
5822
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
5540
5823
|
"button",
|
|
5541
5824
|
{
|
|
5542
5825
|
className: `vpg-config-toggle ${showPivotConfig ? "active" : ""}`,
|
|
5543
5826
|
onClick: () => setShowPivotConfig(!showPivotConfig),
|
|
5544
5827
|
children: [
|
|
5545
|
-
/* @__PURE__ */ (0,
|
|
5828
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5546
5829
|
"path",
|
|
5547
5830
|
{
|
|
5548
5831
|
strokeLinecap: "round",
|
|
@@ -5557,8 +5840,8 @@ function DataGrid({
|
|
|
5557
5840
|
]
|
|
5558
5841
|
}
|
|
5559
5842
|
),
|
|
5560
|
-
pivotIsConfigured && /* @__PURE__ */ (0,
|
|
5561
|
-
/* @__PURE__ */ (0,
|
|
5843
|
+
pivotIsConfigured && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "vpg-pivot-status", children: [
|
|
5844
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5562
5845
|
"path",
|
|
5563
5846
|
{
|
|
5564
5847
|
fillRule: "evenodd",
|
|
@@ -5566,13 +5849,13 @@ function DataGrid({
|
|
|
5566
5849
|
clipRule: "evenodd"
|
|
5567
5850
|
}
|
|
5568
5851
|
) }),
|
|
5569
|
-
/* @__PURE__ */ (0,
|
|
5852
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: "Pivot configured" })
|
|
5570
5853
|
] })
|
|
5571
5854
|
] })
|
|
5572
5855
|
] }),
|
|
5573
|
-
/* @__PURE__ */ (0,
|
|
5574
|
-
viewMode === "grid" && activeFilterCount > 0 && /* @__PURE__ */ (0,
|
|
5575
|
-
/* @__PURE__ */ (0,
|
|
5856
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "vpg-toolbar-right", children: [
|
|
5857
|
+
viewMode === "grid" && activeFilterCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("button", { className: "vpg-clear-filters", onClick: clearAllFilters, children: [
|
|
5858
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5576
5859
|
"path",
|
|
5577
5860
|
{
|
|
5578
5861
|
strokeLinecap: "round",
|
|
@@ -5583,7 +5866,7 @@ function DataGrid({
|
|
|
5583
5866
|
) }),
|
|
5584
5867
|
"Clear Filters"
|
|
5585
5868
|
] }),
|
|
5586
|
-
viewMode === "grid" && isShowingAIData && /* @__PURE__ */ (0,
|
|
5869
|
+
viewMode === "grid" && isShowingAIData && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
5587
5870
|
"button",
|
|
5588
5871
|
{
|
|
5589
5872
|
className: `vpg-reset-data-btn${isLoadingFullData ? " vpg-loading-btn" : ""}`,
|
|
@@ -5591,7 +5874,7 @@ function DataGrid({
|
|
|
5591
5874
|
title: "Reset to full dataset",
|
|
5592
5875
|
onClick: resetToFullData,
|
|
5593
5876
|
children: [
|
|
5594
|
-
/* @__PURE__ */ (0,
|
|
5877
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: `vpg-icon${isLoadingFullData ? " vpg-spin" : ""}`, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5595
5878
|
"path",
|
|
5596
5879
|
{
|
|
5597
5880
|
strokeLinecap: "round",
|
|
@@ -5600,17 +5883,17 @@ function DataGrid({
|
|
|
5600
5883
|
d: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
|
|
5601
5884
|
}
|
|
5602
5885
|
) }),
|
|
5603
|
-
/* @__PURE__ */ (0,
|
|
5886
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: isLoadingFullData ? "Loading..." : "Full Data" })
|
|
5604
5887
|
]
|
|
5605
5888
|
}
|
|
5606
5889
|
),
|
|
5607
|
-
enableClipboard && selectionBounds && viewMode === "grid" && /* @__PURE__ */ (0,
|
|
5890
|
+
enableClipboard && selectionBounds && viewMode === "grid" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5608
5891
|
"button",
|
|
5609
5892
|
{
|
|
5610
5893
|
className: "vpg-icon-btn",
|
|
5611
5894
|
title: "Copy selection (Ctrl+C)",
|
|
5612
5895
|
onClick: copySelectionToClipboard,
|
|
5613
|
-
children: /* @__PURE__ */ (0,
|
|
5896
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5614
5897
|
"path",
|
|
5615
5898
|
{
|
|
5616
5899
|
strokeLinecap: "round",
|
|
@@ -5621,14 +5904,14 @@ function DataGrid({
|
|
|
5621
5904
|
) })
|
|
5622
5905
|
}
|
|
5623
5906
|
),
|
|
5624
|
-
enableExport && viewMode === "grid" && /* @__PURE__ */ (0,
|
|
5907
|
+
enableExport && viewMode === "grid" && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
5625
5908
|
"button",
|
|
5626
5909
|
{
|
|
5627
5910
|
className: "vpg-export-btn",
|
|
5628
5911
|
title: "Export to CSV",
|
|
5629
5912
|
onClick: handleExport,
|
|
5630
5913
|
children: [
|
|
5631
|
-
/* @__PURE__ */ (0,
|
|
5914
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5632
5915
|
"path",
|
|
5633
5916
|
{
|
|
5634
5917
|
strokeLinecap: "round",
|
|
@@ -5641,7 +5924,7 @@ function DataGrid({
|
|
|
5641
5924
|
]
|
|
5642
5925
|
}
|
|
5643
5926
|
),
|
|
5644
|
-
enableExport && viewMode === "pivot" && pivotIsConfigured && /* @__PURE__ */ (0,
|
|
5927
|
+
enableExport && viewMode === "pivot" && pivotIsConfigured && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
5645
5928
|
"button",
|
|
5646
5929
|
{
|
|
5647
5930
|
className: `vpg-export-btn ${!isPro ? "vpg-export-btn-disabled" : ""}`,
|
|
@@ -5649,7 +5932,7 @@ function DataGrid({
|
|
|
5649
5932
|
title: isPro ? "Export Pivot to CSV" : "Export Pivot to CSV (Pro feature)",
|
|
5650
5933
|
onClick: () => isPro && handleExport(),
|
|
5651
5934
|
children: [
|
|
5652
|
-
/* @__PURE__ */ (0,
|
|
5935
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "vpg-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5653
5936
|
"path",
|
|
5654
5937
|
{
|
|
5655
5938
|
strokeLinecap: "round",
|
|
@@ -5665,7 +5948,7 @@ function DataGrid({
|
|
|
5665
5948
|
)
|
|
5666
5949
|
] })
|
|
5667
5950
|
] }),
|
|
5668
|
-
showAIAnalyst && aiAnalyst && /* @__PURE__ */ (0,
|
|
5951
|
+
showAIAnalyst && aiAnalyst && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "vpg-ai-view", style: { display: viewMode === "ai" ? void 0 : "none" }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5669
5952
|
AIAnalyst,
|
|
5670
5953
|
{
|
|
5671
5954
|
ref: aiAnalystRef,
|
|
@@ -5677,13 +5960,13 @@ function DataGrid({
|
|
|
5677
5960
|
onError: handleAIError
|
|
5678
5961
|
}
|
|
5679
5962
|
) }),
|
|
5680
|
-
viewMode === "grid" && /* @__PURE__ */ (0,
|
|
5681
|
-
loading && /* @__PURE__ */ (0,
|
|
5682
|
-
/* @__PURE__ */ (0,
|
|
5683
|
-
/* @__PURE__ */ (0,
|
|
5963
|
+
viewMode === "grid" && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { ref: tableContainerRef, className: "vpg-grid-container", tabIndex: 0, children: [
|
|
5964
|
+
loading && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "vpg-loading", children: [
|
|
5965
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "vpg-spinner" }),
|
|
5966
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: "Loading data..." })
|
|
5684
5967
|
] }),
|
|
5685
|
-
!loading && displayData.length === 0 && /* @__PURE__ */ (0,
|
|
5686
|
-
/* @__PURE__ */ (0,
|
|
5968
|
+
!loading && displayData.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "vpg-empty", children: [
|
|
5969
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "vpg-empty-icon", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "vpg-icon-lg", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5687
5970
|
"path",
|
|
5688
5971
|
{
|
|
5689
5972
|
strokeLinecap: "round",
|
|
@@ -5692,10 +5975,10 @@ function DataGrid({
|
|
|
5692
5975
|
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"
|
|
5693
5976
|
}
|
|
5694
5977
|
) }) }),
|
|
5695
|
-
/* @__PURE__ */ (0,
|
|
5978
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: "No data available" })
|
|
5696
5979
|
] }),
|
|
5697
|
-
!loading && displayData.length > 0 && filteredRowCount === 0 && /* @__PURE__ */ (0,
|
|
5698
|
-
/* @__PURE__ */ (0,
|
|
5980
|
+
!loading && displayData.length > 0 && filteredRowCount === 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "vpg-empty", children: [
|
|
5981
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "vpg-empty-icon vpg-warning", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "vpg-icon-lg", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5699
5982
|
"path",
|
|
5700
5983
|
{
|
|
5701
5984
|
strokeLinecap: "round",
|
|
@@ -5704,11 +5987,11 @@ function DataGrid({
|
|
|
5704
5987
|
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"
|
|
5705
5988
|
}
|
|
5706
5989
|
) }) }),
|
|
5707
|
-
/* @__PURE__ */ (0,
|
|
5708
|
-
/* @__PURE__ */ (0,
|
|
5990
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: "No matching records" }),
|
|
5991
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { className: "vpg-clear-link", onClick: clearAllFilters, children: "Clear all filters" })
|
|
5709
5992
|
] }),
|
|
5710
|
-
!loading && filteredRowCount > 0 && /* @__PURE__ */ (0,
|
|
5711
|
-
/* @__PURE__ */ (0,
|
|
5993
|
+
!loading && filteredRowCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "vpg-table-wrapper", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("table", { className: "vpg-table", style: { minWidth: `${totalTableWidth}px` }, children: [
|
|
5994
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("tr", { children: columnKeys.map((colId) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
5712
5995
|
"th",
|
|
5713
5996
|
{
|
|
5714
5997
|
className: `vpg-header-cell ${hasActiveFilter(colId) ? "vpg-has-filter" : ""} ${getSortDirection(colId) !== null ? "vpg-is-sorted" : ""} ${activeFilterColumn === colId ? "vpg-is-active" : ""}`,
|
|
@@ -5723,16 +6006,16 @@ function DataGrid({
|
|
|
5723
6006
|
}
|
|
5724
6007
|
},
|
|
5725
6008
|
children: [
|
|
5726
|
-
/* @__PURE__ */ (0,
|
|
5727
|
-
/* @__PURE__ */ (0,
|
|
5728
|
-
/* @__PURE__ */ (0,
|
|
5729
|
-
getSortDirection(colId) && /* @__PURE__ */ (0,
|
|
6009
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "vpg-header-content", children: [
|
|
6010
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "vpg-header-text", children: colId }),
|
|
6011
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "vpg-header-icons", children: [
|
|
6012
|
+
getSortDirection(colId) && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "vpg-sort-indicator", children: getSortDirection(colId) === "asc" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5730
6013
|
"svg",
|
|
5731
6014
|
{
|
|
5732
6015
|
className: "vpg-icon-sm",
|
|
5733
6016
|
fill: "currentColor",
|
|
5734
6017
|
viewBox: "0 0 20 20",
|
|
5735
|
-
children: /* @__PURE__ */ (0,
|
|
6018
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5736
6019
|
"path",
|
|
5737
6020
|
{
|
|
5738
6021
|
fillRule: "evenodd",
|
|
@@ -5741,13 +6024,13 @@ function DataGrid({
|
|
|
5741
6024
|
}
|
|
5742
6025
|
)
|
|
5743
6026
|
}
|
|
5744
|
-
) : /* @__PURE__ */ (0,
|
|
6027
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5745
6028
|
"svg",
|
|
5746
6029
|
{
|
|
5747
6030
|
className: "vpg-icon-sm",
|
|
5748
6031
|
fill: "currentColor",
|
|
5749
6032
|
viewBox: "0 0 20 20",
|
|
5750
|
-
children: /* @__PURE__ */ (0,
|
|
6033
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5751
6034
|
"path",
|
|
5752
6035
|
{
|
|
5753
6036
|
fillRule: "evenodd",
|
|
@@ -5757,13 +6040,13 @@ function DataGrid({
|
|
|
5757
6040
|
)
|
|
5758
6041
|
}
|
|
5759
6042
|
) }),
|
|
5760
|
-
hasActiveFilter(colId) && /* @__PURE__ */ (0,
|
|
6043
|
+
hasActiveFilter(colId) && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "vpg-filter-indicator", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5761
6044
|
"svg",
|
|
5762
6045
|
{
|
|
5763
6046
|
className: "vpg-icon-xs",
|
|
5764
6047
|
fill: "currentColor",
|
|
5765
6048
|
viewBox: "0 0 20 20",
|
|
5766
|
-
children: /* @__PURE__ */ (0,
|
|
6049
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5767
6050
|
"path",
|
|
5768
6051
|
{
|
|
5769
6052
|
fillRule: "evenodd",
|
|
@@ -5773,14 +6056,14 @@ function DataGrid({
|
|
|
5773
6056
|
)
|
|
5774
6057
|
}
|
|
5775
6058
|
) }),
|
|
5776
|
-
/* @__PURE__ */ (0,
|
|
6059
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "vpg-dropdown-arrow", title: "Filter & Sort", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5777
6060
|
"svg",
|
|
5778
6061
|
{
|
|
5779
6062
|
className: "vpg-icon-sm",
|
|
5780
6063
|
fill: "none",
|
|
5781
6064
|
stroke: "currentColor",
|
|
5782
6065
|
viewBox: "0 0 24 24",
|
|
5783
|
-
children: /* @__PURE__ */ (0,
|
|
6066
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5784
6067
|
"path",
|
|
5785
6068
|
{
|
|
5786
6069
|
strokeLinecap: "round",
|
|
@@ -5793,7 +6076,7 @@ function DataGrid({
|
|
|
5793
6076
|
) })
|
|
5794
6077
|
] })
|
|
5795
6078
|
] }),
|
|
5796
|
-
enableColumnResize && /* @__PURE__ */ (0,
|
|
6079
|
+
enableColumnResize && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5797
6080
|
"div",
|
|
5798
6081
|
{
|
|
5799
6082
|
className: "vpg-resize-handle",
|
|
@@ -5804,7 +6087,7 @@ function DataGrid({
|
|
|
5804
6087
|
},
|
|
5805
6088
|
colId
|
|
5806
6089
|
)) }) }),
|
|
5807
|
-
/* @__PURE__ */ (0,
|
|
6090
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("tbody", { ref: tableBodyRef, children: paginatedRows.map((row, rowIndex) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("tr", { className: "vpg-row", children: columnKeys.map((colId, colIndex) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5808
6091
|
"td",
|
|
5809
6092
|
{
|
|
5810
6093
|
className: `vpg-cell ${isCellSelected(rowIndex, colIndex) ? "vpg-selected" : ""} ${getColumnStats(colId).type === "number" ? "vpg-is-number" : ""}`,
|
|
@@ -5822,8 +6105,8 @@ function DataGrid({
|
|
|
5822
6105
|
)) }, row.id)) })
|
|
5823
6106
|
] }) })
|
|
5824
6107
|
] }),
|
|
5825
|
-
viewMode === "pivot" && /* @__PURE__ */ (0,
|
|
5826
|
-
showPivotConfig && canUsePivot && /* @__PURE__ */ (0,
|
|
6108
|
+
viewMode === "pivot" && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "vpg-pivot-container", children: [
|
|
6109
|
+
showPivotConfig && canUsePivot && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "vpg-pivot-config-panel", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5827
6110
|
PivotConfig,
|
|
5828
6111
|
{
|
|
5829
6112
|
availableFields: pivotAvailableFields,
|
|
@@ -5851,7 +6134,7 @@ function DataGrid({
|
|
|
5851
6134
|
onUpdateCalculatedField: addCalculatedField
|
|
5852
6135
|
}
|
|
5853
6136
|
) }),
|
|
5854
|
-
/* @__PURE__ */ (0,
|
|
6137
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: `vpg-pivot-main ${!showPivotConfig ? "vpg-full-width" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5855
6138
|
PivotSkeleton,
|
|
5856
6139
|
{
|
|
5857
6140
|
rowFields: pivotRowFields,
|
|
@@ -5877,10 +6160,10 @@ function DataGrid({
|
|
|
5877
6160
|
}
|
|
5878
6161
|
) })
|
|
5879
6162
|
] }),
|
|
5880
|
-
viewMode === "chart" && /* @__PURE__ */ (0,
|
|
5881
|
-
activeFilterInfo && activeFilterInfo.length > 0 && /* @__PURE__ */ (0,
|
|
5882
|
-
/* @__PURE__ */ (0,
|
|
5883
|
-
/* @__PURE__ */ (0,
|
|
6163
|
+
viewMode === "chart" && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "vpg-chart-view", children: [
|
|
6164
|
+
activeFilterInfo && activeFilterInfo.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "vpg-chart-filter-bar", children: [
|
|
6165
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "vpg-icon", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { fillRule: "evenodd", d: "M3 3a1 1 0 011-1h12a1 1 0 011 1v3a1 1 0 01-.293.707L12 11.414V15a1 1 0 01-.293.707l-2 2A1 1 0 018 17v-5.586L3.293 6.707A1 1 0 013 6V3z", clipRule: "evenodd" }) }),
|
|
6166
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
|
|
5884
6167
|
"Chart showing",
|
|
5885
6168
|
filteredRowCount.toLocaleString(),
|
|
5886
6169
|
" ",
|
|
@@ -5889,9 +6172,9 @@ function DataGrid({
|
|
|
5889
6172
|
" ",
|
|
5890
6173
|
"records"
|
|
5891
6174
|
] }),
|
|
5892
|
-
/* @__PURE__ */ (0,
|
|
6175
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { className: "vpg-chart-clear-filters", onClick: clearAllFilters, children: "Clear filters" })
|
|
5893
6176
|
] }),
|
|
5894
|
-
/* @__PURE__ */ (0,
|
|
6177
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5895
6178
|
ChartBuilder,
|
|
5896
6179
|
{
|
|
5897
6180
|
data: filteredDataForPivot,
|
|
@@ -5900,55 +6183,55 @@ function DataGrid({
|
|
|
5900
6183
|
}
|
|
5901
6184
|
)
|
|
5902
6185
|
] }),
|
|
5903
|
-
/* @__PURE__ */ (0,
|
|
5904
|
-
/* @__PURE__ */ (0,
|
|
5905
|
-
/* @__PURE__ */ (0,
|
|
6186
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "vpg-footer", children: [
|
|
6187
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "vpg-footer-left", children: viewMode === "grid" ? enablePagination ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
6188
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
|
|
5906
6189
|
((currentPage - 1) * pageSize + 1).toLocaleString(),
|
|
5907
6190
|
"-",
|
|
5908
6191
|
Math.min(currentPage * pageSize, totalSearchedRows).toLocaleString()
|
|
5909
6192
|
] }),
|
|
5910
|
-
/* @__PURE__ */ (0,
|
|
5911
|
-
/* @__PURE__ */ (0,
|
|
5912
|
-
totalSearchedRows !== totalRowCount && /* @__PURE__ */ (0,
|
|
6193
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "vpg-separator", children: "of" }),
|
|
6194
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: totalSearchedRows.toLocaleString() }),
|
|
6195
|
+
totalSearchedRows !== totalRowCount && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "vpg-filtered-note", children: [
|
|
5913
6196
|
"(",
|
|
5914
6197
|
totalRowCount.toLocaleString(),
|
|
5915
6198
|
" ",
|
|
5916
6199
|
"total)"
|
|
5917
6200
|
] })
|
|
5918
|
-
] }) : filteredRowCount === totalRowCount && totalSearchedRows === totalRowCount ? /* @__PURE__ */ (0,
|
|
6201
|
+
] }) : filteredRowCount === totalRowCount && totalSearchedRows === totalRowCount ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
|
|
5919
6202
|
totalRowCount.toLocaleString(),
|
|
5920
6203
|
" ",
|
|
5921
6204
|
"records"
|
|
5922
|
-
] }) : /* @__PURE__ */ (0,
|
|
5923
|
-
/* @__PURE__ */ (0,
|
|
5924
|
-
/* @__PURE__ */ (0,
|
|
5925
|
-
/* @__PURE__ */ (0,
|
|
5926
|
-
/* @__PURE__ */ (0,
|
|
5927
|
-
] }) : viewMode === "pivot" ? /* @__PURE__ */ (0,
|
|
5928
|
-
/* @__PURE__ */ (0,
|
|
5929
|
-
/* @__PURE__ */ (0,
|
|
5930
|
-
/* @__PURE__ */ (0,
|
|
6205
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
6206
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "vpg-filtered-count", children: totalSearchedRows.toLocaleString() }),
|
|
6207
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "vpg-separator", children: "of" }),
|
|
6208
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: totalRowCount.toLocaleString() }),
|
|
6209
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "vpg-separator", children: "records" })
|
|
6210
|
+
] }) : viewMode === "pivot" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
6211
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "vpg-pivot-label", children: "Pivot Table" }),
|
|
6212
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "vpg-separator", children: "\u2022" }),
|
|
6213
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
|
|
5931
6214
|
totalRowCount.toLocaleString(),
|
|
5932
6215
|
" ",
|
|
5933
6216
|
"source records"
|
|
5934
6217
|
] })
|
|
5935
|
-
] }) : /* @__PURE__ */ (0,
|
|
5936
|
-
/* @__PURE__ */ (0,
|
|
5937
|
-
/* @__PURE__ */ (0,
|
|
5938
|
-
/* @__PURE__ */ (0,
|
|
6218
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
6219
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "vpg-chart-label", children: "Chart Builder" }),
|
|
6220
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "vpg-separator", children: "\u2022" }),
|
|
6221
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
|
|
5939
6222
|
totalRowCount.toLocaleString(),
|
|
5940
6223
|
" ",
|
|
5941
6224
|
"records"
|
|
5942
6225
|
] })
|
|
5943
6226
|
] }) }),
|
|
5944
|
-
enablePagination && viewMode === "grid" && totalPages > 1 && /* @__PURE__ */ (0,
|
|
5945
|
-
/* @__PURE__ */ (0,
|
|
6227
|
+
enablePagination && viewMode === "grid" && totalPages > 1 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "vpg-pagination", children: [
|
|
6228
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5946
6229
|
"button",
|
|
5947
6230
|
{
|
|
5948
6231
|
className: "vpg-page-btn",
|
|
5949
6232
|
disabled: currentPage === 1,
|
|
5950
6233
|
onClick: () => setCurrentPage(1),
|
|
5951
|
-
children: /* @__PURE__ */ (0,
|
|
6234
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5952
6235
|
"path",
|
|
5953
6236
|
{
|
|
5954
6237
|
strokeLinecap: "round",
|
|
@@ -5959,13 +6242,13 @@ function DataGrid({
|
|
|
5959
6242
|
) })
|
|
5960
6243
|
}
|
|
5961
6244
|
),
|
|
5962
|
-
/* @__PURE__ */ (0,
|
|
6245
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5963
6246
|
"button",
|
|
5964
6247
|
{
|
|
5965
6248
|
className: "vpg-page-btn",
|
|
5966
6249
|
disabled: currentPage === 1,
|
|
5967
6250
|
onClick: () => setCurrentPage((p) => Math.max(1, p - 1)),
|
|
5968
|
-
children: /* @__PURE__ */ (0,
|
|
6251
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5969
6252
|
"path",
|
|
5970
6253
|
{
|
|
5971
6254
|
strokeLinecap: "round",
|
|
@@ -5976,7 +6259,7 @@ function DataGrid({
|
|
|
5976
6259
|
) })
|
|
5977
6260
|
}
|
|
5978
6261
|
),
|
|
5979
|
-
/* @__PURE__ */ (0,
|
|
6262
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "vpg-page-info", children: [
|
|
5980
6263
|
"Page",
|
|
5981
6264
|
" ",
|
|
5982
6265
|
currentPage,
|
|
@@ -5985,13 +6268,13 @@ function DataGrid({
|
|
|
5985
6268
|
" ",
|
|
5986
6269
|
totalPages
|
|
5987
6270
|
] }),
|
|
5988
|
-
/* @__PURE__ */ (0,
|
|
6271
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5989
6272
|
"button",
|
|
5990
6273
|
{
|
|
5991
6274
|
className: "vpg-page-btn",
|
|
5992
6275
|
disabled: currentPage === totalPages,
|
|
5993
6276
|
onClick: () => setCurrentPage((p) => Math.min(totalPages, p + 1)),
|
|
5994
|
-
children: /* @__PURE__ */ (0,
|
|
6277
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5995
6278
|
"path",
|
|
5996
6279
|
{
|
|
5997
6280
|
strokeLinecap: "round",
|
|
@@ -6002,13 +6285,13 @@ function DataGrid({
|
|
|
6002
6285
|
) })
|
|
6003
6286
|
}
|
|
6004
6287
|
),
|
|
6005
|
-
/* @__PURE__ */ (0,
|
|
6288
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
6006
6289
|
"button",
|
|
6007
6290
|
{
|
|
6008
6291
|
className: "vpg-page-btn",
|
|
6009
6292
|
disabled: currentPage === totalPages,
|
|
6010
6293
|
onClick: () => setCurrentPage(totalPages),
|
|
6011
|
-
children: /* @__PURE__ */ (0,
|
|
6294
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "vpg-icon-sm", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
6012
6295
|
"path",
|
|
6013
6296
|
{
|
|
6014
6297
|
strokeLinecap: "round",
|
|
@@ -6020,45 +6303,45 @@ function DataGrid({
|
|
|
6020
6303
|
}
|
|
6021
6304
|
)
|
|
6022
6305
|
] }),
|
|
6023
|
-
viewMode === "grid" && selectionStats && selectionStats.count > 1 && /* @__PURE__ */ (0,
|
|
6024
|
-
/* @__PURE__ */ (0,
|
|
6025
|
-
/* @__PURE__ */ (0,
|
|
6026
|
-
/* @__PURE__ */ (0,
|
|
6306
|
+
viewMode === "grid" && selectionStats && selectionStats.count > 1 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "vpg-selection-stats", children: [
|
|
6307
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "vpg-stat", children: [
|
|
6308
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "vpg-stat-label", children: "Count:" }),
|
|
6309
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "vpg-stat-value", children: selectionStats.count })
|
|
6027
6310
|
] }),
|
|
6028
|
-
selectionStats.numericCount > 0 && /* @__PURE__ */ (0,
|
|
6029
|
-
/* @__PURE__ */ (0,
|
|
6030
|
-
/* @__PURE__ */ (0,
|
|
6031
|
-
/* @__PURE__ */ (0,
|
|
6032
|
-
/* @__PURE__ */ (0,
|
|
6311
|
+
selectionStats.numericCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
6312
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "vpg-stat-divider", children: "|" }),
|
|
6313
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "vpg-stat", children: [
|
|
6314
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "vpg-stat-label", children: "Sum:" }),
|
|
6315
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.sum) })
|
|
6033
6316
|
] }),
|
|
6034
|
-
/* @__PURE__ */ (0,
|
|
6035
|
-
/* @__PURE__ */ (0,
|
|
6036
|
-
/* @__PURE__ */ (0,
|
|
6037
|
-
/* @__PURE__ */ (0,
|
|
6317
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "vpg-stat-divider", children: "|" }),
|
|
6318
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "vpg-stat", children: [
|
|
6319
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "vpg-stat-label", children: "Avg:" }),
|
|
6320
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "vpg-stat-value", children: formatStatValue(selectionStats.avg) })
|
|
6038
6321
|
] })
|
|
6039
6322
|
] })
|
|
6040
6323
|
] }),
|
|
6041
|
-
/* @__PURE__ */ (0,
|
|
6042
|
-
/* @__PURE__ */ (0,
|
|
6043
|
-
/* @__PURE__ */ (0,
|
|
6044
|
-
/* @__PURE__ */ (0,
|
|
6045
|
-
] }) : showWatermark ? /* @__PURE__ */ (0,
|
|
6046
|
-
/* @__PURE__ */ (0,
|
|
6047
|
-
/* @__PURE__ */ (0,
|
|
6048
|
-
/* @__PURE__ */ (0,
|
|
6049
|
-
/* @__PURE__ */ (0,
|
|
6050
|
-
/* @__PURE__ */ (0,
|
|
6324
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "vpg-footer-right", children: isDemo ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "vpg-demo-banner", children: [
|
|
6325
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "vpg-demo-badge", children: "DEMO" }),
|
|
6326
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: "Pro features enabled" }),
|
|
6327
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("a", { href: "https://tiny-pivot.com/#pricing", target: "_blank", rel: "noopener noreferrer", children: "Get License \u2192" })
|
|
6328
|
+
] }) : showWatermark ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "vpg-watermark-inline", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("a", { href: "https://tiny-pivot.com", target: "_blank", rel: "noopener noreferrer", children: [
|
|
6329
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.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: [
|
|
6330
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("rect", { x: "3", y: "3", width: "7", height: "7" }),
|
|
6331
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("rect", { x: "14", y: "3", width: "7", height: "7" }),
|
|
6332
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("rect", { x: "14", y: "14", width: "7", height: "7" }),
|
|
6333
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("rect", { x: "3", y: "14", width: "7", height: "7" })
|
|
6051
6334
|
] }),
|
|
6052
6335
|
"Powered by TinyPivot"
|
|
6053
6336
|
] }) }) : null })
|
|
6054
6337
|
] }),
|
|
6055
|
-
enableVerticalResize && /* @__PURE__ */ (0,
|
|
6056
|
-
/* @__PURE__ */ (0,
|
|
6057
|
-
/* @__PURE__ */ (0,
|
|
6058
|
-
/* @__PURE__ */ (0,
|
|
6338
|
+
enableVerticalResize && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "vpg-vertical-resize-handle", onMouseDown: startVerticalResize, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "vpg-resize-grip", children: [
|
|
6339
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", {}),
|
|
6340
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", {}),
|
|
6341
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", {})
|
|
6059
6342
|
] }) }),
|
|
6060
6343
|
activeFilterColumn && typeof document !== "undefined" && (0, import_react_dom2.createPortal)(
|
|
6061
|
-
/* @__PURE__ */ (0,
|
|
6344
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
6062
6345
|
"div",
|
|
6063
6346
|
{
|
|
6064
6347
|
className: "vpg-filter-portal",
|
|
@@ -6069,7 +6352,7 @@ function DataGrid({
|
|
|
6069
6352
|
maxHeight: `${filterDropdownPosition.maxHeight}px`,
|
|
6070
6353
|
zIndex: 9999
|
|
6071
6354
|
},
|
|
6072
|
-
children: /* @__PURE__ */ (0,
|
|
6355
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
6073
6356
|
ColumnFilter,
|
|
6074
6357
|
{
|
|
6075
6358
|
columnId: activeFilterColumn,
|
|
@@ -6078,8 +6361,12 @@ function DataGrid({
|
|
|
6078
6361
|
selectedValues: getColumnFilterValues(activeFilterColumn),
|
|
6079
6362
|
sortDirection: getSortDirection(activeFilterColumn),
|
|
6080
6363
|
numericRange: getNumericRangeFilter(activeFilterColumn),
|
|
6364
|
+
dateRange: getDateRangeFilter(activeFilterColumn),
|
|
6365
|
+
numberFormat,
|
|
6366
|
+
dateFormat,
|
|
6081
6367
|
onFilter: (values) => handleFilter(activeFilterColumn, values),
|
|
6082
6368
|
onRangeFilter: (range) => handleRangeFilter(activeFilterColumn, range),
|
|
6369
|
+
onDateRangeFilter: (range) => handleDateRangeFilter(activeFilterColumn, range),
|
|
6083
6370
|
onSort: (dir) => handleSort(activeFilterColumn, dir),
|
|
6084
6371
|
onClose: closeFilterDropdown
|
|
6085
6372
|
}
|