@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.
- package/CHANGELOG.md +209 -0
- package/DataGrid/useDataGridProps.js +4 -4
- package/components/DataGridVirtualScroller.js +5 -3
- package/components/GridPagination.d.ts +43 -1
- package/components/GridPagination.js +1 -2
- package/components/GridRow.d.ts +1 -4
- package/components/GridRow.js +9 -8
- package/components/base/GridBody.js +1 -2
- package/components/base/GridOverlays.js +52 -12
- package/components/cell/GridBooleanCell.js +2 -1
- package/components/columnSelection/GridCellCheckboxRenderer.d.ts +2 -2
- package/components/columnSelection/GridCellCheckboxRenderer.js +1 -6
- package/components/containers/GridOverlay.js +0 -5
- package/components/panel/filterPanel/GridFilterForm.js +2 -1
- package/components/toolbar/GridToolbarFilterButton.js +8 -4
- package/constants/gridClasses.d.ts +8 -0
- package/hooks/core/pipeProcessing/gridPipeProcessingApi.d.ts +1 -1
- package/hooks/core/strategyProcessing/gridStrategyProcessingApi.d.ts +1 -1
- package/hooks/features/columnHeaders/useGridColumnHeaders.js +1 -1
- package/hooks/features/editRows/useGridCellEditing.new.js +18 -9
- package/hooks/features/editRows/useGridEditing.new.js +3 -2
- package/hooks/features/editRows/useGridEditing.old.js +2 -1
- package/hooks/features/editRows/useGridRowEditing.new.js +18 -9
- package/hooks/features/export/useGridPrintExport.js +31 -17
- package/hooks/features/export/utils.js +1 -5
- package/hooks/features/filter/gridFilterSelector.js +2 -2
- package/hooks/features/filter/useGridFilter.js +6 -6
- package/hooks/features/pagination/gridPaginationSelector.js +2 -2
- package/hooks/features/rows/gridRowsInterfaces.d.ts +106 -0
- package/hooks/features/rows/{gridRowsState.js → gridRowsInterfaces.js} +0 -0
- package/hooks/features/rows/gridRowsSelector.d.ts +17 -7
- package/hooks/features/rows/gridRowsSelector.js +38 -6
- package/hooks/features/rows/gridRowsUtils.d.ts +16 -4
- package/hooks/features/rows/gridRowsUtils.js +222 -39
- package/hooks/features/rows/index.d.ts +3 -3
- package/hooks/features/rows/index.js +2 -2
- package/hooks/features/rows/useGridRows.js +161 -124
- package/hooks/features/rows/useGridRowsPreProcessors.js +78 -26
- package/hooks/features/selection/useGridSelection.js +2 -2
- package/hooks/features/sorting/gridSortingSelector.js +9 -4
- package/hooks/features/sorting/gridSortingState.d.ts +2 -2
- package/hooks/features/sorting/useGridSorting.js +9 -33
- package/hooks/features/virtualization/useGridVirtualScroller.d.ts +4 -7
- package/hooks/features/virtualization/useGridVirtualScroller.js +11 -17
- package/index.js +1 -1
- package/internals/index.d.ts +2 -1
- package/internals/index.js +1 -0
- package/legacy/DataGrid/useDataGridProps.js +4 -4
- package/legacy/components/DataGridVirtualScroller.js +5 -3
- package/legacy/components/GridPagination.js +1 -2
- package/legacy/components/GridRow.js +9 -8
- package/legacy/components/base/GridBody.js +1 -2
- package/legacy/components/base/GridOverlays.js +54 -12
- package/legacy/components/cell/GridBooleanCell.js +2 -1
- package/legacy/components/columnSelection/GridCellCheckboxRenderer.js +1 -6
- package/legacy/components/containers/GridOverlay.js +0 -5
- package/legacy/components/panel/filterPanel/GridFilterForm.js +2 -1
- package/legacy/components/toolbar/GridToolbarFilterButton.js +3 -1
- package/legacy/hooks/features/columnHeaders/useGridColumnHeaders.js +1 -1
- package/legacy/hooks/features/editRows/useGridCellEditing.new.js +18 -9
- package/legacy/hooks/features/editRows/useGridEditing.new.js +3 -2
- package/legacy/hooks/features/editRows/useGridEditing.old.js +2 -1
- package/legacy/hooks/features/editRows/useGridRowEditing.new.js +18 -9
- package/legacy/hooks/features/export/useGridPrintExport.js +33 -20
- package/legacy/hooks/features/export/utils.js +1 -3
- package/legacy/hooks/features/filter/gridFilterSelector.js +2 -2
- package/legacy/hooks/features/filter/useGridFilter.js +6 -6
- package/legacy/hooks/features/pagination/gridPaginationSelector.js +2 -2
- package/legacy/hooks/features/rows/{gridRowsState.js → gridRowsInterfaces.js} +0 -0
- package/legacy/hooks/features/rows/gridRowsSelector.js +52 -9
- package/legacy/hooks/features/rows/gridRowsUtils.js +238 -46
- package/legacy/hooks/features/rows/index.js +2 -2
- package/legacy/hooks/features/rows/useGridRows.js +163 -134
- package/legacy/hooks/features/rows/useGridRowsPreProcessors.js +81 -26
- package/legacy/hooks/features/selection/useGridSelection.js +2 -2
- package/legacy/hooks/features/sorting/gridSortingSelector.js +5 -2
- package/legacy/hooks/features/sorting/useGridSorting.js +11 -33
- package/legacy/hooks/features/virtualization/useGridVirtualScroller.js +11 -17
- package/legacy/index.js +1 -1
- package/legacy/internals/index.js +1 -0
- package/legacy/models/gridFeatureMode.js +1 -4
- package/models/api/gridParamsApi.d.ts +2 -2
- package/models/api/gridRowApi.d.ts +7 -5
- package/models/events/gridEventLookup.d.ts +3 -3
- package/models/gridApiCaches.d.ts +1 -1
- package/models/gridFeatureMode.d.ts +0 -4
- package/models/gridFeatureMode.js +1 -4
- package/models/gridRows.d.ts +100 -30
- package/models/gridSortModel.d.ts +2 -2
- package/models/params/gridCellParams.d.ts +7 -11
- package/modern/DataGrid/useDataGridProps.js +4 -4
- package/modern/components/DataGridVirtualScroller.js +5 -3
- package/modern/components/GridPagination.js +1 -2
- package/modern/components/GridRow.js +9 -8
- package/modern/components/base/GridBody.js +1 -2
- package/modern/components/base/GridOverlays.js +52 -12
- package/modern/components/cell/GridBooleanCell.js +2 -1
- package/modern/components/columnSelection/GridCellCheckboxRenderer.js +1 -6
- package/modern/components/containers/GridOverlay.js +0 -5
- package/modern/components/panel/filterPanel/GridFilterForm.js +2 -1
- package/modern/components/toolbar/GridToolbarFilterButton.js +1 -1
- package/modern/hooks/features/columnHeaders/useGridColumnHeaders.js +1 -1
- package/modern/hooks/features/editRows/useGridCellEditing.new.js +18 -9
- package/modern/hooks/features/editRows/useGridEditing.new.js +3 -2
- package/modern/hooks/features/editRows/useGridEditing.old.js +2 -1
- package/modern/hooks/features/editRows/useGridRowEditing.new.js +18 -9
- package/modern/hooks/features/export/useGridPrintExport.js +30 -16
- package/modern/hooks/features/export/utils.js +1 -1
- package/modern/hooks/features/filter/gridFilterSelector.js +2 -2
- package/modern/hooks/features/filter/useGridFilter.js +6 -6
- package/modern/hooks/features/pagination/gridPaginationSelector.js +2 -2
- package/modern/hooks/features/rows/{gridRowsState.js → gridRowsInterfaces.js} +0 -0
- package/modern/hooks/features/rows/gridRowsSelector.js +28 -6
- package/modern/hooks/features/rows/gridRowsUtils.js +220 -37
- package/modern/hooks/features/rows/index.js +2 -2
- package/modern/hooks/features/rows/useGridRows.js +158 -121
- package/modern/hooks/features/rows/useGridRowsPreProcessors.js +78 -26
- package/modern/hooks/features/selection/useGridSelection.js +2 -2
- package/modern/hooks/features/sorting/gridSortingSelector.js +3 -2
- package/modern/hooks/features/sorting/useGridSorting.js +9 -33
- package/modern/hooks/features/virtualization/useGridVirtualScroller.js +10 -16
- package/modern/index.js +1 -1
- package/modern/internals/index.js +1 -0
- package/modern/models/gridFeatureMode.js +1 -4
- package/node/DataGrid/useDataGridProps.js +3 -3
- package/node/components/DataGridVirtualScroller.js +5 -3
- package/node/components/GridPagination.js +1 -2
- package/node/components/GridRow.js +9 -7
- package/node/components/base/GridBody.js +1 -3
- package/node/components/base/GridOverlays.js +57 -12
- package/node/components/cell/GridBooleanCell.js +3 -1
- package/node/components/columnSelection/GridCellCheckboxRenderer.js +1 -6
- package/node/components/containers/GridOverlay.js +0 -5
- package/node/components/panel/filterPanel/GridFilterForm.js +2 -1
- package/node/components/toolbar/GridToolbarFilterButton.js +8 -4
- package/node/hooks/features/columnHeaders/useGridColumnHeaders.js +1 -1
- package/node/hooks/features/editRows/useGridCellEditing.new.js +20 -10
- package/node/hooks/features/editRows/useGridEditing.new.js +4 -2
- package/node/hooks/features/editRows/useGridEditing.old.js +3 -1
- package/node/hooks/features/editRows/useGridRowEditing.new.js +20 -10
- package/node/hooks/features/export/useGridPrintExport.js +31 -17
- package/node/hooks/features/export/utils.js +1 -5
- package/node/hooks/features/filter/gridFilterSelector.js +1 -1
- package/node/hooks/features/filter/useGridFilter.js +5 -6
- package/node/hooks/features/pagination/gridPaginationSelector.js +1 -1
- package/node/hooks/features/rows/{gridRowsState.js → gridRowsInterfaces.js} +0 -0
- package/node/hooks/features/rows/gridRowsSelector.js +43 -10
- package/node/hooks/features/rows/gridRowsUtils.js +239 -40
- package/node/hooks/features/rows/index.js +23 -9
- package/node/hooks/features/rows/useGridRows.js +161 -122
- package/node/hooks/features/rows/useGridRowsPreProcessors.js +81 -26
- package/node/hooks/features/selection/useGridSelection.js +2 -2
- package/node/hooks/features/sorting/gridSortingSelector.js +9 -4
- package/node/hooks/features/sorting/useGridSorting.js +9 -33
- package/node/hooks/features/virtualization/useGridVirtualScroller.js +11 -17
- package/node/index.js +1 -1
- package/node/internals/index.js +14 -2
- package/node/models/gridFeatureMode.js +1 -7
- package/package.json +1 -1
- package/themeAugmentation/props.d.ts +2 -2
- 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,
|
|
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
|
};
|
|
@@ -37,23 +38,42 @@ export const useGridRows = (apiRef, props) => {
|
|
|
37
38
|
const currentPage = useGridVisibleRows(apiRef, props);
|
|
38
39
|
const lastUpdateMs = React.useRef(Date.now());
|
|
39
40
|
const timeout = React.useRef(null);
|
|
40
|
-
const getRow = React.useCallback(id =>
|
|
41
|
+
const getRow = React.useCallback(id => {
|
|
42
|
+
const model = gridRowsLookupSelector(apiRef)[id];
|
|
43
|
+
|
|
44
|
+
if (model) {
|
|
45
|
+
return model;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const node = apiRef.current.getRowNode(id);
|
|
49
|
+
|
|
50
|
+
if (node && isAutoGeneratedRow(node)) {
|
|
51
|
+
// TODO rows v6: Is it the best approach ?
|
|
52
|
+
return {};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return null;
|
|
56
|
+
}, [apiRef]);
|
|
41
57
|
const lookup = React.useMemo(() => currentPage.rows.reduce((acc, {
|
|
42
58
|
id
|
|
43
59
|
}, index) => {
|
|
44
60
|
acc[id] = index;
|
|
45
61
|
return acc;
|
|
46
62
|
}, {}), [currentPage.rows]);
|
|
47
|
-
const throttledRowsChange = React.useCallback((
|
|
63
|
+
const throttledRowsChange = React.useCallback(({
|
|
64
|
+
cache,
|
|
65
|
+
throttle
|
|
66
|
+
}) => {
|
|
48
67
|
const run = () => {
|
|
49
68
|
timeout.current = null;
|
|
50
69
|
lastUpdateMs.current = Date.now();
|
|
51
70
|
apiRef.current.setState(state => _extends({}, state, {
|
|
52
71
|
rows: getRowsStateFromCache({
|
|
53
72
|
apiRef,
|
|
54
|
-
previousTree: gridRowTreeSelector(apiRef),
|
|
55
73
|
rowCountProp: props.rowCount,
|
|
56
|
-
loadingProp: props.loading
|
|
74
|
+
loadingProp: props.loading,
|
|
75
|
+
previousTree: gridRowTreeSelector(apiRef),
|
|
76
|
+
previousTreeDepths: gridRowTreeDepthsSelector(apiRef)
|
|
57
77
|
})
|
|
58
78
|
}));
|
|
59
79
|
apiRef.current.publishEvent('rowsSet');
|
|
@@ -65,7 +85,7 @@ export const useGridRows = (apiRef, props) => {
|
|
|
65
85
|
timeout.current = null;
|
|
66
86
|
}
|
|
67
87
|
|
|
68
|
-
apiRef.current.unstable_caches.rows =
|
|
88
|
+
apiRef.current.unstable_caches.rows = cache;
|
|
69
89
|
|
|
70
90
|
if (!throttle) {
|
|
71
91
|
run();
|
|
@@ -87,72 +107,38 @@ export const useGridRows = (apiRef, props) => {
|
|
|
87
107
|
|
|
88
108
|
const setRows = React.useCallback(rows => {
|
|
89
109
|
logger.debug(`Updating all rows, new length ${rows.length}`);
|
|
90
|
-
throttledRowsChange(
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
110
|
+
throttledRowsChange({
|
|
111
|
+
cache: createRowsInternalCache({
|
|
112
|
+
rows,
|
|
113
|
+
getRowId: props.getRowId,
|
|
114
|
+
loading: props.loading
|
|
115
|
+
}),
|
|
116
|
+
throttle: true
|
|
117
|
+
});
|
|
95
118
|
}, [logger, props.getRowId, props.loading, throttledRowsChange]);
|
|
96
119
|
const updateRows = React.useCallback(updates => {
|
|
97
120
|
if (props.signature === GridSignature.DataGrid && updates.length > 1) {
|
|
98
121
|
// TODO: Add test with direct call to `apiRef.current.updateRows` in DataGrid after enabling the `apiRef` on the free plan.
|
|
99
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'));
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
const uniqueUpdates = new Map();
|
|
104
|
-
updates.forEach(update => {
|
|
105
|
-
const id = getRowIdFromRowModel(update, props.getRowId, 'A row was provided without id when calling updateRows():');
|
|
123
|
+
}
|
|
106
124
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
125
|
+
const cache = updateCacheWithNewRows({
|
|
126
|
+
updates,
|
|
127
|
+
getRowId: props.getRowId,
|
|
128
|
+
previousCache: apiRef.current.unstable_caches.rows
|
|
112
129
|
});
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
rowsBeforePartialUpdates: prevCache.rowsBeforePartialUpdates,
|
|
117
|
-
loadingPropBeforePartialUpdates: prevCache.loadingPropBeforePartialUpdates,
|
|
118
|
-
idRowsLookup: _extends({}, prevCache.idRowsLookup),
|
|
119
|
-
idToIdLookup: _extends({}, prevCache.idToIdLookup),
|
|
120
|
-
ids: [...prevCache.ids]
|
|
121
|
-
};
|
|
122
|
-
uniqueUpdates.forEach((partialRow, id) => {
|
|
123
|
-
// eslint-disable-next-line no-underscore-dangle
|
|
124
|
-
if (partialRow._action === 'delete') {
|
|
125
|
-
delete newCache.idRowsLookup[id];
|
|
126
|
-
delete newCache.idToIdLookup[id];
|
|
127
|
-
deletedRowIds.push(id);
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const oldRow = apiRef.current.getRow(id);
|
|
132
|
-
|
|
133
|
-
if (!oldRow) {
|
|
134
|
-
newCache.idRowsLookup[id] = partialRow;
|
|
135
|
-
newCache.idToIdLookup[id] = id;
|
|
136
|
-
newCache.ids.push(id);
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
newCache.idRowsLookup[id] = _extends({}, apiRef.current.getRow(id), partialRow);
|
|
130
|
+
throttledRowsChange({
|
|
131
|
+
cache,
|
|
132
|
+
throttle: true
|
|
141
133
|
});
|
|
142
|
-
|
|
143
|
-
if (deletedRowIds.length > 0) {
|
|
144
|
-
newCache.ids = newCache.ids.filter(id => !deletedRowIds.includes(id));
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
throttledRowsChange(newCache, true);
|
|
148
134
|
}, [props.signature, props.getRowId, throttledRowsChange, apiRef]);
|
|
149
135
|
const getRowModels = React.useCallback(() => {
|
|
150
|
-
const
|
|
136
|
+
const dataRows = gridDataRowIdsSelector(apiRef);
|
|
151
137
|
const idRowsLookup = gridRowsLookupSelector(apiRef);
|
|
152
|
-
return new Map(
|
|
138
|
+
return new Map(dataRows.map(id => [id, idRowsLookup[id] ?? {}]));
|
|
153
139
|
}, [apiRef]);
|
|
154
140
|
const getRowsCount = React.useCallback(() => gridRowCountSelector(apiRef), [apiRef]);
|
|
155
|
-
const getAllRowIds = React.useCallback(() =>
|
|
141
|
+
const getAllRowIds = React.useCallback(() => gridDataRowIdsSelector(apiRef), [apiRef]);
|
|
156
142
|
const getRowIndexRelativeToVisibleRows = React.useCallback(id => lookup[id], [lookup]);
|
|
157
143
|
const setRowChildrenExpansion = React.useCallback((id, isExpanded) => {
|
|
158
144
|
const currentNode = apiRef.current.getRowNode(id);
|
|
@@ -161,6 +147,10 @@ export const useGridRows = (apiRef, props) => {
|
|
|
161
147
|
throw new Error(`MUI: No row with id #${id} found`);
|
|
162
148
|
}
|
|
163
149
|
|
|
150
|
+
if (currentNode.type !== 'group') {
|
|
151
|
+
throw new Error('MUI: Only group nodes can be expanded or collapsed');
|
|
152
|
+
}
|
|
153
|
+
|
|
164
154
|
const newNode = _extends({}, currentNode, {
|
|
165
155
|
childrenExpanded: isExpanded
|
|
166
156
|
});
|
|
@@ -200,9 +190,8 @@ export const useGridRows = (apiRef, props) => {
|
|
|
200
190
|
|
|
201
191
|
for (let index = startIndex; index < sortedRowIds.length && tree[sortedRowIds[index]].depth > groupNode.depth; index += 1) {
|
|
202
192
|
const id = sortedRowIds[index];
|
|
203
|
-
const node = tree[id];
|
|
204
193
|
|
|
205
|
-
if (!skipAutoGeneratedRows || !
|
|
194
|
+
if (!skipAutoGeneratedRows || !isAutoGeneratedRow(tree[id])) {
|
|
206
195
|
children.push(id);
|
|
207
196
|
}
|
|
208
197
|
}
|
|
@@ -218,21 +207,42 @@ export const useGridRows = (apiRef, props) => {
|
|
|
218
207
|
return children;
|
|
219
208
|
}, [apiRef]);
|
|
220
209
|
const setRowIndex = React.useCallback((rowId, targetIndex) => {
|
|
221
|
-
const
|
|
222
|
-
const oldIndex = allRows.findIndex(row => row === rowId);
|
|
210
|
+
const node = apiRef.current.getRowNode(rowId);
|
|
223
211
|
|
|
224
|
-
if (
|
|
225
|
-
|
|
212
|
+
if (!node) {
|
|
213
|
+
throw new Error(`MUI: No row with id #${rowId} found`);
|
|
226
214
|
}
|
|
227
215
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
216
|
+
if (node.parent !== GRID_ROOT_GROUP_ID) {
|
|
217
|
+
throw new Error(`MUI: The row reordering do not support reordering of grouped rows yet`);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (node.type !== 'leaf') {
|
|
221
|
+
throw new Error(`MUI: The row reordering do not support reordering of footer or grouping rows`);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
apiRef.current.setState(state => {
|
|
225
|
+
const group = gridRowTreeSelector(state, apiRef.current.instanceId)[GRID_ROOT_GROUP_ID];
|
|
226
|
+
const allRows = group.children;
|
|
227
|
+
const oldIndex = allRows.findIndex(row => row === rowId);
|
|
228
|
+
|
|
229
|
+
if (oldIndex === -1 || oldIndex === targetIndex) {
|
|
230
|
+
return state;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
logger.debug(`Moving row ${rowId} to index ${targetIndex}`);
|
|
234
|
+
const updatedRows = [...allRows];
|
|
235
|
+
updatedRows.splice(targetIndex, 0, updatedRows.splice(oldIndex, 1)[0]);
|
|
236
|
+
return _extends({}, state, {
|
|
237
|
+
rows: _extends({}, state.rows, {
|
|
238
|
+
tree: _extends({}, state.rows.tree, {
|
|
239
|
+
[GRID_ROOT_GROUP_ID]: _extends({}, group, {
|
|
240
|
+
children: updatedRows
|
|
241
|
+
})
|
|
242
|
+
})
|
|
243
|
+
})
|
|
244
|
+
});
|
|
245
|
+
});
|
|
236
246
|
apiRef.current.publishEvent('rowsSet');
|
|
237
247
|
}, [apiRef, logger]);
|
|
238
248
|
const replaceRows = React.useCallback((firstRowToRender, newRows) => {
|
|
@@ -244,49 +254,51 @@ export const useGridRows = (apiRef, props) => {
|
|
|
244
254
|
return;
|
|
245
255
|
}
|
|
246
256
|
|
|
247
|
-
const
|
|
248
|
-
const updatedRows = [...allRows];
|
|
249
|
-
const idRowsLookup = gridRowsLookupSelector(apiRef);
|
|
250
|
-
const idToIdLookup = gridRowsIdToIdLookupSelector(apiRef);
|
|
251
|
-
const tree = gridRowTreeSelector(apiRef);
|
|
257
|
+
const treeDepth = gridRowMaximumTreeDepthSelector(apiRef);
|
|
252
258
|
|
|
253
|
-
|
|
259
|
+
if (treeDepth > 1) {
|
|
260
|
+
throw new Error('`apiRef.current.unstable_replaceRows` is not compatible with tree data and row grouping');
|
|
261
|
+
}
|
|
254
262
|
|
|
255
|
-
const
|
|
263
|
+
const tree = _extends({}, gridRowTreeSelector(apiRef));
|
|
256
264
|
|
|
257
|
-
const
|
|
265
|
+
const dataRowIdToModelLookup = _extends({}, gridRowsLookupSelector(apiRef));
|
|
258
266
|
|
|
259
|
-
const
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
const [replacedRowId] =
|
|
268
|
-
delete
|
|
269
|
-
delete
|
|
270
|
-
delete
|
|
271
|
-
});
|
|
272
|
-
newRowEntries.forEach(row => {
|
|
267
|
+
const dataRowIdToIdLookup = _extends({}, gridRowsDataRowIdToIdLookupSelector(apiRef));
|
|
268
|
+
|
|
269
|
+
const rootGroup = tree[GRID_ROOT_GROUP_ID];
|
|
270
|
+
const rootGroupChildren = [...rootGroup.children];
|
|
271
|
+
|
|
272
|
+
for (let i = 0; i < newRows.length; i += 1) {
|
|
273
|
+
const rowModel = newRows[i];
|
|
274
|
+
const rowId = getRowIdFromRowModel(rowModel, props.getRowId, 'A row was provided without id when calling replaceRows().');
|
|
275
|
+
const [replacedRowId] = rootGroupChildren.splice(firstRowToRender + i, 1, rowId);
|
|
276
|
+
delete dataRowIdToModelLookup[replacedRowId];
|
|
277
|
+
delete dataRowIdToIdLookup[replacedRowId];
|
|
278
|
+
delete tree[replacedRowId];
|
|
273
279
|
const rowTreeNodeConfig = {
|
|
274
|
-
id:
|
|
275
|
-
parent: null,
|
|
280
|
+
id: rowId,
|
|
276
281
|
depth: 0,
|
|
277
|
-
|
|
278
|
-
|
|
282
|
+
parent: GRID_ROOT_GROUP_ID,
|
|
283
|
+
type: 'leaf',
|
|
284
|
+
groupingKey: null
|
|
279
285
|
};
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
}
|
|
286
|
+
dataRowIdToModelLookup[rowId] = rowModel;
|
|
287
|
+
dataRowIdToIdLookup[rowId] = rowId;
|
|
288
|
+
tree[rowId] = rowTreeNodeConfig;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
tree[GRID_ROOT_GROUP_ID] = _extends({}, rootGroup, {
|
|
292
|
+
children: rootGroupChildren
|
|
293
|
+
}); // Removes potential remaining skeleton rows from the dataRowIds.
|
|
294
|
+
|
|
295
|
+
const dataRowIds = rootGroupChildren.filter(childId => tree[childId].type === 'leaf');
|
|
284
296
|
apiRef.current.setState(state => _extends({}, state, {
|
|
285
297
|
rows: _extends({}, state.rows, {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
298
|
+
dataRowIdToModelLookup,
|
|
299
|
+
dataRowIdToIdLookup,
|
|
300
|
+
dataRowIds,
|
|
301
|
+
tree
|
|
290
302
|
})
|
|
291
303
|
}));
|
|
292
304
|
apiRef.current.publishEvent('rowsSet');
|
|
@@ -316,7 +328,12 @@ export const useGridRows = (apiRef, props) => {
|
|
|
316
328
|
if (apiRef.current.unstable_caches.rows.rowsBeforePartialUpdates === props.rows) {
|
|
317
329
|
// The `props.rows` did not change since the last row grouping
|
|
318
330
|
// We can use the current rows cache which contains the partial updates done recently.
|
|
319
|
-
cache = apiRef.current.unstable_caches.rows
|
|
331
|
+
cache = _extends({}, apiRef.current.unstable_caches.rows, {
|
|
332
|
+
updates: {
|
|
333
|
+
type: 'full',
|
|
334
|
+
rows: gridDataRowIdsSelector(apiRef)
|
|
335
|
+
}
|
|
336
|
+
});
|
|
320
337
|
} else {
|
|
321
338
|
// The `props.rows` has changed since the last row grouping
|
|
322
339
|
// We must use the new `props.rows` on the new grouping
|
|
@@ -328,7 +345,10 @@ export const useGridRows = (apiRef, props) => {
|
|
|
328
345
|
});
|
|
329
346
|
}
|
|
330
347
|
|
|
331
|
-
throttledRowsChange(
|
|
348
|
+
throttledRowsChange({
|
|
349
|
+
cache,
|
|
350
|
+
throttle: false
|
|
351
|
+
});
|
|
332
352
|
}, [logger, apiRef, props.rows, props.getRowId, props.loading, throttledRowsChange]);
|
|
333
353
|
const handleStrategyProcessorChange = React.useCallback(methodName => {
|
|
334
354
|
if (methodName === 'rowTreeCreation') {
|
|
@@ -349,12 +369,26 @@ export const useGridRows = (apiRef, props) => {
|
|
|
349
369
|
*/
|
|
350
370
|
|
|
351
371
|
const applyHydrateRowsProcessor = React.useCallback(() => {
|
|
352
|
-
apiRef.current.setState(state =>
|
|
353
|
-
|
|
354
|
-
|
|
372
|
+
apiRef.current.setState(state => {
|
|
373
|
+
const response = apiRef.current.unstable_applyPipeProcessors('hydrateRows', {
|
|
374
|
+
tree: gridRowTreeSelector(state, apiRef.current.instanceId),
|
|
375
|
+
treeDepths: gridRowTreeDepthsSelector(state, apiRef.current.instanceId),
|
|
376
|
+
dataRowIds: gridDataRowIdsSelector(state, apiRef.current.instanceId),
|
|
377
|
+
dataRowIdToModelLookup: gridRowsLookupSelector(state, apiRef.current.instanceId),
|
|
378
|
+
dataRowIdToIdLookup: gridRowsDataRowIdToIdLookupSelector(state, apiRef.current.instanceId)
|
|
379
|
+
});
|
|
380
|
+
return _extends({}, state, {
|
|
381
|
+
rows: _extends({}, state.rows, response, {
|
|
382
|
+
totalTopLevelRowCount: getTopLevelRowCount({
|
|
383
|
+
tree: response.tree,
|
|
384
|
+
rowCountProp: props.rowCount
|
|
385
|
+
})
|
|
386
|
+
})
|
|
387
|
+
});
|
|
388
|
+
});
|
|
355
389
|
apiRef.current.publishEvent('rowsSet');
|
|
356
390
|
apiRef.current.forceUpdate();
|
|
357
|
-
}, [apiRef]);
|
|
391
|
+
}, [apiRef, props.rowCount]);
|
|
358
392
|
useGridRegisterPipeApplier(apiRef, 'hydrateRows', applyHydrateRowsProcessor);
|
|
359
393
|
useGridApiMethod(apiRef, rowApi, 'GridRowApi');
|
|
360
394
|
/**
|
|
@@ -396,10 +430,13 @@ export const useGridRows = (apiRef, props) => {
|
|
|
396
430
|
}
|
|
397
431
|
|
|
398
432
|
logger.debug(`Updating all rows, new length ${props.rows.length}`);
|
|
399
|
-
throttledRowsChange(
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
433
|
+
throttledRowsChange({
|
|
434
|
+
cache: createRowsInternalCache({
|
|
435
|
+
rows: props.rows,
|
|
436
|
+
getRowId: props.getRowId,
|
|
437
|
+
loading: props.loading
|
|
438
|
+
}),
|
|
439
|
+
throttle: false
|
|
440
|
+
});
|
|
404
441
|
}, [props.rows, props.rowCount, props.getRowId, props.loading, logger, throttledRowsChange, apiRef]);
|
|
405
442
|
};
|
|
@@ -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
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
};
|
|
@@ -113,7 +113,7 @@ export const useGridSelection = (apiRef, props) => {
|
|
|
113
113
|
|
|
114
114
|
const rowNode = apiRef.current.getRowNode(id);
|
|
115
115
|
|
|
116
|
-
if (rowNode?.
|
|
116
|
+
if (rowNode?.type === 'footer' || rowNode?.type === 'pinnedRow') {
|
|
117
117
|
return false;
|
|
118
118
|
}
|
|
119
119
|
|
|
@@ -265,7 +265,7 @@ export const useGridSelection = (apiRef, props) => {
|
|
|
265
265
|
}
|
|
266
266
|
}
|
|
267
267
|
|
|
268
|
-
if (params.rowNode.
|
|
268
|
+
if (params.rowNode.type === 'pinnedRow') {
|
|
269
269
|
return;
|
|
270
270
|
}
|
|
271
271
|
|
|
@@ -17,9 +17,10 @@ export const gridSortedRowIdsSelector = createSelector(gridSortingStateSelector,
|
|
|
17
17
|
* @category Sorting
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
export const gridSortedRowEntriesSelector = createSelector(gridSortedRowIdsSelector, gridRowsLookupSelector,
|
|
20
|
+
export const gridSortedRowEntriesSelector = createSelector(gridSortedRowIdsSelector, gridRowsLookupSelector, // TODO rows v6: Is this the best approach ?
|
|
21
|
+
(sortedIds, idRowsLookup) => sortedIds.map(id => ({
|
|
21
22
|
id,
|
|
22
|
-
model: idRowsLookup[id]
|
|
23
|
+
model: idRowsLookup[id] ?? {}
|
|
23
24
|
})));
|
|
24
25
|
/**
|
|
25
26
|
* Get the current sorting model.
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import { GridFeatureModeConstant } from '../../../models/gridFeatureMode';
|
|
4
3
|
import { isEnterKey } from '../../../utils/keyboardUtils';
|
|
5
4
|
import { useGridApiEventHandler } from '../../utils/useGridApiEventHandler';
|
|
6
5
|
import { useGridApiMethod } from '../../utils/useGridApiMethod';
|
|
7
6
|
import { useGridLogger } from '../../utils/useGridLogger';
|
|
8
7
|
import { gridColumnLookupSelector } from '../columns/gridColumnsSelector';
|
|
9
8
|
import { gridSortedRowEntriesSelector, gridSortedRowIdsSelector, gridSortModelSelector } from './gridSortingSelector';
|
|
10
|
-
import {
|
|
9
|
+
import { GRID_ROOT_GROUP_ID, gridRowTreeSelector } from '../rows';
|
|
11
10
|
import { useFirstRender } from '../../utils/useFirstRender';
|
|
12
11
|
import { useGridRegisterStrategyProcessor, GRID_DEFAULT_STRATEGY } from '../../core/strategyProcessing';
|
|
13
12
|
import { buildAggregatedSortingApplier, mergeStateWithSortModel, getNextGridSortDirection, sanitizeSortModel } from './gridSortingUtils';
|
|
14
13
|
import { useGridRegisterPipeProcessor } from '../../core/pipeProcessing';
|
|
14
|
+
import { getTreeNodeDescendants } from '../rows/gridRowsUtils';
|
|
15
15
|
export const sortingStateInitializer = (state, props) => {
|
|
16
16
|
const sortModel = props.sortModel ?? props.initialState?.sorting?.sortModel ?? [];
|
|
17
17
|
return _extends({}, state, {
|
|
@@ -74,11 +74,11 @@ export const useGridSorting = (apiRef, props) => {
|
|
|
74
74
|
|
|
75
75
|
const applySorting = React.useCallback(() => {
|
|
76
76
|
apiRef.current.setState(state => {
|
|
77
|
-
if (props.sortingMode ===
|
|
77
|
+
if (props.sortingMode === 'server') {
|
|
78
78
|
logger.debug('Skipping sorting rows as sortingMode = server');
|
|
79
79
|
return _extends({}, state, {
|
|
80
80
|
sorting: _extends({}, state.sorting, {
|
|
81
|
-
sortedRows:
|
|
81
|
+
sortedRows: getTreeNodeDescendants(gridRowTreeSelector(apiRef), GRID_ROOT_GROUP_ID, false)
|
|
82
82
|
})
|
|
83
83
|
});
|
|
84
84
|
}
|
|
@@ -178,38 +178,14 @@ export const useGridSorting = (apiRef, props) => {
|
|
|
178
178
|
}, [apiRef, props.disableMultipleColumnsSorting]);
|
|
179
179
|
const flatSortingMethod = React.useCallback(params => {
|
|
180
180
|
const rowTree = gridRowTreeSelector(apiRef);
|
|
181
|
+
const rootGroupNode = rowTree[GRID_ROOT_GROUP_ID];
|
|
182
|
+
const sortedChildren = params.sortRowList ? params.sortRowList(rootGroupNode.children.map(childId => rowTree[childId])) : [...rootGroupNode.children];
|
|
181
183
|
|
|
182
|
-
if (
|
|
183
|
-
|
|
184
|
-
const footerRowIds = [];
|
|
185
|
-
gridRowIdsSelector(apiRef).forEach(rowId => {
|
|
186
|
-
if (rowTree[rowId].isPinned) {
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
if (rowTree[rowId].position === 'footer') {
|
|
191
|
-
footerRowIds.push(rowId);
|
|
192
|
-
} else {
|
|
193
|
-
bodyRowIds.push(rowId);
|
|
194
|
-
}
|
|
195
|
-
});
|
|
196
|
-
return [...bodyRowIds, ...footerRowIds];
|
|
184
|
+
if (rootGroupNode.footerId != null) {
|
|
185
|
+
sortedChildren.push(rootGroupNode.footerId);
|
|
197
186
|
}
|
|
198
187
|
|
|
199
|
-
|
|
200
|
-
const footerRowIds = [];
|
|
201
|
-
Object.values(rowTree).forEach(rowNode => {
|
|
202
|
-
if (rowNode.isPinned) {
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
if (rowNode.position === 'footer') {
|
|
207
|
-
footerRowIds.push(rowNode.id);
|
|
208
|
-
} else {
|
|
209
|
-
bodyRows.push(rowNode);
|
|
210
|
-
}
|
|
211
|
-
});
|
|
212
|
-
return [...params.sortRowList(bodyRows), ...footerRowIds];
|
|
188
|
+
return sortedChildren;
|
|
213
189
|
}, [apiRef]);
|
|
214
190
|
useGridRegisterPipeProcessor(apiRef, 'exportState', stateExportPreProcessing);
|
|
215
191
|
useGridRegisterPipeProcessor(apiRef, 'restoreState', stateRestorePreProcessing);
|