@mui/x-data-grid-pro 7.0.0-beta.6 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +311 -12
- package/DataGridPro/DataGridPro.js +18 -18
- package/DataGridPro/useDataGridProComponent.js +2 -3
- package/README.md +1 -1
- package/components/GridColumnHeaders.d.ts +1 -2
- package/components/GridColumnHeaders.js +7 -164
- package/components/headerFiltering/GridHeaderFilterCell.d.ts +8 -1
- package/components/headerFiltering/GridHeaderFilterCell.js +26 -9
- package/esm/DataGridPro/DataGridPro.js +18 -18
- package/esm/DataGridPro/useDataGridProComponent.js +1 -2
- package/esm/components/GridColumnHeaders.js +9 -166
- package/esm/components/GridDetailPanelToggleCell.js +1 -2
- package/esm/components/GridTreeDataGroupingCell.js +2 -3
- package/esm/components/headerFiltering/GridHeaderFilterCell.js +39 -26
- package/esm/components/headerFiltering/GridHeaderFilterClearButton.js +1 -2
- package/esm/components/headerFiltering/GridHeaderFilterMenu.js +1 -2
- package/esm/components/headerFiltering/GridHeaderFilterMenuContainer.js +1 -2
- package/esm/hooks/features/columnHeaders/useGridColumnHeaders.js +49 -16
- package/esm/hooks/features/columnPinning/useGridColumnPinning.js +7 -10
- package/esm/hooks/features/columnPinning/useGridColumnPinningPreProcessors.js +2 -0
- package/esm/hooks/features/columnReorder/useGridColumnReorder.js +2 -4
- package/esm/hooks/features/detailPanel/useGridDetailPanel.js +5 -10
- package/esm/hooks/features/detailPanel/useGridDetailPanelCache.js +1 -2
- package/esm/hooks/features/index.js +0 -1
- package/esm/hooks/features/infiniteLoader/useGridInfiniteLoader.js +6 -10
- package/esm/hooks/features/lazyLoader/useGridLazyLoader.js +3 -23
- package/esm/hooks/features/lazyLoader/useGridLazyLoaderPreProcessors.js +2 -6
- package/esm/hooks/features/rowPinning/useGridRowPinning.js +3 -5
- package/esm/hooks/features/rowPinning/useGridRowPinningPreProcessors.js +5 -7
- package/esm/hooks/features/treeData/gridTreeDataGroupColDef.js +1 -1
- package/esm/hooks/features/treeData/gridTreeDataUtils.js +1 -2
- package/esm/hooks/features/treeData/useGridTreeDataPreProcessors.js +1 -2
- package/esm/internals/index.js +0 -1
- package/esm/utils/releaseInfo.js +1 -1
- package/esm/utils/tree/insertDataRowInTree.js +8 -9
- package/esm/utils/tree/removeDataRowFromTree.js +3 -3
- package/esm/utils/tree/sortRowTree.js +1 -1
- package/esm/utils/tree/updateRowTree.js +1 -1
- package/esm/utils/tree/utils.js +6 -9
- package/hooks/features/columnHeaders/useGridColumnHeaders.d.ts +3 -5
- package/hooks/features/columnHeaders/useGridColumnHeaders.js +44 -11
- package/hooks/features/columnPinning/useGridColumnPinning.js +3 -3
- package/hooks/features/columnPinning/useGridColumnPinningPreProcessors.js +2 -0
- package/hooks/features/detailPanel/useGridDetailPanel.js +1 -1
- package/hooks/features/index.d.ts +0 -1
- package/hooks/features/index.js +0 -11
- package/hooks/features/infiniteLoader/useGridInfiniteLoader.js +2 -2
- package/hooks/features/lazyLoader/useGridLazyLoader.d.ts +1 -1
- package/hooks/features/lazyLoader/useGridLazyLoader.js +1 -19
- package/hooks/features/lazyLoader/useGridLazyLoaderPreProcessors.js +2 -5
- package/index.js +1 -1
- package/internals/index.d.ts +0 -1
- package/internals/index.js +0 -15
- package/models/dataGridProProps.d.ts +3 -36
- package/models/dataSource.d.ts +1 -1
- package/models/gridApiPro.d.ts +4 -4
- package/models/gridStatePro.d.ts +1 -2
- package/modern/DataGridPro/DataGridPro.js +18 -18
- package/modern/DataGridPro/useDataGridProComponent.js +1 -2
- package/modern/components/GridColumnHeaders.js +9 -166
- package/modern/components/headerFiltering/GridHeaderFilterCell.js +27 -10
- package/modern/hooks/features/columnHeaders/useGridColumnHeaders.js +46 -12
- package/modern/hooks/features/columnPinning/useGridColumnPinning.js +3 -3
- package/modern/hooks/features/columnPinning/useGridColumnPinningPreProcessors.js +2 -0
- package/modern/hooks/features/detailPanel/useGridDetailPanel.js +1 -1
- package/modern/hooks/features/index.js +0 -1
- package/modern/hooks/features/infiniteLoader/useGridInfiniteLoader.js +2 -2
- package/modern/hooks/features/lazyLoader/useGridLazyLoader.js +1 -19
- package/modern/hooks/features/lazyLoader/useGridLazyLoaderPreProcessors.js +2 -5
- package/modern/index.js +1 -1
- package/modern/internals/index.js +0 -1
- package/modern/utils/releaseInfo.js +1 -1
- package/package.json +6 -6
- package/typeOverloads/modules.d.ts +3 -3
- package/utils/releaseInfo.js +1 -1
- package/components/GridScrollArea.d.ts +0 -10
- package/components/GridScrollArea.js +0 -145
- package/esm/components/GridScrollArea.js +0 -137
- package/esm/hooks/features/columnResize/columnResizeSelector.js +0 -3
- package/esm/hooks/features/columnResize/columnResizeState.js +0 -1
- package/esm/hooks/features/columnResize/gridColumnResizeApi.js +0 -10
- package/esm/hooks/features/columnResize/index.js +0 -3
- package/esm/hooks/features/columnResize/useGridColumnResize.js +0 -547
- package/esm/utils/domUtils.js +0 -109
- package/hooks/features/columnResize/columnResizeSelector.d.ts +0 -3
- package/hooks/features/columnResize/columnResizeSelector.js +0 -10
- package/hooks/features/columnResize/columnResizeState.d.ts +0 -3
- package/hooks/features/columnResize/columnResizeState.js +0 -5
- package/hooks/features/columnResize/gridColumnResizeApi.d.ts +0 -44
- package/hooks/features/columnResize/gridColumnResizeApi.js +0 -16
- package/hooks/features/columnResize/index.d.ts +0 -3
- package/hooks/features/columnResize/index.js +0 -38
- package/hooks/features/columnResize/useGridColumnResize.d.ts +0 -10
- package/hooks/features/columnResize/useGridColumnResize.js +0 -548
- package/modern/components/GridScrollArea.js +0 -137
- package/modern/hooks/features/columnResize/columnResizeSelector.js +0 -3
- package/modern/hooks/features/columnResize/columnResizeState.js +0 -1
- package/modern/hooks/features/columnResize/gridColumnResizeApi.js +0 -10
- package/modern/hooks/features/columnResize/index.js +0 -3
- package/modern/hooks/features/columnResize/useGridColumnResize.js +0 -537
- package/modern/utils/domUtils.js +0 -107
- package/utils/domUtils.d.ts +0 -11
- package/utils/domUtils.js +0 -121
|
@@ -3,14 +3,13 @@ import * as React from 'react';
|
|
|
3
3
|
import { useGridSelector, gridVisibleColumnDefinitionsSelector, gridColumnsTotalWidthSelector, gridColumnPositionsSelector, useGridApiMethod, useGridApiEventHandler, GridPinnedColumnPosition, gridColumnFieldsSelector } from '@mui/x-data-grid';
|
|
4
4
|
import { useGridRegisterPipeProcessor, gridPinnedColumnsSelector, gridVisiblePinnedColumnDefinitionsSelector } from '@mui/x-data-grid/internals';
|
|
5
5
|
export const columnPinningStateInitializer = (state, props, apiRef) => {
|
|
6
|
-
var _props$initialState;
|
|
7
6
|
apiRef.current.caches.columnPinning = {
|
|
8
7
|
orderedFieldsBeforePinningColumns: null
|
|
9
8
|
};
|
|
10
9
|
let model;
|
|
11
10
|
if (props.pinnedColumns) {
|
|
12
11
|
model = props.pinnedColumns;
|
|
13
|
-
} else if (
|
|
12
|
+
} else if (props.initialState?.pinnedColumns) {
|
|
14
13
|
model = props.initialState.pinnedColumns;
|
|
15
14
|
} else {
|
|
16
15
|
model = {};
|
|
@@ -20,7 +19,6 @@ export const columnPinningStateInitializer = (state, props, apiRef) => {
|
|
|
20
19
|
});
|
|
21
20
|
};
|
|
22
21
|
export const useGridColumnPinning = (apiRef, props) => {
|
|
23
|
-
var _props$initialState3;
|
|
24
22
|
const pinnedColumns = useGridSelector(apiRef, gridPinnedColumnsSelector);
|
|
25
23
|
|
|
26
24
|
/**
|
|
@@ -84,7 +82,6 @@ export const useGridColumnPinning = (apiRef, props) => {
|
|
|
84
82
|
return initialValue;
|
|
85
83
|
}, [apiRef]);
|
|
86
84
|
const stateExportPreProcessing = React.useCallback((prevState, context) => {
|
|
87
|
-
var _props$initialState2, _pinnedColumnsToExpor, _pinnedColumnsToExpor2;
|
|
88
85
|
const pinnedColumnsToExport = gridPinnedColumnsSelector(apiRef.current.state);
|
|
89
86
|
const shouldExportPinnedColumns =
|
|
90
87
|
// Always export if the `exportOnlyDirtyModels` property is not activated
|
|
@@ -92,16 +89,16 @@ export const useGridColumnPinning = (apiRef, props) => {
|
|
|
92
89
|
// Always export if the model is controlled
|
|
93
90
|
props.pinnedColumns != null ||
|
|
94
91
|
// Always export if the model has been initialized
|
|
95
|
-
|
|
92
|
+
props.initialState?.pinnedColumns != null ||
|
|
96
93
|
// Export if the model is not empty
|
|
97
|
-
(
|
|
94
|
+
(pinnedColumnsToExport.left ?? []).length > 0 || (pinnedColumnsToExport.right ?? []).length > 0;
|
|
98
95
|
if (!shouldExportPinnedColumns) {
|
|
99
96
|
return prevState;
|
|
100
97
|
}
|
|
101
98
|
return _extends({}, prevState, {
|
|
102
99
|
pinnedColumns: pinnedColumnsToExport
|
|
103
100
|
});
|
|
104
|
-
}, [apiRef, props.pinnedColumns,
|
|
101
|
+
}, [apiRef, props.pinnedColumns, props.initialState?.pinnedColumns]);
|
|
105
102
|
const stateRestorePreProcessing = React.useCallback((params, context) => {
|
|
106
103
|
const newPinnedColumns = context.stateToRestore.pinnedColumns;
|
|
107
104
|
if (newPinnedColumns != null) {
|
|
@@ -181,16 +178,16 @@ export const useGridColumnPinning = (apiRef, props) => {
|
|
|
181
178
|
* on must be moved to left or right to make room for it. The ^^^ below represents the column
|
|
182
179
|
* which gave space to receive X.
|
|
183
180
|
*
|
|
184
|
-
* | X | B | C | D | -> | B | C | D | X | (
|
|
181
|
+
* | X | B | C | D | -> | B | C | D | X | (for example X moved to after D, so delta=1)
|
|
185
182
|
* ^^^ ^^^
|
|
186
183
|
*
|
|
187
|
-
* | A | B | C | X | -> | X | A | B | C | (
|
|
184
|
+
* | A | B | C | X | -> | X | A | B | C | (for example X moved before A, so delta=-1)
|
|
188
185
|
* ^^^ ^^^
|
|
189
186
|
*
|
|
190
187
|
* If column P is pinned, it will not move to provide space. However, it will jump to the next
|
|
191
188
|
* non-pinned column.
|
|
192
189
|
*
|
|
193
|
-
* | X | B | P | D | -> | B | D | P | X | (
|
|
190
|
+
* | X | B | P | D | -> | B | D | P | X | (for example X moved to after D, with P pinned)
|
|
194
191
|
* ^^^ ^^^
|
|
195
192
|
*/
|
|
196
193
|
const siblingField = latestColumnFields[targetIndex - delta];
|
|
@@ -107,4 +107,6 @@ export const useGridColumnPinningPreProcessors = (apiRef, props) => {
|
|
|
107
107
|
});
|
|
108
108
|
}, [apiRef, disableColumnPinning, pinnedColumns]);
|
|
109
109
|
useGridRegisterPipeProcessor(apiRef, 'hydrateColumns', reorderPinnedColumns);
|
|
110
|
+
const isColumnPinned = React.useCallback((initialValue, field) => apiRef.current.isColumnPinned(field), [apiRef]);
|
|
111
|
+
useGridRegisterPipeProcessor(apiRef, 'isColumnPinned', isColumnPinned);
|
|
110
112
|
};
|
|
@@ -83,8 +83,7 @@ export const useGridColumnReorder = (apiRef, props) => {
|
|
|
83
83
|
// The limitingGroupId is the id of the group from which the dragged column should not escape
|
|
84
84
|
let limitingGroupId = null;
|
|
85
85
|
draggingColumnGroupPath.forEach(groupId => {
|
|
86
|
-
|
|
87
|
-
if (!((_groupsLookup$groupId = groupsLookup[groupId]) != null && _groupsLookup$groupId.freeReordering)) {
|
|
86
|
+
if (!groupsLookup[groupId]?.freeReordering) {
|
|
88
87
|
// Only consider group that are made of more than one column
|
|
89
88
|
if (columnIndex > 0 && getGroupPathFromColumnIndex(columnIndex - 1).includes(groupId)) {
|
|
90
89
|
limitingGroupId = groupId;
|
|
@@ -115,9 +114,8 @@ export const useGridColumnReorder = (apiRef, props) => {
|
|
|
115
114
|
getGroupPathFromColumnIndex(rightIndex).forEach(groupId => {
|
|
116
115
|
if (getGroupPathFromColumnIndex(leftIndex).includes(groupId)) {
|
|
117
116
|
if (!draggingColumnGroupPath.includes(groupId)) {
|
|
118
|
-
var _groupsLookup$groupId2;
|
|
119
117
|
// moving here split the group groupId in two distincts chunks
|
|
120
|
-
if (!
|
|
118
|
+
if (!groupsLookup[groupId]?.freeReordering) {
|
|
121
119
|
forbiddenIndexes.current[indexToForbid] = true;
|
|
122
120
|
}
|
|
123
121
|
}
|
|
@@ -8,11 +8,10 @@ import { gridDetailPanelExpandedRowIdsSelector, gridDetailPanelExpandedRowsConte
|
|
|
8
8
|
// called 3 times when opening/closing a panel.
|
|
9
9
|
|
|
10
10
|
export const detailPanelStateInitializer = (state, props) => {
|
|
11
|
-
var _ref, _props$detailPanelExp, _props$initialState;
|
|
12
11
|
return _extends({}, state, {
|
|
13
12
|
detailPanel: {
|
|
14
13
|
heightCache: {},
|
|
15
|
-
expandedRowIds:
|
|
14
|
+
expandedRowIds: props.detailPanelExpandedRowIds ?? props.initialState?.detailPanel?.expandedRowIds ?? []
|
|
16
15
|
}
|
|
17
16
|
});
|
|
18
17
|
};
|
|
@@ -30,7 +29,6 @@ function cacheContentAndHeight(apiRef, getDetailPanelContent, getDetailPanelHeig
|
|
|
30
29
|
return acc;
|
|
31
30
|
}, {});
|
|
32
31
|
const heightCache = rowIds.reduce((acc, id) => {
|
|
33
|
-
var _previousHeightCache$;
|
|
34
32
|
if (contentCache[id] == null) {
|
|
35
33
|
return acc;
|
|
36
34
|
}
|
|
@@ -39,7 +37,7 @@ function cacheContentAndHeight(apiRef, getDetailPanelContent, getDetailPanelHeig
|
|
|
39
37
|
const autoHeight = height === 'auto';
|
|
40
38
|
acc[id] = {
|
|
41
39
|
autoHeight,
|
|
42
|
-
height: autoHeight ?
|
|
40
|
+
height: autoHeight ? previousHeightCache[id]?.height : height
|
|
43
41
|
};
|
|
44
42
|
return acc;
|
|
45
43
|
}, {});
|
|
@@ -149,20 +147,18 @@ export const useGridDetailPanel = (apiRef, props) => {
|
|
|
149
147
|
}
|
|
150
148
|
}, [apiRef, props.detailPanelExpandedRowIds]);
|
|
151
149
|
const updateCachesAndForceUpdate = React.useCallback(() => {
|
|
152
|
-
var _apiRef$current$updat, _apiRef$current;
|
|
153
150
|
apiRef.current.setState(state => {
|
|
154
151
|
return _extends({}, state, {
|
|
155
152
|
detailPanel: _extends({}, state.detailPanel, cacheContentAndHeight(apiRef, props.getDetailPanelContent, props.getDetailPanelHeight, state.detailPanel.heightCache))
|
|
156
153
|
});
|
|
157
154
|
});
|
|
158
|
-
|
|
155
|
+
apiRef.current.updateDimensions?.();
|
|
159
156
|
apiRef.current.forceUpdate();
|
|
160
157
|
}, [apiRef, props.getDetailPanelContent, props.getDetailPanelHeight]);
|
|
161
158
|
useGridApiEventHandler(apiRef, 'sortedRowsSet', updateCachesAndForceUpdate);
|
|
162
159
|
const previousGetDetailPanelContentProp = React.useRef();
|
|
163
160
|
const previousGetDetailPanelHeightProp = React.useRef();
|
|
164
161
|
const updateCachesIfNeeded = React.useCallback(() => {
|
|
165
|
-
var _apiRef$current$updat2, _apiRef$current2;
|
|
166
162
|
if (props.getDetailPanelContent === previousGetDetailPanelContentProp.current && props.getDetailPanelHeight === previousGetDetailPanelHeightProp.current) {
|
|
167
163
|
return;
|
|
168
164
|
}
|
|
@@ -171,19 +167,18 @@ export const useGridDetailPanel = (apiRef, props) => {
|
|
|
171
167
|
detailPanel: _extends({}, state.detailPanel, cacheContentAndHeight(apiRef, props.getDetailPanelContent, props.getDetailPanelHeight, state.detailPanel.heightCache))
|
|
172
168
|
});
|
|
173
169
|
});
|
|
174
|
-
|
|
170
|
+
apiRef.current.updateDimensions?.();
|
|
175
171
|
previousGetDetailPanelContentProp.current = props.getDetailPanelContent;
|
|
176
172
|
previousGetDetailPanelHeightProp.current = props.getDetailPanelHeight;
|
|
177
173
|
}, [apiRef, props.getDetailPanelContent, props.getDetailPanelHeight]);
|
|
178
174
|
const addDetailHeight = React.useCallback((initialValue, row) => {
|
|
179
|
-
var _heightCache$row$id;
|
|
180
175
|
if (!expandedRowIds || expandedRowIds.length === 0 || !expandedRowIds.includes(row.id)) {
|
|
181
176
|
initialValue.detail = 0;
|
|
182
177
|
return initialValue;
|
|
183
178
|
}
|
|
184
179
|
updateCachesIfNeeded();
|
|
185
180
|
const heightCache = gridDetailPanelExpandedRowsHeightCacheSelector(apiRef);
|
|
186
|
-
initialValue.detail =
|
|
181
|
+
initialValue.detail = heightCache[row.id] ?? 0; // Fallback to zero because the cache might not be ready yet (for example page was changed)
|
|
187
182
|
return initialValue;
|
|
188
183
|
}, [apiRef, expandedRowIds, updateCachesIfNeeded]);
|
|
189
184
|
useGridRegisterPipeProcessor(apiRef, 'rowHeight', addDetailHeight);
|
|
@@ -15,7 +15,6 @@ function cacheContentAndHeight(apiRef, getDetailPanelContent, getDetailPanelHeig
|
|
|
15
15
|
return acc;
|
|
16
16
|
}, {});
|
|
17
17
|
const heightCache = rowIds.reduce((acc, id) => {
|
|
18
|
-
var _previousHeightCache$;
|
|
19
18
|
if (contentCache[id] == null) {
|
|
20
19
|
return acc;
|
|
21
20
|
}
|
|
@@ -24,7 +23,7 @@ function cacheContentAndHeight(apiRef, getDetailPanelContent, getDetailPanelHeig
|
|
|
24
23
|
const autoHeight = height === 'auto';
|
|
25
24
|
acc[id] = {
|
|
26
25
|
autoHeight,
|
|
27
|
-
height: !autoHeight ? height :
|
|
26
|
+
height: !autoHeight ? height : previousHeightCache[id]?.height
|
|
28
27
|
};
|
|
29
28
|
return acc;
|
|
30
29
|
}, {});
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// Only export the variable and types that should be publicly exposed and re-exported from `@mui/x-data-grid-pro`
|
|
2
2
|
export * from './columnPinning';
|
|
3
3
|
export * from './columnReorder';
|
|
4
|
-
export * from './columnResize';
|
|
5
4
|
export * from './rowReorder';
|
|
6
5
|
export * from './treeData';
|
|
7
6
|
export * from './detailPanel';
|
|
@@ -26,7 +26,6 @@ export const useGridInfiniteLoader = (apiRef, props) => {
|
|
|
26
26
|
const currentRatio = entry.intersectionRatio;
|
|
27
27
|
const isIntersecting = entry.isIntersecting;
|
|
28
28
|
if (isIntersecting && currentRatio === 1) {
|
|
29
|
-
var _observer$current;
|
|
30
29
|
const viewportPageSize = apiRef.current.getViewportPageSize();
|
|
31
30
|
const rowScrollEndParams = {
|
|
32
31
|
visibleColumns,
|
|
@@ -34,7 +33,7 @@ export const useGridInfiniteLoader = (apiRef, props) => {
|
|
|
34
33
|
visibleRowsCount: currentPage.rows.length
|
|
35
34
|
};
|
|
36
35
|
apiRef.current.publishEvent('rowsScrollEnd', rowScrollEndParams);
|
|
37
|
-
|
|
36
|
+
observer.current?.disconnect();
|
|
38
37
|
// do not observe this node anymore
|
|
39
38
|
triggerElement.current = null;
|
|
40
39
|
}
|
|
@@ -43,14 +42,13 @@ export const useGridInfiniteLoader = (apiRef, props) => {
|
|
|
43
42
|
const dimensions = useGridSelector(apiRef, gridDimensionsSelector);
|
|
44
43
|
const marginBottom = props.scrollEndThreshold - (dimensions.hasScrollX ? dimensions.scrollbarSize : 0);
|
|
45
44
|
React.useEffect(() => {
|
|
46
|
-
var _observer$current2;
|
|
47
45
|
if (!isEnabled) {
|
|
48
46
|
return;
|
|
49
47
|
}
|
|
50
48
|
if (!virtualScroller) {
|
|
51
49
|
return;
|
|
52
50
|
}
|
|
53
|
-
|
|
51
|
+
observer.current?.disconnect();
|
|
54
52
|
observer.current = new IntersectionObserver(handleLoadMoreRows, {
|
|
55
53
|
threshold: 1,
|
|
56
54
|
root: virtualScroller,
|
|
@@ -66,12 +64,10 @@ export const useGridInfiniteLoader = (apiRef, props) => {
|
|
|
66
64
|
return;
|
|
67
65
|
}
|
|
68
66
|
if (triggerElement.current !== node) {
|
|
69
|
-
|
|
70
|
-
(_observer$current3 = observer.current) == null || _observer$current3.disconnect();
|
|
67
|
+
observer.current?.disconnect();
|
|
71
68
|
triggerElement.current = node;
|
|
72
69
|
if (triggerElement.current) {
|
|
73
|
-
|
|
74
|
-
(_observer$current4 = observer.current) == null || _observer$current4.observe(triggerElement.current);
|
|
70
|
+
observer.current?.observe(triggerElement.current);
|
|
75
71
|
}
|
|
76
72
|
}
|
|
77
73
|
}, [isEnabled]);
|
|
@@ -89,9 +85,9 @@ export const useGridInfiniteLoader = (apiRef, props) => {
|
|
|
89
85
|
role: "presentation"
|
|
90
86
|
}, `trigger-${lastRowId}`);
|
|
91
87
|
}, [isEnabled, triggerRef]);
|
|
92
|
-
const
|
|
88
|
+
const infiniteLoaderPrivateApi = {
|
|
93
89
|
getInfiniteLoadingTriggerElement
|
|
94
90
|
};
|
|
95
|
-
useGridApiMethod(apiRef,
|
|
91
|
+
useGridApiMethod(apiRef, infiniteLoaderPrivateApi, 'private');
|
|
96
92
|
useGridApiOptionHandler(apiRef, 'rowsScrollEnd', props.onRowsScrollEnd);
|
|
97
93
|
};
|
|
@@ -15,9 +15,8 @@ function findSkeletonRowsSection({
|
|
|
15
15
|
let endIndex = visibleRowsSection.length - 1;
|
|
16
16
|
let isSkeletonSectionFound = false;
|
|
17
17
|
while (!isSkeletonSectionFound && firstRowIndex < lastRowIndex) {
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
const isEndingWithASkeletonRow = ((_apiRef$current$getRo2 = apiRef.current.getRowNode(visibleRowsSection[endIndex].id)) == null ? void 0 : _apiRef$current$getRo2.type) === 'skeletonRow';
|
|
18
|
+
const isStartingWithASkeletonRow = apiRef.current.getRowNode(visibleRowsSection[startIndex].id)?.type === 'skeletonRow';
|
|
19
|
+
const isEndingWithASkeletonRow = apiRef.current.getRowNode(visibleRowsSection[endIndex].id)?.type === 'skeletonRow';
|
|
21
20
|
if (isStartingWithASkeletonRow && isEndingWithASkeletonRow) {
|
|
22
21
|
isSkeletonSectionFound = true;
|
|
23
22
|
}
|
|
@@ -35,18 +34,6 @@ function findSkeletonRowsSection({
|
|
|
35
34
|
lastRowIndex
|
|
36
35
|
} : undefined;
|
|
37
36
|
}
|
|
38
|
-
function isLazyLoadingDisabled({
|
|
39
|
-
lazyLoadingFeatureFlag,
|
|
40
|
-
rowsLoadingMode
|
|
41
|
-
}) {
|
|
42
|
-
if (!lazyLoadingFeatureFlag) {
|
|
43
|
-
return true;
|
|
44
|
-
}
|
|
45
|
-
if (rowsLoadingMode !== 'server') {
|
|
46
|
-
return true;
|
|
47
|
-
}
|
|
48
|
-
return false;
|
|
49
|
-
}
|
|
50
37
|
|
|
51
38
|
/**
|
|
52
39
|
* @requires useGridRows (state)
|
|
@@ -55,20 +42,13 @@ function isLazyLoadingDisabled({
|
|
|
55
42
|
* @requires useGridScroll (method
|
|
56
43
|
*/
|
|
57
44
|
export const useGridLazyLoader = (privateApiRef, props) => {
|
|
58
|
-
var _props$experimentalFe;
|
|
59
45
|
const sortModel = useGridSelector(privateApiRef, gridSortModelSelector);
|
|
60
46
|
const filterModel = useGridSelector(privateApiRef, gridFilterModelSelector);
|
|
61
47
|
const renderedRowsIntervalCache = React.useRef({
|
|
62
48
|
firstRowToRender: 0,
|
|
63
49
|
lastRowToRender: 0
|
|
64
50
|
});
|
|
65
|
-
const
|
|
66
|
-
lazyLoading
|
|
67
|
-
} = (_props$experimentalFe = props.experimentalFeatures) != null ? _props$experimentalFe : {};
|
|
68
|
-
const isDisabled = isLazyLoadingDisabled({
|
|
69
|
-
lazyLoadingFeatureFlag: lazyLoading,
|
|
70
|
-
rowsLoadingMode: props.rowsLoadingMode
|
|
71
|
-
});
|
|
51
|
+
const isDisabled = props.rowsLoadingMode !== 'server';
|
|
72
52
|
const handleRenderedRowsIntervalChange = React.useCallback(params => {
|
|
73
53
|
if (isDisabled) {
|
|
74
54
|
return;
|
|
@@ -5,13 +5,9 @@ import { GRID_ROOT_GROUP_ID } from '@mui/x-data-grid';
|
|
|
5
5
|
export const GRID_SKELETON_ROW_ROOT_ID = 'auto-generated-skeleton-row-root';
|
|
6
6
|
const getSkeletonRowId = index => `${GRID_SKELETON_ROW_ROOT_ID}-${index}`;
|
|
7
7
|
export const useGridLazyLoaderPreProcessors = (privateApiRef, props) => {
|
|
8
|
-
var _props$experimentalFe;
|
|
9
|
-
const {
|
|
10
|
-
lazyLoading
|
|
11
|
-
} = (_props$experimentalFe = props.experimentalFeatures) != null ? _props$experimentalFe : {};
|
|
12
8
|
const addSkeletonRows = React.useCallback(groupingParams => {
|
|
13
9
|
const rootGroup = groupingParams.tree[GRID_ROOT_GROUP_ID];
|
|
14
|
-
if (
|
|
10
|
+
if (props.rowsLoadingMode !== 'server' || !props.rowCount || rootGroup.children.length >= props.rowCount) {
|
|
15
11
|
return groupingParams;
|
|
16
12
|
}
|
|
17
13
|
const tree = _extends({}, groupingParams.tree);
|
|
@@ -33,6 +29,6 @@ export const useGridLazyLoaderPreProcessors = (privateApiRef, props) => {
|
|
|
33
29
|
return _extends({}, groupingParams, {
|
|
34
30
|
tree
|
|
35
31
|
});
|
|
36
|
-
}, [props.rowCount, props.rowsLoadingMode
|
|
32
|
+
}, [props.rowCount, props.rowsLoadingMode]);
|
|
37
33
|
useGridRegisterPipeProcessor(privateApiRef, 'hydrateRows', addSkeletonRows);
|
|
38
34
|
};
|
|
@@ -3,18 +3,17 @@ import * as React from 'react';
|
|
|
3
3
|
import { useGridApiMethod } from '@mui/x-data-grid';
|
|
4
4
|
import { getRowIdFromRowModel } from '@mui/x-data-grid/internals';
|
|
5
5
|
function createPinnedRowsInternalCache(pinnedRows, getRowId) {
|
|
6
|
-
var _pinnedRows$top, _pinnedRows$bottom;
|
|
7
6
|
const cache = {
|
|
8
7
|
topIds: [],
|
|
9
8
|
bottomIds: [],
|
|
10
9
|
idLookup: {}
|
|
11
10
|
};
|
|
12
|
-
pinnedRows
|
|
11
|
+
pinnedRows?.top?.forEach(rowModel => {
|
|
13
12
|
const id = getRowIdFromRowModel(rowModel, getRowId);
|
|
14
13
|
cache.topIds.push(id);
|
|
15
14
|
cache.idLookup[id] = rowModel;
|
|
16
15
|
});
|
|
17
|
-
pinnedRows
|
|
16
|
+
pinnedRows?.bottom?.forEach(rowModel => {
|
|
18
17
|
const id = getRowIdFromRowModel(rowModel, getRowId);
|
|
19
18
|
cache.bottomIds.push(id);
|
|
20
19
|
cache.idLookup[id] = rowModel;
|
|
@@ -22,11 +21,10 @@ function createPinnedRowsInternalCache(pinnedRows, getRowId) {
|
|
|
22
21
|
return cache;
|
|
23
22
|
}
|
|
24
23
|
export const rowPinningStateInitializer = (state, props, apiRef) => {
|
|
25
|
-
var _state$rows;
|
|
26
24
|
apiRef.current.caches.pinnedRows = createPinnedRowsInternalCache(props.pinnedRows, props.getRowId);
|
|
27
25
|
return _extends({}, state, {
|
|
28
26
|
rows: _extends({}, state.rows, {
|
|
29
|
-
additionalRowGroups: _extends({},
|
|
27
|
+
additionalRowGroups: _extends({}, state.rows?.additionalRowGroups, {
|
|
30
28
|
pinnedRows: {
|
|
31
29
|
top: [],
|
|
32
30
|
bottom: []
|
|
@@ -11,7 +11,6 @@ export function addPinnedRow({
|
|
|
11
11
|
apiRef,
|
|
12
12
|
isAutoGenerated
|
|
13
13
|
}) {
|
|
14
|
-
var _groupingParams$addit, _groupingParams$addit2;
|
|
15
14
|
const dataRowIdToModelLookup = _extends({}, groupingParams.dataRowIdToModelLookup);
|
|
16
15
|
const dataRowIdToIdLookup = _extends({}, groupingParams.dataRowIdToIdLookup);
|
|
17
16
|
const tree = _extends({}, groupingParams.tree);
|
|
@@ -35,12 +34,12 @@ export function addPinnedRow({
|
|
|
35
34
|
|
|
36
35
|
apiRef.current.caches.rows.dataRowIdToModelLookup[rowId] = _extends({}, rowModel);
|
|
37
36
|
apiRef.current.caches.rows.dataRowIdToIdLookup[rowId] = rowId;
|
|
38
|
-
const previousPinnedRows =
|
|
37
|
+
const previousPinnedRows = groupingParams.additionalRowGroups?.pinnedRows || {};
|
|
39
38
|
const newPinnedRow = {
|
|
40
39
|
id: rowId,
|
|
41
40
|
model: rowModel
|
|
42
41
|
};
|
|
43
|
-
if (
|
|
42
|
+
if (groupingParams.additionalRowGroups?.pinnedRows?.[position]?.includes(newPinnedRow)) {
|
|
44
43
|
return _extends({}, groupingParams, {
|
|
45
44
|
dataRowIdToModelLookup,
|
|
46
45
|
dataRowIdToIdLookup,
|
|
@@ -62,7 +61,6 @@ export function addPinnedRow({
|
|
|
62
61
|
}
|
|
63
62
|
export const useGridRowPinningPreProcessors = apiRef => {
|
|
64
63
|
const addPinnedRows = React.useCallback(groupingParams => {
|
|
65
|
-
var _pinnedRowsCache$topI, _pinnedRowsCache$bott, _pinnedRowsCache$bott2, _pinnedRowsCache$topI2;
|
|
66
64
|
const pinnedRowsCache = apiRef.current.caches.pinnedRows || {};
|
|
67
65
|
let newGroupingParams = _extends({}, groupingParams, {
|
|
68
66
|
additionalRowGroups: _extends({}, groupingParams.additionalRowGroups, {
|
|
@@ -70,7 +68,7 @@ export const useGridRowPinningPreProcessors = apiRef => {
|
|
|
70
68
|
pinnedRows: {}
|
|
71
69
|
})
|
|
72
70
|
});
|
|
73
|
-
|
|
71
|
+
pinnedRowsCache.topIds?.forEach(rowId => {
|
|
74
72
|
newGroupingParams = addPinnedRow({
|
|
75
73
|
groupingParams: newGroupingParams,
|
|
76
74
|
rowModel: pinnedRowsCache.idLookup[rowId],
|
|
@@ -80,7 +78,7 @@ export const useGridRowPinningPreProcessors = apiRef => {
|
|
|
80
78
|
isAutoGenerated: false
|
|
81
79
|
});
|
|
82
80
|
});
|
|
83
|
-
|
|
81
|
+
pinnedRowsCache.bottomIds?.forEach(rowId => {
|
|
84
82
|
newGroupingParams = addPinnedRow({
|
|
85
83
|
groupingParams: newGroupingParams,
|
|
86
84
|
rowModel: pinnedRowsCache.idLookup[rowId],
|
|
@@ -92,7 +90,7 @@ export const useGridRowPinningPreProcessors = apiRef => {
|
|
|
92
90
|
});
|
|
93
91
|
|
|
94
92
|
// If row with the same `id` is present both in `rows` and `pinnedRows` - remove it from the root group children
|
|
95
|
-
if (
|
|
93
|
+
if (pinnedRowsCache.bottomIds?.length || pinnedRowsCache.topIds?.length) {
|
|
96
94
|
const shouldKeepRow = rowId => {
|
|
97
95
|
if (newGroupingParams.tree[rowId] && newGroupingParams.tree[rowId].type === 'pinnedRow') {
|
|
98
96
|
return false;
|
|
@@ -15,7 +15,7 @@ export const GRID_TREE_DATA_GROUPING_COL_DEF = _extends({}, GRID_STRING_COL_DEF,
|
|
|
15
15
|
valueGetter: (value, row, column, apiRef) => {
|
|
16
16
|
const rowId = apiRef.current.getRowId(row);
|
|
17
17
|
const rowNode = apiRef.current.getRowNode(rowId);
|
|
18
|
-
return
|
|
18
|
+
return rowNode?.type === 'group' || rowNode?.type === 'leaf' ? rowNode.groupingKey : undefined;
|
|
19
19
|
}
|
|
20
20
|
});
|
|
21
21
|
export const GRID_TREE_DATA_GROUPING_FIELD = '__tree_data_group__';
|
|
@@ -35,9 +35,8 @@ export const filterRowTreeFromTreeData = params => {
|
|
|
35
35
|
let filteredDescendantCount = 0;
|
|
36
36
|
if (node.type === 'group') {
|
|
37
37
|
node.children.forEach(childId => {
|
|
38
|
-
var _isMatchingFilters;
|
|
39
38
|
const childNode = rowTree[childId];
|
|
40
|
-
const childSubTreeSize = filterTreeNode(childNode,
|
|
39
|
+
const childSubTreeSize = filterTreeNode(childNode, isMatchingFilters ?? isParentMatchingFilters, areAncestorsExpanded && !!node.childrenExpanded);
|
|
41
40
|
filteredDescendantCount += childSubTreeSize;
|
|
42
41
|
});
|
|
43
42
|
}
|
|
@@ -17,7 +17,6 @@ export const useGridTreeDataPreProcessors = (privateApiRef, props) => {
|
|
|
17
17
|
privateApiRef.current.setStrategyAvailability('rowTree', TREE_DATA_STRATEGY, props.treeData ? () => true : () => false);
|
|
18
18
|
}, [privateApiRef, props.treeData]);
|
|
19
19
|
const getGroupingColDef = React.useCallback(() => {
|
|
20
|
-
var _colDefOverride;
|
|
21
20
|
const groupingColDefProp = props.groupingColDef;
|
|
22
21
|
let colDefOverride;
|
|
23
22
|
if (typeof groupingColDefProp === 'function') {
|
|
@@ -29,7 +28,7 @@ export const useGridTreeDataPreProcessors = (privateApiRef, props) => {
|
|
|
29
28
|
} else {
|
|
30
29
|
colDefOverride = groupingColDefProp;
|
|
31
30
|
}
|
|
32
|
-
const _ref =
|
|
31
|
+
const _ref = colDefOverride ?? {},
|
|
33
32
|
{
|
|
34
33
|
hideDescendantCount
|
|
35
34
|
} = _ref,
|
package/esm/internals/index.js
CHANGED
|
@@ -5,7 +5,6 @@ export { DATA_GRID_PRO_DEFAULT_SLOTS_COMPONENTS } from '../constants/dataGridPro
|
|
|
5
5
|
|
|
6
6
|
// eslint-disable-next-line import/export
|
|
7
7
|
export { useGridColumnHeaders } from '../hooks/features/columnHeaders/useGridColumnHeaders';
|
|
8
|
-
export { useGridColumnResize, columnResizeStateInitializer } from '../hooks/features/columnResize/useGridColumnResize';
|
|
9
8
|
export { useGridColumnPinning, columnPinningStateInitializer } from '../hooks/features/columnPinning/useGridColumnPinning';
|
|
10
9
|
export { useGridColumnPinningPreProcessors } from '../hooks/features/columnPinning/useGridColumnPinningPreProcessors';
|
|
11
10
|
export { useGridColumnReorder, columnReorderStateInitializer } from '../hooks/features/columnReorder/useGridColumnReorder';
|
package/esm/utils/releaseInfo.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ponyfillGlobal } from '@mui/utils';
|
|
2
2
|
export const getReleaseInfo = () => {
|
|
3
|
-
const releaseInfo = "
|
|
3
|
+
const releaseInfo = "MTcxMTA1ODQwMDAwMA==";
|
|
4
4
|
if (process.env.NODE_ENV !== 'production') {
|
|
5
5
|
// A simple hack to set the value in the test environment (has no build step).
|
|
6
6
|
// eslint-disable-next-line no-useless-concat
|
|
@@ -19,14 +19,13 @@ export const insertDataRowInTree = ({
|
|
|
19
19
|
}) => {
|
|
20
20
|
let parentNodeId = GRID_ROOT_GROUP_ID;
|
|
21
21
|
for (let depth = 0; depth < path.length; depth += 1) {
|
|
22
|
-
var _childrenFromPath;
|
|
23
22
|
const {
|
|
24
23
|
key,
|
|
25
24
|
field
|
|
26
25
|
} = path[depth];
|
|
27
|
-
const fieldWithDefaultValue = field
|
|
28
|
-
const keyWithDefaultValue = key
|
|
29
|
-
const existingNodeIdWithPartialPath =
|
|
26
|
+
const fieldWithDefaultValue = field ?? '__no_field__';
|
|
27
|
+
const keyWithDefaultValue = key ?? '__no_key__';
|
|
28
|
+
const existingNodeIdWithPartialPath = tree[parentNodeId].childrenFromPath?.[fieldWithDefaultValue]?.[keyWithDefaultValue.toString()];
|
|
30
29
|
|
|
31
30
|
// When we reach the last step of the path,
|
|
32
31
|
// We need to create a node for the row passed to `insertNodeInTree`
|
|
@@ -41,7 +40,7 @@ export const insertDataRowInTree = ({
|
|
|
41
40
|
parent: parentNodeId,
|
|
42
41
|
groupingKey: key
|
|
43
42
|
};
|
|
44
|
-
updatedGroupsManager
|
|
43
|
+
updatedGroupsManager?.addAction(parentNodeId, 'insertChildren');
|
|
45
44
|
insertNodeInTree(leafNode, tree, treeDepths, previousTree);
|
|
46
45
|
} else {
|
|
47
46
|
const existingNodeWithPartialPath = tree[existingNodeIdWithPartialPath];
|
|
@@ -49,8 +48,8 @@ export const insertDataRowInTree = ({
|
|
|
49
48
|
// If we already have an auto-generated group matching the partial path,
|
|
50
49
|
// We replace it with the node from of data row passed to `insertNodeInTree`
|
|
51
50
|
if (existingNodeWithPartialPath.type === 'group' && existingNodeWithPartialPath.isAutoGenerated) {
|
|
52
|
-
updatedGroupsManager
|
|
53
|
-
updatedGroupsManager
|
|
51
|
+
updatedGroupsManager?.addAction(parentNodeId, 'removeChildren');
|
|
52
|
+
updatedGroupsManager?.addAction(parentNodeId, 'insertChildren');
|
|
54
53
|
updateGroupNodeIdAndAutoGenerated({
|
|
55
54
|
tree,
|
|
56
55
|
previousTree,
|
|
@@ -64,7 +63,7 @@ export const insertDataRowInTree = ({
|
|
|
64
63
|
} else {
|
|
65
64
|
// If we have another row matching the partial path, then there is a duplicate in the dataset.
|
|
66
65
|
// We warn the user and skip the current row.
|
|
67
|
-
onDuplicatePath
|
|
66
|
+
onDuplicatePath?.(existingNodeIdWithPartialPath, id, path);
|
|
68
67
|
}
|
|
69
68
|
}
|
|
70
69
|
}
|
|
@@ -87,7 +86,7 @@ export const insertDataRowInTree = ({
|
|
|
87
86
|
childrenFromPath: {},
|
|
88
87
|
childrenExpanded: false
|
|
89
88
|
};
|
|
90
|
-
updatedGroupsManager
|
|
89
|
+
updatedGroupsManager?.addAction(parentNodeId, 'insertChildren');
|
|
91
90
|
insertNodeInTree(updateGroupDefaultExpansion(autoGeneratedGroupNode, defaultGroupingExpansionDepth, isGroupExpandedByDefault), tree, treeDepths, previousTree);
|
|
92
91
|
parentNodeId = nodeId;
|
|
93
92
|
}
|
|
@@ -19,7 +19,7 @@ const removeNodeAndCleanParent = ({
|
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
21
|
const parentNode = tree[node.parent];
|
|
22
|
-
updatedGroupsManager
|
|
22
|
+
updatedGroupsManager?.addAction(parentNode.id, 'removeChildren');
|
|
23
23
|
const shouldDeleteGroup = parentNode.id !== GRID_ROOT_GROUP_ID && parentNode.children.length === 0;
|
|
24
24
|
if (shouldDeleteGroup) {
|
|
25
25
|
if (parentNode.isAutoGenerated) {
|
|
@@ -45,8 +45,8 @@ const replaceDataGroupWithAutoGeneratedGroup = ({
|
|
|
45
45
|
treeDepths,
|
|
46
46
|
updatedGroupsManager
|
|
47
47
|
}) => {
|
|
48
|
-
updatedGroupsManager
|
|
49
|
-
updatedGroupsManager
|
|
48
|
+
updatedGroupsManager?.addAction(node.parent, 'removeChildren');
|
|
49
|
+
updatedGroupsManager?.addAction(node.parent, 'insertChildren');
|
|
50
50
|
updateGroupNodeIdAndAutoGenerated({
|
|
51
51
|
previousTree: null,
|
|
52
52
|
tree,
|
|
@@ -106,7 +106,7 @@ export const sortRowTree = params => {
|
|
|
106
106
|
const rootList = List.from(sortedGroupedByParentRows.get(GRID_ROOT_GROUP_ID));
|
|
107
107
|
rootList.forEach(node => {
|
|
108
108
|
const children = sortedGroupedByParentRows.get(node.data);
|
|
109
|
-
if (children
|
|
109
|
+
if (children?.length) {
|
|
110
110
|
node.insertAfter(List.from(children));
|
|
111
111
|
}
|
|
112
112
|
});
|
|
@@ -63,7 +63,7 @@ export const updateRowTree = params => {
|
|
|
63
63
|
defaultGroupingExpansionDepth: params.defaultGroupingExpansionDepth
|
|
64
64
|
});
|
|
65
65
|
} else {
|
|
66
|
-
updatedGroupsManager
|
|
66
|
+
updatedGroupsManager?.addAction(tree[id].parent, 'modifyChildren');
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
|
package/esm/utils/tree/utils.js
CHANGED
|
@@ -37,22 +37,20 @@ export const updateGroupDefaultExpansion = (node, defaultGroupingExpansionDepth,
|
|
|
37
37
|
* Insert a node in the tree
|
|
38
38
|
*/
|
|
39
39
|
export const insertNodeInTree = (node, tree, treeDepths, previousTree) => {
|
|
40
|
-
var _treeDepths$node$dept;
|
|
41
40
|
// 1. Insert node in the tree.
|
|
42
41
|
tree[node.id] = node;
|
|
43
42
|
|
|
44
43
|
// 2. Increment the `treeDepths` object for the node's depth.
|
|
45
|
-
treeDepths[node.depth] = (
|
|
44
|
+
treeDepths[node.depth] = (treeDepths[node.depth] ?? 0) + 1;
|
|
46
45
|
|
|
47
46
|
// 3. Register the new node in its parent.
|
|
48
47
|
const parentNode = tree[node.parent];
|
|
49
48
|
if (node.type === 'group' || node.type === 'leaf') {
|
|
50
|
-
var _groupingField, _groupingKey, _parentNode$childrenF;
|
|
51
49
|
// For groups and leaves,
|
|
52
50
|
// Register the node from its parents `children` and `childrenFromPath` properties.
|
|
53
|
-
const groupingFieldName =
|
|
54
|
-
const groupingKeyName =
|
|
55
|
-
const groupingField =
|
|
51
|
+
const groupingFieldName = node.groupingField ?? '__no_field__';
|
|
52
|
+
const groupingKeyName = node.groupingKey ?? '__no_key__';
|
|
53
|
+
const groupingField = parentNode.childrenFromPath?.[groupingFieldName];
|
|
56
54
|
if (previousTree !== null && previousTree[parentNode.id] === tree[parentNode.id]) {
|
|
57
55
|
parentNode.children = [...parentNode.children, node.id];
|
|
58
56
|
} else {
|
|
@@ -104,9 +102,8 @@ export const removeNodeFromTree = ({
|
|
|
104
102
|
// For groups and leaves,
|
|
105
103
|
// Unregister the node from its parents `children` and `childrenFromPath` properties.
|
|
106
104
|
else {
|
|
107
|
-
|
|
108
|
-
const
|
|
109
|
-
const groupingKey = (_groupingKey2 = node.groupingKey) != null ? _groupingKey2 : '__no_key__';
|
|
105
|
+
const groupingField = node.groupingField ?? '__no_field__';
|
|
106
|
+
const groupingKey = node.groupingKey ?? '__no_key__';
|
|
110
107
|
|
|
111
108
|
// TODO rows v6: Can we avoid this linear complexity ?
|
|
112
109
|
const children = parentNode.children.filter(childId => childId !== node.id);
|