@mui/x-data-grid-premium 5.13.1 → 5.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.
Files changed (122) hide show
  1. package/CHANGELOG.md +44 -1
  2. package/DataGridPremium/DataGridPremium.js +47 -0
  3. package/DataGridPremium/useDataGridPremiumComponent.js +6 -1
  4. package/DataGridPremium/useDataGridPremiumProps.js +17 -7
  5. package/components/GridAggregationColumnMenuItem.d.ts +9 -0
  6. package/components/GridAggregationColumnMenuItem.js +93 -0
  7. package/components/GridAggregationHeader.d.ts +4 -0
  8. package/components/GridAggregationHeader.js +94 -0
  9. package/components/GridExcelExportMenuItem.js +11 -4
  10. package/components/GridFooterCell.d.ts +9 -0
  11. package/components/GridFooterCell.js +51 -0
  12. package/components/GridGroupingColumnFooterCell.d.ts +4 -0
  13. package/components/GridGroupingColumnFooterCell.js +29 -0
  14. package/hooks/features/aggregation/createAggregationLookup.d.ts +10 -0
  15. package/hooks/features/aggregation/createAggregationLookup.js +128 -0
  16. package/hooks/features/aggregation/gridAggregationFunctions.d.ts +8 -0
  17. package/hooks/features/aggregation/gridAggregationFunctions.js +96 -0
  18. package/hooks/features/aggregation/gridAggregationInterfaces.d.ts +104 -0
  19. package/hooks/features/aggregation/gridAggregationInterfaces.js +1 -0
  20. package/hooks/features/aggregation/gridAggregationSelectors.d.ts +4 -0
  21. package/hooks/features/aggregation/gridAggregationSelectors.js +5 -0
  22. package/hooks/features/aggregation/gridAggregationUtils.d.ts +40 -0
  23. package/hooks/features/aggregation/gridAggregationUtils.js +177 -0
  24. package/hooks/features/aggregation/index.d.ts +4 -0
  25. package/hooks/features/aggregation/index.js +4 -0
  26. package/hooks/features/aggregation/useGridAggregation.d.ts +6 -0
  27. package/hooks/features/aggregation/useGridAggregation.js +94 -0
  28. package/hooks/features/aggregation/useGridAggregationPreProcessors.d.ts +4 -0
  29. package/hooks/features/aggregation/useGridAggregationPreProcessors.js +137 -0
  30. package/hooks/features/aggregation/wrapColumnWithAggregation.d.ts +29 -0
  31. package/hooks/features/aggregation/wrapColumnWithAggregation.js +257 -0
  32. package/hooks/features/export/serializer/excelSerializer.js +2 -1
  33. package/hooks/features/index.d.ts +1 -0
  34. package/hooks/features/index.js +1 -0
  35. package/hooks/features/rowGrouping/createGroupingColDef.js +13 -2
  36. package/hooks/features/rowGrouping/gridRowGroupingUtils.js +5 -1
  37. package/hooks/features/rowGrouping/useGridRowGrouping.d.ts +1 -1
  38. package/hooks/features/rowGrouping/useGridRowGrouping.js +20 -10
  39. package/index.js +1 -1
  40. package/legacy/DataGridPremium/DataGridPremium.js +47 -0
  41. package/legacy/DataGridPremium/useDataGridPremiumComponent.js +6 -1
  42. package/legacy/DataGridPremium/useDataGridPremiumProps.js +12 -2
  43. package/legacy/components/GridAggregationColumnMenuItem.js +95 -0
  44. package/legacy/components/GridAggregationHeader.js +95 -0
  45. package/legacy/components/GridExcelExportMenuItem.js +11 -4
  46. package/legacy/components/GridFooterCell.js +63 -0
  47. package/legacy/components/GridGroupingColumnFooterCell.js +27 -0
  48. package/legacy/hooks/features/aggregation/createAggregationLookup.js +127 -0
  49. package/legacy/hooks/features/aggregation/gridAggregationFunctions.js +94 -0
  50. package/legacy/hooks/features/aggregation/gridAggregationInterfaces.js +1 -0
  51. package/legacy/hooks/features/aggregation/gridAggregationSelectors.js +11 -0
  52. package/legacy/hooks/features/aggregation/gridAggregationUtils.js +189 -0
  53. package/legacy/hooks/features/aggregation/index.js +4 -0
  54. package/legacy/hooks/features/aggregation/useGridAggregation.js +95 -0
  55. package/legacy/hooks/features/aggregation/useGridAggregationPreProcessors.js +140 -0
  56. package/legacy/hooks/features/aggregation/wrapColumnWithAggregation.js +262 -0
  57. package/legacy/hooks/features/export/serializer/excelSerializer.js +2 -1
  58. package/legacy/hooks/features/index.js +1 -0
  59. package/legacy/hooks/features/rowGrouping/createGroupingColDef.js +13 -2
  60. package/legacy/hooks/features/rowGrouping/gridRowGroupingUtils.js +5 -1
  61. package/legacy/hooks/features/rowGrouping/useGridRowGrouping.js +24 -10
  62. package/legacy/index.js +1 -1
  63. package/legacy/typeOverloads/index.js +1 -1
  64. package/legacy/utils/releaseInfo.js +1 -1
  65. package/models/dataGridPremiumProps.d.ts +46 -1
  66. package/models/gridApiPremium.d.ts +2 -2
  67. package/models/gridStatePremium.d.ts +3 -1
  68. package/modern/DataGridPremium/DataGridPremium.js +47 -0
  69. package/modern/DataGridPremium/useDataGridPremiumComponent.js +6 -1
  70. package/modern/DataGridPremium/useDataGridPremiumProps.js +8 -2
  71. package/modern/components/GridAggregationColumnMenuItem.js +93 -0
  72. package/modern/components/GridAggregationHeader.js +92 -0
  73. package/modern/components/GridExcelExportMenuItem.js +11 -4
  74. package/modern/components/GridFooterCell.js +51 -0
  75. package/modern/components/GridGroupingColumnFooterCell.js +29 -0
  76. package/modern/hooks/features/aggregation/createAggregationLookup.js +122 -0
  77. package/modern/hooks/features/aggregation/gridAggregationFunctions.js +96 -0
  78. package/modern/hooks/features/aggregation/gridAggregationInterfaces.js +1 -0
  79. package/modern/hooks/features/aggregation/gridAggregationSelectors.js +5 -0
  80. package/modern/hooks/features/aggregation/gridAggregationUtils.js +175 -0
  81. package/modern/hooks/features/aggregation/index.js +4 -0
  82. package/modern/hooks/features/aggregation/useGridAggregation.js +92 -0
  83. package/modern/hooks/features/aggregation/useGridAggregationPreProcessors.js +135 -0
  84. package/modern/hooks/features/aggregation/wrapColumnWithAggregation.js +251 -0
  85. package/modern/hooks/features/export/serializer/excelSerializer.js +2 -1
  86. package/modern/hooks/features/index.js +1 -0
  87. package/modern/hooks/features/rowGrouping/createGroupingColDef.js +13 -2
  88. package/modern/hooks/features/rowGrouping/gridRowGroupingUtils.js +5 -1
  89. package/modern/hooks/features/rowGrouping/useGridRowGrouping.js +17 -11
  90. package/modern/index.js +1 -1
  91. package/modern/typeOverloads/index.js +1 -1
  92. package/modern/utils/releaseInfo.js +1 -1
  93. package/node/DataGridPremium/DataGridPremium.js +47 -0
  94. package/node/DataGridPremium/useDataGridPremiumComponent.js +8 -1
  95. package/node/DataGridPremium/useDataGridPremiumProps.js +17 -6
  96. package/node/components/GridAggregationColumnMenuItem.js +120 -0
  97. package/node/components/GridAggregationHeader.js +115 -0
  98. package/node/components/GridExcelExportMenuItem.js +12 -4
  99. package/node/components/GridFooterCell.js +73 -0
  100. package/node/components/GridGroupingColumnFooterCell.js +46 -0
  101. package/node/hooks/features/aggregation/createAggregationLookup.js +139 -0
  102. package/node/hooks/features/aggregation/gridAggregationFunctions.js +105 -0
  103. package/node/hooks/features/aggregation/gridAggregationInterfaces.js +5 -0
  104. package/node/hooks/features/aggregation/gridAggregationSelectors.js +17 -0
  105. package/node/hooks/features/aggregation/gridAggregationUtils.js +212 -0
  106. package/node/hooks/features/aggregation/index.js +65 -0
  107. package/node/hooks/features/aggregation/useGridAggregation.js +118 -0
  108. package/node/hooks/features/aggregation/useGridAggregationPreProcessors.js +161 -0
  109. package/node/hooks/features/aggregation/wrapColumnWithAggregation.js +279 -0
  110. package/node/hooks/features/export/serializer/excelSerializer.js +2 -1
  111. package/node/hooks/features/index.js +13 -0
  112. package/node/hooks/features/rowGrouping/createGroupingColDef.js +14 -2
  113. package/node/hooks/features/rowGrouping/gridRowGroupingUtils.js +5 -1
  114. package/node/hooks/features/rowGrouping/useGridRowGrouping.js +19 -10
  115. package/node/index.js +1 -1
  116. package/node/typeOverloads/index.js +16 -1
  117. package/node/utils/releaseInfo.js +1 -1
  118. package/package.json +4 -4
  119. package/typeOverloads/index.d.ts +1 -1
  120. package/typeOverloads/index.js +1 -1
  121. package/typeOverloads/modules.d.ts +32 -2
  122. package/utils/releaseInfo.js +1 -1
