@mui/x-data-grid 6.0.0-alpha.0 → 6.0.0-alpha.2

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 (161) hide show
  1. package/CHANGELOG.md +209 -0
  2. package/DataGrid/useDataGridProps.js +4 -4
  3. package/components/DataGridVirtualScroller.js +5 -3
  4. package/components/GridPagination.d.ts +43 -1
  5. package/components/GridPagination.js +1 -2
  6. package/components/GridRow.d.ts +1 -4
  7. package/components/GridRow.js +9 -8
  8. package/components/base/GridBody.js +1 -2
  9. package/components/base/GridOverlays.js +52 -12
  10. package/components/cell/GridBooleanCell.js +2 -1
  11. package/components/columnSelection/GridCellCheckboxRenderer.d.ts +2 -2
  12. package/components/columnSelection/GridCellCheckboxRenderer.js +1 -6
  13. package/components/containers/GridOverlay.js +0 -5
  14. package/components/panel/filterPanel/GridFilterForm.js +2 -1
  15. package/components/toolbar/GridToolbarFilterButton.js +8 -4
  16. package/constants/gridClasses.d.ts +8 -0
  17. package/hooks/core/pipeProcessing/gridPipeProcessingApi.d.ts +1 -1
  18. package/hooks/core/strategyProcessing/gridStrategyProcessingApi.d.ts +1 -1
  19. package/hooks/features/columnHeaders/useGridColumnHeaders.js +1 -1
  20. package/hooks/features/editRows/useGridCellEditing.new.js +18 -9
  21. package/hooks/features/editRows/useGridEditing.new.js +3 -2
  22. package/hooks/features/editRows/useGridEditing.old.js +2 -1
  23. package/hooks/features/editRows/useGridRowEditing.new.js +18 -9
  24. package/hooks/features/export/useGridPrintExport.js +31 -17
  25. package/hooks/features/export/utils.js +1 -5
  26. package/hooks/features/filter/gridFilterSelector.js +2 -2
  27. package/hooks/features/filter/useGridFilter.js +6 -6
  28. package/hooks/features/pagination/gridPaginationSelector.js +2 -2
  29. package/hooks/features/rows/gridRowsInterfaces.d.ts +106 -0
  30. package/hooks/features/rows/{gridRowsState.js → gridRowsInterfaces.js} +0 -0
  31. package/hooks/features/rows/gridRowsSelector.d.ts +17 -7
  32. package/hooks/features/rows/gridRowsSelector.js +38 -6
  33. package/hooks/features/rows/gridRowsUtils.d.ts +16 -4
  34. package/hooks/features/rows/gridRowsUtils.js +222 -39
  35. package/hooks/features/rows/index.d.ts +3 -3
  36. package/hooks/features/rows/index.js +2 -2
  37. package/hooks/features/rows/useGridRows.js +161 -124
  38. package/hooks/features/rows/useGridRowsPreProcessors.js +78 -26
  39. package/hooks/features/selection/useGridSelection.js +2 -2
  40. package/hooks/features/sorting/gridSortingSelector.js +9 -4
  41. package/hooks/features/sorting/gridSortingState.d.ts +2 -2
  42. package/hooks/features/sorting/useGridSorting.js +9 -33
  43. package/hooks/features/virtualization/useGridVirtualScroller.d.ts +4 -7
  44. package/hooks/features/virtualization/useGridVirtualScroller.js +11 -17
  45. package/index.js +1 -1
  46. package/internals/index.d.ts +2 -1
  47. package/internals/index.js +1 -0
  48. package/legacy/DataGrid/useDataGridProps.js +4 -4
  49. package/legacy/components/DataGridVirtualScroller.js +5 -3
  50. package/legacy/components/GridPagination.js +1 -2
  51. package/legacy/components/GridRow.js +9 -8
  52. package/legacy/components/base/GridBody.js +1 -2
  53. package/legacy/components/base/GridOverlays.js +54 -12
  54. package/legacy/components/cell/GridBooleanCell.js +2 -1
  55. package/legacy/components/columnSelection/GridCellCheckboxRenderer.js +1 -6
  56. package/legacy/components/containers/GridOverlay.js +0 -5
  57. package/legacy/components/panel/filterPanel/GridFilterForm.js +2 -1
  58. package/legacy/components/toolbar/GridToolbarFilterButton.js +3 -1
  59. package/legacy/hooks/features/columnHeaders/useGridColumnHeaders.js +1 -1
  60. package/legacy/hooks/features/editRows/useGridCellEditing.new.js +18 -9
  61. package/legacy/hooks/features/editRows/useGridEditing.new.js +3 -2
  62. package/legacy/hooks/features/editRows/useGridEditing.old.js +2 -1
  63. package/legacy/hooks/features/editRows/useGridRowEditing.new.js +18 -9
  64. package/legacy/hooks/features/export/useGridPrintExport.js +33 -20
  65. package/legacy/hooks/features/export/utils.js +1 -3
  66. package/legacy/hooks/features/filter/gridFilterSelector.js +2 -2
  67. package/legacy/hooks/features/filter/useGridFilter.js +6 -6
  68. package/legacy/hooks/features/pagination/gridPaginationSelector.js +2 -2
  69. package/legacy/hooks/features/rows/{gridRowsState.js → gridRowsInterfaces.js} +0 -0
  70. package/legacy/hooks/features/rows/gridRowsSelector.js +52 -9
  71. package/legacy/hooks/features/rows/gridRowsUtils.js +238 -46
  72. package/legacy/hooks/features/rows/index.js +2 -2
  73. package/legacy/hooks/features/rows/useGridRows.js +163 -134
  74. package/legacy/hooks/features/rows/useGridRowsPreProcessors.js +81 -26
  75. package/legacy/hooks/features/selection/useGridSelection.js +2 -2
  76. package/legacy/hooks/features/sorting/gridSortingSelector.js +5 -2
  77. package/legacy/hooks/features/sorting/useGridSorting.js +11 -33
  78. package/legacy/hooks/features/virtualization/useGridVirtualScroller.js +11 -17
  79. package/legacy/index.js +1 -1
  80. package/legacy/internals/index.js +1 -0
  81. package/legacy/models/gridFeatureMode.js +1 -4
  82. package/models/api/gridParamsApi.d.ts +2 -2
  83. package/models/api/gridRowApi.d.ts +7 -5
  84. package/models/events/gridEventLookup.d.ts +3 -3
  85. package/models/gridApiCaches.d.ts +1 -1
  86. package/models/gridFeatureMode.d.ts +0 -4
  87. package/models/gridFeatureMode.js +1 -4
  88. package/models/gridRows.d.ts +100 -30
  89. package/models/gridSortModel.d.ts +2 -2
  90. package/models/params/gridCellParams.d.ts +7 -11
  91. package/modern/DataGrid/useDataGridProps.js +4 -4
  92. package/modern/components/DataGridVirtualScroller.js +5 -3
  93. package/modern/components/GridPagination.js +1 -2
  94. package/modern/components/GridRow.js +9 -8
  95. package/modern/components/base/GridBody.js +1 -2
  96. package/modern/components/base/GridOverlays.js +52 -12
  97. package/modern/components/cell/GridBooleanCell.js +2 -1
  98. package/modern/components/columnSelection/GridCellCheckboxRenderer.js +1 -6
  99. package/modern/components/containers/GridOverlay.js +0 -5
  100. package/modern/components/panel/filterPanel/GridFilterForm.js +2 -1
  101. package/modern/components/toolbar/GridToolbarFilterButton.js +1 -1
  102. package/modern/hooks/features/columnHeaders/useGridColumnHeaders.js +1 -1
  103. package/modern/hooks/features/editRows/useGridCellEditing.new.js +18 -9
  104. package/modern/hooks/features/editRows/useGridEditing.new.js +3 -2
  105. package/modern/hooks/features/editRows/useGridEditing.old.js +2 -1
  106. package/modern/hooks/features/editRows/useGridRowEditing.new.js +18 -9
  107. package/modern/hooks/features/export/useGridPrintExport.js +30 -16
  108. package/modern/hooks/features/export/utils.js +1 -1
  109. package/modern/hooks/features/filter/gridFilterSelector.js +2 -2
  110. package/modern/hooks/features/filter/useGridFilter.js +6 -6
  111. package/modern/hooks/features/pagination/gridPaginationSelector.js +2 -2
  112. package/modern/hooks/features/rows/{gridRowsState.js → gridRowsInterfaces.js} +0 -0
  113. package/modern/hooks/features/rows/gridRowsSelector.js +28 -6
  114. package/modern/hooks/features/rows/gridRowsUtils.js +220 -37
  115. package/modern/hooks/features/rows/index.js +2 -2
  116. package/modern/hooks/features/rows/useGridRows.js +158 -121
  117. package/modern/hooks/features/rows/useGridRowsPreProcessors.js +78 -26
  118. package/modern/hooks/features/selection/useGridSelection.js +2 -2
  119. package/modern/hooks/features/sorting/gridSortingSelector.js +3 -2
  120. package/modern/hooks/features/sorting/useGridSorting.js +9 -33
  121. package/modern/hooks/features/virtualization/useGridVirtualScroller.js +10 -16
  122. package/modern/index.js +1 -1
  123. package/modern/internals/index.js +1 -0
  124. package/modern/models/gridFeatureMode.js +1 -4
  125. package/node/DataGrid/useDataGridProps.js +3 -3
  126. package/node/components/DataGridVirtualScroller.js +5 -3
  127. package/node/components/GridPagination.js +1 -2
  128. package/node/components/GridRow.js +9 -7
  129. package/node/components/base/GridBody.js +1 -3
  130. package/node/components/base/GridOverlays.js +57 -12
  131. package/node/components/cell/GridBooleanCell.js +3 -1
  132. package/node/components/columnSelection/GridCellCheckboxRenderer.js +1 -6
  133. package/node/components/containers/GridOverlay.js +0 -5
  134. package/node/components/panel/filterPanel/GridFilterForm.js +2 -1
  135. package/node/components/toolbar/GridToolbarFilterButton.js +8 -4
  136. package/node/hooks/features/columnHeaders/useGridColumnHeaders.js +1 -1
  137. package/node/hooks/features/editRows/useGridCellEditing.new.js +20 -10
  138. package/node/hooks/features/editRows/useGridEditing.new.js +4 -2
  139. package/node/hooks/features/editRows/useGridEditing.old.js +3 -1
  140. package/node/hooks/features/editRows/useGridRowEditing.new.js +20 -10
  141. package/node/hooks/features/export/useGridPrintExport.js +31 -17
  142. package/node/hooks/features/export/utils.js +1 -5
  143. package/node/hooks/features/filter/gridFilterSelector.js +1 -1
  144. package/node/hooks/features/filter/useGridFilter.js +5 -6
  145. package/node/hooks/features/pagination/gridPaginationSelector.js +1 -1
  146. package/node/hooks/features/rows/{gridRowsState.js → gridRowsInterfaces.js} +0 -0
  147. package/node/hooks/features/rows/gridRowsSelector.js +43 -10
  148. package/node/hooks/features/rows/gridRowsUtils.js +239 -40
  149. package/node/hooks/features/rows/index.js +23 -9
  150. package/node/hooks/features/rows/useGridRows.js +161 -122
  151. package/node/hooks/features/rows/useGridRowsPreProcessors.js +81 -26
  152. package/node/hooks/features/selection/useGridSelection.js +2 -2
  153. package/node/hooks/features/sorting/gridSortingSelector.js +9 -4
  154. package/node/hooks/features/sorting/useGridSorting.js +9 -33
  155. package/node/hooks/features/virtualization/useGridVirtualScroller.js +11 -17
  156. package/node/index.js +1 -1
  157. package/node/internals/index.js +14 -2
  158. package/node/models/gridFeatureMode.js +1 -7
  159. package/package.json +1 -1
  160. package/themeAugmentation/props.d.ts +2 -2
  161. package/hooks/features/rows/gridRowsState.d.ts +0 -60
