@mui/x-data-grid-premium 8.13.1 → 8.14.0
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/CHANGELOG.md +109 -1
- package/DataGridPremium/DataGridPremium.js +7 -5
- package/DataGridPremium/useDataGridPremiumProps.js +3 -2
- package/components/GridDataSourceGroupingCriteriaCell.js +8 -2
- package/components/GridPremiumToolbar.js +1 -2
- package/components/pivotPanel/GridPivotPanelField.js +4 -4
- package/esm/DataGridPremium/DataGridPremium.js +7 -5
- package/esm/DataGridPremium/useDataGridPremiumProps.js +3 -2
- package/esm/components/GridDataSourceGroupingCriteriaCell.js +9 -3
- package/esm/components/GridPremiumToolbar.js +1 -2
- package/esm/components/pivotPanel/GridPivotPanelField.js +4 -4
- package/esm/hooks/features/aggregation/useGridAggregation.js +3 -2
- package/esm/hooks/features/dataSource/models.d.ts +52 -1
- package/esm/hooks/features/dataSource/useGridDataSourcePremium.js +30 -5
- package/esm/hooks/features/dataSource/utils.d.ts +6 -0
- package/esm/hooks/features/dataSource/utils.js +140 -0
- package/esm/hooks/features/index.d.ts +2 -1
- package/esm/hooks/features/index.js +2 -1
- package/esm/hooks/features/pivoting/gridPivotingInterfaces.d.ts +23 -13
- package/esm/hooks/features/pivoting/gridPivotingSelectors.d.ts +1 -1
- package/esm/hooks/features/pivoting/index.d.ts +1 -0
- package/esm/hooks/features/pivoting/index.js +1 -0
- package/esm/hooks/features/pivoting/useGridPivoting.d.ts +1 -1
- package/esm/hooks/features/pivoting/useGridPivoting.js +83 -32
- package/esm/hooks/features/pivoting/utils.d.ts +7 -9
- package/esm/hooks/features/pivoting/utils.js +39 -24
- package/esm/hooks/features/rowGrouping/createGroupingColDef.js +1 -1
- package/esm/hooks/features/rowGrouping/useGridDataSourceRowGroupingPreProcessors.js +7 -3
- package/esm/hooks/features/rowGrouping/useGridRowGrouping.d.ts +1 -1
- package/esm/index.js +1 -1
- package/esm/models/dataGridPremiumProps.d.ts +15 -14
- package/hooks/features/aggregation/useGridAggregation.js +2 -1
- package/hooks/features/dataSource/models.d.ts +52 -1
- package/hooks/features/dataSource/useGridDataSourcePremium.js +29 -4
- package/hooks/features/dataSource/utils.d.ts +6 -0
- package/hooks/features/dataSource/utils.js +148 -0
- package/hooks/features/index.d.ts +2 -1
- package/hooks/features/index.js +11 -0
- package/hooks/features/pivoting/gridPivotingInterfaces.d.ts +23 -13
- package/hooks/features/pivoting/gridPivotingSelectors.d.ts +1 -1
- package/hooks/features/pivoting/index.d.ts +1 -0
- package/hooks/features/pivoting/index.js +12 -0
- package/hooks/features/pivoting/useGridPivoting.d.ts +1 -1
- package/hooks/features/pivoting/useGridPivoting.js +82 -31
- package/hooks/features/pivoting/utils.d.ts +7 -9
- package/hooks/features/pivoting/utils.js +42 -27
- package/hooks/features/rowGrouping/createGroupingColDef.js +1 -1
- package/hooks/features/rowGrouping/useGridDataSourceRowGroupingPreProcessors.js +6 -2
- package/hooks/features/rowGrouping/useGridRowGrouping.d.ts +1 -1
- package/index.js +1 -1
- package/models/dataGridPremiumProps.d.ts +15 -14
- package/package.json +6 -7
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
+
import { gridStringOrNumberComparator } from '@mui/x-data-grid-pro';
|
|
3
|
+
export const getPropsOverrides = (pivotColumns, pivotingColDef, pivotModel, initialColumns, apiRef) => {
|
|
4
|
+
const visiblePivotColumns = pivotModel.columns.filter(column => !column.hidden);
|
|
5
|
+
const visiblePivotValues = pivotModel.values.filter(value => !value.hidden);
|
|
6
|
+
const columns = Array.from(initialColumns.values());
|
|
7
|
+
|
|
8
|
+
// Build column grouping model from pivot column paths
|
|
9
|
+
const columnGroupingModel = [];
|
|
10
|
+
const columnGroupingModelLookup = new Map();
|
|
11
|
+
|
|
12
|
+
// Build new columns lookup and ordered fields
|
|
13
|
+
const newColumns = {};
|
|
14
|
+
|
|
15
|
+
// Build aggregation model
|
|
16
|
+
const aggregationModel = {};
|
|
17
|
+
|
|
18
|
+
// Create unique combinations of all values from pivotColumns and pivotValues
|
|
19
|
+
const uniquePaths = [];
|
|
20
|
+
const processPath = (currentPath, remainingColumns, level) => {
|
|
21
|
+
if (level === visiblePivotColumns.length) {
|
|
22
|
+
uniquePaths.push([...currentPath]);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
remainingColumns.forEach(column => {
|
|
26
|
+
processPath([...currentPath, {
|
|
27
|
+
key: column.key,
|
|
28
|
+
field: visiblePivotColumns[level].field,
|
|
29
|
+
value: column.group
|
|
30
|
+
}], column.children || [], level + 1);
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
processPath([], pivotColumns, 0);
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Column group headers are sorted by the leaf columns order in the column definition.
|
|
37
|
+
* Store the values of each column group path to be able to sort them by pivot column sort order.
|
|
38
|
+
* The values are stored by the column group level which allows easier sorting by going through the column group levels in reverse order.
|
|
39
|
+
* Store raw value to be able to determine if the value was formatted on the client using `getRowValue`.
|
|
40
|
+
* Values sent from the server as strings will not be sorted on the client.
|
|
41
|
+
*/
|
|
42
|
+
const columnGroupPathValues = [];
|
|
43
|
+
uniquePaths.forEach(columnPath => {
|
|
44
|
+
const columnPathKeys = columnPath.map(path => path.key);
|
|
45
|
+
const columnPathValues = columnPath.map(path => path.value);
|
|
46
|
+
visiblePivotValues.forEach(pivotValue => {
|
|
47
|
+
// Find the original column definition for the last field
|
|
48
|
+
const originalColumn = initialColumns.get(pivotValue.field);
|
|
49
|
+
// get the overrides defined from the data source definition
|
|
50
|
+
const overrides = pivotingColDef(pivotValue.field, columnPathKeys);
|
|
51
|
+
|
|
52
|
+
// Create new column definition based on original column
|
|
53
|
+
const newColumnDef = _extends({}, originalColumn, overrides, {
|
|
54
|
+
aggregable: false,
|
|
55
|
+
groupable: false,
|
|
56
|
+
filterable: false,
|
|
57
|
+
hideable: false,
|
|
58
|
+
editable: false,
|
|
59
|
+
disableReorder: true
|
|
60
|
+
});
|
|
61
|
+
const pivotFieldName = newColumnDef.field;
|
|
62
|
+
newColumns[pivotFieldName] = newColumnDef;
|
|
63
|
+
aggregationModel[pivotFieldName] = pivotValue.aggFunc;
|
|
64
|
+
|
|
65
|
+
// Build column grouping model
|
|
66
|
+
const combinedPathValues = [...columnPathValues, pivotValue.field].map((path, index) => typeof path === 'string' ? path : apiRef.current.getRowValue(path, initialColumns.get(visiblePivotColumns[index].field)));
|
|
67
|
+
columnGroupPathValues.push({
|
|
68
|
+
field: pivotFieldName,
|
|
69
|
+
pathValues: combinedPathValues.slice(0, -1),
|
|
70
|
+
pathValuesRaw: columnPathValues
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Build the hierarchy for column groups
|
|
74
|
+
for (let i = 0; i < combinedPathValues.length - 1; i += 1) {
|
|
75
|
+
const currentField = visiblePivotColumns[i].field;
|
|
76
|
+
const groupPath = combinedPathValues.slice(0, i + 1);
|
|
77
|
+
const groupId = groupPath.join('-');
|
|
78
|
+
let headerName = columnPathValues[groupPath.length - 1];
|
|
79
|
+
if (typeof headerName !== 'string') {
|
|
80
|
+
headerName = apiRef.current.getRowFormattedValue(headerName, initialColumns.get(currentField));
|
|
81
|
+
}
|
|
82
|
+
if (typeof headerName === 'number') {
|
|
83
|
+
headerName = String(headerName);
|
|
84
|
+
}
|
|
85
|
+
if (typeof headerName !== 'string') {
|
|
86
|
+
throw new Error(`MUI X: Header name for a column group based on ${currentField} cannot be converted to a string.`);
|
|
87
|
+
}
|
|
88
|
+
if (!columnGroupingModelLookup.has(groupId)) {
|
|
89
|
+
const columnGroup = {
|
|
90
|
+
groupId,
|
|
91
|
+
headerName,
|
|
92
|
+
children: []
|
|
93
|
+
};
|
|
94
|
+
columnGroupingModelLookup.set(groupId, columnGroup);
|
|
95
|
+
if (i === 0) {
|
|
96
|
+
columnGroupingModel.push(columnGroup);
|
|
97
|
+
} else {
|
|
98
|
+
const parentGroupId = groupPath.slice(0, -1).join('-');
|
|
99
|
+
const parentGroup = columnGroupingModelLookup.get(parentGroupId);
|
|
100
|
+
if (parentGroup) {
|
|
101
|
+
parentGroup.children.push(columnGroup);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Add the final column to the appropriate group
|
|
108
|
+
const parentGroupId = combinedPathValues.slice(0, -1).join('-');
|
|
109
|
+
const parentGroup = columnGroupingModelLookup.get(parentGroupId);
|
|
110
|
+
if (parentGroup) {
|
|
111
|
+
parentGroup.children.push({
|
|
112
|
+
field: pivotFieldName
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
for (let i = visiblePivotColumns.length - 1; i >= 0; i -= 1) {
|
|
118
|
+
const sort = visiblePivotColumns[i].sort;
|
|
119
|
+
if (!sort) {
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
columnGroupPathValues.sort((a, b) => {
|
|
123
|
+
// Do not sort values that are returned as strings
|
|
124
|
+
if (typeof a.pathValuesRaw[i] === 'string' && typeof b.pathValuesRaw[i] === 'string') {
|
|
125
|
+
return 0;
|
|
126
|
+
}
|
|
127
|
+
return (sort === 'asc' ? 1 : -1) * gridStringOrNumberComparator(a.pathValues[i], b.pathValues[i], {}, {});
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
if (visiblePivotColumns.length > 0) {
|
|
131
|
+
for (let i = 0; i < columnGroupPathValues.length; i += 1) {
|
|
132
|
+
columns.push(newColumns[columnGroupPathValues[i].field]);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
columns,
|
|
137
|
+
columnGroupingModel,
|
|
138
|
+
aggregationModel
|
|
139
|
+
};
|
|
140
|
+
};
|
|
@@ -3,4 +3,5 @@ export * from "./rowGrouping/index.js";
|
|
|
3
3
|
export * from "./export/index.js";
|
|
4
4
|
export * from "./cellSelection/index.js";
|
|
5
5
|
export * from "./aiAssistant/index.js";
|
|
6
|
-
export * from "./sidebar/index.js";
|
|
6
|
+
export * from "./sidebar/index.js";
|
|
7
|
+
export * from "./pivoting/index.js";
|
|
@@ -4,4 +4,5 @@ export * from "./rowGrouping/index.js";
|
|
|
4
4
|
export * from "./export/index.js";
|
|
5
5
|
export * from "./cellSelection/index.js";
|
|
6
6
|
export * from "./aiAssistant/index.js";
|
|
7
|
-
export * from "./sidebar/index.js";
|
|
7
|
+
export * from "./sidebar/index.js";
|
|
8
|
+
export * from "./pivoting/index.js";
|
|
@@ -3,22 +3,25 @@ import type { GridPivotingPrivateApiCommunity, GridPivotingStatePartial } from '
|
|
|
3
3
|
import type { RefObject } from '@mui/x-internals/types';
|
|
4
4
|
import type { DataGridPremiumProcessedProps } from "../../../models/dataGridPremiumProps.js";
|
|
5
5
|
import type { GridInitialStatePremium } from "../../../models/gridStatePremium.js";
|
|
6
|
-
export type
|
|
7
|
-
|
|
6
|
+
export type GridPivotingStaticPropsOverrides = {
|
|
7
|
+
rowGroupingModel: DataGridPremiumProcessedProps['rowGroupingModel'];
|
|
8
|
+
getAggregationPosition: DataGridPremiumProcessedProps['getAggregationPosition'];
|
|
9
|
+
columnVisibilityModel: DataGridPremiumProcessedProps['columnVisibilityModel'];
|
|
10
|
+
groupingColDef: DataGridPremiumProcessedProps['groupingColDef'];
|
|
11
|
+
headerFilters: DataGridPremiumProcessedProps['headerFilters'];
|
|
12
|
+
disableAggregation: DataGridPremiumProcessedProps['disableAggregation'];
|
|
13
|
+
disableRowGrouping: DataGridPremiumProcessedProps['disableRowGrouping'];
|
|
14
|
+
};
|
|
15
|
+
export type GridPivotingDynamicPropsOverrides = {
|
|
16
|
+
rows?: DataGridPremiumProcessedProps['rows'];
|
|
8
17
|
columns: DataGridPremiumProcessedProps['columns'];
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
getAggregationPosition: NonNullable<DataGridPremiumProcessedProps['getAggregationPosition']>;
|
|
12
|
-
columnVisibilityModel: NonNullable<DataGridPremiumProcessedProps['columnVisibilityModel']>;
|
|
13
|
-
columnGroupingModel: NonNullable<DataGridPremiumProcessedProps['columnGroupingModel']>;
|
|
14
|
-
groupingColDef: NonNullable<DataGridPremiumProcessedProps['groupingColDef']>;
|
|
15
|
-
headerFilters: NonNullable<DataGridPremiumProcessedProps['headerFilters']>;
|
|
16
|
-
disableAggregation: NonNullable<DataGridPremiumProcessedProps['disableAggregation']>;
|
|
17
|
-
disableRowGrouping: NonNullable<DataGridPremiumProcessedProps['disableRowGrouping']>;
|
|
18
|
+
aggregationModel: DataGridPremiumProcessedProps['aggregationModel'];
|
|
19
|
+
columnGroupingModel: DataGridPremiumProcessedProps['columnGroupingModel'];
|
|
18
20
|
};
|
|
21
|
+
export type GridPivotingPropsOverrides = GridPivotingStaticPropsOverrides & GridPivotingDynamicPropsOverrides;
|
|
19
22
|
export interface GridPivotingState extends GridPivotingStatePartial {
|
|
20
23
|
model: GridPivotModel;
|
|
21
|
-
propsOverrides: GridPivotingPropsOverrides | undefined;
|
|
24
|
+
propsOverrides: GridPivotingPropsOverrides | GridPivotingStaticPropsOverrides | {} | undefined;
|
|
22
25
|
}
|
|
23
26
|
export interface GridPivotingInitialState {
|
|
24
27
|
model?: GridPivotModel;
|
|
@@ -73,7 +76,14 @@ export interface GridPivotingPrivateApi extends GridPivotingPrivateApiCommunity
|
|
|
73
76
|
targetFieldPosition?: DropPosition;
|
|
74
77
|
}) => void;
|
|
75
78
|
}
|
|
76
|
-
export type GridPivotingColDefOverrides = Pick<GridColDef, 'width' | 'flex' | 'headerName' | 'description' | 'align' | 'headerAlign' | 'cellClassName' | 'headerClassName' | 'display' | 'maxWidth' | 'minWidth' | 'resizable' | 'sortingOrder'>;
|
|
79
|
+
export type GridPivotingColDefOverrides = Pick<GridColDef, 'field' | 'width' | 'flex' | 'headerName' | 'description' | 'align' | 'headerAlign' | 'cellClassName' | 'headerClassName' | 'display' | 'maxWidth' | 'minWidth' | 'resizable' | 'sortingOrder'>;
|
|
80
|
+
/**
|
|
81
|
+
* The column definition overrides callback for the columns generated by the pivoting feature.
|
|
82
|
+
* @param {string} originalColumnField The field of the original column.
|
|
83
|
+
* @param {string[]} columnGroupPath The path of the column groups the column belongs to.
|
|
84
|
+
* @returns {Partial<GridPivotingColDefOverrides> | undefined | void} The column definition overrides.
|
|
85
|
+
*/
|
|
86
|
+
export type PivotingColDefCallback = (originalColumnField: GridColDef['field'], columnGroupPath: string[]) => Partial<GridPivotingColDefOverrides> | undefined;
|
|
77
87
|
export interface GridPivotingInternalCache {
|
|
78
88
|
nonPivotDataRef: RefObject<{
|
|
79
89
|
rows: GridRowModel[];
|
|
@@ -7,5 +7,5 @@ export declare const gridPivotModelSelector: (args_0: import("react").RefObject<
|
|
|
7
7
|
} | null>) => import("./gridPivotingInterfaces.js").GridPivotModel;
|
|
8
8
|
export declare const gridPivotPropsOverridesSelector: (args_0: import("react").RefObject<{
|
|
9
9
|
state: GridStatePremium;
|
|
10
|
-
} | null>) =>
|
|
10
|
+
} | null>) => {} | undefined;
|
|
11
11
|
export { gridPivotActiveSelector, gridPivotInitialColumnsSelector } from '@mui/x-data-grid/internals';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { gridPivotModelSelector } from "./gridPivotingSelectors.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { gridPivotModelSelector } from "./gridPivotingSelectors.js";
|
|
@@ -4,5 +4,5 @@ import { GridStateInitializer } from '@mui/x-data-grid-pro/internals';
|
|
|
4
4
|
import type { DataGridPremiumProcessedProps } from "../../../models/dataGridPremiumProps.js";
|
|
5
5
|
import { GridPrivateApiPremium } from "../../../models/gridApiPremium.js";
|
|
6
6
|
export declare const pivotingStateInitializer: GridStateInitializer<Pick<DataGridPremiumProcessedProps, 'pivotActive' | 'pivotModel' | 'pivotPanelOpen' | 'initialState' | 'disablePivoting' | 'getPivotDerivedColumns' | 'columns'>, GridPrivateApiPremium>;
|
|
7
|
-
export declare const useGridPivoting: (apiRef: RefObject<GridPrivateApiPremium>, props: Pick<DataGridPremiumProcessedProps, "pivotActive" | "onPivotActiveChange" | "pivotModel" | "onPivotModelChange" | "pivotPanelOpen" | "onPivotPanelOpenChange" | "disablePivoting" | "getPivotDerivedColumns" | "pivotingColDef" | "groupingColDef" | "aggregationFunctions">, originalColumnsProp: readonly GridColDef[], originalRowsProp: readonly GridRowModel[]) => void;
|
|
7
|
+
export declare const useGridPivoting: (apiRef: RefObject<GridPrivateApiPremium>, props: Pick<DataGridPremiumProcessedProps, "pivotActive" | "onPivotActiveChange" | "pivotModel" | "onPivotModelChange" | "pivotPanelOpen" | "onPivotPanelOpenChange" | "disablePivoting" | "getPivotDerivedColumns" | "pivotingColDef" | "groupingColDef" | "aggregationFunctions" | "loading" | "dataSource">, originalColumnsProp: readonly GridColDef[], originalRowsProp: readonly GridRowModel[]) => void;
|
|
8
8
|
export declare const useGridPivotingExportState: (apiRef: RefObject<GridPrivateApiPremium>) => void;
|
|
@@ -6,7 +6,7 @@ import useOnMount from '@mui/utils/useOnMount';
|
|
|
6
6
|
import { useGridApiMethod, useGridRegisterPipeProcessor, useGridSelector, gridPivotInitialColumnsSelector } from '@mui/x-data-grid-pro/internals';
|
|
7
7
|
import { GridPivotPanel } from "../../../components/pivotPanel/index.js";
|
|
8
8
|
import { gridPivotModelSelector, gridPivotActiveSelector, gridPivotPanelOpenSelector } from "./gridPivotingSelectors.js";
|
|
9
|
-
import { getInitialColumns,
|
|
9
|
+
import { getInitialColumns, getPivotForcedProps, createPivotPropsFromRows } from "./utils.js";
|
|
10
10
|
import { getAvailableAggregationFunctions } from "../aggregation/gridAggregationUtils.js";
|
|
11
11
|
import { GridSidebarValue } from "../sidebar/index.js";
|
|
12
12
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
@@ -24,7 +24,7 @@ export const pivotingStateInitializer = (state, props, apiRef) => {
|
|
|
24
24
|
current: undefined
|
|
25
25
|
}
|
|
26
26
|
};
|
|
27
|
-
if (
|
|
27
|
+
if (props.disablePivoting) {
|
|
28
28
|
return _extends({}, state, {
|
|
29
29
|
pivoting: {
|
|
30
30
|
active: false,
|
|
@@ -49,11 +49,12 @@ export const pivotingStateInitializer = (state, props, apiRef) => {
|
|
|
49
49
|
};
|
|
50
50
|
export const useGridPivoting = (apiRef, props, originalColumnsProp, originalRowsProp) => {
|
|
51
51
|
const isPivotActive = useGridSelector(apiRef, gridPivotActiveSelector);
|
|
52
|
+
const isLoading = props.loading ?? gridRowsLoadingSelector(apiRef);
|
|
52
53
|
const {
|
|
53
54
|
exportedStateRef,
|
|
54
55
|
nonPivotDataRef
|
|
55
56
|
} = apiRef.current.caches.pivoting;
|
|
56
|
-
const isPivotingAvailable =
|
|
57
|
+
const isPivotingAvailable = !props.disablePivoting;
|
|
57
58
|
apiRef.current.registerControlState({
|
|
58
59
|
stateId: 'pivotModel',
|
|
59
60
|
propModel: props.pivotModel,
|
|
@@ -79,16 +80,19 @@ export const useGridPivoting = (apiRef, props, originalColumnsProp, originalRows
|
|
|
79
80
|
if (!exportedStateRef.current) {
|
|
80
81
|
exportedStateRef.current = apiRef.current.exportState();
|
|
81
82
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
let rows = [];
|
|
84
|
+
if (!props.dataSource) {
|
|
85
|
+
const rowIds = gridDataRowIdsSelector(apiRef);
|
|
86
|
+
const rowsLookup = gridRowsLookupSelector(apiRef);
|
|
87
|
+
rows = rowIds.map(id => rowsLookup[id]);
|
|
88
|
+
}
|
|
85
89
|
const initialColumns = getInitialColumns(originalColumnsProp, props.getPivotDerivedColumns, apiRef.current.getLocaleText);
|
|
86
90
|
return {
|
|
87
91
|
rows,
|
|
88
92
|
columns: initialColumns,
|
|
89
93
|
originalRowsProp
|
|
90
94
|
};
|
|
91
|
-
}, [apiRef, props.getPivotDerivedColumns, originalColumnsProp, originalRowsProp, exportedStateRef]);
|
|
95
|
+
}, [apiRef, props.getPivotDerivedColumns, originalColumnsProp, originalRowsProp, exportedStateRef, props.dataSource]);
|
|
92
96
|
const computePivotingState = React.useCallback(({
|
|
93
97
|
active,
|
|
94
98
|
model: pivotModel
|
|
@@ -101,32 +105,39 @@ export const useGridPivoting = (apiRef, props, originalColumnsProp, originalRows
|
|
|
101
105
|
rows: [],
|
|
102
106
|
columns: new Map()
|
|
103
107
|
};
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
+
let propsOverrides = getPivotForcedProps(pivotModel, columns, props.groupingColDef);
|
|
109
|
+
|
|
110
|
+
// without data source, add more props overrides based on the data
|
|
111
|
+
if (!isLoading && !props.dataSource) {
|
|
112
|
+
propsOverrides = _extends({}, propsOverrides, createPivotPropsFromRows({
|
|
108
113
|
rows,
|
|
109
114
|
columns,
|
|
110
115
|
pivotModel,
|
|
111
|
-
apiRef: apiRef,
|
|
112
116
|
pivotingColDef: props.pivotingColDef,
|
|
113
|
-
|
|
114
|
-
})
|
|
117
|
+
apiRef
|
|
118
|
+
}));
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
initialColumns: columns,
|
|
122
|
+
propsOverrides
|
|
115
123
|
};
|
|
116
124
|
}
|
|
117
|
-
return
|
|
118
|
-
}, [apiRef, props.pivotingColDef, props.groupingColDef, nonPivotDataRef]);
|
|
125
|
+
return {};
|
|
126
|
+
}, [apiRef, isLoading, props.dataSource, props.pivotingColDef, props.groupingColDef, nonPivotDataRef]);
|
|
119
127
|
useOnMount(() => {
|
|
120
128
|
if (!isPivotingAvailable || !isPivotActive) {
|
|
121
129
|
return undefined;
|
|
122
130
|
}
|
|
123
131
|
nonPivotDataRef.current = getInitialData();
|
|
124
|
-
const isLoading = gridRowsLoadingSelector(apiRef) ?? false;
|
|
125
|
-
if (isLoading) {
|
|
126
|
-
return undefined;
|
|
127
|
-
}
|
|
128
132
|
apiRef.current.setState(state => {
|
|
129
|
-
const
|
|
133
|
+
const {
|
|
134
|
+
initialColumns,
|
|
135
|
+
propsOverrides
|
|
136
|
+
} = computePivotingState(state.pivoting);
|
|
137
|
+
const pivotingState = _extends({}, state.pivoting, {
|
|
138
|
+
initialColumns: initialColumns || state.pivoting.initialColumns,
|
|
139
|
+
propsOverrides: _extends({}, state.pivoting.propsOverrides, propsOverrides)
|
|
140
|
+
});
|
|
130
141
|
return _extends({}, state, {
|
|
131
142
|
pivoting: pivotingState
|
|
132
143
|
});
|
|
@@ -156,9 +167,15 @@ export const useGridPivoting = (apiRef, props, originalColumnsProp, originalRows
|
|
|
156
167
|
if (state.pivoting?.model === newPivotModel) {
|
|
157
168
|
return state;
|
|
158
169
|
}
|
|
159
|
-
const
|
|
170
|
+
const {
|
|
171
|
+
initialColumns,
|
|
172
|
+
propsOverrides
|
|
173
|
+
} = computePivotingState(_extends({}, state.pivoting, {
|
|
160
174
|
model: newPivotModel
|
|
161
|
-
}))
|
|
175
|
+
}));
|
|
176
|
+
const newPivotingState = _extends({}, state.pivoting, {
|
|
177
|
+
initialColumns: initialColumns || state.pivoting.initialColumns,
|
|
178
|
+
propsOverrides: _extends({}, state.pivoting.propsOverrides, propsOverrides),
|
|
162
179
|
model: newPivotModel
|
|
163
180
|
});
|
|
164
181
|
return _extends({}, state, {
|
|
@@ -198,7 +215,7 @@ export const useGridPivoting = (apiRef, props, originalColumnsProp, originalRows
|
|
|
198
215
|
const aggFunc = isSameSection ? prev.values.find(item => item.field === field)?.aggFunc : getAvailableAggregationFunctions({
|
|
199
216
|
aggregationFunctions: props.aggregationFunctions,
|
|
200
217
|
colDef: initialColumns.get(field),
|
|
201
|
-
isDataSource:
|
|
218
|
+
isDataSource: !!props.dataSource
|
|
202
219
|
})[0];
|
|
203
220
|
newSectionArray.splice(toIndex, 0, {
|
|
204
221
|
field,
|
|
@@ -227,7 +244,7 @@ export const useGridPivoting = (apiRef, props, originalColumnsProp, originalRows
|
|
|
227
244
|
}
|
|
228
245
|
return newModel;
|
|
229
246
|
});
|
|
230
|
-
}, [apiRef, props.aggregationFunctions]);
|
|
247
|
+
}, [apiRef, props.aggregationFunctions, props.dataSource]);
|
|
231
248
|
const setPivotActive = React.useCallback(callback => {
|
|
232
249
|
if (!isPivotingAvailable) {
|
|
233
250
|
return;
|
|
@@ -240,9 +257,15 @@ export const useGridPivoting = (apiRef, props, originalColumnsProp, originalRows
|
|
|
240
257
|
if (newPivotMode) {
|
|
241
258
|
nonPivotDataRef.current = getInitialData();
|
|
242
259
|
}
|
|
243
|
-
const
|
|
260
|
+
const {
|
|
261
|
+
initialColumns,
|
|
262
|
+
propsOverrides
|
|
263
|
+
} = computePivotingState(_extends({}, state.pivoting, {
|
|
244
264
|
active: newPivotMode
|
|
245
|
-
}))
|
|
265
|
+
}));
|
|
266
|
+
const newPivotingState = _extends({}, state.pivoting, {
|
|
267
|
+
initialColumns: initialColumns || state.pivoting.initialColumns,
|
|
268
|
+
propsOverrides: _extends({}, state.pivoting.propsOverrides, propsOverrides),
|
|
246
269
|
active: newPivotMode
|
|
247
270
|
});
|
|
248
271
|
const newState = _extends({}, state, {
|
|
@@ -286,15 +309,19 @@ export const useGridPivoting = (apiRef, props, originalColumnsProp, originalRows
|
|
|
286
309
|
nonPivotDataRef.current.columns = getInitialColumns(columns, props.getPivotDerivedColumns, apiRef.current.getLocaleText);
|
|
287
310
|
}
|
|
288
311
|
apiRef.current.setState(state => {
|
|
312
|
+
const {
|
|
313
|
+
propsOverrides
|
|
314
|
+
} = computePivotingState(state.pivoting);
|
|
289
315
|
return _extends({}, state, {
|
|
290
|
-
pivoting: _extends({}, state.pivoting,
|
|
291
|
-
initialColumns: nonPivotDataRef.current?.columns
|
|
316
|
+
pivoting: _extends({}, state.pivoting, {
|
|
317
|
+
initialColumns: nonPivotDataRef.current?.columns,
|
|
318
|
+
propsOverrides: _extends({}, state.pivoting.propsOverrides, propsOverrides)
|
|
292
319
|
})
|
|
293
320
|
});
|
|
294
321
|
});
|
|
295
322
|
}, [isPivotingAvailable, apiRef, props.getPivotDerivedColumns, computePivotingState, nonPivotDataRef]);
|
|
296
323
|
const updateNonPivotRows = React.useCallback((rows, keepPreviousRows = true) => {
|
|
297
|
-
if (!nonPivotDataRef.current || !isPivotingAvailable || !rows || rows.length === 0) {
|
|
324
|
+
if (!nonPivotDataRef.current || props.dataSource || !isPivotingAvailable || !rows || rows.length === 0) {
|
|
298
325
|
return;
|
|
299
326
|
}
|
|
300
327
|
if (keepPreviousRows) {
|
|
@@ -316,18 +343,42 @@ export const useGridPivoting = (apiRef, props, originalColumnsProp, originalRows
|
|
|
316
343
|
nonPivotDataRef.current.rows = rows;
|
|
317
344
|
}
|
|
318
345
|
apiRef.current.setState(state => {
|
|
346
|
+
const {
|
|
347
|
+
initialColumns,
|
|
348
|
+
propsOverrides
|
|
349
|
+
} = computePivotingState(state.pivoting);
|
|
319
350
|
return _extends({}, state, {
|
|
320
|
-
pivoting: _extends({}, state.pivoting,
|
|
351
|
+
pivoting: _extends({}, state.pivoting, {
|
|
352
|
+
initialColumns: initialColumns || state.pivoting.initialColumns,
|
|
353
|
+
propsOverrides: _extends({}, state.pivoting.propsOverrides, propsOverrides)
|
|
354
|
+
})
|
|
321
355
|
});
|
|
322
356
|
});
|
|
323
|
-
}, [apiRef, computePivotingState, isPivotingAvailable, nonPivotDataRef]);
|
|
357
|
+
}, [apiRef, computePivotingState, isPivotingAvailable, nonPivotDataRef, props.dataSource]);
|
|
324
358
|
const addPivotingPanel = React.useCallback((initialValue, value) => {
|
|
325
359
|
if (isPivotingAvailable && value === GridSidebarValue.Pivot) {
|
|
326
360
|
return /*#__PURE__*/_jsx(GridPivotPanel, {});
|
|
327
361
|
}
|
|
328
362
|
return initialValue;
|
|
329
363
|
}, [isPivotingAvailable]);
|
|
364
|
+
const addGetRowsParams = React.useCallback(params => {
|
|
365
|
+
if (!isPivotingAvailable || !isPivotActive) {
|
|
366
|
+
return params;
|
|
367
|
+
}
|
|
368
|
+
const pivotModel = gridPivotModelSelector(apiRef);
|
|
369
|
+
const visibleColumns = pivotModel.columns.filter(column => !column.hidden);
|
|
370
|
+
const visibleRows = pivotModel.rows.filter(row => !row.hidden);
|
|
371
|
+
const visibleValues = pivotModel.values.filter(value => !value.hidden);
|
|
372
|
+
return _extends({}, params, {
|
|
373
|
+
pivotModel: {
|
|
374
|
+
columns: visibleColumns,
|
|
375
|
+
rows: visibleRows,
|
|
376
|
+
values: visibleValues
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
}, [apiRef, isPivotingAvailable, isPivotActive]);
|
|
330
380
|
useGridRegisterPipeProcessor(apiRef, 'sidebar', addPivotingPanel);
|
|
381
|
+
useGridRegisterPipeProcessor(apiRef, 'getRowsParams', addGetRowsParams);
|
|
331
382
|
useGridApiMethod(apiRef, {
|
|
332
383
|
setPivotModel,
|
|
333
384
|
setPivotActive,
|
|
@@ -2,22 +2,20 @@ import { GridColDef, GridRowModel, GridLocaleTextApi } from '@mui/x-data-grid-pr
|
|
|
2
2
|
import type { RefObject } from '@mui/x-internals/types';
|
|
3
3
|
import type { DataGridPremiumProcessedProps } from "../../../models/dataGridPremiumProps.js";
|
|
4
4
|
import type { GridApiPremium } from "../../../models/gridApiPremium.js";
|
|
5
|
-
import type {
|
|
6
|
-
export declare const
|
|
7
|
-
export declare const defaultGetPivotDerivedColumns: DataGridPremiumProcessedProps['getPivotDerivedColumns'];
|
|
5
|
+
import type { GridPivotingStaticPropsOverrides, GridPivotingDynamicPropsOverrides, GridPivotModel } from "./gridPivotingInterfaces.js";
|
|
6
|
+
export declare const defaultGetPivotDerivedColumns: NonNullable<DataGridPremiumProcessedProps['getPivotDerivedColumns']>;
|
|
8
7
|
export declare const getInitialColumns: (originalColumns: DataGridPremiumProcessedProps["columns"], getPivotDerivedColumns: DataGridPremiumProcessedProps["getPivotDerivedColumns"], getLocaleText: GridLocaleTextApi["getLocaleText"]) => Map<string, GridColDef>;
|
|
9
|
-
export declare const
|
|
8
|
+
export declare const getPivotForcedProps: (pivotModel: GridPivotModel, columns: Map<string, GridColDef>, groupingColDef: DataGridPremiumProcessedProps["groupingColDef"]) => GridPivotingStaticPropsOverrides;
|
|
9
|
+
export declare const createPivotPropsFromRows: ({
|
|
10
10
|
rows,
|
|
11
11
|
columns,
|
|
12
12
|
pivotModel,
|
|
13
|
-
apiRef,
|
|
14
13
|
pivotingColDef,
|
|
15
|
-
|
|
14
|
+
apiRef
|
|
16
15
|
}: {
|
|
17
16
|
rows: GridRowModel[];
|
|
18
17
|
columns: Map<string, GridColDef>;
|
|
19
18
|
pivotModel: GridPivotModel;
|
|
20
|
-
apiRef: RefObject<GridApiPremium>;
|
|
21
19
|
pivotingColDef: DataGridPremiumProcessedProps["pivotingColDef"];
|
|
22
|
-
|
|
23
|
-
}) =>
|
|
20
|
+
apiRef: RefObject<GridApiPremium>;
|
|
21
|
+
}) => GridPivotingDynamicPropsOverrides;
|
|
@@ -4,9 +4,6 @@ import { getDefaultColTypeDef } from '@mui/x-data-grid-pro/internals';
|
|
|
4
4
|
import { COLUMN_GROUP_ID_SEPARATOR } from "../../../constants/columnGroups.js";
|
|
5
5
|
import { isGroupingColumn } from "../rowGrouping/index.js";
|
|
6
6
|
import { defaultGetAggregationPosition } from "../aggregation/gridAggregationUtils.js";
|
|
7
|
-
export const isPivotingAvailable = props => {
|
|
8
|
-
return !props.disablePivoting;
|
|
9
|
-
};
|
|
10
7
|
export const defaultGetPivotDerivedColumns = (column, getLocaleText) => {
|
|
11
8
|
if (column.type === 'date') {
|
|
12
9
|
const field = column.field;
|
|
@@ -39,11 +36,17 @@ export const getInitialColumns = (originalColumns, getPivotDerivedColumns, getLo
|
|
|
39
36
|
}
|
|
40
37
|
return initialColumns;
|
|
41
38
|
};
|
|
42
|
-
|
|
39
|
+
const sortColumnGroups = (columnGroups, pivotModelColumns, depth = 0) => {
|
|
43
40
|
if (depth > pivotModelColumns.length - 1) {
|
|
44
41
|
return;
|
|
45
42
|
}
|
|
46
43
|
const sort = pivotModelColumns[depth].sort;
|
|
44
|
+
if (columnGroups.length < 2) {
|
|
45
|
+
if (columnGroups[0]?.children) {
|
|
46
|
+
sortColumnGroups(columnGroups[0].children, pivotModelColumns, depth + 1);
|
|
47
|
+
}
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
47
50
|
columnGroups.sort((a, b) => {
|
|
48
51
|
if (isLeaf(a) || isLeaf(b)) {
|
|
49
52
|
return 0;
|
|
@@ -59,20 +62,46 @@ function sortColumnGroups(columnGroups, pivotModelColumns, depth = 0) {
|
|
|
59
62
|
}
|
|
60
63
|
return (sort === 'asc' ? 1 : -1) * gridStringOrNumberComparator(a.rawHeaderName, b.rawHeaderName, {}, {});
|
|
61
64
|
});
|
|
62
|
-
}
|
|
63
|
-
export const
|
|
65
|
+
};
|
|
66
|
+
export const getPivotForcedProps = (pivotModel, columns, groupingColDef) => {
|
|
67
|
+
const visibleRows = pivotModel.rows.filter(row => !row.hidden);
|
|
68
|
+
const visibleColumns = pivotModel.columns.filter(column => !column.hidden);
|
|
69
|
+
const visibleValues = pivotModel.values.filter(value => !value.hidden);
|
|
70
|
+
const columnVisibilityModel = {};
|
|
71
|
+
for (const column of columns.values()) {
|
|
72
|
+
columnVisibilityModel[column.field] = false;
|
|
73
|
+
}
|
|
74
|
+
if (visibleColumns.length === 0) {
|
|
75
|
+
visibleValues.forEach(value => {
|
|
76
|
+
delete columnVisibilityModel[value.field];
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
const groupingColDefOverrides = params => _extends({}, typeof groupingColDef === 'function' ? groupingColDef(params) : groupingColDef || {}, {
|
|
80
|
+
filterable: false,
|
|
81
|
+
aggregable: false,
|
|
82
|
+
hideable: false
|
|
83
|
+
});
|
|
84
|
+
return {
|
|
85
|
+
columnVisibilityModel,
|
|
86
|
+
rowGroupingModel: visibleRows.map(row => row.field),
|
|
87
|
+
getAggregationPosition: defaultGetAggregationPosition,
|
|
88
|
+
groupingColDef: groupingColDefOverrides,
|
|
89
|
+
headerFilters: false,
|
|
90
|
+
disableAggregation: false,
|
|
91
|
+
disableRowGrouping: false
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
export const createPivotPropsFromRows = ({
|
|
64
95
|
rows,
|
|
65
96
|
columns,
|
|
66
97
|
pivotModel,
|
|
67
|
-
apiRef,
|
|
68
98
|
pivotingColDef,
|
|
69
|
-
|
|
99
|
+
apiRef
|
|
70
100
|
}) => {
|
|
71
101
|
const visibleColumns = pivotModel.columns.filter(column => !column.hidden);
|
|
72
102
|
const visibleRows = pivotModel.rows.filter(row => !row.hidden);
|
|
73
103
|
const visibleValues = pivotModel.values.filter(value => !value.hidden);
|
|
74
104
|
let pivotColumns = [];
|
|
75
|
-
const columnVisibilityModel = {};
|
|
76
105
|
const pivotColumnsIncludedInPivotValues = [];
|
|
77
106
|
const initialColumns = new Map();
|
|
78
107
|
for (const column of columns.values()) {
|
|
@@ -96,7 +125,6 @@ export const getPivotedData = ({
|
|
|
96
125
|
} else {
|
|
97
126
|
pivotColumns.push(columnToAdd);
|
|
98
127
|
}
|
|
99
|
-
columnVisibilityModel[column.field] = false;
|
|
100
128
|
}
|
|
101
129
|
}
|
|
102
130
|
pivotColumns = pivotColumns.concat(pivotColumnsIncludedInPivotValues);
|
|
@@ -124,7 +152,6 @@ export const getPivotedData = ({
|
|
|
124
152
|
newRows = rows;
|
|
125
153
|
visibleValues.forEach(pivotValue => {
|
|
126
154
|
aggregationModel[pivotValue.field] = pivotValue.aggFunc;
|
|
127
|
-
delete columnVisibilityModel[pivotValue.field];
|
|
128
155
|
});
|
|
129
156
|
} else {
|
|
130
157
|
for (let i = 0; i < rows.length; i += 1) {
|
|
@@ -250,22 +277,10 @@ export const getPivotedData = ({
|
|
|
250
277
|
}
|
|
251
278
|
}
|
|
252
279
|
createColumns(columnGroupingModel);
|
|
253
|
-
const groupingColDefOverrides = params => _extends({}, typeof groupingColDef === 'function' ? groupingColDef(params) : groupingColDef || {}, {
|
|
254
|
-
filterable: false,
|
|
255
|
-
aggregable: false,
|
|
256
|
-
hideable: false
|
|
257
|
-
});
|
|
258
280
|
return {
|
|
259
281
|
rows: visibleRows.length > 0 ? newRows : [],
|
|
260
282
|
columns: pivotColumns,
|
|
261
|
-
rowGroupingModel: visibleRows.map(row => row.field),
|
|
262
|
-
aggregationModel,
|
|
263
|
-
getAggregationPosition: defaultGetAggregationPosition,
|
|
264
|
-
columnVisibilityModel,
|
|
265
283
|
columnGroupingModel,
|
|
266
|
-
|
|
267
|
-
headerFilters: false,
|
|
268
|
-
disableAggregation: false,
|
|
269
|
-
disableRowGrouping: false
|
|
284
|
+
aggregationModel
|
|
270
285
|
};
|
|
271
286
|
};
|
|
@@ -83,7 +83,7 @@ function getGroupingCriteriaProperties(groupedByColDef, rowGroupingColumnMode, r
|
|
|
83
83
|
valueFormatter = (value, row, column, apiRef) => {
|
|
84
84
|
const rowId = gridRowIdSelector(apiRef, row);
|
|
85
85
|
const rowNode = gridRowNodeSelector(apiRef, rowId);
|
|
86
|
-
if (rowNode
|
|
86
|
+
if (rowNode?.type === 'group') {
|
|
87
87
|
const originalColDef = columnsLookup[rowNode.groupingField];
|
|
88
88
|
if (originalColDef.type === 'singleSelect') {
|
|
89
89
|
// the default valueFormatter of a singleSelect colDef won't work with the grouping column values
|