@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
@@ -2,12 +2,12 @@ import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
3
  import { useGridApiMethod } from '../../utils/useGridApiMethod';
4
4
  import { useGridLogger } from '../../utils/useGridLogger';
5
- import { gridRowCountSelector, gridRowsLookupSelector, gridRowTreeSelector, gridRowIdsSelector, gridRowGroupingNameSelector, gridRowsIdToIdLookupSelector } from './gridRowsSelector';
5
+ import { gridRowCountSelector, gridRowsLookupSelector, gridRowTreeSelector, gridRowGroupingNameSelector, gridRowTreeDepthsSelector, gridDataRowIdsSelector, gridRowsDataRowIdToIdLookupSelector, gridRowMaximumTreeDepthSelector } from './gridRowsSelector';
6
6
  import { GridSignature, useGridApiEventHandler } from '../../utils/useGridApiEventHandler';
7
7
  import { useGridVisibleRows } from '../../utils/useGridVisibleRows';
8
8
  import { gridSortedRowIdsSelector } from '../sorting/gridSortingSelector';
9
9
  import { gridFilteredRowsLookupSelector } from '../filter/gridFilterSelector';
10
- import { getTreeNodeDescendants, createRowsInternalCache, getRowsStateFromCache, getRowIdFromRowModel } from './gridRowsUtils';
10
+ import { getTreeNodeDescendants, createRowsInternalCache, getRowsStateFromCache, isAutoGeneratedRow, GRID_ROOT_GROUP_ID, updateCacheWithNewRows, getTopLevelRowCount, getRowIdFromRowModel } from './gridRowsUtils';
11
11
  import { useGridRegisterPipeApplier } from '../../core/pipeProcessing';
