@mui/x-data-grid-premium 5.15.2 → 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 (50) hide show
  1. package/CHANGELOG.md +177 -2
  2. package/DataGridPremium/DataGridPremium.js +20 -1
  3. package/DataGridPremium/useDataGridPremiumComponent.js +4 -1
  4. package/README.md +3 -2
  5. package/hooks/features/aggregation/createAggregationLookup.js +15 -0
  6. package/hooks/features/aggregation/gridAggregationUtils.d.ts +1 -1
  7. package/hooks/features/aggregation/gridAggregationUtils.js +6 -6
  8. package/hooks/features/aggregation/useGridAggregation.js +3 -3
  9. package/hooks/features/aggregation/wrapColumnWithAggregation.js +4 -3
  10. package/hooks/features/rowGrouping/gridRowGroupingInterfaces.d.ts +7 -1
  11. package/hooks/features/rowGrouping/gridRowGroupingUtils.d.ts +11 -2
  12. package/hooks/features/rowGrouping/gridRowGroupingUtils.js +35 -1
  13. package/hooks/features/rowGrouping/useGridRowGrouping.js +12 -8
  14. package/hooks/features/rowGrouping/useGridRowGroupingPreProcessors.js +19 -12
  15. package/index.js +1 -1
  16. package/legacy/DataGridPremium/DataGridPremium.js +20 -1
  17. package/legacy/DataGridPremium/useDataGridPremiumComponent.js +4 -1
  18. package/legacy/hooks/features/aggregation/createAggregationLookup.js +15 -0
  19. package/legacy/hooks/features/aggregation/gridAggregationUtils.js +6 -6
  20. package/legacy/hooks/features/aggregation/useGridAggregation.js +3 -3
  21. package/legacy/hooks/features/aggregation/wrapColumnWithAggregation.js +4 -3
  22. package/legacy/hooks/features/rowGrouping/gridRowGroupingUtils.js +39 -1
  23. package/legacy/hooks/features/rowGrouping/useGridRowGrouping.js +12 -8
  24. package/legacy/hooks/features/rowGrouping/useGridRowGroupingPreProcessors.js +19 -12
  25. package/legacy/index.js +1 -1
  26. package/legacy/utils/releaseInfo.js +1 -1
  27. package/modern/DataGridPremium/DataGridPremium.js +20 -1
  28. package/modern/DataGridPremium/useDataGridPremiumComponent.js +4 -1
  29. package/modern/hooks/features/aggregation/createAggregationLookup.js +13 -0
  30. package/modern/hooks/features/aggregation/gridAggregationUtils.js +6 -6
  31. package/modern/hooks/features/aggregation/useGridAggregation.js +3 -3
  32. package/modern/hooks/features/aggregation/wrapColumnWithAggregation.js +3 -2
  33. package/modern/hooks/features/rowGrouping/gridRowGroupingUtils.js +31 -1
  34. package/modern/hooks/features/rowGrouping/useGridRowGrouping.js +12 -8
  35. package/modern/hooks/features/rowGrouping/useGridRowGroupingPreProcessors.js +19 -12
  36. package/modern/index.js +1 -1
  37. package/modern/utils/releaseInfo.js +1 -1
  38. package/node/DataGridPremium/DataGridPremium.js +20 -1
  39. package/node/DataGridPremium/useDataGridPremiumComponent.js +3 -0
  40. package/node/hooks/features/aggregation/createAggregationLookup.js +15 -0
  41. package/node/hooks/features/aggregation/gridAggregationUtils.js +8 -8
  42. package/node/hooks/features/aggregation/useGridAggregation.js +2 -2
  43. package/node/hooks/features/aggregation/wrapColumnWithAggregation.js +4 -3
  44. package/node/hooks/features/rowGrouping/gridRowGroupingUtils.js +43 -3
  45. package/node/hooks/features/rowGrouping/useGridRowGrouping.js +9 -5
  46. package/node/hooks/features/rowGrouping/useGridRowGroupingPreProcessors.js +18 -11
  47. package/node/index.js +1 -1
  48. package/node/utils/releaseInfo.js +1 -1
  49. package/package.json +6 -6
  50. package/utils/releaseInfo.js +1 -1
