@mui/x-data-grid 5.11.0 → 5.12.1

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 (217) hide show
  1. package/CHANGELOG.md +237 -16
  2. package/DataGrid/DataGrid.js +26 -1
  3. package/README.md +3 -4
  4. package/components/GridRow.d.ts +1 -1
  5. package/components/GridRow.js +51 -12
  6. package/components/base/GridOverlays.js +1 -1
  7. package/components/cell/GridActionsCellItem.d.ts +1 -1
  8. package/components/cell/GridCell.d.ts +2 -1
  9. package/components/cell/GridCell.js +12 -7
  10. package/components/columnHeaders/GridColumnHeaderItem.js +4 -3
  11. package/components/containers/GridRoot.js +25 -5
  12. package/components/containers/GridRootStyles.js +7 -2
  13. package/components/menu/GridMenu.js +9 -2
  14. package/components/panel/GridColumnsPanel.js +10 -2
  15. package/components/panel/GridPanelWrapper.d.ts +1 -1
  16. package/components/panel/GridPanelWrapper.js +3 -3
  17. package/components/panel/filterPanel/GridFilterForm.d.ts +61 -4
  18. package/components/panel/filterPanel/GridFilterForm.js +88 -8
  19. package/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.js +0 -1
  20. package/components/panel/filterPanel/GridFilterPanel.d.ts +8 -5
  21. package/components/panel/filterPanel/GridFilterPanel.js +25 -9
  22. package/components/toolbar/GridToolbarFilterButton.d.ts +1 -1
  23. package/components/toolbar/GridToolbarQuickFilter.d.ts +7 -0
  24. package/components/toolbar/GridToolbarQuickFilter.js +58 -6
  25. package/constants/defaultGridSlotsComponents.js +4 -2
  26. package/constants/gridClasses.d.ts +16 -0
  27. package/constants/gridClasses.js +1 -1
  28. package/hooks/core/pipeProcessing/gridPipeProcessingApi.d.ts +4 -0
  29. package/hooks/core/pipeProcessing/useGridPipeProcessing.js +10 -9
  30. package/hooks/core/useGridStateInitialization.js +19 -6
  31. package/hooks/features/columnMenu/useGridColumnMenu.js +22 -0
  32. package/hooks/features/columns/gridColumnsInterfaces.d.ts +3 -0
  33. package/hooks/features/columns/useGridColumns.js +13 -15
  34. package/hooks/features/editRows/useGridCellEditing.new.js +11 -4
  35. package/hooks/features/editRows/useGridEditing.old.js +1 -1
  36. package/hooks/features/editRows/useGridRowEditing.new.js +10 -4
  37. package/hooks/features/events/useGridEvents.d.ts +1 -1
  38. package/hooks/features/events/useGridEvents.js +2 -0
  39. package/hooks/features/filter/gridFilterSelector.d.ts +5 -0
  40. package/hooks/features/filter/gridFilterSelector.js +6 -0
  41. package/hooks/features/filter/gridFilterUtils.d.ts +10 -2
  42. package/hooks/features/filter/gridFilterUtils.js +3 -6
  43. package/hooks/features/filter/useGridFilter.js +29 -12
  44. package/hooks/features/pagination/useGridPage.js +1 -1
  45. package/hooks/features/pagination/useGridPageSize.js +1 -1
  46. package/hooks/features/rows/gridRowsState.d.ts +14 -5
  47. package/hooks/features/rows/gridRowsUtils.d.ts +13 -1
  48. package/hooks/features/rows/gridRowsUtils.js +54 -0
  49. package/hooks/features/rows/useGridRows.js +63 -102
  50. package/hooks/features/rows/useGridRowsMeta.d.ts +1 -1
  51. package/hooks/features/rows/useGridRowsMeta.js +107 -43
  52. package/hooks/features/selection/useGridSelection.js +1 -1
  53. package/hooks/features/sorting/useGridSorting.js +1 -1
  54. package/hooks/features/virtualization/useGridVirtualScroller.d.ts +1 -0
  55. package/hooks/features/virtualization/useGridVirtualScroller.js +27 -7
  56. package/index.js +1 -1
  57. package/internals/index.d.ts +1 -0
  58. package/legacy/DataGrid/DataGrid.js +26 -1
  59. package/legacy/components/GridRow.js +56 -12
  60. package/legacy/components/base/GridOverlays.js +1 -1
  61. package/legacy/components/cell/GridCell.js +12 -7
  62. package/legacy/components/columnHeaders/GridColumnHeaderItem.js +6 -3
  63. package/legacy/components/containers/GridRoot.js +23 -5
  64. package/legacy/components/containers/GridRootStyles.js +9 -6
  65. package/legacy/components/menu/GridMenu.js +9 -2
  66. package/legacy/components/panel/GridColumnsPanel.js +12 -2
  67. package/legacy/components/panel/GridPanelWrapper.js +3 -3
  68. package/legacy/components/panel/filterPanel/GridFilterForm.js +89 -8
  69. package/legacy/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.js +0 -1
  70. package/legacy/components/panel/filterPanel/GridFilterPanel.js +27 -10
  71. package/legacy/components/toolbar/GridToolbarQuickFilter.js +68 -8
  72. package/legacy/constants/defaultGridSlotsComponents.js +4 -2
  73. package/legacy/constants/gridClasses.js +1 -1
  74. package/legacy/hooks/core/pipeProcessing/useGridPipeProcessing.js +10 -10
  75. package/legacy/hooks/core/useGridStateInitialization.js +18 -6
  76. package/legacy/hooks/features/columnMenu/useGridColumnMenu.js +22 -0
  77. package/legacy/hooks/features/columns/useGridColumns.js +13 -15
  78. package/legacy/hooks/features/editRows/useGridCellEditing.new.js +14 -7
  79. package/legacy/hooks/features/editRows/useGridEditing.old.js +1 -1
  80. package/legacy/hooks/features/editRows/useGridRowEditing.new.js +10 -4
  81. package/legacy/hooks/features/events/useGridEvents.js +2 -0
  82. package/legacy/hooks/features/filter/gridFilterSelector.js +8 -0
  83. package/legacy/hooks/features/filter/gridFilterUtils.js +4 -7
  84. package/legacy/hooks/features/filter/useGridFilter.js +33 -12
  85. package/legacy/hooks/features/pagination/useGridPage.js +1 -1
  86. package/legacy/hooks/features/pagination/useGridPageSize.js +1 -1
  87. package/legacy/hooks/features/rows/gridRowsUtils.js +55 -0
  88. package/legacy/hooks/features/rows/useGridRows.js +75 -111
  89. package/legacy/hooks/features/rows/useGridRowsMeta.js +104 -41
  90. package/legacy/hooks/features/selection/useGridSelection.js +1 -1
  91. package/legacy/hooks/features/sorting/useGridSorting.js +1 -1
  92. package/legacy/hooks/features/virtualization/useGridVirtualScroller.js +46 -22
  93. package/legacy/index.js +1 -1
  94. package/legacy/locales/heIL.js +9 -9
  95. package/legacy/locales/jaJP.js +28 -24
  96. package/legacy/locales/nbNO.js +127 -0
  97. package/legacy/locales/ruRU.js +9 -9
  98. package/legacy/locales/trTR.js +7 -7
  99. package/legacy/models/events/gridEvents.js +2 -0
  100. package/legacy/models/gridApiCaches.js +1 -0
  101. package/legacy/models/params/gridMenuParams.js +1 -0
  102. package/legacy/models/params/index.js +2 -1
  103. package/locales/heIL.js +9 -9
  104. package/locales/jaJP.js +24 -24
  105. package/locales/nbNO.d.ts +2 -0
  106. package/locales/nbNO.js +115 -0
  107. package/locales/ruRU.js +9 -9
  108. package/locales/trTR.js +7 -7
  109. package/models/api/gridCallbackDetails.d.ts +6 -1
  110. package/models/api/gridCoreApi.d.ts +2 -6
  111. package/models/api/gridFilterApi.d.ts +8 -1
  112. package/models/api/gridRowsMetaApi.d.ts +24 -0
  113. package/models/api/gridStateApi.d.ts +14 -3
  114. package/models/colDef/gridColDef.d.ts +3 -3
  115. package/models/events/gridEventLookup.d.ts +16 -1
  116. package/models/events/gridEvents.d.ts +3 -1
  117. package/models/events/gridEvents.js +2 -0
  118. package/models/gridApiCaches.d.ts +6 -0
  119. package/models/gridApiCaches.js +1 -0
  120. package/models/gridIconSlotsComponent.d.ts +10 -0
  121. package/models/params/gridMenuParams.d.ts +7 -0
  122. package/models/params/gridMenuParams.js +1 -0
  123. package/models/params/gridRowParams.d.ts +1 -1
  124. package/models/params/index.d.ts +1 -0
  125. package/models/params/index.js +2 -1
  126. package/models/props/DataGridProps.d.ts +24 -2
  127. package/modern/DataGrid/DataGrid.js +26 -1
  128. package/modern/components/GridRow.js +51 -12
  129. package/modern/components/base/GridOverlays.js +1 -1
  130. package/modern/components/cell/GridCell.js +12 -7
  131. package/modern/components/columnHeaders/GridColumnHeaderItem.js +4 -3
  132. package/modern/components/containers/GridRoot.js +25 -3
  133. package/modern/components/containers/GridRootStyles.js +7 -2
  134. package/modern/components/menu/GridMenu.js +9 -2
  135. package/modern/components/panel/GridColumnsPanel.js +10 -2
  136. package/modern/components/panel/GridPanelWrapper.js +3 -3
  137. package/modern/components/panel/filterPanel/GridFilterForm.js +88 -8
  138. package/modern/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.js +0 -1
  139. package/modern/components/panel/filterPanel/GridFilterPanel.js +25 -9
  140. package/modern/components/toolbar/GridToolbarQuickFilter.js +58 -6
  141. package/modern/constants/defaultGridSlotsComponents.js +4 -2
  142. package/modern/constants/gridClasses.js +1 -1
  143. package/modern/hooks/core/pipeProcessing/useGridPipeProcessing.js +10 -9
  144. package/modern/hooks/core/useGridStateInitialization.js +19 -6
  145. package/modern/hooks/features/columnMenu/useGridColumnMenu.js +22 -0
  146. package/modern/hooks/features/columns/useGridColumns.js +12 -14
  147. package/modern/hooks/features/editRows/useGridCellEditing.new.js +10 -3
  148. package/modern/hooks/features/editRows/useGridEditing.old.js +1 -1
  149. package/modern/hooks/features/editRows/useGridRowEditing.new.js +9 -3
  150. package/modern/hooks/features/events/useGridEvents.js +2 -0
  151. package/modern/hooks/features/filter/gridFilterSelector.js +6 -0
  152. package/modern/hooks/features/filter/gridFilterUtils.js +3 -6
  153. package/modern/hooks/features/filter/useGridFilter.js +29 -12
  154. package/modern/hooks/features/pagination/useGridPage.js +1 -1
  155. package/modern/hooks/features/pagination/useGridPageSize.js +1 -1
  156. package/modern/hooks/features/rows/gridRowsUtils.js +54 -0
  157. package/modern/hooks/features/rows/useGridRows.js +63 -102
  158. package/modern/hooks/features/rows/useGridRowsMeta.js +105 -37
  159. package/modern/hooks/features/selection/useGridSelection.js +1 -1
  160. package/modern/hooks/features/sorting/useGridSorting.js +1 -1
  161. package/modern/hooks/features/virtualization/useGridVirtualScroller.js +27 -7
  162. package/modern/index.js +1 -1
  163. package/modern/locales/heIL.js +9 -9
  164. package/modern/locales/jaJP.js +24 -24
  165. package/modern/locales/nbNO.js +115 -0
  166. package/modern/locales/ruRU.js +9 -9
  167. package/modern/locales/trTR.js +7 -7
  168. package/modern/models/events/gridEvents.js +2 -0
  169. package/modern/models/gridApiCaches.js +1 -0
  170. package/modern/models/params/gridMenuParams.js +1 -0
  171. package/modern/models/params/index.js +2 -1
  172. package/node/DataGrid/DataGrid.js +26 -1
  173. package/node/components/GridRow.js +53 -12
  174. package/node/components/base/GridOverlays.js +1 -1
  175. package/node/components/cell/GridCell.js +12 -7
  176. package/node/components/columnHeaders/GridColumnHeaderItem.js +4 -3
  177. package/node/components/containers/GridRoot.js +24 -3
  178. package/node/components/containers/GridRootStyles.js +7 -2
  179. package/node/components/menu/GridMenu.js +10 -2
  180. package/node/components/panel/GridColumnsPanel.js +10 -2
  181. package/node/components/panel/GridPanelWrapper.js +5 -3
  182. package/node/components/panel/filterPanel/GridFilterForm.js +91 -9
  183. package/node/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.js +0 -1
  184. package/node/components/panel/filterPanel/GridFilterPanel.js +27 -9
  185. package/node/components/toolbar/GridToolbarQuickFilter.js +61 -6
  186. package/node/constants/defaultGridSlotsComponents.js +3 -1
  187. package/node/constants/gridClasses.js +1 -1
  188. package/node/hooks/core/pipeProcessing/useGridPipeProcessing.js +10 -8
  189. package/node/hooks/core/useGridStateInitialization.js +19 -6
  190. package/node/hooks/features/columnMenu/useGridColumnMenu.js +23 -0
  191. package/node/hooks/features/columns/useGridColumns.js +13 -15
  192. package/node/hooks/features/editRows/useGridCellEditing.new.js +11 -4
  193. package/node/hooks/features/editRows/useGridEditing.old.js +1 -1
  194. package/node/hooks/features/editRows/useGridRowEditing.new.js +10 -4
  195. package/node/hooks/features/events/useGridEvents.js +2 -0
  196. package/node/hooks/features/filter/gridFilterSelector.js +9 -2
  197. package/node/hooks/features/filter/gridFilterUtils.js +4 -5
  198. package/node/hooks/features/filter/useGridFilter.js +28 -11
  199. package/node/hooks/features/pagination/useGridPage.js +1 -1
  200. package/node/hooks/features/pagination/useGridPageSize.js +1 -1
  201. package/node/hooks/features/rows/gridRowsUtils.js +67 -1
  202. package/node/hooks/features/rows/useGridRows.js +63 -99
  203. package/node/hooks/features/rows/useGridRowsMeta.js +107 -43
  204. package/node/hooks/features/selection/useGridSelection.js +1 -1
  205. package/node/hooks/features/sorting/useGridSorting.js +1 -1
  206. package/node/hooks/features/virtualization/useGridVirtualScroller.js +27 -7
  207. package/node/index.js +1 -1
  208. package/node/locales/heIL.js +9 -9
  209. package/node/locales/jaJP.js +24 -24
  210. package/node/locales/nbNO.js +125 -0
  211. package/node/locales/ruRU.js +9 -9
  212. package/node/locales/trTR.js +7 -7
  213. package/node/models/events/gridEvents.js +2 -0
  214. package/node/models/gridApiCaches.js +5 -0
  215. package/node/models/params/gridMenuParams.js +5 -0
  216. package/node/models/params/index.js +13 -0
  217. package/package.json +7 -5