12
12
  export const rowsStateInitializer = (state, props, apiRef) => {
13
13
  apiRef.current.unstable_caches.rows = createRowsInternalCache({
@@ -18,9 +18,10 @@ export const rowsStateInitializer = (state, props, apiRef) => {
18
18
  return _extends({}, state, {
19
19
  rows: getRowsStateFromCache({
20
20
  apiRef,
21
- previousTree: null,
22
21
  rowCountProp: props.rowCount,
23
- loadingProp: props.loading
22
+ loadingProp: props.loading,
23
+ previousTree: null,
24
+ previousTreeDepths: null
24
25
  })
25
26
  });
26
27
  };
@@ -38,9 +39,20 @@ export const useGridRows = (apiRef, props) => {
38
39
  const lastUpdateMs = React.useRef(Date.now());
39
40
  const timeout = React.useRef(null);
40
41
  const getRow = React.useCallback(id => {
41
- var _ref;
42
+ const model = gridRowsLookupSelector(apiRef)[id];
43
+
44
+ if (model) {
45
+ return model;
46
+ }
47
+
48
+ const node = apiRef.current.getRowNode(id);
42
49
 
43
- return (_ref = gridRowsLookupSelector(apiRef)[id]) != null ? _ref : null;
50
+ if (node && isAutoGeneratedRow(node)) {
51
+ // TODO rows v6: Is it the best approach ?
52
+ return {};
53
+ }
54
+
55
+ return null;
44
56
  }, [apiRef]);
45
57
  const lookup = React.useMemo(() => currentPage.rows.reduce((acc, {
46
58
  id
@@ -48,16 +60,20 @@ export const useGridRows = (apiRef, props) => {
48
60
  acc[id] = index;
49
61
  return acc;
50
62
  }, {}), [currentPage.rows]);
51
- const throttledRowsChange = React.useCallback((newCache, throttle) => {
63
+ const throttledRowsChange = React.useCallback(({
64
+ cache,
65
+ throttle
66
+ }) => {
52
67
  const run = () => {
53
68
  timeout.current = null;
54
69
  lastUpdateMs.current = Date.now();
55
70
  apiRef.current.setState(state => _extends({}, state, {
56
71
  rows: getRowsStateFromCache({
57
72
  apiRef,
58
- previousTree: gridRowTreeSelector(apiRef),
59
73
  rowCountProp: props.rowCount,
60
- loadingProp: props.loading
74
+ loadingProp: props.loading,
75
+ previousTree: gridRowTreeSelector(apiRef),
76
+ previousTreeDepths: gridRowTreeDepthsSelector(apiRef)
61
77
  })
62
78
  }));
63
79
  apiRef.current.publishEvent('rowsSet');
@@ -69,7 +85,7 @@ export const useGridRows = (apiRef, props) => {
69
85
  timeout.current = null;
70
86
  }
71
87
 
72
- apiRef.current.unstable_caches.rows = newCache;
88
+ apiRef.current.unstable_caches.rows = cache;
73
89
 
74
90
  if (!throttle) {
75
91
  run();
@@ -91,72 +107,42 @@ export const useGridRows = (apiRef, props) => {
91
107
 
92
108
  const setRows = React.useCallback(rows => {
93
109
  logger.debug(`Updating all rows, new length ${rows.length}`);
94
- throttledRowsChange(createRowsInternalCache({
95
- rows,
96
- getRowId: props.getRowId,
97
- loading: props.loading
98
- }), true);
110
+ throttledRowsChange({
111
+ cache: createRowsInternalCache({
112
+ rows,
113
+ getRowId: props.getRowId,
114
+ loading: props.loading
115
+ }),
116
+ throttle: true
117
+ });
99
118
  }, [logger, props.getRowId, props.loading, throttledRowsChange]);
100
119
  const updateRows = React.useCallback(updates => {
101
120
  if (props.signature === GridSignature.DataGrid && updates.length > 1) {
102
121
  // TODO: Add test with direct call to `apiRef.current.updateRows` in DataGrid after enabling the `apiRef` on the free plan.
103
122
  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'));
104
- } // we remove duplicate updates. A server can batch updates, and send several updates for the same row in one fn call.
105
-
106
-
107
- const uniqueUpdates = new Map();
108
- updates.forEach(update => {
109
- const id = getRowIdFromRowModel(update, props.getRowId, 'A row was provided without id when calling updateRows():');
123
+ }
110
124
 
111
- if (uniqueUpdates.has(id)) {
112
- uniqueUpdates.set(id, _extends({}, uniqueUpdates.get(id), update));
113
- } else {
114
- uniqueUpdates.set(id, update);
115
- }
125
+ const cache = updateCacheWithNewRows({
126
+ updates,
127
+ getRowId: props.getRowId,
128
+ previousCache: apiRef.current.unstable_caches.rows
116
129
  });
117
- const deletedRowIds = [];
118
- const prevCache = apiRef.current.unstable_caches.rows;
119
- const newCache = {
120
- rowsBeforePartialUpdates: prevCache.rowsBeforePartialUpdates,
121
- loadingPropBeforePartialUpdates: prevCache.loadingPropBeforePartialUpdates,
122
- idRowsLookup: _extends({}, prevCache.idRowsLookup),
123
- idToIdLookup: _extends({}, prevCache.idToIdLookup),
124
- ids: [...prevCache.ids]
125
- };
126
- uniqueUpdates.forEach((partialRow, id) => {
127
- // eslint-disable-next-line no-underscore-dangle
128
- if (partialRow._action === 'delete') {
129
- delete newCache.idRowsLookup[id];
130
- delete newCache.idToIdLookup[id];
131
- deletedRowIds.push(id);
132
- return;
133
- }
134
-
135
- const oldRow = apiRef.current.getRow(id);
136
-
137
- if (!oldRow) {
138
- newCache.idRowsLookup[id] = partialRow;
139
- newCache.idToIdLookup[id] = id;
140
- newCache.ids.push(id);
141
- return;
142
- }
143
-
144
- newCache.idRowsLookup[id] = _extends({}, apiRef.current.getRow(id), partialRow);
130
+ throttledRowsChange({
131
+ cache,
132
+ throttle: true
145
133
  });
146
-
147
- if (deletedRowIds.length > 0) {
148
- newCache.ids = newCache.ids.filter(id => !deletedRowIds.includes(id));
149
- }
150
-
151
- throttledRowsChange(newCache, true);
152
134
  }, [props.signature, props.getRowId, throttledRowsChange, apiRef]);
153
135
  const getRowModels = React.useCallback(() => {
154
- const allRows = gridRowIdsSelector(apiRef);
136
+ const dataRows = gridDataRowIdsSelector(apiRef);
155
137
  const idRowsLookup = gridRowsLookupSelector(apiRef);
156
- return new Map(allRows.map(id => [id, idRowsLookup[id]]));
138
+ return new Map(dataRows.map(id => {
139
+ var _idRowsLookup$id;
140
+
141
+ return [id, (_idRowsLookup$id = idRowsLookup[id]) != null ? _idRowsLookup$id : {}];
142
+ }));
157
143
  }, [apiRef]);
158
144
  const getRowsCount = React.useCallback(() => gridRowCountSelector(apiRef), [apiRef]);
159
- const getAllRowIds = React.useCallback(() => gridRowIdsSelector(apiRef), [apiRef]);
145
+ const getAllRowIds = React.useCallback(() => gridDataRowIdsSelector(apiRef), [apiRef]);
160
146
  const getRowIndexRelativeToVisibleRows = React.useCallback(id => lookup[id], [lookup]);
161
147
  const setRowChildrenExpansion = React.useCallback((id, isExpanded) => {
162
148
  const currentNode = apiRef.current.getRowNode(id);
@@ -165,6 +151,10 @@ export const useGridRows = (apiRef, props) => {
165
151
  throw new Error(`MUI: No row with id #${id} found`);
166
152
  }
167
153
 
154
+ if (currentNode.type !== 'group') {
155
+ throw new Error('MUI: Only group nodes can be expanded or collapsed');
156
+ }
157
+
168
158
  const newNode = _extends({}, currentNode, {
169
159
  childrenExpanded: isExpanded
170
160
  });
@@ -182,9 +172,9 @@ export const useGridRows = (apiRef, props) => {
182
172
  apiRef.current.publishEvent('rowExpansionChange', newNode);
183
173
  }, [apiRef]);
184
174
  const getRowNode = React.useCallback(id => {
185
- var _gridRowTreeSelector$;
175
+ var _ref;
186
176
 
187
- return (_gridRowTreeSelector$ = gridRowTreeSelector(apiRef)[id]) != null ? _gridRowTreeSelector$ : null;
177
+ return (_ref = gridRowTreeSelector(apiRef)[id]) != null ? _ref : null;
188
178
  }, [apiRef]);
189
179
  const getRowGroupChildren = React.useCallback(({
190
180
  skipAutoGeneratedRows = true,
@@ -208,9 +198,8 @@ export const useGridRows = (apiRef, props) => {
208
198
 
209
199
  for (let index = startIndex; index < sortedRowIds.length && tree[sortedRowIds[index]].depth > groupNode.depth; index += 1) {
210
200
  const id = sortedRowIds[index];
211
- const node = tree[id];
212
201
 
213
- if (!skipAutoGeneratedRows || !node.isAutoGenerated) {
202
+ if (!skipAutoGeneratedRows || !isAutoGeneratedRow(tree[id])) {
214
203
  children.push(id);
215
204
  }
216
205
  }
@@ -226,21 +215,42 @@ export const useGridRows = (apiRef, props) => {
226
215
  return children;
227
216
  }, [apiRef]);
228
217
  const setRowIndex = React.useCallback((rowId, targetIndex) => {
229
- const allRows = gridRowIdsSelector(apiRef);
230
- const oldIndex = allRows.findIndex(row => row === rowId);
218
+ const node = apiRef.current.getRowNode(rowId);
231
219
 
232
- if (oldIndex === -1 || oldIndex === targetIndex) {
233
- return;
220
+ if (!node) {
221
+ throw new Error(`MUI: No row with id #${rowId} found`);
234
222
  }
235
223
 
236
- logger.debug(`Moving row ${rowId} to index ${targetIndex}`);
237
- const updatedRows = [...allRows];
238
- updatedRows.splice(targetIndex, 0, updatedRows.splice(oldIndex, 1)[0]);
239
- apiRef.current.setState(state => _extends({}, state, {
240
- rows: _extends({}, state.rows, {
241
- ids: updatedRows
242
- })
243
- }));
224
+ if (node.parent !== GRID_ROOT_GROUP_ID) {
225
+ throw new Error(`MUI: The row reordering do not support reordering of grouped rows yet`);
226
+ }
227
+
228
+ if (node.type !== 'leaf') {
229
+ throw new Error(`MUI: The row reordering do not support reordering of footer or grouping rows`);
230
+ }
231
+
232
+ apiRef.current.setState(state => {
233
+ const group = gridRowTreeSelector(state, apiRef.current.instanceId)[GRID_ROOT_GROUP_ID];
234
+ const allRows = group.children;
235
+ const oldIndex = allRows.findIndex(row => row === rowId);
236
+
237
+ if (oldIndex === -1 || oldIndex === targetIndex) {
238
+ return state;
239
+ }
240
+
241
+ logger.debug(`Moving row ${rowId} to index ${targetIndex}`);
242
+ const updatedRows = [...allRows];
243
+ updatedRows.splice(targetIndex, 0, updatedRows.splice(oldIndex, 1)[0]);
244
+ return _extends({}, state, {
245
+ rows: _extends({}, state.rows, {
246
+ tree: _extends({}, state.rows.tree, {
247
+ [GRID_ROOT_GROUP_ID]: _extends({}, group, {
248
+ children: updatedRows
249
+ })
250
+ })
251
+ })
252
+ });
253
+ });
244
254
  apiRef.current.publishEvent('rowsSet');
245
255
  }, [apiRef, logger]);
246
256
  const replaceRows = React.useCallback((firstRowToRender, newRows) => {
@@ -252,49 +262,51 @@ export const useGridRows = (apiRef, props) => {
252
262
  return;
253
263
  }
254
264
 
255
- const allRows = gridRowIdsSelector(apiRef);
256
- const updatedRows = [...allRows];
257
- const idRowsLookup = gridRowsLookupSelector(apiRef);
258
- const idToIdLookup = gridRowsIdToIdLookupSelector(apiRef);
259
- const tree = gridRowTreeSelector(apiRef);
265
+ const treeDepth = gridRowMaximumTreeDepthSelector(apiRef);
260
266
 
261
- const updatedIdRowsLookup = _extends({}, idRowsLookup);
267
+ if (treeDepth > 1) {
268
+ throw new Error('`apiRef.current.unstable_replaceRows` is not compatible with tree data and row grouping');
269
+ }
262
270
 
263
- const updatedIdToIdLookup = _extends({}, idToIdLookup);
271
+ const tree = _extends({}, gridRowTreeSelector(apiRef));
264
272
 
265
- const updatedTree = _extends({}, tree);
273
+ const dataRowIdToModelLookup = _extends({}, gridRowsLookupSelector(apiRef));
266
274
 
267
- const newRowEntries = newRows.map(newRowModel => {
268
- const rowId = getRowIdFromRowModel(newRowModel, props.getRowId, 'A row was provided without id when calling replaceRows().');
269
- return {
270
- id: rowId,
271
- model: newRowModel
272
- };
273
- });
274
- newRowEntries.forEach((row, index) => {
275
- const [replacedRowId] = updatedRows.splice(firstRowToRender + index, 1, row.id);
276
- delete updatedIdRowsLookup[replacedRowId];
277
- delete updatedIdToIdLookup[replacedRowId];
278
- delete updatedTree[replacedRowId];
279
- });
280
- newRowEntries.forEach(row => {
275
+ const dataRowIdToIdLookup = _extends({}, gridRowsDataRowIdToIdLookupSelector(apiRef));
276
+
277
+ const rootGroup = tree[GRID_ROOT_GROUP_ID];
278
+ const rootGroupChildren = [...rootGroup.children];
279
+
280
+ for (let i = 0; i < newRows.length; i += 1) {
281
+ const rowModel = newRows[i];
282
+ const rowId = getRowIdFromRowModel(rowModel, props.getRowId, 'A row was provided without id when calling replaceRows().');
283
+ const [replacedRowId] = rootGroupChildren.splice(firstRowToRender + i, 1, rowId);
284
+ delete dataRowIdToModelLookup[replacedRowId];
285
+ delete dataRowIdToIdLookup[replacedRowId];
286
+ delete tree[replacedRowId];
281
287
  const rowTreeNodeConfig = {
282
- id: row.id,
283
- parent: null,
288
+ id: rowId,
284
289
  depth: 0,
285
- groupingKey: null,
286
- groupingField: null
290
+ parent: GRID_ROOT_GROUP_ID,
291
+ type: 'leaf',
292
+ groupingKey: null
287
293
  };
288
- updatedIdRowsLookup[row.id] = row.model;
289
- updatedIdToIdLookup[row.id] = row.id;
290
- updatedTree[row.id] = rowTreeNodeConfig;
291
- });
294
+ dataRowIdToModelLookup[rowId] = rowModel;
295
+ dataRowIdToIdLookup[rowId] = rowId;
296
+ tree[rowId] = rowTreeNodeConfig;
297
+ }
298
+
299
+ tree[GRID_ROOT_GROUP_ID] = _extends({}, rootGroup, {
300
+ children: rootGroupChildren
301
+ }); // Removes potential remaining skeleton rows from the dataRowIds.
302
+
303
+ const dataRowIds = rootGroupChildren.filter(childId => tree[childId].type === 'leaf');
292
304
  apiRef.current.setState(state => _extends({}, state, {
293
305
  rows: _extends({}, state.rows, {
294
- idRowsLookup: updatedIdRowsLookup,
295
- idToIdLookup: updatedIdToIdLookup,
296
- tree: updatedTree,
297
- ids: updatedRows
306
+ dataRowIdToModelLookup,
307
+ dataRowIdToIdLookup,
308
+ dataRowIds,
309
+ tree
298
310
  })
299
311
  }));
300
312
  apiRef.current.publishEvent('rowsSet');
@@ -324,7 +336,12 @@ export const useGridRows = (apiRef, props) => {
324
336
  if (apiRef.current.unstable_caches.rows.rowsBeforePartialUpdates === props.rows) {
325
337
  // The `props.rows` did not change since the last row grouping
326
338
  // We can use the current rows cache which contains the partial updates done recently.
327
- cache = apiRef.current.unstable_caches.rows;
339
+ cache = _extends({}, apiRef.current.unstable_caches.rows, {
340
+ updates: {
341
+ type: 'full',
342
+ rows: gridDataRowIdsSelector(apiRef)
343
+ }
344
+ });
328
345
  } else {
329
346
  // The `props.rows` has changed since the last row grouping
330
347
  // We must use the new `props.rows` on the new grouping
@@ -336,7 +353,10 @@ export const useGridRows = (apiRef, props) => {
336
353
  });
337
354
  }
338
355
 
339
- throttledRowsChange(cache, false);
356
+ throttledRowsChange({
357
+ cache,
358
+ throttle: false
359
+ });
340
360
  }, [logger, apiRef, props.rows, props.getRowId, props.loading, throttledRowsChange]);
341
361
  const handleStrategyProcessorChange = React.useCallback(methodName => {
342
362
  if (methodName === 'rowTreeCreation') {
@@ -357,12 +377,26 @@ export const useGridRows = (apiRef, props) => {
357
377
  */
358
378
 
359
379
  const applyHydrateRowsProcessor = React.useCallback(() => {
360
- apiRef.current.setState(state => _extends({}, state, {
361
- rows: _extends({}, state.rows, apiRef.current.unstable_applyPipeProcessors('hydrateRows', state.rows.groupingResponseBeforeRowHydration))
362
- }));
380
+ apiRef.current.setState(state => {
381
+ const response = apiRef.current.unstable_applyPipeProcessors('hydrateRows', {
382
+ tree: gridRowTreeSelector(state, apiRef.current.instanceId),
383
+ treeDepths: gridRowTreeDepthsSelector(state, apiRef.current.instanceId),
384
+ dataRowIds: gridDataRowIdsSelector(state, apiRef.current.instanceId),
385
+ dataRowIdToModelLookup: gridRowsLookupSelector(state, apiRef.current.instanceId),
386
+ dataRowIdToIdLookup: gridRowsDataRowIdToIdLookupSelector(state, apiRef.current.instanceId)
387
+ });
388
+ return _extends({}, state, {
389
+ rows: _extends({}, state.rows, response, {
390
+ totalTopLevelRowCount: getTopLevelRowCount({
391
+ tree: response.tree,
392
+ rowCountProp: props.rowCount
393
+ })
394
+ })
395
+ });
396
+ });
363
397
  apiRef.current.publishEvent('rowsSet');
364
398
  apiRef.current.forceUpdate();
365
- }, [apiRef]);
399
+ }, [apiRef, props.rowCount]);
366
400
  useGridRegisterPipeApplier(apiRef, 'hydrateRows', applyHydrateRowsProcessor);
367
401
  useGridApiMethod(apiRef, rowApi, 'GridRowApi');
368
402
  /**
@@ -404,10 +438,13 @@ export const useGridRows = (apiRef, props) => {
404
438
  }
405
439
 
406
440
  logger.debug(`Updating all rows, new length ${props.rows.length}`);
407
- throttledRowsChange(createRowsInternalCache({
408
- rows: props.rows,
409
- getRowId: props.getRowId,
410
- loading: props.loading
411
- }), false);
441
+ throttledRowsChange({
442
+ cache: createRowsInternalCache({
443
+ rows: props.rows,
444
+ getRowId: props.getRowId,
445
+ loading: props.loading
446
+ }),
447
+ throttle: false
448
+ });
412
449
  }, [props.rows, props.rowCount, props.getRowId, props.loading, logger, throttledRowsChange, apiRef]);
413
450
  };
@@ -1,40 +1,92 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
1
2
  import { GRID_DEFAULT_STRATEGY, useGridRegisterStrategyProcessor } from '../../core/strategyProcessing';
3
+ import { buildRootGroup, GRID_ROOT_GROUP_ID } from './gridRowsUtils';
2
4
 
3
- const flatRowTreeCreationMethod = ({
4
- ids,
5
- idRowsLookup,
6
- idToIdLookup,
7
- previousTree
5
+ const createFlatRowTree = rows => {
6
+ const tree = {
7
+ [GRID_ROOT_GROUP_ID]: _extends({}, buildRootGroup(), {
8
+ children: rows
9
+ })
10
+ };
11
+
12
+ for (let i = 0; i < rows.length; i += 1) {
13
+ const rowId = rows[i];
14
+ tree[rowId] = {
15
+ id: rowId,
16
+ depth: 0,
17
+ parent: GRID_ROOT_GROUP_ID,
18
+ type: 'leaf',
19
+ groupingKey: null
20
+ };
21
+ }
22
+
23
+ return {
24
+ groupingName: GRID_DEFAULT_STRATEGY,
25
+ tree,
26
+ treeDepths: {
27
+ 0: rows.length
28
+ },
29
+ dataRowIds: rows
30
+ };
31
+ };
32
+
33
+ const updateFlatRowTree = ({
34
+ previousTree,
35
+ actions
8
36
  }) => {
9
- const tree = {};
10
-
11
- for (let i = 0; i < ids.length; i += 1) {
12
- const rowId = ids[i];
13
-
14
- if (previousTree && previousTree[rowId] && previousTree[rowId].depth === 0 && previousTree[rowId].parent == null && // pinned row can be unpinned
15
- !previousTree[rowId].isPinned) {
16
- tree[rowId] = previousTree[rowId];
17
- } else {
18
- tree[rowId] = {
19
- id: rowId,
20
- depth: 0,
21
- parent: null,
22
- groupingKey: '',
23
- groupingField: null
24
- };
25
- }
37
+ const tree = _extends({}, previousTree);
38
+
39
+ const idsToRemoveFromRootGroup = {};
40
+
41
+ for (let i = 0; i < actions.remove.length; i += 1) {
42
+ const idToDelete = actions.remove[i];
43
+ idsToRemoveFromRootGroup[idToDelete] = true;
44
+ delete tree[idToDelete];
45
+ }
46
+
47
+ for (let i = 0; i < actions.insert.length; i += 1) {
48
+ const idToInsert = actions.insert[i];
49
+ tree[idToInsert] = {
50
+ id: idToInsert,
51
+ depth: 0,
52
+ parent: GRID_ROOT_GROUP_ID,
53
+ type: 'leaf',
54
+ groupingKey: null
55
+ };
56
+ } // TODO rows v6: Support row unpinning
57
+
58
+
59
+ const rootGroup = tree[GRID_ROOT_GROUP_ID];
60
+ let rootGroupChildren = [...rootGroup.children, ...actions.insert];
61
+
62
+ if (Object.values(idsToRemoveFromRootGroup).length) {
63
+ rootGroupChildren = rootGroupChildren.filter(id => !idsToRemoveFromRootGroup[id]);
26
64
  }
27
65
 
66
+ tree[GRID_ROOT_GROUP_ID] = _extends({}, rootGroup, {
67
+ children: rootGroupChildren
68
+ });
28
69
  return {
29
70
  groupingName: GRID_DEFAULT_STRATEGY,
30
71
  tree,
31
- treeDepth: 1,
32
- idRowsLookup,
33
- idToIdLookup,
34
- ids
72
+ treeDepths: {
73
+ 0: rootGroupChildren.length
74
+ },
75
+ dataRowIds: rootGroupChildren
35
76
  };
36
77
  };
37
78
 
79
+ const flatRowTreeCreationMethod = params => {
80
+ if (params.updates.type === 'full') {
81
+ return createFlatRowTree(params.updates.rows);
82
+ }
83
+
84
+ return updateFlatRowTree({
85
+ previousTree: params.previousTree,
86
+ actions: params.updates.actions
87
+ });
88
+ };
89
+
38
90
  export const useGridRowsPreProcessors = apiRef => {
39
91
  useGridRegisterStrategyProcessor(apiRef, GRID_DEFAULT_STRATEGY, 'rowTreeCreation', flatRowTreeCreationMethod);
40
92
  };
@@ -119,7 +119,7 @@ export const useGridSelection = (apiRef, props) => {
119
119
 
120
120
  const rowNode = apiRef.current.getRowNode(id);
121
121
 
122
- if ((rowNode == null ? void 0 : rowNode.position) === 'footer' || rowNode != null && rowNode.isPinned) {
122
+ if ((rowNode == null ? void 0 : rowNode.type) === 'footer' || (rowNode == null ? void 0 : rowNode.type) === 'pinnedRow') {
123
123
  return false;
124
124
  }
125
125
 
@@ -271,7 +271,7 @@ export const useGridSelection = (apiRef, props) => {
271
271
  }
272
272
  }
273
273
 
274
- if (params.rowNode.isPinned) {
274
+ if (params.rowNode.type === 'pinnedRow') {
275
275
  return;
276
276
  }
277
277
 
@@ -17,10 +17,15 @@ export const gridSortedRowIdsSelector = createSelector(gridSortingStateSelector,
17
17
  * @category Sorting
18
18
  */
19
19
 
20
- export const gridSortedRowEntriesSelector = createSelector(gridSortedRowIdsSelector, gridRowsLookupSelector, (sortedIds, idRowsLookup) => sortedIds.map(id => ({
21
- id,
22
- model: idRowsLookup[id]
23
- })));
20
+ export const gridSortedRowEntriesSelector = createSelector(gridSortedRowIdsSelector, gridRowsLookupSelector, // TODO rows v6: Is this the best approach ?
21
+ (sortedIds, idRowsLookup) => sortedIds.map(id => {
22
+ var _idRowsLookup$id;
23
+
24
+ return {
25
+ id,
26
+ model: (_idRowsLookup$id = idRowsLookup[id]) != null ? _idRowsLookup$id : {}
27
+ };
28
+ }));
24
29
  /**
25
30
  * Get the current sorting model.
26
31
  * @category Sorting
@@ -1,4 +1,4 @@
1
- import { GridRowId, GridRowTreeNodeConfig } from '../../../models/gridRows';
1
+ import { GridRowId, GridTreeNode } from '../../../models/gridRows';
2
2
  import { GridSortModel } from '../../../models/gridSortModel';
3
3
  export interface GridSortingState {
4
4
  sortedRows: GridRowId[];
@@ -7,7 +7,7 @@ export interface GridSortingState {
7
7
  export interface GridSortingInitialState {
8
8
  sortModel?: GridSortModel;
9
9
  }
10
- export declare type GridSortingModelApplier = (rowList: GridRowTreeNodeConfig[]) => GridRowId[];
10
+ export declare type GridSortingModelApplier = (rowList: GridTreeNode[]) => GridRowId[];
11
11
  export interface GridSortingMethodParams {
12
12
  sortRowList: GridSortingModelApplier | null;
13
13
  }