@@ -124,6 +124,7 @@ process.env.NODE_ENV !== "production" ? DataGridPremiumRaw.propTypes = {
124
124
  * @default 3
125
125
  */
126
126
  columnBuffer: PropTypes.number,
127
+ columnGroupingModel: PropTypes.arrayOf(PropTypes.object),
127
128
 
128
129
  /**
129
130
  * Set of columns of type [[GridColumns]].
@@ -305,6 +306,8 @@ process.env.NODE_ENV !== "production" ? DataGridPremiumRaw.propTypes = {
305
306
  */
306
307
  experimentalFeatures: PropTypes.shape({
307
308
  aggregation: PropTypes.bool,
309
+ columnGrouping: PropTypes.bool,
310
+ lazyLoading: PropTypes.bool,
308
311
  newEditingApi: PropTypes.bool,
309
312
  preventCommitWhileValidating: PropTypes.bool,
310
313
  rowPinning: PropTypes.bool,
@@ -517,7 +520,7 @@ process.env.NODE_ENV !== "production" ? DataGridPremiumRaw.propTypes = {
517
520
 
518
521
  /**
519
522
  * Allows to pass the logging level or false to turn off logging.
520
- * @default "debug"
523
+ * @default "error" ("warn" in dev mode)
521
524
  */
522
525
  logLevel: PropTypes.oneOf(['debug', 'error', 'info', 'warn', false]),
523
526
 
@@ -714,6 +717,14 @@ process.env.NODE_ENV !== "production" ? DataGridPremiumRaw.propTypes = {
714
717
  */
715
718
  onError: PropTypes.func,
716
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
+
717
728
  /**
718
729
  * Callback fired when the Filter model changes before the filters are applied.
719
730
  * @param {GridFilterModel} model With all properties from [[GridFilterModel]].
@@ -978,6 +989,14 @@ process.env.NODE_ENV !== "production" ? DataGridPremiumRaw.propTypes = {
978
989
  */
979
990
  rows: PropTypes.array.isRequired,
980
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
+
981
1000
  /**
982
1001
  * Sets the type of space between rows added by `getRowSpacing`.
983
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, useGridRowPinning, useGridRowPinningPreProcessors, rowPinningStateInitializer } 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';
@@ -13,6 +13,7 @@ export var useDataGridPremiumComponent = function useDataGridPremiumComponent(in
13
13
  * Register all pre-processors called during state initialization here.
14
14
  */
15
15
 
16
+ useGridColumnGroupingPreProcessors(apiRef, props);
16
17
  useGridSelectionPreProcessors(apiRef, props);
17
18
  useGridRowReorderPreProcessors(apiRef, props);
18
19
  useGridRowGroupingPreProcessors(apiRef, props);
@@ -47,6 +48,7 @@ export var useDataGridPremiumComponent = function useDataGridPremiumComponent(in
47
48
  useGridInitializeState(paginationStateInitializer, apiRef, props);
48
49
  useGridInitializeState(rowsMetaStateInitializer, apiRef, props);
49
50
  useGridInitializeState(columnMenuStateInitializer, apiRef, props);
51
+ useGridInitializeState(columnGroupsStateInitializer, apiRef, props);
50
52
  useGridRowGrouping(apiRef, props);
51
53
  useGridTreeData(apiRef);
52
54
  useGridAggregation(apiRef, props);
@@ -59,6 +61,7 @@ export var useDataGridPremiumComponent = function useDataGridPremiumComponent(in
59
61
  useGridParamsApi(apiRef);
60
62
  useGridDetailPanel(apiRef, props);
61
63
  useGridColumnSpanning(apiRef);
64
+ useGridColumnGrouping(apiRef, props);
62
65
  var useGridEditing = (_props$experimentalFe2 = props.experimentalFeatures) != null && _props$experimentalFe2.newEditingApi ? useGridEditing_new : useGridEditing_old;
63
66
  useGridEditing(apiRef, props);
64
67
  useGridFocus(apiRef, props);
@@ -24,8 +24,23 @@ var getAggregationCellValue = function getAggregationCellValue(_ref) {
24
24
 
25
25
  var values = [];
26
26
  rowIds.forEach(function (rowId) {
27
+ var _rowNode$children;
28
+
27
29
  if (aggregationRowsScope === 'filtered' && filteredRowsLookup[rowId] === false) {
28
30
  return;
31
+ } // If the row is a group, we want to aggregate based on its children
32
+ // 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
33
+ // A
34
+ // A.A
35
+ // A.B
36
+ // A.B.A
37
+ // A.B.B
38
+
39
+
40
+ var rowNode = apiRef.current.getRowNode(rowId);
41
+
42
+ if ((_rowNode$children = rowNode.children) != null && _rowNode$children.length) {
43
+ return;
29
44
  }
30
45
 
31
46
  values.push(apiRef.current.getCellValue(rowId, field));
@@ -161,27 +161,27 @@ export var addFooterRows = function addFooterRows(_ref6) {
161
161
  * Compares two sets of aggregation rules to determine if they are equal or not.
162
162
  */
163
163
 
164
- export var hasAggregationRulesChanged = function hasAggregationRulesChanged(previousValue, newValue) {
164
+ export var areAggregationRulesEqual = function areAggregationRulesEqual(previousValue, newValue) {
165
165
  var previousFields = Object.keys(previousValue != null ? previousValue : {});
166
166
  var newFields = Object.keys(newValue);
167
167
 
168
168
  if (!isDeepEqual(previousFields, newFields)) {
169
- return true;
169
+ return false;
170
170
  }
171
171
 
172
- return newFields.some(function (field) {
172
+ return newFields.every(function (field) {
173
173
  var previousRule = previousValue == null ? void 0 : previousValue[field];
174
174
  var newRule = newValue[field];
175
175
 
176
176
  if ((previousRule == null ? void 0 : previousRule.aggregationFunction) !== (newRule == null ? void 0 : newRule.aggregationFunction)) {
177
- return true;
177
+ return false;
178
178
  }
179
179
 
180
180
  if ((previousRule == null ? void 0 : previousRule.aggregationFunctionName) !== (newRule == null ? void 0 : newRule.aggregationFunctionName)) {
181
- return true;
181
+ return false;
182
182
  }
183
183
 
184
- return false;
184
+ return true;
185
185
  });
186
186
  };
187
187
  export var getAggregationFunctionLabel = function getAggregationFunctionLabel(_ref7) {
@@ -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 var aggregationStateInitializer = function aggregationStateInitializer(state, props, apiRef) {
8
8
  var _ref, _props$aggregationMod, _props$initialState, _props$initialState$a;
@@ -70,13 +70,13 @@ export var useGridAggregation = function useGridAggregation(apiRef, props) {
70
70
  aggregationFunctions: props.aggregationFunctions
71
71
  }); // Re-apply the row hydration to add / remove the aggregation footers
72
72
 
73
- if (hasAggregationRulesChanged(rulesOnLastRowHydration, aggregationRules)) {
73
+ if (!areAggregationRulesEqual(rulesOnLastRowHydration, aggregationRules)) {
74
74
  apiRef.current.unstable_requestPipeProcessorsApplication('hydrateRows');
75
75
  applyAggregation();
76
76
  } // Re-apply the column hydration to wrap / unwrap the aggregated columns
77
77
 
78
78
 
79
- if (hasAggregationRulesChanged(rulesOnLastColumnHydration, aggregationRules)) {
79
+ if (!areAggregationRulesEqual(rulesOnLastColumnHydration, aggregationRules)) {
80
80
  apiRef.current.unstable_requestPipeProcessorsApplication('hydrateColumns');
81
81
  }
82
82
  }, [apiRef, applyAggregation, props.aggregationFunctions, props.disableAggregation]);
@@ -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.15.2
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 = "MTY2MDE2NTIwMDAwMA==";
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).
@@ -124,6 +124,7 @@ process.env.NODE_ENV !== "production" ? DataGridPremiumRaw.propTypes = {
124
124
  * @default 3
125
125
  */
126
126
  columnBuffer: PropTypes.number,
127
+ columnGroupingModel: PropTypes.arrayOf(PropTypes.object),
127
128
 
128
129
  /**
129
130
  * Set of columns of type [[GridColumns]].
@@ -305,6 +306,8 @@ process.env.NODE_ENV !== "production" ? DataGridPremiumRaw.propTypes = {
305
306
  */
306
307
  experimentalFeatures: PropTypes.shape({
307
308
  aggregation: PropTypes.bool,
309
+ columnGrouping: PropTypes.bool,
310
+ lazyLoading: PropTypes.bool,
308
311
  newEditingApi: PropTypes.bool,
309
312
  preventCommitWhileValidating: PropTypes.bool,
310
313
  rowPinning: PropTypes.bool,
@@ -517,7 +520,7 @@ process.env.NODE_ENV !== "production" ? DataGridPremiumRaw.propTypes = {
517
520
 
518
521
  /**
519
522
  * Allows to pass the logging level or false to turn off logging.
520
- * @default "debug"
523
+ * @default "error" ("warn" in dev mode)
521
524
  */
522
525
  logLevel: PropTypes.oneOf(['debug', 'error', 'info', 'warn', false]),
523
526
 
@@ -714,6 +717,14 @@ process.env.NODE_ENV !== "production" ? DataGridPremiumRaw.propTypes = {
714
717
  */
715
718
  onError: PropTypes.func,
716
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
+
717
728
  /**
718
729
  * Callback fired when the Filter model changes before the filters are applied.
719
730
  * @param {GridFilterModel} model With all properties from [[GridFilterModel]].
@@ -978,6 +989,14 @@ process.env.NODE_ENV !== "production" ? DataGridPremiumRaw.propTypes = {
978
989
  */
979
990
  rows: PropTypes.array.isRequired,
980
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
+
981
1000
  /**
982
1001
  * Sets the type of space between rows added by `getRowSpacing`.
983
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, useGridRowPinning, useGridRowPinningPreProcessors, rowPinningStateInitializer } 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';
@@ -11,6 +11,7 @@ export const useDataGridPremiumComponent = (inputApiRef, props) => {
11
11
  * Register all pre-processors called during state initialization here.
12
12
  */
13
13
 
14
+ useGridColumnGroupingPreProcessors(apiRef, props);
14
15
  useGridSelectionPreProcessors(apiRef, props);
15
16
  useGridRowReorderPreProcessors(apiRef, props);
16
17
  useGridRowGroupingPreProcessors(apiRef, props);
@@ -45,6 +46,7 @@ export const useDataGridPremiumComponent = (inputApiRef, props) => {
45
46
  useGridInitializeState(paginationStateInitializer, apiRef, props);
46
47
  useGridInitializeState(rowsMetaStateInitializer, apiRef, props);
47
48
  useGridInitializeState(columnMenuStateInitializer, apiRef, props);
49
+ useGridInitializeState(columnGroupsStateInitializer, apiRef, props);
48
50
  useGridRowGrouping(apiRef, props);
49
51
  useGridTreeData(apiRef);
50
52
  useGridAggregation(apiRef, props);
@@ -57,6 +59,7 @@ export const useDataGridPremiumComponent = (inputApiRef, props) => {
57
59
  useGridParamsApi(apiRef);
58
60
  useGridDetailPanel(apiRef, props);
59
61
  useGridColumnSpanning(apiRef);
62
+ useGridColumnGrouping(apiRef, props);
60
63
  const useGridEditing = props.experimentalFeatures?.newEditingApi ? useGridEditing_new : useGridEditing_old;
61
64
  useGridEditing(apiRef, props);
62
65
  useGridFocus(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
  };