@mui/x-data-grid-premium 5.16.0 → 5.17.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 (49) hide show
  1. package/CHANGELOG.md +78 -1
  2. package/DataGridPremium/DataGridPremium.js +17 -0
  3. package/DataGridPremium/useDataGridPremiumComponent.js +2 -1
  4. package/hooks/features/aggregation/createAggregationLookup.js +15 -0
  5. package/hooks/features/aggregation/gridAggregationUtils.d.ts +1 -1
  6. package/hooks/features/aggregation/gridAggregationUtils.js +6 -6
  7. package/hooks/features/aggregation/useGridAggregation.js +3 -3
  8. package/hooks/features/aggregation/wrapColumnWithAggregation.js +4 -3
  9. package/hooks/features/rowGrouping/gridRowGroupingInterfaces.d.ts +7 -1
  10. package/hooks/features/rowGrouping/gridRowGroupingUtils.d.ts +11 -2
  11. package/hooks/features/rowGrouping/gridRowGroupingUtils.js +35 -1
  12. package/hooks/features/rowGrouping/useGridRowGrouping.js +12 -8
  13. package/hooks/features/rowGrouping/useGridRowGroupingPreProcessors.js +19 -12
  14. package/index.js +1 -1
  15. package/legacy/DataGridPremium/DataGridPremium.js +17 -0
  16. package/legacy/DataGridPremium/useDataGridPremiumComponent.js +2 -1
  17. package/legacy/hooks/features/aggregation/createAggregationLookup.js +15 -0
  18. package/legacy/hooks/features/aggregation/gridAggregationUtils.js +6 -6
  19. package/legacy/hooks/features/aggregation/useGridAggregation.js +3 -3
  20. package/legacy/hooks/features/aggregation/wrapColumnWithAggregation.js +4 -3
  21. package/legacy/hooks/features/rowGrouping/gridRowGroupingUtils.js +39 -1
  22. package/legacy/hooks/features/rowGrouping/useGridRowGrouping.js +12 -8
  23. package/legacy/hooks/features/rowGrouping/useGridRowGroupingPreProcessors.js +19 -12
  24. package/legacy/index.js +1 -1
  25. package/legacy/utils/releaseInfo.js +1 -1
  26. package/modern/DataGridPremium/DataGridPremium.js +17 -0
  27. package/modern/DataGridPremium/useDataGridPremiumComponent.js +2 -1
  28. package/modern/hooks/features/aggregation/createAggregationLookup.js +13 -0
  29. package/modern/hooks/features/aggregation/gridAggregationUtils.js +6 -6
  30. package/modern/hooks/features/aggregation/useGridAggregation.js +3 -3
  31. package/modern/hooks/features/aggregation/wrapColumnWithAggregation.js +3 -2
  32. package/modern/hooks/features/rowGrouping/gridRowGroupingUtils.js +31 -1
  33. package/modern/hooks/features/rowGrouping/useGridRowGrouping.js +12 -8
  34. package/modern/hooks/features/rowGrouping/useGridRowGroupingPreProcessors.js +19 -12
  35. package/modern/index.js +1 -1
  36. package/modern/utils/releaseInfo.js +1 -1
  37. package/node/DataGridPremium/DataGridPremium.js +17 -0
  38. package/node/DataGridPremium/useDataGridPremiumComponent.js +1 -0
  39. package/node/hooks/features/aggregation/createAggregationLookup.js +15 -0
  40. package/node/hooks/features/aggregation/gridAggregationUtils.js +8 -8
  41. package/node/hooks/features/aggregation/useGridAggregation.js +2 -2
  42. package/node/hooks/features/aggregation/wrapColumnWithAggregation.js +4 -3
  43. package/node/hooks/features/rowGrouping/gridRowGroupingUtils.js +43 -3
  44. package/node/hooks/features/rowGrouping/useGridRowGrouping.js +9 -5
  45. package/node/hooks/features/rowGrouping/useGridRowGroupingPreProcessors.js +18 -11
  46. package/node/index.js +1 -1
  47. package/node/utils/releaseInfo.js +1 -1
  48. package/package.json +4 -4
  49. package/utils/releaseInfo.js +1 -1
@@ -163,11 +163,12 @@ export var wrapColumnWithAggregationValue = function wrapColumnWithAggregationVa
163
163
  aggregationRule = _ref6.aggregationRule;
164
164
 
165
165
  var getCellAggregationResult = function getCellAggregationResult(id, field) {
166
- var _parent, _gridAggregationLooku;
166
+ var _rowNode$children, _rowNode$parent, _gridAggregationLooku;
167
167
 
168
168
  var cellAggregationPosition = null;
169
+ var rowNode = apiRef.current.getRowNode(id);
169
170
 
170
- if (id.toString().startsWith('auto-generated-row-')) {
171
+ if ((_rowNode$children = rowNode.children) != null && _rowNode$children.length) {
171
172
  cellAggregationPosition = 'inline';
172
173
  } else if (id.toString().startsWith('auto-generated-group-footer-')) {
173
174
  cellAggregationPosition = 'footer';
@@ -178,7 +179,7 @@ export var wrapColumnWithAggregationValue = function wrapColumnWithAggregationVa
178
179
  } // TODO: Add custom root id
179
180
 
180
181
 
181
- var groupId = cellAggregationPosition === 'inline' ? id : (_parent = apiRef.current.getRowNode(id).parent) != null ? _parent : '';
182
+ var groupId = cellAggregationPosition === 'inline' ? id : (_rowNode$parent = rowNode.parent) != null ? _rowNode$parent : '';
182
183
  var aggregationResult = (_gridAggregationLooku = gridAggregationLookupSelector(apiRef)[groupId]) == null ? void 0 : _gridAggregationLooku[field];
183
184
 
184
185
  if (!aggregationResult || aggregationResult.position !== cellAggregationPosition) {
@@ -88,7 +88,7 @@ export var filterRowTreeFromGroupingColumns = function filterRowTreeFromGrouping
88
88
  return result.passingFilterItems;
89
89
  }), allResults.map(function (result) {
90
90
  return result.passingQuickFilterValues;
91
- }), filterModel);
91
+ }), filterModel, params.apiRef);
92
92
  }