@@ -10,7 +10,7 @@ import { gridColumnFieldsSelector } from '../columns';
10
10
  * @return {GridFilterItem} The clean filter item with an uniq ID and an always-defined operatorValue.
11
11
  * TODO: Make the typing reflect the different between GridFilterInputItem and GridFilterItem.
12
12
  */
13
- const cleanFilterItem = (item, apiRef) => {
13
+ export const cleanFilterItem = (item, apiRef) => {
14
14
  const cleanItem = _extends({}, item);
15
15
 
16
16
  if (cleanItem.id == null) {
@@ -25,7 +25,6 @@ const cleanFilterItem = (item, apiRef) => {
25
25
 
26
26
  return cleanItem;
27
27
  };
28
-
29
28
  const filterModelDisableMultiColumnsFilteringWarning = buildWarning(['MUI: The `filterModel` can only contain a single item when the `disableMultipleColumnsFiltering` prop is set to `true`.', 'If you are using the community version of the `DataGrid`, this prop is always `true`.'], 'error');
30
29
  const filterModelMissingItemIdWarning = buildWarning("MUI: The 'id' field is required on `filterModel.items` when you use multiple filters.", 'error');
31
30
  const filterModelMissingItemOperatorWarning = buildWarning(['MUI: One of your filtering item have no `operatorValue` provided.', 'This property will become required on `@mui/x-data-grid@6.X`.']);
@@ -65,10 +64,8 @@ export const sanitizeFilterModel = (model, disableMultipleColumnsFiltering, apiR
65
64
 
66
65
  return model;
67
66
  };
68
- export const mergeStateWithFilterModel = (filterModel, disableMultipleColumnsFiltering, apiRef) => state => _extends({}, state, {
69
- filter: _extends({}, state.filter, {
70
- filterModel: sanitizeFilterModel(filterModel, disableMultipleColumnsFiltering, apiRef)
71
- })
67
+ export const mergeStateWithFilterModel = (filterModel, disableMultipleColumnsFiltering, apiRef) => filteringState => _extends({}, filteringState, {
68
+ filterModel: sanitizeFilterModel(filterModel, disableMultipleColumnsFiltering, apiRef)
72
69
  });
73
70
  /**
74
71
  * Generates a method to easily check if a row is matching the current filter model.
@@ -12,7 +12,7 @@ import { useFirstRender } from '../../utils/useFirstRender';
12
12
  import { gridRowIdsSelector } from '../rows';
13
13
  import { useGridRegisterPipeProcessor } from '../../core/pipeProcessing';
14
14
  import { GRID_DEFAULT_STRATEGY, useGridRegisterStrategyProcessor } from '../../core/strategyProcessing';
15
- import { buildAggregatedFilterApplier, sanitizeFilterModel, mergeStateWithFilterModel } from './gridFilterUtils';
15
+ import { buildAggregatedFilterApplier, sanitizeFilterModel, mergeStateWithFilterModel, cleanFilterItem } from './gridFilterUtils';
16
16
  import { isDeepEqual } from '../../../utils/utils';
17
17
  import { jsx as _jsx } from "react/jsx-runtime";
18
18
  export const filterStateInitializer = (state, props, apiRef) => {
@@ -37,7 +37,7 @@ export const useGridFilter = (apiRef, props) => {
37
37
  var _props$componentsProp2;
38
38
 
39
39
  const logger = useGridLogger(apiRef, 'useGridFilter');
40
- apiRef.current.unstable_updateControlState({
40
+ apiRef.current.unstable_registerControlState({
41
41
  stateId: 'filter',
42
42
  propModel: props.filterModel,
43
43
  propOnChange: props.onFilterModelChange,
@@ -78,7 +78,23 @@ export const useGridFilter = (apiRef, props) => {
78
78
 
79
79
  apiRef.current.setFilterModel(_extends({}, filterModel, {
80
80
  items
81
- }));
81
+ }), 'upsertFilterItem');
82
+ }, [apiRef]);
83
+ const upsertFilterItems = React.useCallback(items => {
84
+ const filterModel = gridFilterModelSelector(apiRef);
85
+ const existingItems = [...filterModel.items];
86
+ items.forEach(item => {
87
+ const itemIndex = items.findIndex(filterItem => filterItem.id === item.id);
88
+
89
+ if (itemIndex === -1) {
90
+ existingItems.push(item);
91
+ } else {
92
+ existingItems[itemIndex] = item;
93
+ }
94
+ });
95
+ apiRef.current.setFilterModel(_extends({}, filterModel, {
96
+ items
97
+ }), 'upsertFilterItems');
82
98
  }, [apiRef]);
83
99
  const deleteFilterItem = React.useCallback(itemToDelete => {
84
100
  const filterModel = gridFilterModelSelector(apiRef);
@@ -90,7 +106,7 @@ export const useGridFilter = (apiRef, props) => {
90
106
 
91
107
  apiRef.current.setFilterModel(_extends({}, filterModel, {
92
108
  items
93
- }));
109
+ }), 'deleteFilterItem');
94
110
  }, [apiRef]);
95
111
  const showFilterPanel = React.useCallback(targetColumnField => {
96
112
  logger.debug('Displaying filter panel');
@@ -104,13 +120,13 @@ export const useGridFilter = (apiRef, props) => {
104
120
  if (filterItemOnTarget) {
105
121
  newFilterItems = filterItemsWithValue;
106
122
  } else if (props.disableMultipleColumnsFiltering) {
107
- newFilterItems = [{
123
+ newFilterItems = [cleanFilterItem({
108
124
  columnField: targetColumnField
109
- }];
125
+ }, apiRef)];
110
126
  } else {
111
- newFilterItems = [...filterItemsWithValue, {
127
+ newFilterItems = [...filterItemsWithValue, cleanFilterItem({
112
128
  columnField: targetColumnField
113
- }];
129
+ }, apiRef)];
114
130
  }
115
131
 
116
132
  apiRef.current.setFilterModel(_extends({}, filterModel, {
@@ -133,7 +149,7 @@ export const useGridFilter = (apiRef, props) => {
133
149
 
134
150
  apiRef.current.setFilterModel(_extends({}, filterModel, {
135
151
  linkOperator
136
- }));
152
+ }), 'changeLogicOperator');
137
153
  }, [apiRef]);
138
154
  const setQuickFilterValues = React.useCallback(values => {
139
155
  const filterModel = gridFilterModelSelector(apiRef);
@@ -146,12 +162,12 @@ export const useGridFilter = (apiRef, props) => {
146
162
  quickFilterValues: [...values]
147
163
  }));
148
164
  }, [apiRef]);
149
- const setFilterModel = React.useCallback(model => {
165
+ const setFilterModel = React.useCallback((model, reason) => {
150
166
  const currentModel = gridFilterModelSelector(apiRef);
151
167
 
152
168
  if (currentModel !== model) {
153
169
  logger.debug('Setting filter model');
154
- apiRef.current.setState(mergeStateWithFilterModel(model, props.disableMultipleColumnsFiltering, apiRef));
170
+ apiRef.current.unstable_updateControlState('filter', mergeStateWithFilterModel(model, props.disableMultipleColumnsFiltering, apiRef), reason);
155
171
  apiRef.current.unstable_applyFilters();
156
172
  }
157
173
  }, [apiRef, logger, props.disableMultipleColumnsFiltering]);
@@ -164,6 +180,7 @@ export const useGridFilter = (apiRef, props) => {
164
180
  unstable_applyFilters: applyFilters,
165
181
  deleteFilterItem,
166
182
  upsertFilterItem,
183
+ upsertFilterItems,
167
184
  setFilterModel,
168
185
  showFilterPanel,
169
186
  hideFilterPanel,
@@ -197,7 +214,7 @@ export const useGridFilter = (apiRef, props) => {
197
214
  return params;
198
215
  }
199
216
 
200
- apiRef.current.setState(mergeStateWithFilterModel(filterModel, props.disableMultipleColumnsFiltering, apiRef));
217
+ apiRef.current.unstable_updateControlState('filter', mergeStateWithFilterModel(filterModel, props.disableMultipleColumnsFiltering, apiRef), 'restoreState');
201
218
  return _extends({}, params, {
202
219
  callbacks: [...params.callbacks, apiRef.current.unstable_applyFilters]
203
220
  });
@@ -39,7 +39,7 @@ export const useGridPage = (apiRef, props) => {
39
39
 
40
40
  const logger = useGridLogger(apiRef, 'useGridPage');
41
41
  const visibleTopLevelRowCount = useGridSelector(apiRef, gridVisibleTopLevelRowCountSelector);
42
- apiRef.current.unstable_updateControlState({
42
+ apiRef.current.unstable_registerControlState({
43
43
  stateId: 'page',
44
44
  propModel: props.page,
45
45
  propOnChange: props.onPageChange,
@@ -21,7 +21,7 @@ export const useGridPageSize = (apiRef, props) => {
21
21
 
22
22
  const logger = useGridLogger(apiRef, 'useGridPageSize');
23
23
  const rowHeight = useGridSelector(apiRef, gridDensityRowHeightSelector);
24
- apiRef.current.unstable_updateControlState({
24
+ apiRef.current.unstable_registerControlState({
25
25
  stateId: 'pageSize',
26
26
  propModel: props.pageSize,
27
27
  propOnChange: props.onPageSizeChange,
@@ -1,4 +1,5 @@
1
- import { GridRowId, GridRowsLookup, GridRowsProp, GridRowTreeConfig } from '../../../models/gridRows';
1
+ import { GridRowId, GridRowsLookup, GridRowTreeConfig } from '../../../models/gridRows';
2
+ import type { DataGridProcessedProps } from '../../../models/props/DataGridProps';
2
3
  export interface GridRowTreeCreationParams {
3
4
  ids: GridRowId[];
4
5
  idRowsLookup: GridRowsLookup;
@@ -17,14 +18,16 @@ export interface GridRowTreeCreationValue {
17
18
  idRowsLookup: GridRowsLookup;
18
19
  idToIdLookup: Record<string, GridRowId>;
19
20
  }
20
- export declare type GridRowInternalCacheValue = Omit<GridRowTreeCreationParams, 'previousTree'>;
21
- export interface GridRowsInternalCache {
22
- value: GridRowInternalCacheValue;
21
+ export interface GridRowsInternalCache extends Omit<GridRowTreeCreationParams, 'previousTree'> {
23
22
  /**
24
23
  * The rows as they were the last time all the rows have been updated at once
25
24
  * It is used to avoid processing several time the same set of rows
26
25
  */
27
- rowsBeforePartialUpdates: GridRowsProp;
26
+ rowsBeforePartialUpdates: DataGridProcessedProps['rows'];
27
+ /**
28
+ * The value of the `loading` prop since the last time that the rows state was updated.
29
+ */
30
+ loadingPropBeforePartialUpdates: DataGridProcessedProps['loading'];
28
31
  }
29
32
  export interface GridRowsState extends GridRowTreeCreationValue {
30
33
  /**
@@ -41,4 +44,10 @@ export interface GridRowsState extends GridRowTreeCreationValue {
41
44
  * It does not count the expanded children rows.
42
45
  */
43
46
  totalTopLevelRowCount: number;
47
+ /**
48
+ * Tree returned by the `rowTreeCreation` strategy processor.
49
+ * It is used to re-apply the `hydrateRows` pipe processor without having to recreate the tree.
50
+ */
51
+ groupingResponseBeforeRowHydration: GridRowTreeCreationValue;
44
52
  }
53
+ export declare type GridHydrateRowsValue = GridRowTreeCreationValue;
@@ -1,4 +1,8 @@
1
- import { GridRowId, GridRowModel, GridRowTreeConfig } from '../../../models';
1
+ import * as React from 'react';
2
+ import { GridRowId, GridRowIdGetter, GridRowModel, GridRowTreeConfig } from '../../../models';
3
+ import { DataGridProcessedProps } from '../../../models/props/DataGridProps';
4
+ import { GridApiCommunity } from '../../../models/api/gridApiCommunity';
5
+ import { GridRowsInternalCache, GridRowsState } from './gridRowsState';
2
6
  /**
3
7
  * A helper function to check if the id provided is valid.
4
8
  * @param {GridRowId} id Id as [[GridRowId]].
@@ -6,4 +10,12 @@ import { GridRowId, GridRowModel, GridRowTreeConfig } from '../../../models';
6
10
  * @param {string} detailErrorMessage A custom error message to display for invalid IDs
7
11
  */
8
12
  export declare function checkGridRowIdIsValid(id: GridRowId, row: GridRowModel | Partial<GridRowModel>, detailErrorMessage?: string): void;
13
+ export declare const getRowIdFromRowModel: (rowModel: GridRowModel, getRowId?: GridRowIdGetter<any> | undefined, detailErrorMessage?: string | undefined) => GridRowId;
14
+ export declare const createRowsInternalCache: ({ rows, getRowId, loading, }: Pick<DataGridProcessedProps, 'rows' | 'getRowId' | 'loading'>) => GridRowsInternalCache;
15
+ export declare const getRowsStateFromCache: ({ apiRef, previousTree, rowCountProp, loadingProp, }: {
16
+ apiRef: React.MutableRefObject<GridApiCommunity>;
17
+ previousTree: GridRowTreeConfig | null;
18
+ rowCountProp: number | undefined;
19
+ loadingProp: boolean | undefined;
20
+ }) => GridRowsState;
9
21
  export declare const getTreeNodeDescendants: (tree: GridRowTreeConfig, parentId: GridRowId, skipAutoGeneratedRows: boolean) => GridRowId[];
@@ -1,3 +1,7 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
+ const _excluded = ["rowsBeforePartialUpdates"];
4
+
1
5
  /**
2
6
  * A helper function to check if the id provided is valid.
3
7
  * @param {GridRowId} id Id as [[GridRowId]].
@@ -9,6 +13,56 @@ export function checkGridRowIdIsValid(id, row, detailErrorMessage = 'A row was p
9
13
  throw new Error(['MUI: The data grid component requires all rows to have a unique `id` property.', 'Alternatively, you can use the `getRowId` prop to specify a custom id for each row.', detailErrorMessage, JSON.stringify(row)].join('\n'));
10
14
  }
11
15
  }
16
+ export const getRowIdFromRowModel = (rowModel, getRowId, detailErrorMessage) => {
17
+ const id = getRowId ? getRowId(rowModel) : rowModel.id;
18
+ checkGridRowIdIsValid(id, rowModel, detailErrorMessage);
19
+ return id;
20
+ };
21
+ export const createRowsInternalCache = ({
22
+ rows,
23
+ getRowId,
24
+ loading
25
+ }) => {
26
+ const cache = {
27
+ rowsBeforePartialUpdates: rows,
28
+ loadingPropBeforePartialUpdates: loading,
29
+ idRowsLookup: {},
30
+ idToIdLookup: {},
31
+ ids: []
32
+ };
33
+
34
+ for (let i = 0; i < rows.length; i += 1) {
35
+ const row = rows[i];
36
+ const id = getRowIdFromRowModel(row, getRowId);
37
+ cache.idRowsLookup[id] = row;
38
+ cache.idToIdLookup[id] = id;
39
+ cache.ids.push(id);
40
+ }
41
+
42
+ return cache;
43
+ };
44
+ export const getRowsStateFromCache = ({
45
+ apiRef,
46
+ previousTree,
47
+ rowCountProp,
48
+ loadingProp
49
+ }) => {
50
+ const _apiRef$current$unsta = apiRef.current.unstable_caches.rows,
51
+ cacheForGrouping = _objectWithoutPropertiesLoose(_apiRef$current$unsta, _excluded);
52
+
53
+ const rowCount = rowCountProp != null ? rowCountProp : 0;
54
+ const groupingResponse = apiRef.current.unstable_applyStrategyProcessor('rowTreeCreation', _extends({}, cacheForGrouping, {
55
+ previousTree
56
+ }));
57
+ const processedGroupingResponse = apiRef.current.unstable_applyPipeProcessors('hydrateRows', groupingResponse);
58
+ const dataTopLevelRowCount = processedGroupingResponse.treeDepth === 1 ? processedGroupingResponse.ids.length : Object.values(processedGroupingResponse.tree).filter(node => node.parent == null).length;
59
+ return _extends({}, processedGroupingResponse, {
60
+ groupingResponseBeforeRowHydration: groupingResponse,
61
+ loading: loadingProp,
62
+ totalRowCount: Math.max(rowCount, processedGroupingResponse.ids.length),
63
+ totalTopLevelRowCount: Math.max(rowCount, dataTopLevelRowCount)
64
+ });
65
+ };
12
66
  export const getTreeNodeDescendants = (tree, parentId, skipAutoGeneratedRows) => {
13
67
  var _tree$parentId;
14
68
 
@@ -7,76 +7,21 @@ import { GridSignature, useGridApiEventHandler } from '../../utils/useGridApiEve
7
7
  import { useGridVisibleRows } from '../../utils/useGridVisibleRows';
8
8
  import { gridSortedRowIdsSelector } from '../sorting/gridSortingSelector';
9
9
  import { gridFilteredRowsLookupSelector } from '../filter/gridFilterSelector';
10
- import { checkGridRowIdIsValid, getTreeNodeDescendants } from './gridRowsUtils';
11
-
12
- function getGridRowId(rowModel, getRowId, detailErrorMessage) {
13
- const id = getRowId ? getRowId(rowModel) : rowModel.id;
14
- checkGridRowIdIsValid(id, rowModel, detailErrorMessage);
15
- return id;
16
- }
17
-
18
- const convertRowsPropToState = ({
19
- prevCache: prevState,
20
- rows,
21
- getRowId
22
- }) => {
23
- let value;
24
-
25
- if (rows) {
26
- value = {
27
- idRowsLookup: {},
28
- idToIdLookup: {},
29
- ids: []
30
- };
31
-
32
- for (let i = 0; i < rows.length; i += 1) {
33
- const row = rows[i];
34
- const id = getGridRowId(row, getRowId);
35
- value.idRowsLookup[id] = row;
36
- value.idToIdLookup[id] = id;
37
- value.ids.push(id);
38
- }
39
- } else {
40
- value = prevState.value;
41
- }
42
-
43
- return {
44
- value,
45
- rowsBeforePartialUpdates: rows != null ? rows : prevState.rowsBeforePartialUpdates
46
- };
47
- };
48
-
49
- const getRowsStateFromCache = (rowsCache, previousTree, apiRef, rowCountProp, loadingProp) => {
50
- const {
51
- value
52
- } = rowsCache;
53
- const rowCount = rowCountProp != null ? rowCountProp : 0;
54
- const groupingResponse = apiRef.current.unstable_applyStrategyProcessor('rowTreeCreation', _extends({}, value, {
55
- previousTree
56
- }));
57
- const dataTopLevelRowCount = groupingResponse.treeDepth === 1 ? groupingResponse.ids.length : Object.values(groupingResponse.tree).filter(node => node.parent == null).length;
58
- return _extends({}, groupingResponse, {
59
- loading: loadingProp,
60
- totalRowCount: Math.max(rowCount, groupingResponse.ids.length),
61
- totalTopLevelRowCount: Math.max(rowCount, dataTopLevelRowCount)
62
- });
63
- };
64
-
10
+ import { getTreeNodeDescendants, createRowsInternalCache, getRowsStateFromCache, getRowIdFromRowModel } from './gridRowsUtils';
11
+ import { useGridRegisterPipeApplier } from '../../core/pipeProcessing';
65
12
  export const rowsStateInitializer = (state, props, apiRef) => {
66
- apiRef.current.unstable_caches.rows = convertRowsPropToState({
13
+ apiRef.current.unstable_caches.rows = createRowsInternalCache({
67
14
  rows: props.rows,
68
15
  getRowId: props.getRowId,
69
- prevCache: {
70
- value: {
71
- idRowsLookup: {},
72
- idToIdLookup: {},
73
- ids: []
74
- },
75
- rowsBeforePartialUpdates: []
76
- }
16
+ loading: props.loading
77
17
  });
78
18
  return _extends({}, state, {
79
- rows: getRowsStateFromCache(apiRef.current.unstable_caches.rows, null, apiRef, props.rowCount, props.loading)
19
+ rows: getRowsStateFromCache({
20
+ apiRef,
21
+ previousTree: null,
22
+ rowCountProp: props.rowCount,
23
+ loadingProp: props.loading
24
+ })
80
25
  });
81
26
  };
82
27
  export const useGridRows = (apiRef, props) => {
@@ -105,7 +50,12 @@ export const useGridRows = (apiRef, props) => {
105
50
  timeout.current = null;
106
51
  lastUpdateMs.current = Date.now();
107
52
  apiRef.current.setState(state => _extends({}, state, {
108
- rows: getRowsStateFromCache(apiRef.current.unstable_caches.rows, gridRowTreeSelector(apiRef), apiRef, props.rowCount, props.loading)
53
+ rows: getRowsStateFromCache({
54
+ apiRef,
55
+ previousTree: gridRowTreeSelector(apiRef),
56
+ rowCountProp: props.rowCount,
57
+ loadingProp: props.loading
58
+ })
109
59
  }));
110
60
  apiRef.current.publishEvent('rowsSet');
111
61
  apiRef.current.forceUpdate();
@@ -138,12 +88,12 @@ export const useGridRows = (apiRef, props) => {
138
88
 
139
89
  const setRows = React.useCallback(rows => {
140
90
  logger.debug(`Updating all rows, new length ${rows.length}`);
141
- throttledRowsChange(convertRowsPropToState({
91
+ throttledRowsChange(createRowsInternalCache({
142
92
  rows,
143
- prevCache: apiRef.current.unstable_caches.rows,
144
- getRowId: props.getRowId
93
+ getRowId: props.getRowId,
94
+ loading: props.loading
145
95
  }), true);
146
- }, [apiRef, logger, props.getRowId, throttledRowsChange]);
96
+ }, [logger, props.getRowId, props.loading, throttledRowsChange]);
147
97
  const updateRows = React.useCallback(updates => {
148
98
  if (props.signature === GridSignature.DataGrid && updates.length > 1) {
149
99
  // TODO: Add test with direct call to `apiRef.current.updateRows` in DataGrid after enabling the `apiRef` on the free plan.
@@ -153,7 +103,7 @@ export const useGridRows = (apiRef, props) => {
153
103
 
154
104
  const uniqUpdates = new Map();
155
105
  updates.forEach(update => {
156
- const id = getGridRowId(update, props.getRowId, 'A row was provided without id when calling updateRows():');
106
+ const id = getRowIdFromRowModel(update, props.getRowId, 'A row was provided without id when calling updateRows():');
157
107
 
158
108
  if (uniqUpdates.has(id)) {
159
109
  uniqUpdates.set(id, _extends({}, uniqUpdates.get(id), update));
@@ -162,16 +112,19 @@ export const useGridRows = (apiRef, props) => {
162
112
  }
163
113
  });
164
114
  const deletedRowIds = [];
165
- const newStateValue = {
166
- idRowsLookup: _extends({}, apiRef.current.unstable_caches.rows.value.idRowsLookup),
167
- idToIdLookup: _extends({}, apiRef.current.unstable_caches.rows.value.idToIdLookup),
168
- ids: [...apiRef.current.unstable_caches.rows.value.ids]
115
+ const prevCache = apiRef.current.unstable_caches.rows;
116
+ const newCache = {
117
+ rowsBeforePartialUpdates: prevCache.rowsBeforePartialUpdates,
118
+ loadingPropBeforePartialUpdates: prevCache.loadingPropBeforePartialUpdates,
119
+ idRowsLookup: _extends({}, prevCache.idRowsLookup),
120
+ idToIdLookup: _extends({}, prevCache.idToIdLookup),
121
+ ids: [...prevCache.ids]
169
122
  };
170
123
  uniqUpdates.forEach((partialRow, id) => {
171
124
  // eslint-disable-next-line no-underscore-dangle
172
125
  if (partialRow._action === 'delete') {
173
- delete newStateValue.idRowsLookup[id];
174
- delete newStateValue.idToIdLookup[id];
126
+ delete newCache.idRowsLookup[id];
127
+ delete newCache.idToIdLookup[id];
175
128
  deletedRowIds.push(id);
176
129
  return;
177
130
  }
@@ -179,24 +132,20 @@ export const useGridRows = (apiRef, props) => {
179
132
  const oldRow = apiRef.current.getRow(id);
180
133
 
181
134
  if (!oldRow) {
182
- newStateValue.idRowsLookup[id] = partialRow;
183
- newStateValue.idToIdLookup[id] = id;
184
- newStateValue.ids.push(id);
135
+ newCache.idRowsLookup[id] = partialRow;
136
+ newCache.idToIdLookup[id] = id;
137
+ newCache.ids.push(id);
185
138
  return;
186
139
  }
187
140
 
188
- newStateValue.idRowsLookup[id] = _extends({}, apiRef.current.getRow(id), partialRow);
141
+ newCache.idRowsLookup[id] = _extends({}, apiRef.current.getRow(id), partialRow);
189
142
  });
190
143
 
191
144
  if (deletedRowIds.length > 0) {
192
- newStateValue.ids = newStateValue.ids.filter(id => !deletedRowIds.includes(id));
145
+ newCache.ids = newCache.ids.filter(id => !deletedRowIds.includes(id));
193
146
  }
194
147
 
195
- const state = _extends({}, apiRef.current.unstable_caches.rows, {
196
- value: newStateValue
197
- });
198
-
199
- throttledRowsChange(state, true);
148
+ throttledRowsChange(newCache, true);
200
149
  }, [props.signature, props.getRowId, throttledRowsChange, apiRef]);
201
150
  const getRowModels = React.useCallback(() => {
202
151
  const allRows = gridRowIdsSelector(apiRef);
@@ -310,25 +259,25 @@ export const useGridRows = (apiRef, props) => {
310
259
 
311
260
  const groupRows = React.useCallback(() => {
312
261
  logger.info(`Row grouping pre-processing have changed, regenerating the row tree`);
313
- let rows;
262
+ let cache;
314
263
 
315
264
  if (apiRef.current.unstable_caches.rows.rowsBeforePartialUpdates === props.rows) {
316
- // The `props.rows` has not changed since the last row grouping
317
- // We can keep the potential updates stored in `inputRowsAfterUpdates` on the new grouping
318
- rows = undefined;
265
+ // The `props.rows` did not change since the last row grouping
266
+ // We can use the current rows cache which contains the partial updates done recently.
267
+ cache = apiRef.current.unstable_caches.rows;
319
268
  } else {
320
269
  // The `props.rows` has changed since the last row grouping
321
270
  // We must use the new `props.rows` on the new grouping
322
271
  // This occurs because this event is triggered before the `useEffect` on the rows when both the grouping pre-processing and the rows changes on the same render
323
- rows = props.rows;
272
+ cache = createRowsInternalCache({
273
+ rows: props.rows,
274
+ getRowId: props.getRowId,
275
+ loading: props.loading
276
+ });
324
277
  }
325
278
 
326
- throttledRowsChange(convertRowsPropToState({
327
- rows,
328
- getRowId: props.getRowId,
329
- prevCache: apiRef.current.unstable_caches.rows
330
- }), false);
331
- }, [logger, apiRef, props.rows, props.getRowId, throttledRowsChange]);
279
+ throttledRowsChange(cache, false);
280
+ }, [logger, apiRef, props.rows, props.getRowId, props.loading, throttledRowsChange]);
332
281
  const handleStrategyProcessorChange = React.useCallback(methodName => {
333
282
  if (methodName === 'rowTreeCreation') {
334
283
  groupRows();
@@ -343,6 +292,18 @@ export const useGridRows = (apiRef, props) => {
343
292
  }, [apiRef, groupRows]);
344
293
  useGridApiEventHandler(apiRef, 'activeStrategyProcessorChange', handleStrategyProcessorChange);
345
294
  useGridApiEventHandler(apiRef, 'strategyAvailabilityChange', handleStrategyActivityChange);
295
+ /**
296
+ * APPLIERS
297
+ */
298
+
299
+ const applyHydrateRowsProcessor = React.useCallback(() => {
300
+ apiRef.current.setState(state => _extends({}, state, {
301
+ rows: _extends({}, state.rows, apiRef.current.unstable_applyPipeProcessors('hydrateRows', state.rows.groupingResponseBeforeRowHydration))
302
+ }));
303
+ apiRef.current.publishEvent('rowsSet');
304
+ apiRef.current.forceUpdate();
305
+ }, [apiRef]);
306
+ useGridRegisterPipeApplier(apiRef, 'hydrateRows', applyHydrateRowsProcessor);
346
307
  useGridApiMethod(apiRef, rowApi, 'GridRowApi');
347
308
  /**
348
309
  * EFFECTS
@@ -365,15 +326,15 @@ export const useGridRows = (apiRef, props) => {
365
326
  } // The new rows have already been applied (most likely in the `'rowGroupsPreProcessingChange'` listener)
366
327
 
367
328
 
368
- if (apiRef.current.unstable_caches.rows.rowsBeforePartialUpdates === props.rows) {
329
+ if (apiRef.current.unstable_caches.rows.rowsBeforePartialUpdates === props.rows && apiRef.current.unstable_caches.rows.loadingPropBeforePartialUpdates === props.loading) {
369
330
  return;
370
331
  }
371
332
 
372
333
  logger.debug(`Updating all rows, new length ${props.rows.length}`);
373
- throttledRowsChange(convertRowsPropToState({
334
+ throttledRowsChange(createRowsInternalCache({
374
335
  rows: props.rows,
375
336
  getRowId: props.getRowId,
376
- prevCache: apiRef.current.unstable_caches.rows
337
+ loading: props.loading
377
338
  }), false);
378
- }, [props.rows, props.rowCount, props.getRowId, logger, throttledRowsChange, apiRef]);
339
+ }, [props.rows, props.rowCount, props.getRowId, props.loading, logger, throttledRowsChange, apiRef]);
379
340
  };
@@ -7,4 +7,4 @@ export declare const rowsMetaStateInitializer: GridStateInitializer;
7
7
  * @requires useGridPageSize (method)
8
8
  * @requires useGridPage (method)
9
9
  */
10
- export declare const useGridRowsMeta: (apiRef: React.MutableRefObject<GridApiCommunity>, props: Pick<DataGridProcessedProps, 'getRowHeight' | 'getRowSpacing' | 'pagination' | 'paginationMode'>) => void;
10
+ export declare const useGridRowsMeta: (apiRef: React.MutableRefObject<GridApiCommunity>, props: Pick<DataGridProcessedProps, 'getRowHeight' | 'getEstimatedRowHeight' | 'getRowSpacing' | 'pagination' | 'paginationMode'>) => void;