@@ -42,9 +42,10 @@ const rowsStateInitializer = (state, props, apiRef) => {
42
42
  return (0, _extends2.default)({}, state, {
43
43
  rows: (0, _gridRowsUtils.getRowsStateFromCache)({
44
44
  apiRef,
45
- previousTree: null,
46
45
  rowCountProp: props.rowCount,
47
- loadingProp: props.loading
46
+ loadingProp: props.loading,
47
+ previousTree: null,
48
+ previousTreeDepths: null
48
49
  })
49
50
  });
50
51
  };
@@ -65,9 +66,20 @@ const useGridRows = (apiRef, props) => {
65
66
  const lastUpdateMs = React.useRef(Date.now());
66
67
  const timeout = React.useRef(null);
67
68
  const getRow = React.useCallback(id => {
68
- var _ref;
69
+ const model = (0, _gridRowsSelector.gridRowsLookupSelector)(apiRef)[id];
70
+
71
+ if (model) {
72
+ return model;
73
+ }
74
+
75
+ const node = apiRef.current.getRowNode(id);
69
76
 
70
- return (_ref = (0, _gridRowsSelector.gridRowsLookupSelector)(apiRef)[id]) != null ? _ref : null;
77
+ if (node && (0, _gridRowsUtils.isAutoGeneratedRow)(node)) {
78
+ // TODO rows v6: Is it the best approach ?
79
+ return {};
80
+ }
81
+
82
+ return null;
71
83
  }, [apiRef]);
72
84
  const lookup = React.useMemo(() => currentPage.rows.reduce((acc, {
73
85
  id
@@ -75,16 +87,20 @@ const useGridRows = (apiRef, props) => {
75
87
  acc[id] = index;
76
88
  return acc;
77
89
  }, {}), [currentPage.rows]);
78
- const throttledRowsChange = React.useCallback((newCache, throttle) => {
90
+ const throttledRowsChange = React.useCallback(({
91
+ cache,
92
+ throttle
93
+ }) => {
79
94
  const run = () => {
80
95
  timeout.current = null;
81
96
  lastUpdateMs.current = Date.now();
82
97
  apiRef.current.setState(state => (0, _extends2.default)({}, state, {
83
98
  rows: (0, _gridRowsUtils.getRowsStateFromCache)({
84
99
  apiRef,
85
- previousTree: (0, _gridRowsSelector.gridRowTreeSelector)(apiRef),
86
100
  rowCountProp: props.rowCount,
87
- loadingProp: props.loading
101
+ loadingProp: props.loading,
102
+ previousTree: (0, _gridRowsSelector.gridRowTreeSelector)(apiRef),
103
+ previousTreeDepths: (0, _gridRowsSelector.gridRowTreeDepthsSelector)(apiRef)
88
104
  })
89
105
  }));
90
106
  apiRef.current.publishEvent('rowsSet');
@@ -96,7 +112,7 @@ const useGridRows = (apiRef, props) => {
96
112
  timeout.current = null;
97
113
  }
98
114
 
99
- apiRef.current.unstable_caches.rows = newCache;
115
+ apiRef.current.unstable_caches.rows = cache;
100
116
 
101
117
  if (!throttle) {
102
118
  run();
@@ -118,72 +134,42 @@ const useGridRows = (apiRef, props) => {
118
134
 
119
135
  const setRows = React.useCallback(rows => {
120
136
  logger.debug(`Updating all rows, new length ${rows.length}`);
121
- throttledRowsChange((0, _gridRowsUtils.createRowsInternalCache)({
122
- rows,
123
- getRowId: props.getRowId,
124
- loading: props.loading
125
- }), true);
137
+ throttledRowsChange({
138
+ cache: (0, _gridRowsUtils.createRowsInternalCache)({
139
+ rows,
140
+ getRowId: props.getRowId,
141
+ loading: props.loading
142
+ }),
143
+ throttle: true
144
+ });
126
145
  }, [logger, props.getRowId, props.loading, throttledRowsChange]);
127
146
  const updateRows = React.useCallback(updates => {
128
147
  if (props.signature === _useGridApiEventHandler.GridSignature.DataGrid && updates.length > 1) {
129
148
  // TODO: Add test with direct call to `apiRef.current.updateRows` in DataGrid after enabling the `apiRef` on the free plan.
130
149
  throw new Error(["MUI: You can't update several rows at once in `apiRef.current.updateRows` on the DataGrid.", 'You need to upgrade to DataGridPro or DataGridPremium component to unlock this feature.'].join('\n'));
131
- } // we remove duplicate updates. A server can batch updates, and send several updates for the same row in one fn call.
132
-
133
-
134
- const uniqueUpdates = new Map();
135
- updates.forEach(update => {
136
- const id = (0, _gridRowsUtils.getRowIdFromRowModel)(update, props.getRowId, 'A row was provided without id when calling updateRows():');
150
+ }
137
151
 
138
- if (uniqueUpdates.has(id)) {
139
- uniqueUpdates.set(id, (0, _extends2.default)({}, uniqueUpdates.get(id), update));
140
- } else {
141
- uniqueUpdates.set(id, update);
142
- }
152
+ const cache = (0, _gridRowsUtils.updateCacheWithNewRows)({
153
+ updates,
154
+ getRowId: props.getRowId,
155
+ previousCache: apiRef.current.unstable_caches.rows
143
156
  });
144
- const deletedRowIds = [];
145
- const prevCache = apiRef.current.unstable_caches.rows;
146
- const newCache = {
147
- rowsBeforePartialUpdates: prevCache.rowsBeforePartialUpdates,
148
- loadingPropBeforePartialUpdates: prevCache.loadingPropBeforePartialUpdates,
149
- idRowsLookup: (0, _extends2.default)({}, prevCache.idRowsLookup),
150
- idToIdLookup: (0, _extends2.default)({}, prevCache.idToIdLookup),
151
- ids: [...prevCache.ids]
152
- };
153
- uniqueUpdates.forEach((partialRow, id) => {
154
- // eslint-disable-next-line no-underscore-dangle
155
- if (partialRow._action === 'delete') {
156
- delete newCache.idRowsLookup[id];
157
- delete newCache.idToIdLookup[id];
158
- deletedRowIds.push(id);
159
- return;
160
- }
161
-
162
- const oldRow = apiRef.current.getRow(id);
163
-
164
- if (!oldRow) {
165
- newCache.idRowsLookup[id] = partialRow;
166
- newCache.idToIdLookup[id] = id;
167
- newCache.ids.push(id);
168
- return;
169
- }
170
-
171
- newCache.idRowsLookup[id] = (0, _extends2.default)({}, apiRef.current.getRow(id), partialRow);
157
+ throttledRowsChange({
158
+ cache,
159
+ throttle: true
172
160
  });
173
-
174
- if (deletedRowIds.length > 0) {
175
- newCache.ids = newCache.ids.filter(id => !deletedRowIds.includes(id));
176
- }
177
-
178
- throttledRowsChange(newCache, true);
179
161
  }, [props.signature, props.getRowId, throttledRowsChange, apiRef]);
180
162
  const getRowModels = React.useCallback(() => {
181
- const allRows = (0, _gridRowsSelector.gridRowIdsSelector)(apiRef);
163
+ const dataRows = (0, _gridRowsSelector.gridDataRowIdsSelector)(apiRef);
182
164
  const idRowsLookup = (0, _gridRowsSelector.gridRowsLookupSelector)(apiRef);
183
- return new Map(allRows.map(id => [id, idRowsLookup[id]]));
165
+ return new Map(dataRows.map(id => {
166
+ var _idRowsLookup$id;
167
+
168
+ return [id, (_idRowsLookup$id = idRowsLookup[id]) != null ? _idRowsLookup$id : {}];
169
+ }));
184
170
  }, [apiRef]);
185
171
  const getRowsCount = React.useCallback(() => (0, _gridRowsSelector.gridRowCountSelector)(apiRef), [apiRef]);
186
- const getAllRowIds = React.useCallback(() => (0, _gridRowsSelector.gridRowIdsSelector)(apiRef), [apiRef]);
172
+ const getAllRowIds = React.useCallback(() => (0, _gridRowsSelector.gridDataRowIdsSelector)(apiRef), [apiRef]);
187
173
  const getRowIndexRelativeToVisibleRows = React.useCallback(id => lookup[id], [lookup]);
188
174
  const setRowChildrenExpansion = React.useCallback((id, isExpanded) => {
189
175
  const currentNode = apiRef.current.getRowNode(id);
@@ -192,6 +178,10 @@ const useGridRows = (apiRef, props) => {
192
178
  throw new Error(`MUI: No row with id #${id} found`);
193
179
  }
194
180
 
181
+ if (currentNode.type !== 'group') {
182
+ throw new Error('MUI: Only group nodes can be expanded or collapsed');
183
+ }
184
+
195
185
  const newNode = (0, _extends2.default)({}, currentNode, {
196
186
  childrenExpanded: isExpanded
197
187
  });
@@ -208,9 +198,9 @@ const useGridRows = (apiRef, props) => {
208
198
  apiRef.current.publishEvent('rowExpansionChange', newNode);
209
199
  }, [apiRef]);
210
200
  const getRowNode = React.useCallback(id => {
211
- var _gridRowTreeSelector$;
201
+ var _ref;
212
202
 
213
- return (_gridRowTreeSelector$ = (0, _gridRowsSelector.gridRowTreeSelector)(apiRef)[id]) != null ? _gridRowTreeSelector$ : null;
203
+ return (_ref = (0, _gridRowsSelector.gridRowTreeSelector)(apiRef)[id]) != null ? _ref : null;
214
204
  }, [apiRef]);
215
205
  const getRowGroupChildren = React.useCallback(({
216
206
  skipAutoGeneratedRows = true,
@@ -234,9 +224,8 @@ const useGridRows = (apiRef, props) => {
234
224
 
235
225
  for (let index = startIndex; index < sortedRowIds.length && tree[sortedRowIds[index]].depth > groupNode.depth; index += 1) {
236
226
  const id = sortedRowIds[index];
237
- const node = tree[id];
238
227
 
239
- if (!skipAutoGeneratedRows || !node.isAutoGenerated) {
228
+ if (!skipAutoGeneratedRows || !(0, _gridRowsUtils.isAutoGeneratedRow)(tree[id])) {
240
229
  children.push(id);
241
230
  }
242
231
  }
@@ -252,21 +241,43 @@ const useGridRows = (apiRef, props) => {
252
241
  return children;
253
242
  }, [apiRef]);
254
243
  const setRowIndex = React.useCallback((rowId, targetIndex) => {
255
- const allRows = (0, _gridRowsSelector.gridRowIdsSelector)(apiRef);
256
- const oldIndex = allRows.findIndex(row => row === rowId);
244
+ const node = apiRef.current.getRowNode(rowId);
257
245
 
258
- if (oldIndex === -1 || oldIndex === targetIndex) {
259
- return;
246
+ if (!node) {
247
+ throw new Error(`MUI: No row with id #${rowId} found`);
260
248
  }
261
249
 
262
- logger.debug(`Moving row ${rowId} to index ${targetIndex}`);
263
- const updatedRows = [...allRows];
264
- updatedRows.splice(targetIndex, 0, updatedRows.splice(oldIndex, 1)[0]);
265
- apiRef.current.setState(state => (0, _extends2.default)({}, state, {
266
- rows: (0, _extends2.default)({}, state.rows, {
267
- ids: updatedRows
268
- })
269
- }));
250
+ if (node.parent !== _gridRowsUtils.GRID_ROOT_GROUP_ID) {
251
+ throw new Error(`MUI: The row reordering do not support reordering of grouped rows yet`);
252
+ }
253
+
254
+ if (node.type !== 'leaf') {
255
+ throw new Error(`MUI: The row reordering do not support reordering of footer or grouping rows`);
256
+ }
257
+
258
+ apiRef.current.setState(state => {
259
+ const group = (0, _gridRowsSelector.gridRowTreeSelector)(state, apiRef.current.instanceId)[_gridRowsUtils.GRID_ROOT_GROUP_ID];
260
+
261
+ const allRows = group.children;
262
+ const oldIndex = allRows.findIndex(row => row === rowId);
263
+
264
+ if (oldIndex === -1 || oldIndex === targetIndex) {
265
+ return state;
266
+ }
267
+
268
+ logger.debug(`Moving row ${rowId} to index ${targetIndex}`);
269
+ const updatedRows = [...allRows];
270
+ updatedRows.splice(targetIndex, 0, updatedRows.splice(oldIndex, 1)[0]);
271
+ return (0, _extends2.default)({}, state, {
272
+ rows: (0, _extends2.default)({}, state.rows, {
273
+ tree: (0, _extends2.default)({}, state.rows.tree, {
274
+ [_gridRowsUtils.GRID_ROOT_GROUP_ID]: (0, _extends2.default)({}, group, {
275
+ children: updatedRows
276
+ })
277
+ })
278
+ })
279
+ });
280
+ });
270
281
  apiRef.current.publishEvent('rowsSet');
271
282
  }, [apiRef, logger]);
272
283
  const replaceRows = React.useCallback((firstRowToRender, newRows) => {
@@ -278,45 +289,48 @@ const useGridRows = (apiRef, props) => {
278
289
  return;
279
290
  }
280
291
 
281
- const allRows = (0, _gridRowsSelector.gridRowIdsSelector)(apiRef);
282
- const updatedRows = [...allRows];
283
- const idRowsLookup = (0, _gridRowsSelector.gridRowsLookupSelector)(apiRef);
284
- const idToIdLookup = (0, _gridRowsSelector.gridRowsIdToIdLookupSelector)(apiRef);
285
- const tree = (0, _gridRowsSelector.gridRowTreeSelector)(apiRef);
286
- const updatedIdRowsLookup = (0, _extends2.default)({}, idRowsLookup);
287
- const updatedIdToIdLookup = (0, _extends2.default)({}, idToIdLookup);
288
- const updatedTree = (0, _extends2.default)({}, tree);
289
- const newRowEntries = newRows.map(newRowModel => {
290
- const rowId = (0, _gridRowsUtils.getRowIdFromRowModel)(newRowModel, props.getRowId, 'A row was provided without id when calling replaceRows().');
291
- return {
292
- id: rowId,
293
- model: newRowModel
294
- };
295
- });
296
- newRowEntries.forEach((row, index) => {
297
- const [replacedRowId] = updatedRows.splice(firstRowToRender + index, 1, row.id);
298
- delete updatedIdRowsLookup[replacedRowId];
299
- delete updatedIdToIdLookup[replacedRowId];
300
- delete updatedTree[replacedRowId];
301
- });
302
- newRowEntries.forEach(row => {
292
+ const treeDepth = (0, _gridRowsSelector.gridRowMaximumTreeDepthSelector)(apiRef);
293
+
294
+ if (treeDepth > 1) {
295
+ throw new Error('`apiRef.current.unstable_replaceRows` is not compatible with tree data and row grouping');
296
+ }
297
+
298
+ const tree = (0, _extends2.default)({}, (0, _gridRowsSelector.gridRowTreeSelector)(apiRef));
299
+ const dataRowIdToModelLookup = (0, _extends2.default)({}, (0, _gridRowsSelector.gridRowsLookupSelector)(apiRef));
300
+ const dataRowIdToIdLookup = (0, _extends2.default)({}, (0, _gridRowsSelector.gridRowsDataRowIdToIdLookupSelector)(apiRef));
301
+ const rootGroup = tree[_gridRowsUtils.GRID_ROOT_GROUP_ID];
302
+ const rootGroupChildren = [...rootGroup.children];
303
+
304
+ for (let i = 0; i < newRows.length; i += 1) {
305
+ const rowModel = newRows[i];
306
+ const rowId = (0, _gridRowsUtils.getRowIdFromRowModel)(rowModel, props.getRowId, 'A row was provided without id when calling replaceRows().');
307
+ const [replacedRowId] = rootGroupChildren.splice(firstRowToRender + i, 1, rowId);
308
+ delete dataRowIdToModelLookup[replacedRowId];
309
+ delete dataRowIdToIdLookup[replacedRowId];
310
+ delete tree[replacedRowId];
303
311
  const rowTreeNodeConfig = {
304
- id: row.id,
305
- parent: null,
312
+ id: rowId,
306
313
  depth: 0,
307
- groupingKey: null,
308
- groupingField: null
314
+ parent: _gridRowsUtils.GRID_ROOT_GROUP_ID,
315
+ type: 'leaf',
316
+ groupingKey: null
309
317
  };
310
- updatedIdRowsLookup[row.id] = row.model;
311
- updatedIdToIdLookup[row.id] = row.id;
312
- updatedTree[row.id] = rowTreeNodeConfig;
313
- });
318
+ dataRowIdToModelLookup[rowId] = rowModel;
319
+ dataRowIdToIdLookup[rowId] = rowId;
320
+ tree[rowId] = rowTreeNodeConfig;
321
+ }
322
+
323
+ tree[_gridRowsUtils.GRID_ROOT_GROUP_ID] = (0, _extends2.default)({}, rootGroup, {
324
+ children: rootGroupChildren
325
+ }); // Removes potential remaining skeleton rows from the dataRowIds.
326
+
327
+ const dataRowIds = rootGroupChildren.filter(childId => tree[childId].type === 'leaf');
314
328
  apiRef.current.setState(state => (0, _extends2.default)({}, state, {
315
329
  rows: (0, _extends2.default)({}, state.rows, {
316
- idRowsLookup: updatedIdRowsLookup,
317
- idToIdLookup: updatedIdToIdLookup,
318
- tree: updatedTree,
319
- ids: updatedRows
330
+ dataRowIdToModelLookup,
331
+ dataRowIdToIdLookup,
332
+ dataRowIds,
333
+ tree
320
334
  })
321
335
  }));
322
336
  apiRef.current.publishEvent('rowsSet');
@@ -346,7 +360,12 @@ const useGridRows = (apiRef, props) => {
346
360
  if (apiRef.current.unstable_caches.rows.rowsBeforePartialUpdates === props.rows) {
347
361
  // The `props.rows` did not change since the last row grouping
348
362
  // We can use the current rows cache which contains the partial updates done recently.
349
- cache = apiRef.current.unstable_caches.rows;
363
+ cache = (0, _extends2.default)({}, apiRef.current.unstable_caches.rows, {
364
+ updates: {
365
+ type: 'full',
366
+ rows: (0, _gridRowsSelector.gridDataRowIdsSelector)(apiRef)
367
+ }
368
+ });
350
369
  } else {
351
370
  // The `props.rows` has changed since the last row grouping
352
371
  // We must use the new `props.rows` on the new grouping
@@ -358,7 +377,10 @@ const useGridRows = (apiRef, props) => {
358
377
  });
359
378
  }
360
379
 
361
- throttledRowsChange(cache, false);
380
+ throttledRowsChange({
381
+ cache,
382
+ throttle: false
383
+ });
362
384
  }, [logger, apiRef, props.rows, props.getRowId, props.loading, throttledRowsChange]);
363
385
  const handleStrategyProcessorChange = React.useCallback(methodName => {
364
386
  if (methodName === 'rowTreeCreation') {
@@ -379,12 +401,26 @@ const useGridRows = (apiRef, props) => {
379
401
  */
380
402
 
381
403
  const applyHydrateRowsProcessor = React.useCallback(() => {
382
- apiRef.current.setState(state => (0, _extends2.default)({}, state, {
383
- rows: (0, _extends2.default)({}, state.rows, apiRef.current.unstable_applyPipeProcessors('hydrateRows', state.rows.groupingResponseBeforeRowHydration))
384
- }));
404
+ apiRef.current.setState(state => {
405
+ const response = apiRef.current.unstable_applyPipeProcessors('hydrateRows', {
406
+ tree: (0, _gridRowsSelector.gridRowTreeSelector)(state, apiRef.current.instanceId),
407
+ treeDepths: (0, _gridRowsSelector.gridRowTreeDepthsSelector)(state, apiRef.current.instanceId),
408
+ dataRowIds: (0, _gridRowsSelector.gridDataRowIdsSelector)(state, apiRef.current.instanceId),
409
+ dataRowIdToModelLookup: (0, _gridRowsSelector.gridRowsLookupSelector)(state, apiRef.current.instanceId),
410
+ dataRowIdToIdLookup: (0, _gridRowsSelector.gridRowsDataRowIdToIdLookupSelector)(state, apiRef.current.instanceId)
411
+ });
412
+ return (0, _extends2.default)({}, state, {
413
+ rows: (0, _extends2.default)({}, state.rows, response, {
414
+ totalTopLevelRowCount: (0, _gridRowsUtils.getTopLevelRowCount)({
415
+ tree: response.tree,
416
+ rowCountProp: props.rowCount
417
+ })
418
+ })
419
+ });
420
+ });
385
421
  apiRef.current.publishEvent('rowsSet');
386
422
  apiRef.current.forceUpdate();
387
- }, [apiRef]);
423
+ }, [apiRef, props.rowCount]);
388
424
  (0, _pipeProcessing.useGridRegisterPipeApplier)(apiRef, 'hydrateRows', applyHydrateRowsProcessor);
389
425
  (0, _useGridApiMethod.useGridApiMethod)(apiRef, rowApi, 'GridRowApi');
390
426
  /**
@@ -426,11 +462,14 @@ const useGridRows = (apiRef, props) => {
426
462
  }
427
463
 
428
464
  logger.debug(`Updating all rows, new length ${props.rows.length}`);
429
- throttledRowsChange((0, _gridRowsUtils.createRowsInternalCache)({
430
- rows: props.rows,
431
- getRowId: props.getRowId,
432
- loading: props.loading
433
- }), false);
465
+ throttledRowsChange({
466
+ cache: (0, _gridRowsUtils.createRowsInternalCache)({
467
+ rows: props.rows,
468
+ getRowId: props.getRowId,
469
+ loading: props.loading
470
+ }),
471
+ throttle: false
472
+ });
434
473
  }, [props.rows, props.rowCount, props.getRowId, props.loading, logger, throttledRowsChange, apiRef]);
435
474
  };
436
475
 
@@ -1,47 +1,102 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
3
5
  Object.defineProperty(exports, "__esModule", {
4
6
  value: true
5
7
  });
6
8
  exports.useGridRowsPreProcessors = void 0;
7
9
 
10
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
11
+
8
12
  var _strategyProcessing = require("../../core/strategyProcessing");
9
13
 
10
- const flatRowTreeCreationMethod = ({
11
- ids,
12
- idRowsLookup,
13
- idToIdLookup,
14
- previousTree
14
+ var _gridRowsUtils = require("./gridRowsUtils");
15
+
16
+ const createFlatRowTree = rows => {
17
+ const tree = {
18
+ [_gridRowsUtils.GRID_ROOT_GROUP_ID]: (0, _extends2.default)({}, (0, _gridRowsUtils.buildRootGroup)(), {
19
+ children: rows
20
+ })
21
+ };
22
+
23
+ for (let i = 0; i < rows.length; i += 1) {
24
+ const rowId = rows[i];
25
+ tree[rowId] = {
26
+ id: rowId,
27
+ depth: 0,
28
+ parent: _gridRowsUtils.GRID_ROOT_GROUP_ID,
29
+ type: 'leaf',
30
+ groupingKey: null
31
+ };
32
+ }
33
+
34
+ return {
35
+ groupingName: _strategyProcessing.GRID_DEFAULT_STRATEGY,
36
+ tree,
37
+ treeDepths: {
38
+ 0: rows.length
39
+ },
40
+ dataRowIds: rows
41
+ };
42
+ };
43
+
44
+ const updateFlatRowTree = ({
45
+ previousTree,
46
+ actions
15
47
  }) => {
16
- const tree = {};
17
-
18
- for (let i = 0; i < ids.length; i += 1) {
19
- const rowId = ids[i];
20
-
21
- if (previousTree && previousTree[rowId] && previousTree[rowId].depth === 0 && previousTree[rowId].parent == null && // pinned row can be unpinned
22
- !previousTree[rowId].isPinned) {
23
- tree[rowId] = previousTree[rowId];
24
- } else {
25
- tree[rowId] = {
26
- id: rowId,
27
- depth: 0,
28
- parent: null,
29
- groupingKey: '',
30
- groupingField: null
31
- };
32
- }
48
+ const tree = (0, _extends2.default)({}, previousTree);
49
+ const idsToRemoveFromRootGroup = {};
50
+
51
+ for (let i = 0; i < actions.remove.length; i += 1) {
52
+ const idToDelete = actions.remove[i];
53
+ idsToRemoveFromRootGroup[idToDelete] = true;
54
+ delete tree[idToDelete];
33
55
  }
34
56
 
57
+ for (let i = 0; i < actions.insert.length; i += 1) {
58
+ const idToInsert = actions.insert[i];
59
+ tree[idToInsert] = {
60
+ id: idToInsert,
61
+ depth: 0,
62
+ parent: _gridRowsUtils.GRID_ROOT_GROUP_ID,
63
+ type: 'leaf',
64
+ groupingKey: null
65
+ };
66
+ } // TODO rows v6: Support row unpinning
67
+
68
+
69
+ const rootGroup = tree[_gridRowsUtils.GRID_ROOT_GROUP_ID];
70
+ let rootGroupChildren = [...rootGroup.children, ...actions.insert];
71
+
72
+ if (Object.values(idsToRemoveFromRootGroup).length) {
73
+ rootGroupChildren = rootGroupChildren.filter(id => !idsToRemoveFromRootGroup[id]);
74
+ }
75
+
76
+ tree[_gridRowsUtils.GRID_ROOT_GROUP_ID] = (0, _extends2.default)({}, rootGroup, {
77
+ children: rootGroupChildren
78
+ });
35
79
  return {
36
80
  groupingName: _strategyProcessing.GRID_DEFAULT_STRATEGY,
37
81
  tree,
38
- treeDepth: 1,
39
- idRowsLookup,
40
- idToIdLookup,
41
- ids
82
+ treeDepths: {
83
+ 0: rootGroupChildren.length
84
+ },
85
+ dataRowIds: rootGroupChildren
42
86
  };
43
87
  };
44
88
 
89
+ const flatRowTreeCreationMethod = params => {
90
+ if (params.updates.type === 'full') {
91
+ return createFlatRowTree(params.updates.rows);
92
+ }
93
+
94
+ return updateFlatRowTree({
95
+ previousTree: params.previousTree,
96
+ actions: params.updates.actions
97
+ });
98
+ };
99
+
45
100
  const useGridRowsPreProcessors = apiRef => {
46
101
  (0, _strategyProcessing.useGridRegisterStrategyProcessor)(apiRef, _strategyProcessing.GRID_DEFAULT_STRATEGY, 'rowTreeCreation', flatRowTreeCreationMethod);
47
102
  };
@@ -149,7 +149,7 @@ const useGridSelection = (apiRef, props) => {
149
149
 
150
150
  const rowNode = apiRef.current.getRowNode(id);
151
151
 
152
- if ((rowNode == null ? void 0 : rowNode.position) === 'footer' || rowNode != null && rowNode.isPinned) {
152
+ if ((rowNode == null ? void 0 : rowNode.type) === 'footer' || (rowNode == null ? void 0 : rowNode.type) === 'pinnedRow') {
153
153
  return false;
154
154
  }
155
155
 
@@ -299,7 +299,7 @@ const useGridSelection = (apiRef, props) => {
299
299
  }
300
300
  }
301
301
 
302
- if (params.rowNode.isPinned) {
302
+ if (params.rowNode.type === 'pinnedRow') {
303
303
  return;
304
304
  }
305
305
 
@@ -28,10 +28,15 @@ const gridSortedRowIdsSelector = (0, _createSelector.createSelector)(gridSorting
28
28
  */
29
29
 
30
30
  exports.gridSortedRowIdsSelector = gridSortedRowIdsSelector;
31
- const gridSortedRowEntriesSelector = (0, _createSelector.createSelector)(gridSortedRowIdsSelector, _gridRowsSelector.gridRowsLookupSelector, (sortedIds, idRowsLookup) => sortedIds.map(id => ({
32
- id,
33
- model: idRowsLookup[id]
34
- })));
31
+ const gridSortedRowEntriesSelector = (0, _createSelector.createSelector)(gridSortedRowIdsSelector, _gridRowsSelector.gridRowsLookupSelector, // TODO rows v6: Is this the best approach ?
32
+ (sortedIds, idRowsLookup) => sortedIds.map(id => {
33
+ var _idRowsLookup$id;
34
+
35
+ return {
36
+ id,
37
+ model: (_idRowsLookup$id = idRowsLookup[id]) != null ? _idRowsLookup$id : {}
38
+ };
39
+ }));
35
40
  /**
36
41
  * Get the current sorting model.
37
42
  * @category Sorting
@@ -11,8 +11,6 @@ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")
11
11
 
12
12
  var React = _interopRequireWildcard(require("react"));
13
13
 
14
- var _gridFeatureMode = require("../../../models/gridFeatureMode");
15
-
16
14
  var _keyboardUtils = require("../../../utils/keyboardUtils");
17
15
 
18
16
  var _useGridApiEventHandler = require("../../utils/useGridApiEventHandler");
@@ -35,6 +33,8 @@ var _gridSortingUtils = require("./gridSortingUtils");
35
33
 
36
34
  var _pipeProcessing = require("../../core/pipeProcessing");
37
35
 
36
+ var _gridRowsUtils = require("../rows/gridRowsUtils");
37
+
38
38
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
39
39
 
40
40
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
@@ -112,11 +112,11 @@ const useGridSorting = (apiRef, props) => {
112
112
 
113
113
  const applySorting = React.useCallback(() => {
114
114
  apiRef.current.setState(state => {
115
- if (props.sortingMode === _gridFeatureMode.GridFeatureModeConstant.server) {
115
+ if (props.sortingMode === 'server') {
116
116
  logger.debug('Skipping sorting rows as sortingMode = server');
117
117
  return (0, _extends2.default)({}, state, {
118
118
  sorting: (0, _extends2.default)({}, state.sorting, {
119
- sortedRows: (0, _rows.gridRowIdsSelector)(state, apiRef.current.instanceId)
119
+ sortedRows: (0, _gridRowsUtils.getTreeNodeDescendants)((0, _rows.gridRowTreeSelector)(apiRef), _rows.GRID_ROOT_GROUP_ID, false)
120
120
  })
121
121
  });
122
122
  }
@@ -220,38 +220,14 @@ const useGridSorting = (apiRef, props) => {
220
220
  }, [apiRef, props.disableMultipleColumnsSorting]);
221
221
  const flatSortingMethod = React.useCallback(params => {
222
222
  const rowTree = (0, _rows.gridRowTreeSelector)(apiRef);
223
+ const rootGroupNode = rowTree[_rows.GRID_ROOT_GROUP_ID];
224
+ const sortedChildren = params.sortRowList ? params.sortRowList(rootGroupNode.children.map(childId => rowTree[childId])) : [...rootGroupNode.children];
223
225
 
224
- if (!params.sortRowList) {
225
- const bodyRowIds = [];
226
- const footerRowIds = [];
227
- (0, _rows.gridRowIdsSelector)(apiRef).forEach(rowId => {
228
- if (rowTree[rowId].isPinned) {
229
- return;
230
- }
231
-
232
- if (rowTree[rowId].position === 'footer') {
233
- footerRowIds.push(rowId);
234
- } else {
235
- bodyRowIds.push(rowId);
236
- }
237
- });
238
- return [...bodyRowIds, ...footerRowIds];
226
+ if (rootGroupNode.footerId != null) {
227
+ sortedChildren.push(rootGroupNode.footerId);
239
228
  }
240
229
 
241
- const bodyRows = [];
242
- const footerRowIds = [];
243
- Object.values(rowTree).forEach(rowNode => {
244
- if (rowNode.isPinned) {
245
- return;
246
- }
247
-
248
- if (rowNode.position === 'footer') {
249
- footerRowIds.push(rowNode.id);
250
- } else {
251
- bodyRows.push(rowNode);
252
- }
253
- });
254
- return [...params.sortRowList(bodyRows), ...footerRowIds];
230
+ return sortedChildren;
255
231
  }, [apiRef]);
256
232
  (0, _pipeProcessing.useGridRegisterPipeProcessor)(apiRef, 'exportState', stateExportPreProcessing);
257
233
  (0, _pipeProcessing.useGridRegisterPipeProcessor)(apiRef, 'restoreState', stateRestorePreProcessing);