@@ -0,0 +1,51 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
+ const _excluded = ["formattedValue", "colDef", "cellMode", "row", "api", "getValue", "id", "value", "rowNode", "field", "focusElementRef", "hasFocus", "tabIndex", "isEditable"];
4
+ import * as React from 'react';
5
+ import { getDataGridUtilityClass } from '@mui/x-data-grid';
6
+ import { styled } from '@mui/material/styles';
7
+ import Box from '@mui/material/Box';
8
+ import { unstable_composeClasses as composeClasses } from '@mui/material';
9
+ import { useGridRootProps } from '../hooks/utils/useGridRootProps';
10
+ import { jsx as _jsx } from "react/jsx-runtime";
11
+ const GridFooterCellRoot = styled(Box, {
12
+ name: 'MuiDataGrid',
13
+ slot: 'FooterCell',
14
+ overridesResolver: (_, styles) => styles.footerCell
15
+ })(({
16
+ theme
17
+ }) => ({
18
+ fontWeight: theme.typography.fontWeightMedium,
19
+ color: theme.palette.primary.dark
20
+ }));
21
+
22
+ const useUtilityClasses = ownerState => {
23
+ const {
24
+ classes
25
+ } = ownerState;
26
+ const slots = {
27
+ root: ['footerCell']
28
+ };
29
+ return composeClasses(slots, getDataGridUtilityClass, classes);
30
+ };
31
+
32
+ const GridFooterCell = props => {
33
+ const {
34
+ formattedValue
35
+ } = props,
36
+ other = _objectWithoutPropertiesLoose(props, _excluded);
37
+
38
+ const rootProps = useGridRootProps();
39
+ const ownerState = {
40
+ classes: rootProps.classes
41
+ };
42
+ const classes = useUtilityClasses(ownerState);
43
+ return /*#__PURE__*/_jsx(GridFooterCellRoot, _extends({
44
+ ownerState: ownerState,
45
+ className: classes.root
46
+ }, other, {
47
+ children: formattedValue
48
+ }));
49
+ };
50
+
51
+ export { GridFooterCell };
@@ -0,0 +1,29 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import * as React from 'react';
3
+ import { useGridRootProps } from '../hooks/utils/useGridRootProps';
4
+ import { GridFooterCell } from './GridFooterCell';
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+
7
+ const GridGroupingColumnFooterCell = props => {
8
+ const {
9
+ rowNode
10
+ } = props;
11
+ const rootProps = useGridRootProps();
12
+ let marginLeft;
13
+
14
+ if (rowNode.parent == null) {
15
+ marginLeft = 0;
16
+ } else if (rootProps.rowGroupingColumnMode === 'multiple') {
17
+ marginLeft = 2;
18
+ } else {
19
+ marginLeft = rowNode.depth * 2;
20
+ }
21
+
22
+ return /*#__PURE__*/_jsx(GridFooterCell, _extends({
23
+ sx: {
24
+ ml: marginLeft
25
+ }
26
+ }, props));
27
+ };
28
+
29
+ export { GridGroupingColumnFooterCell };
@@ -0,0 +1,122 @@
1
+ import { gridColumnLookupSelector, gridFilteredRowsLookupSelector, gridRowIdsSelector, gridRowTreeSelector } from '@mui/x-data-grid-pro';
2
+ import { getAggregationRules } from './gridAggregationUtils';
3
+ import { gridAggregationModelSelector } from './gridAggregationSelectors';
4
+
5
+ const getAggregationCellValue = ({
6
+ apiRef,
7
+ groupId,
8
+ field,
9
+ aggregationFunction,
10
+ aggregationRowsScope
11
+ }) => {
12
+ const rowTree = gridRowTreeSelector(apiRef);
13
+ const filteredRowsLookup = gridFilteredRowsLookupSelector(apiRef);
14
+ let rowIds; // TODO: Add custom root id
15
+
16
+ if (groupId === '') {
17
+ rowIds = gridRowIdsSelector(apiRef).filter(rowId => !rowTree[rowId].isAutoGenerated);
18
+ } else {
19
+ rowIds = apiRef.current.getRowGroupChildren({
20
+ groupId
21
+ });
22
+ }
23
+
24
+ const values = [];
25
+ rowIds.forEach(rowId => {
26
+ if (aggregationRowsScope === 'filtered' && filteredRowsLookup[rowId] === false) {
27
+ return;
28
+ }
29
+
30
+ values.push(apiRef.current.getCellValue(rowId, field));
31
+ });
32
+ return aggregationFunction.apply({
33
+ values
34
+ });
35
+ };
36
+
37
+ const getGroupAggregatedValue = ({
38
+ groupId,
39
+ apiRef,
40
+ aggregationRowsScope,
41
+ aggregatedFields,
42
+ aggregationRules,
43
+ position
44
+ }) => {
45
+ const groupAggregationLookup = {};
46
+
47
+ for (let j = 0; j < aggregatedFields.length; j += 1) {
48
+ const aggregatedField = aggregatedFields[j];
49
+ const columnAggregationRules = aggregationRules[aggregatedField];
50
+ groupAggregationLookup[aggregatedField] = {
51
+ position,
52
+ value: getAggregationCellValue({
53
+ apiRef,
54
+ groupId,
55
+ field: aggregatedField,
56
+ aggregationFunction: columnAggregationRules.aggregationFunction,
57
+ aggregationRowsScope
58
+ })
59
+ };
60
+ }
61
+
62
+ return groupAggregationLookup;
63
+ };
64
+
65
+ export const createAggregationLookup = ({
66
+ apiRef,
67
+ aggregationFunctions,
68
+ aggregationRowsScope,
69
+ getAggregationPosition
70
+ }) => {
71
+ const aggregationRules = getAggregationRules({
72
+ columnsLookup: gridColumnLookupSelector(apiRef),
73
+ aggregationModel: gridAggregationModelSelector(apiRef),
74
+ aggregationFunctions
75
+ });
76
+ const aggregatedFields = Object.keys(aggregationRules);
77
+
78
+ if (aggregatedFields.length === 0) {
79
+ return {};
80
+ }
81
+
82
+ const aggregationLookup = {};
83
+ const rowIds = gridRowIdsSelector(apiRef);
84
+ const rowTree = gridRowTreeSelector(apiRef);
85
+
86
+ for (let i = 0; i < rowIds.length; i += 1) {
87
+ const rowId = rowIds[i];
88
+ const node = rowTree[rowId];
89
+ const hasChildren = node.children?.some(childId => (rowTree[childId].position ?? 'body') === 'body');
90
+
91
+ if (hasChildren) {
92
+ const position = getAggregationPosition(node);
93
+
94
+ if (position != null) {
95
+ aggregationLookup[rowId] = getGroupAggregatedValue({
96
+ groupId: rowId,
97
+ apiRef,
98
+ aggregatedFields,
99
+ aggregationRowsScope,
100
+ aggregationRules,
101
+ position
102
+ });
103
+ }
104
+ }
105
+ } // TODO: Add custom root id
106
+
107
+
108
+ const position = getAggregationPosition(null);
109
+
110
+ if (position != null) {
111
+ aggregationLookup[''] = getGroupAggregatedValue({
112
+ groupId: '',
113
+ apiRef,
114
+ aggregatedFields,
115
+ aggregationRowsScope,
116
+ aggregationRules,
117
+ position
118
+ });
119
+ }
120
+
121
+ return aggregationLookup;
122
+ };
@@ -0,0 +1,96 @@
1
+ import { isNumber } from '@mui/x-data-grid-pro/internals';
2
+ const sumAgg = {
3
+ apply: ({
4
+ values
5
+ }) => {
6
+ let sum = 0;
7
+
8
+ for (let i = 0; i < values.length; i += 1) {
9
+ const value = values[i];
10
+
11
+ if (value != null) {
12
+ sum += value;
13
+ }
14
+ }
15
+
16
+ return sum;
17
+ },
18
+ columnTypes: ['number']
19
+ };
20
+ const avgAgg = {
21
+ apply: params => {
22
+ if (params.values.length === 0) {
23
+ return null;
24
+ }
25
+
26
+ const sum = sumAgg.apply(params);
27
+ return sum / params.values.length;
28
+ },
29
+ columnTypes: ['number']
30
+ };
31
+ const minAgg = {
32
+ apply: ({
33
+ values
34
+ }) => {
35
+ if (values.length === 0) {
36
+ return null;
37
+ }
38
+
39
+ let min = +Infinity;
40
+
41
+ for (let i = 0; i < values.length; i += 1) {
42
+ const value = values[i];
43
+
44
+ if (value != null && value < min) {
45
+ min = value;
46
+ }
47
+ }
48
+
49
+ return min;
50
+ },
51
+ columnTypes: ['number', 'date', 'dateTime']
52
+ };
53
+ const maxAgg = {
54
+ apply: ({
55
+ values
56
+ }) => {
57
+ if (values.length === 0) {
58
+ return null;
59
+ }
60
+
61
+ let max = -Infinity;
62
+
63
+ for (let i = 0; i < values.length; i += 1) {
64
+ const value = values[i];
65
+
66
+ if (value != null && value > max) {
67
+ max = value;
68
+ }
69
+ }
70
+
71
+ return max;
72
+ },
73
+ columnTypes: ['number', 'date', 'dateTime']
74
+ };
75
+ const sizeAgg = {
76
+ apply: ({
77
+ values
78
+ }) => {
79
+ return values.length;
80
+ },
81
+ valueFormatter: params => {
82
+ if (params.value == null || !isNumber(params.value)) {
83
+ return params.value;
84
+ }
85
+
86
+ return params.value.toLocaleString();
87
+ },
88
+ hasCellUnit: false
89
+ };
90
+ export const PRIVATE_GRID_AGGREGATION_FUNCTIONS = {
91
+ sum: sumAgg,
92
+ avg: avgAgg,
93
+ min: minAgg,
94
+ max: maxAgg,
95
+ size: sizeAgg
96
+ };
@@ -0,0 +1,5 @@
1
+ import { createSelector } from '@mui/x-data-grid-pro/internals';
2
+ // eslint-disable-next-line @typescript-eslint/naming-convention
3
+ export const private_gridAggregationStateSelector = state => state.private_aggregation;
4
+ export const gridAggregationModelSelector = createSelector(private_gridAggregationStateSelector, aggregationState => aggregationState.model);
5
+ export const gridAggregationLookupSelector = createSelector(private_gridAggregationStateSelector, aggregationState => aggregationState.lookup);
@@ -0,0 +1,175 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import { capitalize } from '@mui/material';
3
+ import { isDeepEqual } from '@mui/x-data-grid-pro/internals';
4
+ export const PRIVATE_GRID_AGGREGATION_ROOT_FOOTER_ROW_ID = 'auto-generated-group-footer-root'; // eslint-disable-next-line @typescript-eslint/naming-convention
5
+
6
+ export const private_getAggregationFooterRowIdFromGroupId = groupId => {
7
+ if (groupId == null) {
8
+ return PRIVATE_GRID_AGGREGATION_ROOT_FOOTER_ROW_ID;
9
+ }
10
+
11
+ return `auto-generated-group-footer-${groupId}`;
12
+ };
13
+ export const canColumnHaveAggregationFunction = ({
14
+ column,
15
+ aggregationFunctionName,
16
+ aggregationFunction
17
+ }) => {
18
+ if (!column || !column.private_aggregable) {
19
+ return false;
20
+ }
21
+
22
+ if (!aggregationFunction) {
23
+ return false;
24
+ }
25
+
26
+ if (column.private_availableAggregationFunctions != null) {
27
+ return column.private_availableAggregationFunctions.includes(aggregationFunctionName);
28
+ }
29
+
30
+ if (!aggregationFunction.columnTypes) {
31
+ return true;
32
+ }
33
+
34
+ return aggregationFunction.columnTypes.includes(column.type);
35
+ };
36
+ export const getAvailableAggregationFunctions = ({
37
+ aggregationFunctions,
38
+ column
39
+ }) => Object.keys(aggregationFunctions).filter(aggregationFunctionName => canColumnHaveAggregationFunction({
40
+ column,
41
+ aggregationFunctionName,
42
+ aggregationFunction: aggregationFunctions[aggregationFunctionName]
43
+ }));
44
+ export const mergeStateWithAggregationModel = aggregationModel => state => _extends({}, state, {
45
+ private_aggregation: _extends({}, state.private_aggregation, {
46
+ model: aggregationModel
47
+ })
48
+ });
49
+ export const getAggregationRules = ({
50
+ columnsLookup,
51
+ aggregationModel,
52
+ aggregationFunctions
53
+ }) => {
54
+ const aggregationRules = {};
55
+ Object.entries(aggregationModel).forEach(([field, columnItem]) => {
56
+ if (columnsLookup[field] && canColumnHaveAggregationFunction({
57
+ column: columnsLookup[field],
58
+ aggregationFunctionName: columnItem,
59
+ aggregationFunction: aggregationFunctions[columnItem]
60
+ })) {
61
+ aggregationRules[field] = {
62
+ aggregationFunctionName: columnItem,
63
+ aggregationFunction: aggregationFunctions[columnItem]
64
+ };
65
+ }
66
+ });
67
+ return aggregationRules;
68
+ };
69
+ /**
70
+ * Add a footer for each group that has at least one column with an aggregated value.
71
+ */
72
+
73
+ export const addFooterRows = ({
74
+ groupingParams,
75
+ aggregationRules,
76
+ getAggregationPosition
77
+ }) => {
78
+ if (Object.keys(aggregationRules).length === 0) {
79
+ return groupingParams;
80
+ }
81
+
82
+ const ids = [...groupingParams.ids];
83
+
84
+ const idRowsLookup = _extends({}, groupingParams.idRowsLookup);
85
+
86
+ const tree = _extends({}, groupingParams.tree);
87
+
88
+ const addGroupFooter = groupNode => {
89
+ const groupId = groupNode?.id ?? null;
90
+
91
+ if (getAggregationPosition(groupNode) !== 'footer') {
92
+ return;
93
+ }
94
+
95
+ const footerId = private_getAggregationFooterRowIdFromGroupId(groupId);
96
+ ids.push(footerId);
97
+ idRowsLookup[footerId] = {};
98
+ tree[footerId] = {
99
+ id: footerId,
100
+ isAutoGenerated: true,
101
+ parent: groupId,
102
+ depth: groupNode ? groupNode.depth + 1 : 0,
103
+ groupingKey: null,
104
+ groupingField: null,
105
+ position: 'footer'
106
+ };
107
+
108
+ if (groupId != null) {
109
+ tree[groupId] = _extends({}, tree[groupId], {
110
+ footerId
111
+ });
112
+ }
113
+ };
114
+
115
+ addGroupFooter(null); // If the tree is flat, we don't need to loop through the rows
116
+
117
+ if (groupingParams.treeDepth > 1) {
118
+ groupingParams.ids.forEach(parentId => {
119
+ const parentNode = tree[parentId];
120
+
121
+ if (parentNode.depth === groupingParams.treeDepth - 1) {
122
+ return;
123
+ }
124
+
125
+ addGroupFooter(parentNode);
126
+ });
127
+ }
128
+
129
+ return _extends({}, groupingParams, {
130
+ ids,
131
+ idRowsLookup,
132
+ tree
133
+ });
134
+ };
135
+ /**
136
+ * Compares two sets of aggregation rules to determine if they are equal or not.
137
+ */
138
+
139
+ export const hasAggregationRulesChanged = (previousValue, newValue) => {
140
+ const previousFields = Object.keys(previousValue ?? {});
141
+ const newFields = Object.keys(newValue);
142
+
143
+ if (!isDeepEqual(previousFields, newFields)) {
144
+ return true;
145
+ }
146
+
147
+ return newFields.some(field => {
148
+ const previousRule = previousValue?.[field];
149
+ const newRule = newValue[field];
150
+
151
+ if (previousRule?.aggregationFunction !== newRule?.aggregationFunction) {
152
+ return true;
153
+ }
154
+
155
+ if (previousRule?.aggregationFunctionName !== newRule?.aggregationFunctionName) {
156
+ return true;
157
+ }
158
+
159
+ return false;
160
+ });
161
+ };
162
+ export const getAggregationFunctionLabel = ({
163
+ apiRef,
164
+ aggregationRule
165
+ }) => {
166
+ if (aggregationRule.aggregationFunction.label != null) {
167
+ return aggregationRule.aggregationFunction.label;
168
+ }
169
+
170
+ try {
171
+ return apiRef.current.getLocaleText(`aggregationFunctionLabel${capitalize(aggregationRule.aggregationFunctionName)}`);
172
+ } catch (e) {
173
+ return aggregationRule.aggregationFunctionName;
174
+ }
175
+ };
@@ -0,0 +1,4 @@
1
+ export * from './gridAggregationInterfaces';
2
+ export * from './gridAggregationSelectors';
3
+ export * from './gridAggregationFunctions';
4
+ export { PRIVATE_GRID_AGGREGATION_ROOT_FOOTER_ROW_ID, private_getAggregationFooterRowIdFromGroupId } from './gridAggregationUtils';
@@ -0,0 +1,92 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import * as React from 'react';
3
+ import { gridColumnLookupSelector, useGridApiEventHandler, useGridApiMethod } from '@mui/x-data-grid-pro';
4
+ import { gridAggregationModelSelector } from './gridAggregationSelectors';
5
+ import { getAggregationRules, mergeStateWithAggregationModel, hasAggregationRulesChanged } from './gridAggregationUtils';
6
+ import { createAggregationLookup } from './createAggregationLookup';
7
+ export const aggregationStateInitializer = (state, props, apiRef) => {
8
+ apiRef.current.unstable_caches.aggregation = {
9
+ rulesOnLastColumnHydration: {},
10
+ rulesOnLastRowHydration: {}
11
+ };
12
+ return _extends({}, state, {
13
+ private_aggregation: {
14
+ model: props.private_aggregationModel ?? props.initialState?.private_aggregation?.model ?? {}
15
+ }
16
+ });
17
+ };
18
+ export const useGridAggregation = (apiRef, props) => {
19
+ apiRef.current.unstable_registerControlState({
20
+ stateId: 'aggregation',
21
+ propModel: props.private_aggregationModel,
22
+ propOnChange: props.private_onAggregationModelChange,
23
+ stateSelector: gridAggregationModelSelector,
24
+ changeEvent: 'aggregationModelChange'
25
+ });
26
+ /**
27
+ * API METHODS
28
+ */
29
+
30
+ const setAggregationModel = React.useCallback(model => {
31
+ const currentModel = gridAggregationModelSelector(apiRef);
32
+
33
+ if (currentModel !== model) {
34
+ apiRef.current.setState(mergeStateWithAggregationModel(model));
35
+ apiRef.current.forceUpdate();
36
+ }
37
+ }, [apiRef]);
38
+ const applyAggregation = React.useCallback(() => {
39
+ const aggregationLookup = createAggregationLookup({
40
+ apiRef,
41
+ getAggregationPosition: props.private_getAggregationPosition,
42
+ aggregationFunctions: props.private_aggregationFunctions,
43
+ aggregationRowsScope: props.private_aggregationRowsScope
44
+ });
45
+ apiRef.current.setState(state => _extends({}, state, {
46
+ private_aggregation: _extends({}, state.private_aggregation, {
47
+ lookup: aggregationLookup
48
+ })
49
+ }));
50
+ }, [apiRef, props.private_getAggregationPosition, props.private_aggregationFunctions, props.private_aggregationRowsScope]);
51
+ const aggregationApi = {
52
+ private_setAggregationModel: setAggregationModel
53
+ };
54
+ useGridApiMethod(apiRef, aggregationApi, 'GridAggregationApi');
55
+ /**
56
+ * EVENTS
57
+ */
58
+
59
+ const checkAggregationRulesDiff = React.useCallback(() => {
60
+ const {
61
+ rulesOnLastRowHydration,
62
+ rulesOnLastColumnHydration
63
+ } = apiRef.current.unstable_caches.aggregation;
64
+ const aggregationRules = props.private_disableAggregation ? {} : getAggregationRules({
65
+ columnsLookup: gridColumnLookupSelector(apiRef),
66
+ aggregationModel: gridAggregationModelSelector(apiRef),
67
+ aggregationFunctions: props.private_aggregationFunctions
68
+ }); // Re-apply the row hydration to add / remove the aggregation footers
69
+
70
+ if (hasAggregationRulesChanged(rulesOnLastRowHydration, aggregationRules)) {
71
+ apiRef.current.unstable_requestPipeProcessorsApplication('hydrateRows');
72
+ applyAggregation();
73
+ } // Re-apply the column hydration to wrap / unwrap the aggregated columns
74
+
75
+
76
+ if (hasAggregationRulesChanged(rulesOnLastColumnHydration, aggregationRules)) {
77
+ apiRef.current.unstable_requestPipeProcessorsApplication('hydrateColumns');
78
+ }
79
+ }, [apiRef, applyAggregation, props.private_aggregationFunctions, props.private_disableAggregation]);
80
+ useGridApiEventHandler(apiRef, 'aggregationModelChange', checkAggregationRulesDiff);
81
+ useGridApiEventHandler(apiRef, 'columnsChange', checkAggregationRulesDiff);
82
+ useGridApiEventHandler(apiRef, 'filteredRowsSet', applyAggregation);
83
+ /**
84
+ * EFFECTS
85
+ */
86
+
87
+ React.useEffect(() => {
88
+ if (props.private_aggregationModel !== undefined) {
89
+ apiRef.current.private_setAggregationModel(props.private_aggregationModel);
90
+ }
91
+ }, [apiRef, props.private_aggregationModel]);
92
+ };