93
93
  }
94
94
 
@@ -162,4 +162,42 @@ export var setStrategyAvailability = function setStrategyAvailability(apiRef, di
162
162
  }
163
163
 
164
164
  apiRef.current.unstable_setStrategyAvailability('rowTree', ROW_GROUPING_STRATEGY, isAvailable);
165
+ };
166
+ export var getGroupingRules = function getGroupingRules(_ref) {
167
+ var sanitizedRowGroupingModel = _ref.sanitizedRowGroupingModel,
168
+ columnsLookup = _ref.columnsLookup;
169
+ return sanitizedRowGroupingModel.map(function (field) {
170
+ var _columnsLookup$field;
171
+
172
+ return {
173
+ field: field,
174
+ groupingValueGetter: (_columnsLookup$field = columnsLookup[field]) == null ? void 0 : _columnsLookup$field.groupingValueGetter
175
+ };
176
+ });
177
+ };
178
+ /**
179
+ * Compares two sets of grouping rules to determine if they are equal or not.
180
+ */
181
+
182
+ export var areGroupingRulesEqual = function areGroupingRulesEqual() {
183
+ var previousValue = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
184
+ var newValue = arguments.length > 1 ? arguments[1] : undefined;
185
+
186
+ if (previousValue.length !== newValue.length) {
187
+ return false;
188
+ }
189
+
190
+ return newValue.every(function (newRule, newRuleIndex) {
191
+ var previousRule = previousValue[newRuleIndex];
192
+
193
+ if (previousRule.groupingValueGetter !== newRule.groupingValueGetter) {
194
+ return false;
195
+ }
196
+
197
+ if (previousRule.field !== newRule.field) {
198
+ return false;
199
+ }
200
+
201
+ return true;
202
+ });
165
203
  };
@@ -2,10 +2,10 @@ import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
2
2
  import _extends from "@babel/runtime/helpers/esm/extends";
3
3
  import * as React from 'react';
4
4
  import MuiDivider from '@mui/material/Divider';
5
- import { useGridApiEventHandler, useGridApiMethod, gridFilteredDescendantCountLookupSelector } from '@mui/x-data-grid-pro';
6
- import { useGridRegisterPipeProcessor, isDeepEqual } from '@mui/x-data-grid-pro/internals';
5
+ import { useGridApiEventHandler, useGridApiMethod, gridFilteredDescendantCountLookupSelector, gridColumnLookupSelector } from '@mui/x-data-grid-pro';
6
+ import { useGridRegisterPipeProcessor } from '@mui/x-data-grid-pro/internals';
7
7
  import { gridRowGroupingModelSelector, gridRowGroupingSanitizedModelSelector } from './gridRowGroupingSelector';
8
- import { getRowGroupingFieldFromGroupingCriteria, ROW_GROUPING_STRATEGY, isGroupingColumn, mergeStateWithRowGroupingModel, setStrategyAvailability } from './gridRowGroupingUtils';
8
+ import { getRowGroupingFieldFromGroupingCriteria, ROW_GROUPING_STRATEGY, isGroupingColumn, mergeStateWithRowGroupingModel, setStrategyAvailability, getGroupingRules, areGroupingRulesEqual } from './gridRowGroupingUtils';
9
9
  import { GridRowGroupableColumnMenuItems } from '../../../components/GridRowGroupableColumnMenuItems';
10
10
  import { GridRowGroupingColumnMenuItems } from '../../../components/GridRowGroupingColumnMenuItems';
