react-open-source-grid 1.6.4 → 1.6.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/{index-BczRxCQn.js → index-BbaZajrS.js} +197 -74
- package/dist/assets/index.js +1 -1
- package/dist/assets/{layoutPersistence-C_jVd_iy.js → layoutPersistence-CPItuVwj.js} +1 -1
- package/dist/index.html +1 -1
- package/dist/lib/components/DataGrid/PivotToolbar.d.ts +29 -0
- package/dist/lib/components/DataGrid/index.d.ts +4 -0
- package/dist/lib/components/DataGrid/pivotEngine.d.ts +55 -0
- package/dist/lib/components/DataGrid/types.d.ts +2 -0
- package/dist/lib/components/PivotDemo.d.ts +8 -0
- package/dist/lib/index.cjs +509 -21
- package/dist/lib/index.js +505 -21
- package/package.json +1 -1
package/dist/lib/index.cjs
CHANGED
|
@@ -355,6 +355,7 @@ __export(index_exports, {
|
|
|
355
355
|
LocalStorageAdapter: () => LocalStorageAdapter,
|
|
356
356
|
MarketDataEngine: () => MarketDataEngine,
|
|
357
357
|
MarketDataGrid: () => MarketDataGrid,
|
|
358
|
+
PivotToolbar: () => PivotToolbar,
|
|
358
359
|
PriorityIndicator: () => PriorityIndicator,
|
|
359
360
|
ProgressBar: () => ProgressBar,
|
|
360
361
|
Rating: () => Rating,
|
|
@@ -367,6 +368,7 @@ __export(index_exports, {
|
|
|
367
368
|
VirtualScroller: () => VirtualScroller,
|
|
368
369
|
WebSocketMockFeed: () => WebSocketMockFeed,
|
|
369
370
|
alpineTheme: () => alpineTheme,
|
|
371
|
+
buildPivot: () => buildPivot,
|
|
370
372
|
buildTreeFromFlat: () => buildTreeFromFlat,
|
|
371
373
|
collapseAllNodes: () => collapseAllNodes,
|
|
372
374
|
countTreeNodes: () => countTreeNodes,
|
|
@@ -377,7 +379,9 @@ __export(index_exports, {
|
|
|
377
379
|
createPreset: () => createPreset,
|
|
378
380
|
darkTheme: () => darkTheme,
|
|
379
381
|
densityConfigs: () => densityConfigs,
|
|
382
|
+
downloadCSV: () => downloadCSV,
|
|
380
383
|
expandAllNodes: () => expandAllNodes,
|
|
384
|
+
exportPivotToCSV: () => exportPivotToCSV,
|
|
381
385
|
exportToCSV: () => exportToCSV,
|
|
382
386
|
exportToXLSX: () => exportToXLSX,
|
|
383
387
|
filterTree: () => filterTree,
|
|
@@ -8445,6 +8449,195 @@ var GridApiImpl = class {
|
|
|
8445
8449
|
}
|
|
8446
8450
|
};
|
|
8447
8451
|
|
|
8452
|
+
// src/components/DataGrid/pivotEngine.ts
|
|
8453
|
+
var AGGREGATORS = {
|
|
8454
|
+
sum: (values) => values.reduce((acc, val) => acc + val, 0),
|
|
8455
|
+
count: (values) => values.length,
|
|
8456
|
+
avg: (values) => values.length > 0 ? values.reduce((acc, val) => acc + val, 0) / values.length : 0,
|
|
8457
|
+
min: (values) => values.length > 0 ? Math.min(...values) : 0,
|
|
8458
|
+
max: (values) => values.length > 0 ? Math.max(...values) : 0
|
|
8459
|
+
};
|
|
8460
|
+
function getUniqueValues(data, column) {
|
|
8461
|
+
const uniqueSet = /* @__PURE__ */ new Set();
|
|
8462
|
+
data.forEach((row) => {
|
|
8463
|
+
const value = row[column];
|
|
8464
|
+
if (value !== null && value !== void 0) {
|
|
8465
|
+
uniqueSet.add(String(value));
|
|
8466
|
+
}
|
|
8467
|
+
});
|
|
8468
|
+
return Array.from(uniqueSet).sort();
|
|
8469
|
+
}
|
|
8470
|
+
function getAggregatorFn(aggregator) {
|
|
8471
|
+
if (typeof aggregator === "function") {
|
|
8472
|
+
return aggregator;
|
|
8473
|
+
}
|
|
8474
|
+
return AGGREGATORS[aggregator] || AGGREGATORS.sum;
|
|
8475
|
+
}
|
|
8476
|
+
function toNumber(value) {
|
|
8477
|
+
if (typeof value === "number") return value;
|
|
8478
|
+
if (typeof value === "string") {
|
|
8479
|
+
const num = parseFloat(value);
|
|
8480
|
+
return isNaN(num) ? 0 : num;
|
|
8481
|
+
}
|
|
8482
|
+
return 0;
|
|
8483
|
+
}
|
|
8484
|
+
function buildPivot(data, config) {
|
|
8485
|
+
const {
|
|
8486
|
+
pivotColumn,
|
|
8487
|
+
valueColumn,
|
|
8488
|
+
rowGroupColumn,
|
|
8489
|
+
aggregator,
|
|
8490
|
+
showTotals = false,
|
|
8491
|
+
showGrandTotal = false
|
|
8492
|
+
} = config;
|
|
8493
|
+
if (!data || data.length === 0) {
|
|
8494
|
+
return {
|
|
8495
|
+
columns: [],
|
|
8496
|
+
rows: [],
|
|
8497
|
+
pivotValues: []
|
|
8498
|
+
};
|
|
8499
|
+
}
|
|
8500
|
+
const pivotValues = getUniqueValues(data, pivotColumn);
|
|
8501
|
+
const rowGroupValues = getUniqueValues(data, rowGroupColumn);
|
|
8502
|
+
const aggregatorFn = getAggregatorFn(aggregator);
|
|
8503
|
+
const groupedData = /* @__PURE__ */ new Map();
|
|
8504
|
+
rowGroupValues.forEach((rowValue) => {
|
|
8505
|
+
const pivotMap = /* @__PURE__ */ new Map();
|
|
8506
|
+
pivotValues.forEach((pivotValue) => {
|
|
8507
|
+
pivotMap.set(pivotValue, []);
|
|
8508
|
+
});
|
|
8509
|
+
groupedData.set(rowValue, pivotMap);
|
|
8510
|
+
});
|
|
8511
|
+
data.forEach((row) => {
|
|
8512
|
+
const rowValue = String(row[rowGroupColumn] ?? "");
|
|
8513
|
+
const pivotValue = String(row[pivotColumn] ?? "");
|
|
8514
|
+
const value = toNumber(row[valueColumn]);
|
|
8515
|
+
if (groupedData.has(rowValue)) {
|
|
8516
|
+
const pivotMap = groupedData.get(rowValue);
|
|
8517
|
+
if (pivotMap.has(pivotValue)) {
|
|
8518
|
+
pivotMap.get(pivotValue).push(value);
|
|
8519
|
+
}
|
|
8520
|
+
}
|
|
8521
|
+
});
|
|
8522
|
+
const columns = [
|
|
8523
|
+
{
|
|
8524
|
+
field: rowGroupColumn,
|
|
8525
|
+
headerName: formatHeaderName(rowGroupColumn),
|
|
8526
|
+
width: 180,
|
|
8527
|
+
sortable: true,
|
|
8528
|
+
filterable: true,
|
|
8529
|
+
isPivotColumn: false
|
|
8530
|
+
}
|
|
8531
|
+
];
|
|
8532
|
+
pivotValues.forEach((pivotValue) => {
|
|
8533
|
+
columns.push({
|
|
8534
|
+
field: pivotValue,
|
|
8535
|
+
headerName: pivotValue,
|
|
8536
|
+
width: 120,
|
|
8537
|
+
sortable: true,
|
|
8538
|
+
filterable: true,
|
|
8539
|
+
isPivotColumn: true
|
|
8540
|
+
});
|
|
8541
|
+
});
|
|
8542
|
+
if (showGrandTotal) {
|
|
8543
|
+
columns.push({
|
|
8544
|
+
field: "__grandTotal",
|
|
8545
|
+
headerName: "Grand Total",
|
|
8546
|
+
width: 120,
|
|
8547
|
+
sortable: true,
|
|
8548
|
+
filterable: false,
|
|
8549
|
+
isTotalColumn: true
|
|
8550
|
+
});
|
|
8551
|
+
}
|
|
8552
|
+
const rows = [];
|
|
8553
|
+
rowGroupValues.forEach((rowValue) => {
|
|
8554
|
+
const pivotMap = groupedData.get(rowValue);
|
|
8555
|
+
const row = {
|
|
8556
|
+
[rowGroupColumn]: rowValue,
|
|
8557
|
+
__id: rowValue
|
|
8558
|
+
// Add unique ID for grid
|
|
8559
|
+
};
|
|
8560
|
+
let grandTotal = 0;
|
|
8561
|
+
pivotValues.forEach((pivotValue) => {
|
|
8562
|
+
const values = pivotMap.get(pivotValue);
|
|
8563
|
+
const aggregatedValue = aggregatorFn(values);
|
|
8564
|
+
row[pivotValue] = aggregatedValue;
|
|
8565
|
+
grandTotal += aggregatedValue;
|
|
8566
|
+
});
|
|
8567
|
+
if (showGrandTotal) {
|
|
8568
|
+
row["__grandTotal"] = grandTotal;
|
|
8569
|
+
}
|
|
8570
|
+
rows.push(row);
|
|
8571
|
+
});
|
|
8572
|
+
let totalsRow;
|
|
8573
|
+
if (showTotals) {
|
|
8574
|
+
totalsRow = {
|
|
8575
|
+
[rowGroupColumn]: "Total",
|
|
8576
|
+
__id: "__totals",
|
|
8577
|
+
__isTotal: true
|
|
8578
|
+
};
|
|
8579
|
+
let overallGrandTotal = 0;
|
|
8580
|
+
pivotValues.forEach((pivotValue) => {
|
|
8581
|
+
const allValues = [];
|
|
8582
|
+
groupedData.forEach((pivotMap) => {
|
|
8583
|
+
const values = pivotMap.get(pivotValue);
|
|
8584
|
+
allValues.push(...values);
|
|
8585
|
+
});
|
|
8586
|
+
const total = aggregatorFn(allValues);
|
|
8587
|
+
totalsRow[pivotValue] = total;
|
|
8588
|
+
overallGrandTotal += total;
|
|
8589
|
+
});
|
|
8590
|
+
if (showGrandTotal) {
|
|
8591
|
+
totalsRow["__grandTotal"] = overallGrandTotal;
|
|
8592
|
+
}
|
|
8593
|
+
}
|
|
8594
|
+
return {
|
|
8595
|
+
columns,
|
|
8596
|
+
rows,
|
|
8597
|
+
pivotValues,
|
|
8598
|
+
totalsRow
|
|
8599
|
+
};
|
|
8600
|
+
}
|
|
8601
|
+
function formatHeaderName(field) {
|
|
8602
|
+
return field.split(/(?=[A-Z])|_|-/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
|
|
8603
|
+
}
|
|
8604
|
+
function exportPivotToCSV(pivotResult) {
|
|
8605
|
+
const { columns, rows, totalsRow } = pivotResult;
|
|
8606
|
+
const headers = columns.map((col) => col.headerName).join(",");
|
|
8607
|
+
const dataRows = rows.map((row) => {
|
|
8608
|
+
return columns.map((col) => {
|
|
8609
|
+
const value = row[col.field];
|
|
8610
|
+
if (typeof value === "string" && value.includes(",")) {
|
|
8611
|
+
return `"${value}"`;
|
|
8612
|
+
}
|
|
8613
|
+
return value ?? "";
|
|
8614
|
+
}).join(",");
|
|
8615
|
+
});
|
|
8616
|
+
if (totalsRow) {
|
|
8617
|
+
const totalRow = columns.map((col) => {
|
|
8618
|
+
const value = totalsRow[col.field];
|
|
8619
|
+
if (typeof value === "string" && value.includes(",")) {
|
|
8620
|
+
return `"${value}"`;
|
|
8621
|
+
}
|
|
8622
|
+
return value ?? "";
|
|
8623
|
+
}).join(",");
|
|
8624
|
+
dataRows.push(totalRow);
|
|
8625
|
+
}
|
|
8626
|
+
return [headers, ...dataRows].join("\n");
|
|
8627
|
+
}
|
|
8628
|
+
function downloadCSV(csvContent, filename = "pivot-table.csv") {
|
|
8629
|
+
const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" });
|
|
8630
|
+
const link = document.createElement("a");
|
|
8631
|
+
const url = URL.createObjectURL(blob);
|
|
8632
|
+
link.setAttribute("href", url);
|
|
8633
|
+
link.setAttribute("download", filename);
|
|
8634
|
+
link.style.visibility = "hidden";
|
|
8635
|
+
document.body.appendChild(link);
|
|
8636
|
+
link.click();
|
|
8637
|
+
document.body.removeChild(link);
|
|
8638
|
+
URL.revokeObjectURL(url);
|
|
8639
|
+
}
|
|
8640
|
+
|
|
8448
8641
|
// src/components/DataGrid/DataGrid.tsx
|
|
8449
8642
|
var DataGrid = (0, import_react23.forwardRef)(({
|
|
8450
8643
|
columns,
|
|
@@ -8459,6 +8652,7 @@ var DataGrid = (0, import_react23.forwardRef)(({
|
|
|
8459
8652
|
rowPinConfig,
|
|
8460
8653
|
contextMenuConfig,
|
|
8461
8654
|
tooltipConfig,
|
|
8655
|
+
pivotConfig,
|
|
8462
8656
|
tableId,
|
|
8463
8657
|
theme: _theme = "quartz",
|
|
8464
8658
|
densityMode: _densityMode = "normal",
|
|
@@ -8479,6 +8673,42 @@ var DataGrid = (0, import_react23.forwardRef)(({
|
|
|
8479
8673
|
);
|
|
8480
8674
|
const [internalRows, setInternalRows] = (0, import_react23.useState)(null);
|
|
8481
8675
|
const activeRows = internalRows !== null ? internalRows : rows;
|
|
8676
|
+
const { pivotedData, effectiveColumns } = (0, import_react23.useMemo)(() => {
|
|
8677
|
+
if (!pivotConfig) {
|
|
8678
|
+
return { pivotedData: activeRows, effectiveColumns: columns };
|
|
8679
|
+
}
|
|
8680
|
+
const pivotResult = buildPivot(activeRows, pivotConfig);
|
|
8681
|
+
console.log("Pivot Result:", {
|
|
8682
|
+
columnsCount: pivotResult.columns.length,
|
|
8683
|
+
columns: pivotResult.columns.map((c) => c.field),
|
|
8684
|
+
rowsCount: pivotResult.rows.length,
|
|
8685
|
+
sampleRow: pivotResult.rows[0]
|
|
8686
|
+
});
|
|
8687
|
+
const pivotColumns = pivotResult.columns.map((col) => ({
|
|
8688
|
+
field: col.field,
|
|
8689
|
+
headerName: col.headerName,
|
|
8690
|
+
width: col.width || 120,
|
|
8691
|
+
sortable: col.sortable !== false,
|
|
8692
|
+
filterable: col.filterable !== false,
|
|
8693
|
+
editable: false,
|
|
8694
|
+
renderCell: col.isTotalColumn || col.isPivotColumn ? (row) => {
|
|
8695
|
+
const value = row[col.field];
|
|
8696
|
+
if (typeof value === "number") {
|
|
8697
|
+
return /* @__PURE__ */ import_react23.default.createElement("span", { style: {
|
|
8698
|
+
fontWeight: col.isTotalColumn ? "700" : "600",
|
|
8699
|
+
color: col.isTotalColumn ? "#0f766e" : "#475569"
|
|
8700
|
+
} }, value.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 }));
|
|
8701
|
+
}
|
|
8702
|
+
return value;
|
|
8703
|
+
} : void 0
|
|
8704
|
+
}));
|
|
8705
|
+
const allRows = pivotResult.totalsRow ? [...pivotResult.rows, pivotResult.totalsRow] : pivotResult.rows;
|
|
8706
|
+
const rowsWithId = allRows.map((row, index) => ({
|
|
8707
|
+
...row,
|
|
8708
|
+
id: row.__id || row.id || `pivot-row-${index}`
|
|
8709
|
+
}));
|
|
8710
|
+
return { pivotedData: rowsWithId, effectiveColumns: pivotColumns };
|
|
8711
|
+
}, [activeRows, columns, pivotConfig]);
|
|
8482
8712
|
const rowsRef = (0, import_react23.useRef)(rows);
|
|
8483
8713
|
(0, import_react23.useEffect)(() => {
|
|
8484
8714
|
if (rows !== rowsRef.current) {
|
|
@@ -8581,8 +8811,8 @@ var DataGrid = (0, import_react23.forwardRef)(({
|
|
|
8581
8811
|
gridApiRef.current = new GridApiImpl(
|
|
8582
8812
|
state,
|
|
8583
8813
|
dispatch,
|
|
8584
|
-
|
|
8585
|
-
|
|
8814
|
+
effectiveColumns,
|
|
8815
|
+
pivotedData,
|
|
8586
8816
|
containerRef,
|
|
8587
8817
|
persistenceManager,
|
|
8588
8818
|
setInternalRows
|
|
@@ -8592,24 +8822,24 @@ var DataGrid = (0, import_react23.forwardRef)(({
|
|
|
8592
8822
|
(0, import_react23.useEffect)(() => {
|
|
8593
8823
|
if (gridApiRef.current && !gridApiRef.current.isDestroyed()) {
|
|
8594
8824
|
gridApiRef.current.updateState(state);
|
|
8595
|
-
gridApiRef.current.updateData(
|
|
8825
|
+
gridApiRef.current.updateData(effectiveColumns, pivotedData);
|
|
8596
8826
|
gridApiRef.current.updateCallbacks(setInternalRows);
|
|
8597
8827
|
}
|
|
8598
|
-
}, [state,
|
|
8828
|
+
}, [state, effectiveColumns, pivotedData, setInternalRows]);
|
|
8599
8829
|
(0, import_react23.useImperativeHandle)(ref, () => {
|
|
8600
8830
|
if (!gridApiRef.current || gridApiRef.current.isDestroyed()) {
|
|
8601
8831
|
gridApiRef.current = new GridApiImpl(
|
|
8602
8832
|
state,
|
|
8603
8833
|
dispatch,
|
|
8604
|
-
|
|
8605
|
-
|
|
8834
|
+
effectiveColumns,
|
|
8835
|
+
pivotedData,
|
|
8606
8836
|
containerRef,
|
|
8607
8837
|
persistenceManager,
|
|
8608
8838
|
setInternalRows
|
|
8609
8839
|
);
|
|
8610
8840
|
}
|
|
8611
8841
|
return gridApiRef.current;
|
|
8612
|
-
}, [state,
|
|
8842
|
+
}, [state, effectiveColumns, pivotedData, persistenceManager]);
|
|
8613
8843
|
const onGridReadyCalledRef = (0, import_react23.useRef)(false);
|
|
8614
8844
|
const onGridReadyCallbackRef = (0, import_react23.useRef)(onGridReady);
|
|
8615
8845
|
(0, import_react23.useEffect)(() => {
|
|
@@ -8690,9 +8920,11 @@ var DataGrid = (0, import_react23.forwardRef)(({
|
|
|
8690
8920
|
...middleColumns,
|
|
8691
8921
|
...pinnedRightFields
|
|
8692
8922
|
];
|
|
8923
|
+
console.log("Display column order:", displayColumnOrder, "from state.columnOrder:", state.columnOrder);
|
|
8693
8924
|
(0, import_react23.useEffect)(() => {
|
|
8694
|
-
|
|
8695
|
-
|
|
8925
|
+
console.log("Dispatching RESET_COLUMNS with", effectiveColumns.length, "columns:", effectiveColumns.map((c) => c.field));
|
|
8926
|
+
dispatch({ type: "RESET_COLUMNS", payload: effectiveColumns });
|
|
8927
|
+
}, [effectiveColumns]);
|
|
8696
8928
|
(0, import_react23.useEffect)(() => {
|
|
8697
8929
|
if (onSelectionChange) {
|
|
8698
8930
|
onSelectionChange(Array.from(state.selection.selectedRows));
|
|
@@ -8708,17 +8940,17 @@ var DataGrid = (0, import_react23.forwardRef)(({
|
|
|
8708
8940
|
}, [state.pinnedRowsTop, state.pinnedRowsBottom]);
|
|
8709
8941
|
(0, import_react23.useEffect)(() => {
|
|
8710
8942
|
if (state.sortConfig.field) {
|
|
8711
|
-
const column =
|
|
8943
|
+
const column = effectiveColumns.find((c) => c.field === state.sortConfig.field);
|
|
8712
8944
|
if (column) {
|
|
8713
8945
|
announceSorting(column.headerName, state.sortConfig.direction);
|
|
8714
8946
|
}
|
|
8715
8947
|
}
|
|
8716
|
-
}, [state.sortConfig.field, state.sortConfig.direction]);
|
|
8948
|
+
}, [state.sortConfig.field, state.sortConfig.direction, effectiveColumns]);
|
|
8717
8949
|
const sortedRows = (0, import_react23.useMemo)(() => {
|
|
8718
8950
|
if (!state.sortConfig.field || !state.sortConfig.direction) {
|
|
8719
|
-
return
|
|
8951
|
+
return pivotedData;
|
|
8720
8952
|
}
|
|
8721
|
-
const sorted = [...
|
|
8953
|
+
const sorted = [...pivotedData].sort((a, b) => {
|
|
8722
8954
|
const aValue = a[state.sortConfig.field];
|
|
8723
8955
|
const bValue = b[state.sortConfig.field];
|
|
8724
8956
|
if (aValue == null && bValue == null) return 0;
|
|
@@ -8735,7 +8967,7 @@ var DataGrid = (0, import_react23.forwardRef)(({
|
|
|
8735
8967
|
sorted.reverse();
|
|
8736
8968
|
}
|
|
8737
8969
|
return sorted;
|
|
8738
|
-
}, [
|
|
8970
|
+
}, [pivotedData, state.sortConfig]);
|
|
8739
8971
|
const filteredRows = (0, import_react23.useMemo)(() => {
|
|
8740
8972
|
if (!hasActiveFilters(state.filterConfig)) {
|
|
8741
8973
|
return sortedRows;
|
|
@@ -8881,7 +9113,7 @@ var DataGrid = (0, import_react23.forwardRef)(({
|
|
|
8881
9113
|
/* @__PURE__ */ import_react23.default.createElement("div", { style: { position: "relative", display: "flex", alignItems: "center", justifyContent: "space-between", paddingLeft: "16px", paddingRight: "16px", paddingTop: "10px", paddingBottom: "10px", backgroundColor: "var(--grid-bg-alt)", borderBottom: "var(--grid-border-width, 1px) solid var(--grid-border)", zIndex: 30 } }, /* @__PURE__ */ import_react23.default.createElement("div", { style: { position: "relative", display: "flex", alignItems: "center", gap: "8px" } }, /* @__PURE__ */ import_react23.default.createElement(
|
|
8882
9114
|
ColumnChooser,
|
|
8883
9115
|
{
|
|
8884
|
-
columns,
|
|
9116
|
+
columns: effectiveColumns,
|
|
8885
9117
|
columnOrder: state.columnOrder,
|
|
8886
9118
|
hiddenColumns: state.hiddenColumns,
|
|
8887
9119
|
onToggleVisibility: (field) => dispatch({ type: "TOGGLE_COLUMN_VISIBILITY", payload: field }),
|
|
@@ -8891,7 +9123,7 @@ var DataGrid = (0, import_react23.forwardRef)(({
|
|
|
8891
9123
|
), /* @__PURE__ */ import_react23.default.createElement(
|
|
8892
9124
|
ExportMenu,
|
|
8893
9125
|
{
|
|
8894
|
-
columns,
|
|
9126
|
+
columns: effectiveColumns,
|
|
8895
9127
|
fullDataset: rows,
|
|
8896
9128
|
filteredData: filteredRows.filter((r) => !("isGroup" in r)),
|
|
8897
9129
|
selectedRows: state.selection.selectedRows,
|
|
@@ -8909,7 +9141,7 @@ var DataGrid = (0, import_react23.forwardRef)(({
|
|
|
8909
9141
|
/* @__PURE__ */ import_react23.default.createElement(
|
|
8910
9142
|
GroupByPanel,
|
|
8911
9143
|
{
|
|
8912
|
-
columns,
|
|
9144
|
+
columns: effectiveColumns,
|
|
8913
9145
|
groupBy: state.groupBy,
|
|
8914
9146
|
dispatch
|
|
8915
9147
|
}
|
|
@@ -8917,7 +9149,7 @@ var DataGrid = (0, import_react23.forwardRef)(({
|
|
|
8917
9149
|
/* @__PURE__ */ import_react23.default.createElement("div", { role: "rowgroup", style: { position: "sticky", top: 0, zIndex: 20, width: "100%" } }, /* @__PURE__ */ import_react23.default.createElement(
|
|
8918
9150
|
GridHeader,
|
|
8919
9151
|
{
|
|
8920
|
-
columns,
|
|
9152
|
+
columns: effectiveColumns,
|
|
8921
9153
|
columnOrder: state.columnOrder,
|
|
8922
9154
|
displayColumnOrder,
|
|
8923
9155
|
columnWidths: state.columnWidths,
|
|
@@ -8936,7 +9168,7 @@ var DataGrid = (0, import_react23.forwardRef)(({
|
|
|
8936
9168
|
), /* @__PURE__ */ import_react23.default.createElement(
|
|
8937
9169
|
ColumnFilters,
|
|
8938
9170
|
{
|
|
8939
|
-
columns,
|
|
9171
|
+
columns: effectiveColumns,
|
|
8940
9172
|
displayColumnOrder,
|
|
8941
9173
|
columnWidths: state.columnWidths,
|
|
8942
9174
|
filterConfig: state.filterConfig,
|
|
@@ -8949,7 +9181,7 @@ var DataGrid = (0, import_react23.forwardRef)(({
|
|
|
8949
9181
|
/* @__PURE__ */ import_react23.default.createElement(
|
|
8950
9182
|
GridBody,
|
|
8951
9183
|
{
|
|
8952
|
-
columns,
|
|
9184
|
+
columns: effectiveColumns,
|
|
8953
9185
|
rows: (virtualScrollConfig == null ? void 0 : virtualScrollConfig.enabled) ? unpinnedRows : paginatedRows,
|
|
8954
9186
|
pinnedRowsTop: pinnedRowsTopData,
|
|
8955
9187
|
pinnedRowsBottom: pinnedRowsBottomData,
|
|
@@ -8989,7 +9221,7 @@ var DataGrid = (0, import_react23.forwardRef)(({
|
|
|
8989
9221
|
(footerConfig == null ? void 0 : footerConfig.show) && footerConfig.aggregates && /* @__PURE__ */ import_react23.default.createElement(
|
|
8990
9222
|
GridFooter,
|
|
8991
9223
|
{
|
|
8992
|
-
columns,
|
|
9224
|
+
columns: effectiveColumns,
|
|
8993
9225
|
displayColumnOrder,
|
|
8994
9226
|
columnWidths: state.columnWidths,
|
|
8995
9227
|
aggregates: globalAggregates,
|
|
@@ -12157,6 +12389,258 @@ function createMockFeed(config) {
|
|
|
12157
12389
|
createConnection: () => createMockWebSocket(feed)
|
|
12158
12390
|
};
|
|
12159
12391
|
}
|
|
12392
|
+
|
|
12393
|
+
// src/components/DataGrid/PivotToolbar.tsx
|
|
12394
|
+
var import_react33 = __toESM(require("react"), 1);
|
|
12395
|
+
var AGGREGATOR_OPTIONS = [
|
|
12396
|
+
{ value: "sum", label: "Sum" },
|
|
12397
|
+
{ value: "avg", label: "Average" },
|
|
12398
|
+
{ value: "count", label: "Count" },
|
|
12399
|
+
{ value: "min", label: "Minimum" },
|
|
12400
|
+
{ value: "max", label: "Maximum" }
|
|
12401
|
+
];
|
|
12402
|
+
var PivotToolbar = ({
|
|
12403
|
+
columns,
|
|
12404
|
+
pivotConfig,
|
|
12405
|
+
onPivotToggle,
|
|
12406
|
+
onConfigChange,
|
|
12407
|
+
isPivotMode = false,
|
|
12408
|
+
style,
|
|
12409
|
+
className
|
|
12410
|
+
}) => {
|
|
12411
|
+
const [isExpanded, setIsExpanded] = (0, import_react33.useState)(isPivotMode);
|
|
12412
|
+
const [rowGroupColumn, setRowGroupColumn] = (0, import_react33.useState)((pivotConfig == null ? void 0 : pivotConfig.rowGroupColumn) || "");
|
|
12413
|
+
const [pivotColumn, setPivotColumn] = (0, import_react33.useState)((pivotConfig == null ? void 0 : pivotConfig.pivotColumn) || "");
|
|
12414
|
+
const [valueColumn, setValueColumn] = (0, import_react33.useState)((pivotConfig == null ? void 0 : pivotConfig.valueColumn) || "");
|
|
12415
|
+
const [aggregator, setAggregator] = (0, import_react33.useState)(
|
|
12416
|
+
(pivotConfig == null ? void 0 : pivotConfig.aggregator) || "sum"
|
|
12417
|
+
);
|
|
12418
|
+
const [showTotals, setShowTotals] = (0, import_react33.useState)((pivotConfig == null ? void 0 : pivotConfig.showTotals) ?? true);
|
|
12419
|
+
const [showGrandTotal, setShowGrandTotal] = (0, import_react33.useState)((pivotConfig == null ? void 0 : pivotConfig.showGrandTotal) ?? true);
|
|
12420
|
+
const isConfigValid = (0, import_react33.useMemo)(() => {
|
|
12421
|
+
return rowGroupColumn && pivotColumn && valueColumn;
|
|
12422
|
+
}, [rowGroupColumn, pivotColumn, valueColumn]);
|
|
12423
|
+
const handleApply = () => {
|
|
12424
|
+
if (!isConfigValid) return;
|
|
12425
|
+
const config = {
|
|
12426
|
+
rowGroupColumn,
|
|
12427
|
+
pivotColumn,
|
|
12428
|
+
valueColumn,
|
|
12429
|
+
aggregator,
|
|
12430
|
+
showTotals,
|
|
12431
|
+
showGrandTotal
|
|
12432
|
+
};
|
|
12433
|
+
onConfigChange(config);
|
|
12434
|
+
onPivotToggle(true);
|
|
12435
|
+
};
|
|
12436
|
+
const handleClear = () => {
|
|
12437
|
+
setRowGroupColumn("");
|
|
12438
|
+
setPivotColumn("");
|
|
12439
|
+
setValueColumn("");
|
|
12440
|
+
setAggregator("sum");
|
|
12441
|
+
setShowTotals(true);
|
|
12442
|
+
setShowGrandTotal(true);
|
|
12443
|
+
onConfigChange(null);
|
|
12444
|
+
onPivotToggle(false);
|
|
12445
|
+
setIsExpanded(false);
|
|
12446
|
+
};
|
|
12447
|
+
const handleToggle = () => {
|
|
12448
|
+
setIsExpanded(!isExpanded);
|
|
12449
|
+
};
|
|
12450
|
+
return /* @__PURE__ */ import_react33.default.createElement(
|
|
12451
|
+
"div",
|
|
12452
|
+
{
|
|
12453
|
+
className,
|
|
12454
|
+
style: {
|
|
12455
|
+
backgroundColor: "#f8fafc",
|
|
12456
|
+
border: "1px solid #e2e8f0",
|
|
12457
|
+
borderRadius: "8px",
|
|
12458
|
+
padding: "12px",
|
|
12459
|
+
...style
|
|
12460
|
+
}
|
|
12461
|
+
},
|
|
12462
|
+
/* @__PURE__ */ import_react33.default.createElement("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: isExpanded ? "12px" : "0" } }, /* @__PURE__ */ import_react33.default.createElement("div", { style: { display: "flex", alignItems: "center", gap: "8px" } }, /* @__PURE__ */ import_react33.default.createElement("span", { style: { fontSize: "20px" } }, "\u{1F4CA}"), /* @__PURE__ */ import_react33.default.createElement("h3", { style: { margin: 0, fontSize: "14px", fontWeight: "600", color: "#1e293b" } }, "Pivot Table"), isPivotMode && /* @__PURE__ */ import_react33.default.createElement("span", { style: {
|
|
12463
|
+
backgroundColor: "#10b981",
|
|
12464
|
+
color: "white",
|
|
12465
|
+
padding: "2px 8px",
|
|
12466
|
+
borderRadius: "12px",
|
|
12467
|
+
fontSize: "11px",
|
|
12468
|
+
fontWeight: "600"
|
|
12469
|
+
} }, "Active")), /* @__PURE__ */ import_react33.default.createElement("div", { style: { display: "flex", gap: "8px" } }, isPivotMode && /* @__PURE__ */ import_react33.default.createElement(
|
|
12470
|
+
"button",
|
|
12471
|
+
{
|
|
12472
|
+
onClick: handleClear,
|
|
12473
|
+
style: {
|
|
12474
|
+
padding: "6px 12px",
|
|
12475
|
+
fontSize: "13px",
|
|
12476
|
+
fontWeight: "500",
|
|
12477
|
+
color: "#dc2626",
|
|
12478
|
+
backgroundColor: "#fee2e2",
|
|
12479
|
+
border: "1px solid #fecaca",
|
|
12480
|
+
borderRadius: "6px",
|
|
12481
|
+
cursor: "pointer",
|
|
12482
|
+
transition: "all 0.15s"
|
|
12483
|
+
},
|
|
12484
|
+
onMouseEnter: (e) => {
|
|
12485
|
+
e.currentTarget.style.backgroundColor = "#fecaca";
|
|
12486
|
+
},
|
|
12487
|
+
onMouseLeave: (e) => {
|
|
12488
|
+
e.currentTarget.style.backgroundColor = "#fee2e2";
|
|
12489
|
+
}
|
|
12490
|
+
},
|
|
12491
|
+
"Clear Pivot"
|
|
12492
|
+
), /* @__PURE__ */ import_react33.default.createElement(
|
|
12493
|
+
"button",
|
|
12494
|
+
{
|
|
12495
|
+
onClick: handleToggle,
|
|
12496
|
+
style: {
|
|
12497
|
+
padding: "6px 10px",
|
|
12498
|
+
fontSize: "13px",
|
|
12499
|
+
color: "#64748b",
|
|
12500
|
+
backgroundColor: "white",
|
|
12501
|
+
border: "1px solid #cbd5e1",
|
|
12502
|
+
borderRadius: "6px",
|
|
12503
|
+
cursor: "pointer",
|
|
12504
|
+
transition: "all 0.15s"
|
|
12505
|
+
},
|
|
12506
|
+
onMouseEnter: (e) => {
|
|
12507
|
+
e.currentTarget.style.backgroundColor = "#f1f5f9";
|
|
12508
|
+
},
|
|
12509
|
+
onMouseLeave: (e) => {
|
|
12510
|
+
e.currentTarget.style.backgroundColor = "white";
|
|
12511
|
+
}
|
|
12512
|
+
},
|
|
12513
|
+
isExpanded ? "\u25B2" : "\u25BC"
|
|
12514
|
+
))),
|
|
12515
|
+
isExpanded && /* @__PURE__ */ import_react33.default.createElement("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(200px, 1fr))", gap: "12px" } }, /* @__PURE__ */ import_react33.default.createElement("div", null, /* @__PURE__ */ import_react33.default.createElement("label", { style: { display: "block", fontSize: "12px", fontWeight: "600", color: "#475569", marginBottom: "6px" } }, "Row Group By ", /* @__PURE__ */ import_react33.default.createElement("span", { style: { color: "#dc2626" } }, "*")), /* @__PURE__ */ import_react33.default.createElement(
|
|
12516
|
+
"select",
|
|
12517
|
+
{
|
|
12518
|
+
value: rowGroupColumn,
|
|
12519
|
+
onChange: (e) => setRowGroupColumn(e.target.value),
|
|
12520
|
+
style: {
|
|
12521
|
+
width: "100%",
|
|
12522
|
+
padding: "8px",
|
|
12523
|
+
fontSize: "13px",
|
|
12524
|
+
border: "1px solid #cbd5e1",
|
|
12525
|
+
borderRadius: "6px",
|
|
12526
|
+
backgroundColor: "white",
|
|
12527
|
+
color: "#1e293b",
|
|
12528
|
+
cursor: "pointer"
|
|
12529
|
+
}
|
|
12530
|
+
},
|
|
12531
|
+
/* @__PURE__ */ import_react33.default.createElement("option", { value: "" }, "Select column..."),
|
|
12532
|
+
columns.map((col) => /* @__PURE__ */ import_react33.default.createElement("option", { key: col.field, value: col.field }, col.headerName))
|
|
12533
|
+
)), /* @__PURE__ */ import_react33.default.createElement("div", null, /* @__PURE__ */ import_react33.default.createElement("label", { style: { display: "block", fontSize: "12px", fontWeight: "600", color: "#475569", marginBottom: "6px" } }, "Pivot Column ", /* @__PURE__ */ import_react33.default.createElement("span", { style: { color: "#dc2626" } }, "*")), /* @__PURE__ */ import_react33.default.createElement(
|
|
12534
|
+
"select",
|
|
12535
|
+
{
|
|
12536
|
+
value: pivotColumn,
|
|
12537
|
+
onChange: (e) => setPivotColumn(e.target.value),
|
|
12538
|
+
style: {
|
|
12539
|
+
width: "100%",
|
|
12540
|
+
padding: "8px",
|
|
12541
|
+
fontSize: "13px",
|
|
12542
|
+
border: "1px solid #cbd5e1",
|
|
12543
|
+
borderRadius: "6px",
|
|
12544
|
+
backgroundColor: "white",
|
|
12545
|
+
color: "#1e293b",
|
|
12546
|
+
cursor: "pointer"
|
|
12547
|
+
}
|
|
12548
|
+
},
|
|
12549
|
+
/* @__PURE__ */ import_react33.default.createElement("option", { value: "" }, "Select column..."),
|
|
12550
|
+
columns.map((col) => /* @__PURE__ */ import_react33.default.createElement("option", { key: col.field, value: col.field }, col.headerName))
|
|
12551
|
+
)), /* @__PURE__ */ import_react33.default.createElement("div", null, /* @__PURE__ */ import_react33.default.createElement("label", { style: { display: "block", fontSize: "12px", fontWeight: "600", color: "#475569", marginBottom: "6px" } }, "Value Column ", /* @__PURE__ */ import_react33.default.createElement("span", { style: { color: "#dc2626" } }, "*")), /* @__PURE__ */ import_react33.default.createElement(
|
|
12552
|
+
"select",
|
|
12553
|
+
{
|
|
12554
|
+
value: valueColumn,
|
|
12555
|
+
onChange: (e) => setValueColumn(e.target.value),
|
|
12556
|
+
style: {
|
|
12557
|
+
width: "100%",
|
|
12558
|
+
padding: "8px",
|
|
12559
|
+
fontSize: "13px",
|
|
12560
|
+
border: "1px solid #cbd5e1",
|
|
12561
|
+
borderRadius: "6px",
|
|
12562
|
+
backgroundColor: "white",
|
|
12563
|
+
color: "#1e293b",
|
|
12564
|
+
cursor: "pointer"
|
|
12565
|
+
}
|
|
12566
|
+
},
|
|
12567
|
+
/* @__PURE__ */ import_react33.default.createElement("option", { value: "" }, "Select column..."),
|
|
12568
|
+
columns.map((col) => /* @__PURE__ */ import_react33.default.createElement("option", { key: col.field, value: col.field }, col.headerName))
|
|
12569
|
+
)), /* @__PURE__ */ import_react33.default.createElement("div", null, /* @__PURE__ */ import_react33.default.createElement("label", { style: { display: "block", fontSize: "12px", fontWeight: "600", color: "#475569", marginBottom: "6px" } }, "Aggregation"), /* @__PURE__ */ import_react33.default.createElement(
|
|
12570
|
+
"select",
|
|
12571
|
+
{
|
|
12572
|
+
value: aggregator,
|
|
12573
|
+
onChange: (e) => setAggregator(e.target.value),
|
|
12574
|
+
style: {
|
|
12575
|
+
width: "100%",
|
|
12576
|
+
padding: "8px",
|
|
12577
|
+
fontSize: "13px",
|
|
12578
|
+
border: "1px solid #cbd5e1",
|
|
12579
|
+
borderRadius: "6px",
|
|
12580
|
+
backgroundColor: "white",
|
|
12581
|
+
color: "#1e293b",
|
|
12582
|
+
cursor: "pointer"
|
|
12583
|
+
}
|
|
12584
|
+
},
|
|
12585
|
+
AGGREGATOR_OPTIONS.map((opt) => /* @__PURE__ */ import_react33.default.createElement("option", { key: opt.value, value: opt.value }, opt.label))
|
|
12586
|
+
)), /* @__PURE__ */ import_react33.default.createElement("div", { style: { display: "flex", flexDirection: "column", gap: "8px", justifyContent: "center" } }, /* @__PURE__ */ import_react33.default.createElement("label", { style: { display: "flex", alignItems: "center", gap: "6px", fontSize: "13px", color: "#475569", cursor: "pointer" } }, /* @__PURE__ */ import_react33.default.createElement(
|
|
12587
|
+
"input",
|
|
12588
|
+
{
|
|
12589
|
+
type: "checkbox",
|
|
12590
|
+
checked: showTotals,
|
|
12591
|
+
onChange: (e) => setShowTotals(e.target.checked),
|
|
12592
|
+
style: { cursor: "pointer" }
|
|
12593
|
+
}
|
|
12594
|
+
), "Show Totals Row"), /* @__PURE__ */ import_react33.default.createElement("label", { style: { display: "flex", alignItems: "center", gap: "6px", fontSize: "13px", color: "#475569", cursor: "pointer" } }, /* @__PURE__ */ import_react33.default.createElement(
|
|
12595
|
+
"input",
|
|
12596
|
+
{
|
|
12597
|
+
type: "checkbox",
|
|
12598
|
+
checked: showGrandTotal,
|
|
12599
|
+
onChange: (e) => setShowGrandTotal(e.target.checked),
|
|
12600
|
+
style: { cursor: "pointer" }
|
|
12601
|
+
}
|
|
12602
|
+
), "Show Grand Total Column")), /* @__PURE__ */ import_react33.default.createElement("div", { style: { display: "flex", alignItems: "flex-end" } }, /* @__PURE__ */ import_react33.default.createElement(
|
|
12603
|
+
"button",
|
|
12604
|
+
{
|
|
12605
|
+
onClick: handleApply,
|
|
12606
|
+
disabled: !isConfigValid,
|
|
12607
|
+
style: {
|
|
12608
|
+
width: "100%",
|
|
12609
|
+
padding: "10px",
|
|
12610
|
+
fontSize: "14px",
|
|
12611
|
+
fontWeight: "600",
|
|
12612
|
+
color: "white",
|
|
12613
|
+
backgroundColor: isConfigValid ? "#2563eb" : "#94a3b8",
|
|
12614
|
+
border: "none",
|
|
12615
|
+
borderRadius: "6px",
|
|
12616
|
+
cursor: isConfigValid ? "pointer" : "not-allowed",
|
|
12617
|
+
transition: "all 0.15s",
|
|
12618
|
+
boxShadow: isConfigValid ? "0 2px 4px rgba(37, 99, 235, 0.2)" : "none"
|
|
12619
|
+
},
|
|
12620
|
+
onMouseEnter: (e) => {
|
|
12621
|
+
if (isConfigValid) {
|
|
12622
|
+
e.currentTarget.style.backgroundColor = "#1d4ed8";
|
|
12623
|
+
}
|
|
12624
|
+
},
|
|
12625
|
+
onMouseLeave: (e) => {
|
|
12626
|
+
if (isConfigValid) {
|
|
12627
|
+
e.currentTarget.style.backgroundColor = "#2563eb";
|
|
12628
|
+
}
|
|
12629
|
+
}
|
|
12630
|
+
},
|
|
12631
|
+
"Apply Pivot"
|
|
12632
|
+
))),
|
|
12633
|
+
isExpanded && /* @__PURE__ */ import_react33.default.createElement("div", { style: {
|
|
12634
|
+
marginTop: "12px",
|
|
12635
|
+
padding: "10px",
|
|
12636
|
+
backgroundColor: "#eff6ff",
|
|
12637
|
+
border: "1px solid #bfdbfe",
|
|
12638
|
+
borderRadius: "6px",
|
|
12639
|
+
fontSize: "12px",
|
|
12640
|
+
color: "#1e40af"
|
|
12641
|
+
} }, /* @__PURE__ */ import_react33.default.createElement("strong", null, "\u{1F4A1} Tip:"), " Select a Row Group column to organize data by, a Pivot column whose values become new columns, and a Value column to aggregate.")
|
|
12642
|
+
);
|
|
12643
|
+
};
|
|
12160
12644
|
// Annotate the CommonJS export names for ESM import in node:
|
|
12161
12645
|
0 && (module.exports = {
|
|
12162
12646
|
AdvancedFilterBuilder,
|
|
@@ -12180,6 +12664,7 @@ function createMockFeed(config) {
|
|
|
12180
12664
|
LocalStorageAdapter,
|
|
12181
12665
|
MarketDataEngine,
|
|
12182
12666
|
MarketDataGrid,
|
|
12667
|
+
PivotToolbar,
|
|
12183
12668
|
PriorityIndicator,
|
|
12184
12669
|
ProgressBar,
|
|
12185
12670
|
Rating,
|
|
@@ -12192,6 +12677,7 @@ function createMockFeed(config) {
|
|
|
12192
12677
|
VirtualScroller,
|
|
12193
12678
|
WebSocketMockFeed,
|
|
12194
12679
|
alpineTheme,
|
|
12680
|
+
buildPivot,
|
|
12195
12681
|
buildTreeFromFlat,
|
|
12196
12682
|
collapseAllNodes,
|
|
12197
12683
|
countTreeNodes,
|
|
@@ -12202,7 +12688,9 @@ function createMockFeed(config) {
|
|
|
12202
12688
|
createPreset,
|
|
12203
12689
|
darkTheme,
|
|
12204
12690
|
densityConfigs,
|
|
12691
|
+
downloadCSV,
|
|
12205
12692
|
expandAllNodes,
|
|
12693
|
+
exportPivotToCSV,
|
|
12206
12694
|
exportToCSV,
|
|
12207
12695
|
exportToXLSX,
|
|
12208
12696
|
filterTree,
|