11
11
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -22,7 +22,7 @@ export var rowGroupingStateInitializer = function rowGroupingStateInitializer(st
22
22
  var _ref, _props$rowGroupingMod, _props$initialState, _props$initialState$r;
23
23
 
24
24
  apiRef.current.unstable_caches.rowGrouping = {
25
- sanitizedModelOnLastRowTreeCreation: []
25
+ rulesOnLastRowTreeCreation: []
26
26
  };
27
27
  return _extends({}, state, {
28
28
  rowGrouping: {
@@ -187,11 +187,15 @@ export var useGridRowGrouping = function useGridRowGrouping(apiRef, props) {
187
187
  }
188
188
  }, [apiRef, props.rowGroupingColumnMode]);
189
189
  var checkGroupingColumnsModelDiff = React.useCallback(function () {
190
- var rowGroupingModel = gridRowGroupingSanitizedModelSelector(apiRef);
191
- var lastGroupingColumnsModelApplied = apiRef.current.unstable_caches.rowGrouping.sanitizedModelOnLastRowTreeCreation;
190
+ var sanitizedRowGroupingModel = gridRowGroupingSanitizedModelSelector(apiRef);
191
+ var rulesOnLastRowTreeCreation = apiRef.current.unstable_caches.rowGrouping.rulesOnLastRowTreeCreation;
192
+ var groupingRules = getGroupingRules({
193
+ sanitizedRowGroupingModel: sanitizedRowGroupingModel,
194
+ columnsLookup: gridColumnLookupSelector(apiRef)
195
+ });
192
196
 
193
- if (!isDeepEqual(lastGroupingColumnsModelApplied, rowGroupingModel)) {
194
- apiRef.current.unstable_caches.rowGrouping.sanitizedModelOnLastRowTreeCreation = rowGroupingModel;
197
+ if (!areGroupingRulesEqual(rulesOnLastRowTreeCreation, groupingRules)) {
198
+ apiRef.current.unstable_caches.rowGrouping.rulesOnLastRowTreeCreation = groupingRules;
195
199
  apiRef.current.unstable_requestPipeProcessorsApplication('hydrateColumns');
196
200
  setStrategyAvailability(apiRef, props.disableRowGrouping); // Refresh the row tree creation strategy processing
197
201
  // TODO: Add a clean way to re-run a strategy processing without publishing a private event
@@ -5,7 +5,7 @@ import { gridColumnLookupSelector, gridRowIdsSelector, gridRowTreeSelector, useF
5
5
  import { useGridRegisterPipeProcessor, useGridRegisterStrategyProcessor, sortRowTree, buildRowTree } from '@mui/x-data-grid-pro/internals';
6
6
  import { gridRowGroupingModelSelector, gridRowGroupingSanitizedModelSelector } from './gridRowGroupingSelector';
7
7
  import { createGroupingColDefForAllGroupingCriteria, createGroupingColDefForOneGroupingCriteria } from './createGroupingColDef';
8
- import { filterRowTreeFromGroupingColumns, getColDefOverrides, ROW_GROUPING_STRATEGY, isGroupingColumn, setStrategyAvailability } from './gridRowGroupingUtils';
8
+ import { filterRowTreeFromGroupingColumns, getColDefOverrides, ROW_GROUPING_STRATEGY, isGroupingColumn, setStrategyAvailability, getGroupingRules } from './gridRowGroupingUtils';
9
9
  export var useGridRowGroupingPreProcessors = function useGridRowGroupingPreProcessors(apiRef, props) {
10
10
  var getGroupingColDefs = React.useCallback(function (columnsState) {
11
11
  if (props.disableRowGrouping) {
@@ -82,21 +82,26 @@ export var useGridRowGroupingPreProcessors = function useGridRowGroupingPreProce
82
82
  return columnsState;
83
83
  }, [getGroupingColDefs]);
84
84
  var createRowTree = React.useCallback(function (params) {
85
- var rowGroupingModel = gridRowGroupingSanitizedModelSelector(apiRef);
85
+ var sanitizedRowGroupingModel = gridRowGroupingSanitizedModelSelector(apiRef);
86
86
  var columnsLookup = gridColumnLookupSelector(apiRef);
87
- apiRef.current.unstable_caches.rowGrouping.sanitizedModelOnLastRowTreeCreation = rowGroupingModel;
87
+ var groupingRules = getGroupingRules({
88
+ sanitizedRowGroupingModel: sanitizedRowGroupingModel,
89
+ columnsLookup: columnsLookup
90
+ });
91
+ apiRef.current.unstable_caches.rowGrouping.rulesOnLastRowTreeCreation = groupingRules;
88
92
 
89
93
  var getCellGroupingCriteria = function getCellGroupingCriteria(_ref) {
90
94
  var row = _ref.row,
91
95
  id = _ref.id,
92
- colDef = _ref.colDef;
96
+ colDef = _ref.colDef,
97
+ groupingRule = _ref.groupingRule;
93
98
  var key;
94
99
 
95
- if (colDef.groupingValueGetter) {
100
+ if (groupingRule.groupingValueGetter) {
96
101
  var groupingValueGetterParams = {
97
102
  colDef: colDef,
98
- field: colDef.field,
99
- value: row[colDef.field],
103
+ field: groupingRule.field,
104
+ value: row[groupingRule.field],
100
105
  id: id,
101
106
  row: row,
102
107
  rowNode: {
@@ -104,9 +109,9 @@ export var useGridRowGroupingPreProcessors = function useGridRowGroupingPreProce
104
109
  id: id
105
110
  }
106
111
  };
107
- key = colDef.groupingValueGetter(groupingValueGetterParams);
112
+ key = groupingRule.groupingValueGetter(groupingValueGetterParams);
108
113
  } else {
109
- key = row[colDef.field];
114
+ key = row[groupingRule.field];
110
115
  }
111
116
 
112
117
  return {
@@ -117,11 +122,12 @@ export var useGridRowGroupingPreProcessors = function useGridRowGroupingPreProce
117
122
 
118
123
  var rows = params.ids.map(function (rowId) {
119
124
  var row = params.idRowsLookup[rowId];
120
- var parentPath = rowGroupingModel.map(function (groupingField) {
125
+ var parentPath = groupingRules.map(function (groupingRule) {
121
126
  return getCellGroupingCriteria({
122
127
  row: row,
123
128
  id: rowId,
124
- colDef: columnsLookup[groupingField]
129
+ groupingRule: groupingRule,
130
+ colDef: columnsLookup[groupingRule.field]
125
131
  });
126
132
  }).filter(function (cell) {
127
133
  return cell.key != null;
@@ -147,7 +153,8 @@ export var useGridRowGroupingPreProcessors = function useGridRowGroupingPreProce
147
153
  return filterRowTreeFromGroupingColumns({
148
154
  rowTree: rowTree,
149
155
  isRowMatchingFilters: params.isRowMatchingFilters,
150
- filterModel: params.filterModel
156
+ filterModel: params.filterModel,
157
+ apiRef: apiRef
151
158
  });
152
159
  }, [apiRef]);
153
160
  var sortRows = React.useCallback(function (params) {
package/legacy/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /** @license MUI v5.16.0
1
+ /** @license MUI v5.17.0
2
2
  *
3
3
  * This source code is licensed under the MIT license found in the
4
4
  * LICENSE file in the root directory of this source tree.
@@ -1,6 +1,6 @@
1
1
  import { ponyfillGlobal } from '@mui/utils';
2
2
  export var getReleaseInfo = function getReleaseInfo() {
3
- var releaseInfo = "MTY2MTM3ODQwMDAwMA==";
3
+ var releaseInfo = "MTY2MjA2NjAwMDAwMA==";
4
4
 
5
5
  if (process.env.NODE_ENV !== 'production') {
6
6
  // A simple hack to set the value in the test environment (has no build step).
@@ -307,6 +307,7 @@ process.env.NODE_ENV !== "production" ? DataGridPremiumRaw.propTypes = {
307
307
  experimentalFeatures: PropTypes.shape({
308
308
  aggregation: PropTypes.bool,
309
309
  columnGrouping: PropTypes.bool,
310
+ lazyLoading: PropTypes.bool,
310
311
  newEditingApi: PropTypes.bool,
311
312
  preventCommitWhileValidating: PropTypes.bool,
312
313
  rowPinning: PropTypes.bool,
@@ -716,6 +717,14 @@ process.env.NODE_ENV !== "production" ? DataGridPremiumRaw.propTypes = {
716
717
  */
717
718
  onError: PropTypes.func,
718
719
 
720
+ /**
721
+ * Callback fired when rowCount is set and the next batch of virtualized rows is rendered.
722
+ * @param {GridFetchRowsParams} params With all properties from [[GridFetchRowsParams]].
723
+ * @param {MuiEvent<{}>} event The event object.
724
+ * @param {GridCallbackDetails} details Additional details for this callback.
725
+ */
726
+ onFetchRows: PropTypes.func,
727
+
719
728
  /**
720
729
  * Callback fired when the Filter model changes before the filters are applied.
721
730
  * @param {GridFilterModel} model With all properties from [[GridFilterModel]].
@@ -980,6 +989,14 @@ process.env.NODE_ENV !== "production" ? DataGridPremiumRaw.propTypes = {
980
989
  */
981
990
  rows: PropTypes.array.isRequired,
982
991
 
992
+ /**
993
+ * Loading rows can be processed on the server or client-side.
994
+ * Set it to 'client' if you would like enable infnite loading.
995
+ * Set it to 'server' if you would like to enable lazy loading.
996
+ * * @default "client"
997
+ */
998
+ rowsLoadingMode: PropTypes.oneOf(['client', 'server']),
999
+
983
1000
  /**
984
1001
  * Sets the type of space between rows added by `getRowSpacing`.
985
1002
  * @default "margin"
@@ -1,4 +1,4 @@
1
- import { useGridInitialization, useGridInitializeState, useGridClipboard, useGridColumnMenu, useGridColumns, columnsStateInitializer, useGridDensity, useGridCsvExport, useGridPrintExport, useGridFilter, filterStateInitializer, useGridFocus, useGridKeyboardNavigation, useGridPagination, paginationStateInitializer, useGridPreferencesPanel, useGridEditing_new, useGridEditing_old, editingStateInitializer_old, editingStateInitializer_new, useGridRows, useGridRowsPreProcessors, rowsStateInitializer, useGridRowsMeta, useGridParamsApi, useGridSelection, useGridSorting, sortingStateInitializer, useGridScroll, useGridEvents, useGridDimensions, useGridStatePersistence, useGridSelectionPreProcessors, columnMenuStateInitializer, densityStateInitializer, focusStateInitializer, preferencePanelStateInitializer, rowsMetaStateInitializer, selectionStateInitializer, useGridColumnReorder, columnReorderStateInitializer, useGridColumnResize, columnResizeStateInitializer, useGridTreeData, useGridTreeDataPreProcessors, useGridColumnPinning, columnPinningStateInitializer, useGridColumnPinningPreProcessors, useGridDetailPanel, detailPanelStateInitializer, useGridDetailPanelPreProcessors, useGridInfiniteLoader, useGridColumnSpanning, useGridRowReorder, useGridRowReorderPreProcessors, useGridColumnGroupingPreProcessors, useGridRowPinning, useGridRowPinningPreProcessors, rowPinningStateInitializer, useGridColumnGrouping } from '@mui/x-data-grid-pro/internals';
1
+ import { useGridInitialization, useGridInitializeState, useGridClipboard, useGridColumnMenu, useGridColumns, columnsStateInitializer, useGridDensity, useGridCsvExport, useGridPrintExport, useGridFilter, filterStateInitializer, useGridFocus, useGridKeyboardNavigation, useGridPagination, paginationStateInitializer, useGridPreferencesPanel, useGridEditing_new, useGridEditing_old, editingStateInitializer_old, editingStateInitializer_new, useGridRows, useGridRowsPreProcessors, rowsStateInitializer, useGridRowsMeta, useGridParamsApi, useGridSelection, useGridSorting, sortingStateInitializer, useGridScroll, useGridEvents, useGridDimensions, useGridStatePersistence, useGridSelectionPreProcessors, columnMenuStateInitializer, densityStateInitializer, focusStateInitializer, preferencePanelStateInitializer, rowsMetaStateInitializer, selectionStateInitializer, useGridColumnReorder, columnReorderStateInitializer, useGridColumnResize, columnResizeStateInitializer, useGridTreeData, useGridTreeDataPreProcessors, useGridColumnPinning, columnPinningStateInitializer, useGridColumnPinningPreProcessors, useGridDetailPanel, detailPanelStateInitializer, useGridDetailPanelPreProcessors, useGridInfiniteLoader, useGridColumnSpanning, useGridRowReorder, useGridRowReorderPreProcessors, useGridColumnGroupingPreProcessors, useGridRowPinning, useGridRowPinningPreProcessors, rowPinningStateInitializer, useGridColumnGrouping, columnGroupsStateInitializer } from '@mui/x-data-grid-pro/internals';
2
2
  // Premium-only features
3
3
  import { useGridAggregation, aggregationStateInitializer } from '../hooks/features/aggregation/useGridAggregation';
4
4
  import { useGridAggregationPreProcessors } from '../hooks/features/aggregation/useGridAggregationPreProcessors';
@@ -46,6 +46,7 @@ export const useDataGridPremiumComponent = (inputApiRef, props) => {
46
46
  useGridInitializeState(paginationStateInitializer, apiRef, props);
47
47
  useGridInitializeState(rowsMetaStateInitializer, apiRef, props);
48
48
  useGridInitializeState(columnMenuStateInitializer, apiRef, props);
49
+ useGridInitializeState(columnGroupsStateInitializer, apiRef, props);
49
50
  useGridRowGrouping(apiRef, props);
50
51
  useGridTreeData(apiRef);
51
52
  useGridAggregation(apiRef, props);
@@ -25,6 +25,19 @@ const getAggregationCellValue = ({
25
25
  rowIds.forEach(rowId => {
26
26
  if (aggregationRowsScope === 'filtered' && filteredRowsLookup[rowId] === false) {
27
27
  return;
28
+ } // If the row is a group, we want to aggregate based on its children
29
+ // For instance in the following tree, we want the aggregated values of A to be based on A.A, A.B.A and A.B.B but not A.B
30
+ // A
31
+ // A.A
32
+ // A.B
33
+ // A.B.A
34
+ // A.B.B
35
+
36
+
37
+ const rowNode = apiRef.current.getRowNode(rowId);
38
+
39
+ if (rowNode.children?.length) {
40
+ return;
28
41
  }
29
42
 
30
43
  values.push(apiRef.current.getCellValue(rowId, field));
@@ -147,27 +147,27 @@ export const addFooterRows = ({
147
147
  * Compares two sets of aggregation rules to determine if they are equal or not.
148
148
  */
149
149
 
150
- export const hasAggregationRulesChanged = (previousValue, newValue) => {
150
+ export const areAggregationRulesEqual = (previousValue, newValue) => {
151
151
  const previousFields = Object.keys(previousValue ?? {});
152
152
  const newFields = Object.keys(newValue);
153
153
 
154
154
  if (!isDeepEqual(previousFields, newFields)) {
155
- return true;
155
+ return false;
156
156
  }
157
157
 
158
- return newFields.some(field => {
158
+ return newFields.every(field => {
159
159
  const previousRule = previousValue?.[field];
160
160
  const newRule = newValue[field];
161
161
 
162
162
  if (previousRule?.aggregationFunction !== newRule?.aggregationFunction) {
163
- return true;
163
+ return false;
164
164
  }
165
165
 
166
166
  if (previousRule?.aggregationFunctionName !== newRule?.aggregationFunctionName) {
167
- return true;
167
+ return false;
168
168
  }
169
169
 
170
- return false;
170
+ return true;
171
171
  });
172
172
  };
173
173
  export const getAggregationFunctionLabel = ({
@@ -2,7 +2,7 @@ import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
3
  import { gridColumnLookupSelector, useGridApiEventHandler, useGridApiMethod } from '@mui/x-data-grid-pro';
4
4
  import { gridAggregationModelSelector } from './gridAggregationSelectors';
5
- import { getAggregationRules, mergeStateWithAggregationModel, hasAggregationRulesChanged } from './gridAggregationUtils';
5
+ import { getAggregationRules, mergeStateWithAggregationModel, areAggregationRulesEqual } from './gridAggregationUtils';
6
6
  import { createAggregationLookup } from './createAggregationLookup';
7
7
  export const aggregationStateInitializer = (state, props, apiRef) => {
8
8
  apiRef.current.unstable_caches.aggregation = {
@@ -67,13 +67,13 @@ export const useGridAggregation = (apiRef, props) => {
67
67
  aggregationFunctions: props.aggregationFunctions
68
68
  }); // Re-apply the row hydration to add / remove the aggregation footers
69
69
 
70
- if (hasAggregationRulesChanged(rulesOnLastRowHydration, aggregationRules)) {
70
+ if (!areAggregationRulesEqual(rulesOnLastRowHydration, aggregationRules)) {
71
71
  apiRef.current.unstable_requestPipeProcessorsApplication('hydrateRows');
72
72
  applyAggregation();
73
73
  } // Re-apply the column hydration to wrap / unwrap the aggregated columns
74
74
 
75
75
 
76
- if (hasAggregationRulesChanged(rulesOnLastColumnHydration, aggregationRules)) {
76
+ if (!areAggregationRulesEqual(rulesOnLastColumnHydration, aggregationRules)) {
77
77
  apiRef.current.unstable_requestPipeProcessorsApplication('hydrateColumns');
78
78
  }
79
79
  }, [apiRef, applyAggregation, props.aggregationFunctions, props.disableAggregation]);
@@ -158,8 +158,9 @@ export const wrapColumnWithAggregationValue = ({
158
158
  }) => {
159
159
  const getCellAggregationResult = (id, field) => {
160
160
  let cellAggregationPosition = null;
161
+ const rowNode = apiRef.current.getRowNode(id);
161
162
 
162
- if (id.toString().startsWith('auto-generated-row-')) {
163
+ if (rowNode.children?.length) {
163
164
  cellAggregationPosition = 'inline';
164
165
  } else if (id.toString().startsWith('auto-generated-group-footer-')) {
165
166
  cellAggregationPosition = 'footer';
@@ -170,7 +171,7 @@ export const wrapColumnWithAggregationValue = ({
170
171
  } // TODO: Add custom root id
171
172
 
172
173
 
173
- const groupId = cellAggregationPosition === 'inline' ? id : apiRef.current.getRowNode(id).parent ?? '';
174
+ const groupId = cellAggregationPosition === 'inline' ? id : rowNode.parent ?? '';
174
175
  const aggregationResult = gridAggregationLookupSelector(apiRef)[groupId]?.[field];
175
176
 
176
177
  if (!aggregationResult || aggregationResult.position !== cellAggregationPosition) {
@@ -77,7 +77,7 @@ export const filterRowTreeFromGroupingColumns = params => {
77
77
  isPassingFiltering = filteredDescendantCount > 0;
78
78
  } else {
79
79
  const allResults = [...ancestorsResults, filterResults];
80
- isPassingFiltering = passFilterLogic(allResults.map(result => result.passingFilterItems), allResults.map(result => result.passingQuickFilterValues), filterModel);
80
+ isPassingFiltering = passFilterLogic(allResults.map(result => result.passingFilterItems), allResults.map(result => result.passingQuickFilterValues), filterModel, params.apiRef);
81
81
  }
82
82
  }
83
83
 
@@ -145,4 +145,34 @@ export const setStrategyAvailability = (apiRef, disableRowGrouping) => {
145
145
  }
146
146
 
147
147
  apiRef.current.unstable_setStrategyAvailability('rowTree', ROW_GROUPING_STRATEGY, isAvailable);
148
+ };
149
+ export const getGroupingRules = ({
150
+ sanitizedRowGroupingModel,
151
+ columnsLookup
152
+ }) => sanitizedRowGroupingModel.map(field => ({
153
+ field,
154
+ groupingValueGetter: columnsLookup[field]?.groupingValueGetter
155
+ }));
156
+ /**
157
+ * Compares two sets of grouping rules to determine if they are equal or not.
158
+ */
159
+
160
+ export const areGroupingRulesEqual = (previousValue = [], newValue) => {
161
+ if (previousValue.length !== newValue.length) {
162
+ return false;
163
+ }
164
+
165
+ return newValue.every((newRule, newRuleIndex) => {
166
+ const previousRule = previousValue[newRuleIndex];
167
+
168
+ if (previousRule.groupingValueGetter !== newRule.groupingValueGetter) {
169
+ return false;
170
+ }
171
+
172
+ if (previousRule.field !== newRule.field) {
173
+ return false;
174
+ }
175
+
176
+ return true;
177
+ });
148
178
  };
@@ -1,10 +1,10 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
3
  import MuiDivider from '@mui/material/Divider';
4
- import { useGridApiEventHandler, useGridApiMethod, gridFilteredDescendantCountLookupSelector } from '@mui/x-data-grid-pro';
5
- import { useGridRegisterPipeProcessor, isDeepEqual } from '@mui/x-data-grid-pro/internals';
4
+ import { useGridApiEventHandler, useGridApiMethod, gridFilteredDescendantCountLookupSelector, gridColumnLookupSelector } from '@mui/x-data-grid-pro';
5
+ import { useGridRegisterPipeProcessor } from '@mui/x-data-grid-pro/internals';
6
6
  import { gridRowGroupingModelSelector, gridRowGroupingSanitizedModelSelector } from './gridRowGroupingSelector';
7
- import { getRowGroupingFieldFromGroupingCriteria, ROW_GROUPING_STRATEGY, isGroupingColumn, mergeStateWithRowGroupingModel, setStrategyAvailability } from './gridRowGroupingUtils';
7
+ import { getRowGroupingFieldFromGroupingCriteria, ROW_GROUPING_STRATEGY, isGroupingColumn, mergeStateWithRowGroupingModel, setStrategyAvailability, getGroupingRules, areGroupingRulesEqual } from './gridRowGroupingUtils';
8
8
  import { GridRowGroupableColumnMenuItems } from '../../../components/GridRowGroupableColumnMenuItems';
9
9
  import { GridRowGroupingColumnMenuItems } from '../../../components/GridRowGroupingColumnMenuItems';
10
10
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -15,7 +15,7 @@ const Divider = () => /*#__PURE__*/_jsx(MuiDivider, {
15
15
 
16
16
  export const rowGroupingStateInitializer = (state, props, apiRef) => {
17
17
  apiRef.current.unstable_caches.rowGrouping = {
18
- sanitizedModelOnLastRowTreeCreation: []
18
+ rulesOnLastRowTreeCreation: []
19
19
  };
20
20
  return _extends({}, state, {
21
21
  rowGrouping: {
@@ -169,11 +169,15 @@ export const useGridRowGrouping = (apiRef, props) => {
169
169
  }
170
170
  }, [apiRef, props.rowGroupingColumnMode]);
171
171
  const checkGroupingColumnsModelDiff = React.useCallback(() => {
172
- const rowGroupingModel = gridRowGroupingSanitizedModelSelector(apiRef);
173
- const lastGroupingColumnsModelApplied = apiRef.current.unstable_caches.rowGrouping.sanitizedModelOnLastRowTreeCreation;
172
+ const sanitizedRowGroupingModel = gridRowGroupingSanitizedModelSelector(apiRef);
173
+ const rulesOnLastRowTreeCreation = apiRef.current.unstable_caches.rowGrouping.rulesOnLastRowTreeCreation;
174
+ const groupingRules = getGroupingRules({
175
+ sanitizedRowGroupingModel,
176
+ columnsLookup: gridColumnLookupSelector(apiRef)
177
+ });
174
178
 
175
- if (!isDeepEqual(lastGroupingColumnsModelApplied, rowGroupingModel)) {
176
- apiRef.current.unstable_caches.rowGrouping.sanitizedModelOnLastRowTreeCreation = rowGroupingModel;
179
+ if (!areGroupingRulesEqual(rulesOnLastRowTreeCreation, groupingRules)) {
180
+ apiRef.current.unstable_caches.rowGrouping.rulesOnLastRowTreeCreation = groupingRules;
177
181
  apiRef.current.unstable_requestPipeProcessorsApplication('hydrateColumns');
178
182
  setStrategyAvailability(apiRef, props.disableRowGrouping); // Refresh the row tree creation strategy processing
179
183
  // TODO: Add a clean way to re-run a strategy processing without publishing a private event
@@ -4,7 +4,7 @@ import { gridColumnLookupSelector, gridRowIdsSelector, gridRowTreeSelector, useF
4
4
  import { useGridRegisterPipeProcessor, useGridRegisterStrategyProcessor, sortRowTree, buildRowTree } from '@mui/x-data-grid-pro/internals';
5
5
  import { gridRowGroupingModelSelector, gridRowGroupingSanitizedModelSelector } from './gridRowGroupingSelector';
6
6
  import { createGroupingColDefForAllGroupingCriteria, createGroupingColDefForOneGroupingCriteria } from './createGroupingColDef';
7
- import { filterRowTreeFromGroupingColumns, getColDefOverrides, ROW_GROUPING_STRATEGY, isGroupingColumn, setStrategyAvailability } from './gridRowGroupingUtils';
7
+ import { filterRowTreeFromGroupingColumns, getColDefOverrides, ROW_GROUPING_STRATEGY, isGroupingColumn, setStrategyAvailability, getGroupingRules } from './gridRowGroupingUtils';
8
8
  export const useGridRowGroupingPreProcessors = (apiRef, props) => {
9
9
  const getGroupingColDefs = React.useCallback(columnsState => {
10
10
  if (props.disableRowGrouping) {
@@ -75,22 +75,27 @@ export const useGridRowGroupingPreProcessors = (apiRef, props) => {
75
75
  return columnsState;
76
76
  }, [getGroupingColDefs]);
77
77
  const createRowTree = React.useCallback(params => {
78
- const rowGroupingModel = gridRowGroupingSanitizedModelSelector(apiRef);
78
+ const sanitizedRowGroupingModel = gridRowGroupingSanitizedModelSelector(apiRef);
79
79
  const columnsLookup = gridColumnLookupSelector(apiRef);
80
- apiRef.current.unstable_caches.rowGrouping.sanitizedModelOnLastRowTreeCreation = rowGroupingModel;
80
+ const groupingRules = getGroupingRules({
81
+ sanitizedRowGroupingModel,
82
+ columnsLookup
83
+ });
84
+ apiRef.current.unstable_caches.rowGrouping.rulesOnLastRowTreeCreation = groupingRules;
81
85
 
82
86
  const getCellGroupingCriteria = ({
83
87
  row,
84
88
  id,
85
- colDef
89
+ colDef,
90
+ groupingRule
86
91
  }) => {
87
92
  let key;
88
93
 
89
- if (colDef.groupingValueGetter) {
94
+ if (groupingRule.groupingValueGetter) {
90
95
  const groupingValueGetterParams = {
91
96
  colDef,
92
- field: colDef.field,
93
- value: row[colDef.field],
97
+ field: groupingRule.field,
98
+ value: row[groupingRule.field],
94
99
  id,
95
100
  row,
96
101
  rowNode: {
@@ -98,9 +103,9 @@ export const useGridRowGroupingPreProcessors = (apiRef, props) => {
98
103
  id
99
104
  }
100
105
  };
101
- key = colDef.groupingValueGetter(groupingValueGetterParams);
106
+ key = groupingRule.groupingValueGetter(groupingValueGetterParams);
102
107
  } else {
103
- key = row[colDef.field];
108
+ key = row[groupingRule.field];
104
109
  }
105
110
 
106
111
  return {
@@ -111,10 +116,11 @@ export const useGridRowGroupingPreProcessors = (apiRef, props) => {
111
116
 
112
117
  const rows = params.ids.map(rowId => {
113
118
  const row = params.idRowsLookup[rowId];
114
- const parentPath = rowGroupingModel.map(groupingField => getCellGroupingCriteria({
119
+ const parentPath = groupingRules.map(groupingRule => getCellGroupingCriteria({
115
120
  row,
116
121
  id: rowId,
117
- colDef: columnsLookup[groupingField]
122
+ groupingRule,
123
+ colDef: columnsLookup[groupingRule.field]
118
124
  })).filter(cell => cell.key != null);
119
125
  const leafGroupingCriteria = {
120
126
  key: rowId.toString(),
@@ -137,7 +143,8 @@ export const useGridRowGroupingPreProcessors = (apiRef, props) => {
137
143
  return filterRowTreeFromGroupingColumns({
138
144
  rowTree,
139
145
  isRowMatchingFilters: params.isRowMatchingFilters,
140
- filterModel: params.filterModel
146
+ filterModel: params.filterModel,
147
+ apiRef
141
148
  });
142
149
  }, [apiRef]);
143
150
  const sortRows = React.useCallback(params => {
package/modern/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /** @license MUI v5.16.0
1
+ /** @license MUI v5.17.0
2
2
  *
3
3
  * This source code is licensed under the MIT license found in the
4
4
  * LICENSE file in the root directory of this source tree.
@@ -1,6 +1,6 @@
1
1
  import { ponyfillGlobal } from '@mui/utils';
2
2
  export const getReleaseInfo = () => {
3
- const releaseInfo = "MTY2MTM3ODQwMDAwMA==";
3
+ const releaseInfo = "MTY2MjA2NjAwMDAwMA==";
4
4
 
5
5
  if (process.env.NODE_ENV !== 'production') {
6
6
  // A simple hack to set the value in the test environment (has no build step).
@@ -330,6 +330,7 @@ process.env.NODE_ENV !== "production" ? DataGridPremiumRaw.propTypes = {
330
330
  experimentalFeatures: _propTypes.default.shape({
331
331
  aggregation: _propTypes.default.bool,
332
332
  columnGrouping: _propTypes.default.bool,
333
+ lazyLoading: _propTypes.default.bool,
333
334
  newEditingApi: _propTypes.default.bool,
334
335
  preventCommitWhileValidating: _propTypes.default.bool,
335
336
  rowPinning: _propTypes.default.bool,
@@ -739,6 +740,14 @@ process.env.NODE_ENV !== "production" ? DataGridPremiumRaw.propTypes = {
739
740
  */
740
741
  onError: _propTypes.default.func,
741
742
 
743
+ /**
744
+ * Callback fired when rowCount is set and the next batch of virtualized rows is rendered.
745
+ * @param {GridFetchRowsParams} params With all properties from [[GridFetchRowsParams]].
746
+ * @param {MuiEvent<{}>} event The event object.
747
+ * @param {GridCallbackDetails} details Additional details for this callback.
748
+ */
749
+ onFetchRows: _propTypes.default.func,
750
+
742
751
  /**
743
752
  * Callback fired when the Filter model changes before the filters are applied.
744
753
  * @param {GridFilterModel} model With all properties from [[GridFilterModel]].
@@ -1003,6 +1012,14 @@ process.env.NODE_ENV !== "production" ? DataGridPremiumRaw.propTypes = {
1003
1012
  */
1004
1013
  rows: _propTypes.default.array.isRequired,
1005
1014
 
1015
+ /**
1016
+ * Loading rows can be processed on the server or client-side.
1017
+ * Set it to 'client' if you would like enable infnite loading.
1018
+ * Set it to 'server' if you would like to enable lazy loading.
1019
+ * * @default "client"
1020
+ */
1021
+ rowsLoadingMode: _propTypes.default.oneOf(['client', 'server']),
1022
+
1006
1023
  /**
1007
1024
  * Sets the type of space between rows added by `getRowSpacing`.
1008
1025
  * @default "margin"
@@ -61,6 +61,7 @@ const useDataGridPremiumComponent = (inputApiRef, props) => {
61
61
  (0, _internals.useGridInitializeState)(_internals.paginationStateInitializer, apiRef, props);
62
62
  (0, _internals.useGridInitializeState)(_internals.rowsMetaStateInitializer, apiRef, props);
63
63
  (0, _internals.useGridInitializeState)(_internals.columnMenuStateInitializer, apiRef, props);
64
+ (0, _internals.useGridInitializeState)(_internals.columnGroupsStateInitializer, apiRef, props);
64
65
  (0, _useGridRowGrouping.useGridRowGrouping)(apiRef, props);
65
66
  (0, _internals.useGridTreeData)(apiRef);
66
67
  (0, _useGridAggregation.useGridAggregation)(apiRef, props);
@@ -32,8 +32,23 @@ const getAggregationCellValue = ({
32
32
 
33
33
  const values = [];
34
34
  rowIds.forEach(rowId => {
35
+ var _rowNode$children;
36
+
35
37
  if (aggregationRowsScope === 'filtered' && filteredRowsLookup[rowId] === false) {
36
38
  return;
39
+ } // If the row is a group, we want to aggregate based on its children
40
+ // For instance in the following tree, we want the aggregated values of A to be based on A.A, A.B.A and A.B.B but not A.B
41
+ // A
42
+ // A.A
43
+ // A.B
44
+ // A.B.A
45
+ // A.B.B
46
+
47
+
48
+ const rowNode = apiRef.current.getRowNode(rowId);
49
+
50
+ if ((_rowNode$children = rowNode.children) != null && _rowNode$children.length) {
51
+ return;
37
52
  }
38
53
 
39
54
  values.push(apiRef.current.getCellValue(rowId, field));