@mui/x-data-grid-pro 5.17.5 → 6.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +297 -19
- package/DataGridPro/DataGridPro.js +4 -14
- package/DataGridPro/useDataGridProProps.js +2 -2
- package/components/DataGridProVirtualScroller.js +2 -2
- package/components/GridDetailPanelToggleCell.js +1 -1
- package/components/GridRowReorderCell.js +4 -6
- package/components/GridTreeDataGroupingCell.d.ts +2 -2
- package/components/GridTreeDataGroupingCell.js +1 -1
- package/hooks/features/detailPanel/useGridDetailPanel.js +2 -2
- package/hooks/features/detailPanel/useGridDetailPanelCache.js +2 -2
- package/hooks/features/infiniteLoader/useGridInfiniteLoader.js +2 -2
- package/hooks/features/lazyLoader/useGridLazyLoader.js +20 -9
- package/hooks/features/lazyLoader/useGridLazyLoaderPreProcessors.d.ts +1 -1
- package/hooks/features/lazyLoader/useGridLazyLoaderPreProcessors.js +20 -6
- package/hooks/features/rowPinning/gridRowPinningInterface.d.ts +2 -2
- package/hooks/features/rowPinning/useGridRowPinningPreProcessors.d.ts +16 -16
- package/hooks/features/rowPinning/useGridRowPinningPreProcessors.js +62 -25
- package/hooks/features/rowReorder/useGridRowReorder.js +5 -5
- package/hooks/features/treeData/gridTreeDataGroupColDef.js +1 -1
- package/hooks/features/treeData/gridTreeDataUtils.js +14 -12
- package/hooks/features/treeData/useGridTreeData.js +2 -6
- package/hooks/features/treeData/useGridTreeDataPreProcessors.js +35 -18
- package/index.js +1 -1
- package/internals/index.d.ts +4 -2
- package/internals/index.js +4 -2
- package/legacy/DataGridPro/DataGridPro.js +4 -14
- package/legacy/DataGridPro/useDataGridProProps.js +2 -2
- package/legacy/components/DataGridProVirtualScroller.js +2 -2
- package/legacy/components/GridDetailPanelToggleCell.js +1 -1
- package/legacy/components/GridRowReorderCell.js +4 -6
- package/legacy/components/GridTreeDataGroupingCell.js +1 -1
- package/legacy/hooks/features/detailPanel/useGridDetailPanel.js +2 -2
- package/legacy/hooks/features/detailPanel/useGridDetailPanelCache.js +2 -2
- package/legacy/hooks/features/infiniteLoader/useGridInfiniteLoader.js +2 -2
- package/legacy/hooks/features/lazyLoader/useGridLazyLoader.js +25 -15
- package/legacy/hooks/features/lazyLoader/useGridLazyLoaderPreProcessors.js +21 -7
- package/legacy/hooks/features/rowPinning/useGridRowPinningPreProcessors.js +62 -25
- package/legacy/hooks/features/rowReorder/useGridRowReorder.js +5 -5
- package/legacy/hooks/features/treeData/gridTreeDataGroupColDef.js +1 -1
- package/legacy/hooks/features/treeData/gridTreeDataUtils.js +14 -12
- package/legacy/hooks/features/treeData/useGridTreeData.js +2 -6
- package/legacy/hooks/features/treeData/useGridTreeDataPreProcessors.js +37 -22
- package/legacy/index.js +1 -1
- package/legacy/internals/index.js +4 -2
- package/legacy/utils/tree/createRowTree.js +36 -0
- package/legacy/utils/tree/index.js +1 -1
- package/legacy/utils/tree/insertDataRowInTree.js +127 -0
- package/legacy/utils/tree/models.js +1 -0
- package/legacy/utils/tree/removeDataRowFromTree.js +97 -0
- package/legacy/utils/tree/sortRowTree.js +49 -43
- package/legacy/utils/tree/updateRowTree.js +81 -0
- package/legacy/utils/tree/utils.js +184 -0
- package/models/dataGridProProps.d.ts +3 -3
- package/modern/DataGridPro/DataGridPro.js +4 -14
- package/modern/DataGridPro/useDataGridProProps.js +2 -2
- package/modern/components/DataGridProVirtualScroller.js +2 -2
- package/modern/components/GridDetailPanelToggleCell.js +1 -1
- package/modern/components/GridRowReorderCell.js +4 -4
- package/modern/components/GridTreeDataGroupingCell.js +1 -1
- package/modern/hooks/features/detailPanel/useGridDetailPanel.js +2 -2
- package/modern/hooks/features/detailPanel/useGridDetailPanelCache.js +2 -2
- package/modern/hooks/features/infiniteLoader/useGridInfiniteLoader.js +2 -2
- package/modern/hooks/features/lazyLoader/useGridLazyLoader.js +20 -9
- package/modern/hooks/features/lazyLoader/useGridLazyLoaderPreProcessors.js +20 -6
- package/modern/hooks/features/rowPinning/useGridRowPinningPreProcessors.js +60 -23
- package/modern/hooks/features/rowReorder/useGridRowReorder.js +5 -3
- package/modern/hooks/features/treeData/gridTreeDataGroupColDef.js +1 -1
- package/modern/hooks/features/treeData/gridTreeDataUtils.js +13 -9
- package/modern/hooks/features/treeData/useGridTreeData.js +2 -4
- package/modern/hooks/features/treeData/useGridTreeDataPreProcessors.js +35 -18
- package/modern/index.js +1 -1
- package/modern/internals/index.js +4 -2
- package/modern/utils/tree/createRowTree.js +35 -0
- package/modern/utils/tree/index.js +1 -1
- package/modern/utils/tree/insertDataRowInTree.js +127 -0
- package/modern/utils/tree/models.js +1 -0
- package/modern/utils/tree/removeDataRowFromTree.js +100 -0
- package/modern/utils/tree/sortRowTree.js +46 -40
- package/modern/utils/tree/updateRowTree.js +83 -0
- package/modern/utils/tree/utils.js +180 -0
- package/node/DataGridPro/DataGridPro.js +4 -14
- package/node/DataGridPro/useDataGridProProps.js +1 -1
- package/node/components/DataGridProVirtualScroller.js +1 -1
- package/node/components/GridDetailPanelToggleCell.js +1 -1
- package/node/components/GridRowReorderCell.js +3 -5
- package/node/components/GridTreeDataGroupingCell.js +1 -1
- package/node/hooks/features/detailPanel/useGridDetailPanel.js +1 -1
- package/node/hooks/features/detailPanel/useGridDetailPanelCache.js +1 -1
- package/node/hooks/features/infiniteLoader/useGridInfiniteLoader.js +1 -1
- package/node/hooks/features/lazyLoader/useGridLazyLoader.js +19 -8
- package/node/hooks/features/lazyLoader/useGridLazyLoaderPreProcessors.js +18 -5
- package/node/hooks/features/rowPinning/useGridRowPinningPreProcessors.js +63 -26
- package/node/hooks/features/rowReorder/useGridRowReorder.js +4 -4
- package/node/hooks/features/treeData/gridTreeDataGroupColDef.js +1 -1
- package/node/hooks/features/treeData/gridTreeDataUtils.js +14 -12
- package/node/hooks/features/treeData/useGridTreeData.js +1 -5
- package/node/hooks/features/treeData/useGridTreeDataPreProcessors.js +35 -17
- package/node/index.js +1 -1
- package/node/internals/index.js +35 -10
- package/node/utils/tree/createRowTree.js +46 -0
- package/node/utils/tree/index.js +2 -2
- package/node/utils/tree/insertDataRowInTree.js +139 -0
- package/node/utils/tree/models.js +5 -0
- package/node/utils/tree/removeDataRowFromTree.js +110 -0
- package/node/utils/tree/sortRowTree.js +50 -43
- package/node/utils/tree/updateRowTree.js +98 -0
- package/node/utils/tree/utils.js +217 -0
- package/package.json +5 -5
- package/utils/tree/createRowTree.d.ts +15 -0
- package/utils/tree/createRowTree.js +35 -0
- package/utils/tree/index.d.ts +1 -1
- package/utils/tree/index.js +1 -1
- package/utils/tree/insertDataRowInTree.d.ts +51 -0
- package/utils/tree/insertDataRowInTree.js +129 -0
- package/utils/tree/models.d.ts +13 -0
- package/utils/tree/models.js +1 -0
- package/utils/tree/removeDataRowFromTree.d.ts +40 -0
- package/utils/tree/removeDataRowFromTree.js +100 -0
- package/utils/tree/sortRowTree.d.ts +6 -1
- package/utils/tree/sortRowTree.js +46 -40
- package/utils/tree/updateRowTree.d.ts +19 -0
- package/utils/tree/updateRowTree.js +83 -0
- package/utils/tree/utils.d.ts +66 -0
- package/utils/tree/utils.js +186 -0
- package/legacy/utils/tree/buildRowTree.js +0 -195
- package/modern/utils/tree/buildRowTree.js +0 -174
- package/node/utils/tree/buildRowTree.js +0 -195
- package/utils/tree/buildRowTree.d.ts +0 -48
- package/utils/tree/buildRowTree.js +0 -186
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { GRID_ROOT_GROUP_ID } from '@mui/x-data-grid';
|
|
2
|
+
import { addGroupDefaultExpansion, getGroupRowIdFromPath, insertNodeInTree, updateGroupNodeIdAndAutoGenerated } from './utils';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Inserts a data row in a tree.
|
|
6
|
+
* For each steps of its path:
|
|
7
|
+
* - if a node exists with the same partial path, it will register this node as the ancestor of the data row.
|
|
8
|
+
* - if not, it will create an auto-generated node and register it as ancestor of the data row.
|
|
9
|
+
*/
|
|
10
|
+
export const insertDataRowInTree = ({
|
|
11
|
+
id,
|
|
12
|
+
path,
|
|
13
|
+
updatedGroupsManager,
|
|
14
|
+
tree,
|
|
15
|
+
treeDepths,
|
|
16
|
+
onDuplicatePath,
|
|
17
|
+
isGroupExpandedByDefault,
|
|
18
|
+
defaultGroupingExpansionDepth
|
|
19
|
+
}) => {
|
|
20
|
+
let parentNodeId = GRID_ROOT_GROUP_ID;
|
|
21
|
+
|
|
22
|
+
for (let depth = 0; depth < path.length; depth += 1) {
|
|
23
|
+
const {
|
|
24
|
+
key,
|
|
25
|
+
field
|
|
26
|
+
} = path[depth];
|
|
27
|
+
const fieldWithDefaultValue = field ?? '__no_field__';
|
|
28
|
+
const keyWithDefaultValue = key ?? '__no_key__';
|
|
29
|
+
const existingNodeIdWithPartialPath = tree[parentNodeId].childrenFromPath?.[fieldWithDefaultValue]?.[keyWithDefaultValue.toString()]; // When we reach the last step of the path,
|
|
30
|
+
// We need to create a node for the row passed to `insertNodeInTree`
|
|
31
|
+
|
|
32
|
+
if (depth === path.length - 1) {
|
|
33
|
+
// If no node matches the full path,
|
|
34
|
+
// We create a leaf node for the data row.
|
|
35
|
+
if (existingNodeIdWithPartialPath == null) {
|
|
36
|
+
const leafNode = {
|
|
37
|
+
type: 'leaf',
|
|
38
|
+
id,
|
|
39
|
+
depth,
|
|
40
|
+
parent: parentNodeId,
|
|
41
|
+
groupingKey: key
|
|
42
|
+
};
|
|
43
|
+
updatedGroupsManager?.addAction(parentNodeId, 'insertChildren');
|
|
44
|
+
insertNodeInTree({
|
|
45
|
+
node: leafNode,
|
|
46
|
+
tree,
|
|
47
|
+
treeDepths
|
|
48
|
+
});
|
|
49
|
+
} else {
|
|
50
|
+
const existingNodeWithPartialPath = tree[existingNodeIdWithPartialPath]; // If we already have an auto-generated group matching the partial path,
|
|
51
|
+
// We replace it with the node from of data row passed to `insertNodeInTree`
|
|
52
|
+
|
|
53
|
+
if (existingNodeWithPartialPath.type === 'group' && existingNodeWithPartialPath.isAutoGenerated) {
|
|
54
|
+
updatedGroupsManager?.addAction(parentNodeId, 'removeChildren');
|
|
55
|
+
updatedGroupsManager?.addAction(parentNodeId, 'insertChildren');
|
|
56
|
+
updateGroupNodeIdAndAutoGenerated({
|
|
57
|
+
tree,
|
|
58
|
+
treeDepths,
|
|
59
|
+
node: existingNodeWithPartialPath,
|
|
60
|
+
updatedNode: {
|
|
61
|
+
id,
|
|
62
|
+
isAutoGenerated: false
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
} else {
|
|
66
|
+
// If we have another row matching the partial path, then there is a duplicate in the dataset.
|
|
67
|
+
// We warn the user and skip the current row.
|
|
68
|
+
onDuplicatePath?.(existingNodeIdWithPartialPath, id, path);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
} // For the intermediary steps of the path,
|
|
72
|
+
// We need to make sure that there is a node matching the partial path.
|
|
73
|
+
//
|
|
74
|
+
// If no node matches the partial path,
|
|
75
|
+
// We create an auto-generated group node.
|
|
76
|
+
else if (existingNodeIdWithPartialPath == null) {
|
|
77
|
+
const nodeId = getGroupRowIdFromPath(path.slice(0, depth + 1));
|
|
78
|
+
const autoGeneratedGroupNode = {
|
|
79
|
+
type: 'group',
|
|
80
|
+
id: nodeId,
|
|
81
|
+
parent: parentNodeId,
|
|
82
|
+
depth,
|
|
83
|
+
isAutoGenerated: true,
|
|
84
|
+
groupingKey: key,
|
|
85
|
+
groupingField: field,
|
|
86
|
+
children: [],
|
|
87
|
+
childrenFromPath: {}
|
|
88
|
+
};
|
|
89
|
+
updatedGroupsManager?.addAction(parentNodeId, 'insertChildren');
|
|
90
|
+
insertNodeInTree({
|
|
91
|
+
node: addGroupDefaultExpansion({
|
|
92
|
+
node: autoGeneratedGroupNode,
|
|
93
|
+
defaultGroupingExpansionDepth,
|
|
94
|
+
isGroupExpandedByDefault
|
|
95
|
+
}),
|
|
96
|
+
tree,
|
|
97
|
+
treeDepths
|
|
98
|
+
});
|
|
99
|
+
parentNodeId = nodeId;
|
|
100
|
+
} // For the intermediary steps of the path
|
|
101
|
+
// If a node matches the partial path, we use it as parent for the next step
|
|
102
|
+
else {
|
|
103
|
+
const currentGroupNode = tree[existingNodeIdWithPartialPath]; // If the node matching the partial path is not a group, we turn it into a group
|
|
104
|
+
|
|
105
|
+
if (currentGroupNode.type !== 'group') {
|
|
106
|
+
const groupNode = {
|
|
107
|
+
type: 'group',
|
|
108
|
+
id: currentGroupNode.id,
|
|
109
|
+
parent: currentGroupNode.parent,
|
|
110
|
+
depth: currentGroupNode.depth,
|
|
111
|
+
isAutoGenerated: false,
|
|
112
|
+
groupingKey: key,
|
|
113
|
+
groupingField: field,
|
|
114
|
+
children: [],
|
|
115
|
+
childrenFromPath: {}
|
|
116
|
+
};
|
|
117
|
+
tree[existingNodeIdWithPartialPath] = addGroupDefaultExpansion({
|
|
118
|
+
node: groupNode,
|
|
119
|
+
defaultGroupingExpansionDepth,
|
|
120
|
+
isGroupExpandedByDefault
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
parentNodeId = currentGroupNode.id;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { GRID_ROOT_GROUP_ID } from '@mui/x-data-grid';
|
|
2
|
+
import { getNodePathInTree, getGroupRowIdFromPath, removeNodeFromTree, updateGroupNodeIdAndAutoGenerated } from './utils';
|
|
3
|
+
|
|
4
|
+
const removeNodeAndCleanParent = ({
|
|
5
|
+
node,
|
|
6
|
+
tree,
|
|
7
|
+
treeDepths,
|
|
8
|
+
updatedGroupsManager
|
|
9
|
+
}) => {
|
|
10
|
+
removeNodeFromTree({
|
|
11
|
+
node,
|
|
12
|
+
tree,
|
|
13
|
+
treeDepths
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
if (node.type === 'group' && node.footerId != null) {
|
|
17
|
+
removeNodeFromTree({
|
|
18
|
+
node: tree[node.footerId],
|
|
19
|
+
tree,
|
|
20
|
+
treeDepths
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const parentNode = tree[node.parent];
|
|
25
|
+
updatedGroupsManager?.addAction(parentNode.id, 'removeChildren');
|
|
26
|
+
const shouldDeleteGroup = parentNode.id !== GRID_ROOT_GROUP_ID && parentNode.children.length === 0;
|
|
27
|
+
|
|
28
|
+
if (shouldDeleteGroup) {
|
|
29
|
+
if (parentNode.isAutoGenerated) {
|
|
30
|
+
removeNodeAndCleanParent({
|
|
31
|
+
node,
|
|
32
|
+
tree,
|
|
33
|
+
treeDepths
|
|
34
|
+
});
|
|
35
|
+
} else {
|
|
36
|
+
tree[parentNode.id] = {
|
|
37
|
+
type: 'leaf',
|
|
38
|
+
id: parentNode.id,
|
|
39
|
+
depth: parentNode.depth,
|
|
40
|
+
parent: parentNode.parent,
|
|
41
|
+
groupingKey: parentNode.groupingKey
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const replaceDataGroupWithAutoGeneratedGroup = ({
|
|
48
|
+
node,
|
|
49
|
+
tree,
|
|
50
|
+
treeDepths,
|
|
51
|
+
updatedGroupsManager
|
|
52
|
+
}) => {
|
|
53
|
+
updatedGroupsManager?.addAction(node.parent, 'removeChildren');
|
|
54
|
+
updatedGroupsManager?.addAction(node.parent, 'insertChildren');
|
|
55
|
+
updateGroupNodeIdAndAutoGenerated({
|
|
56
|
+
tree,
|
|
57
|
+
treeDepths,
|
|
58
|
+
node,
|
|
59
|
+
updatedNode: {
|
|
60
|
+
id: getGroupRowIdFromPath(getNodePathInTree({
|
|
61
|
+
id: node.id,
|
|
62
|
+
tree
|
|
63
|
+
})),
|
|
64
|
+
isAutoGenerated: true
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Removed a data row from the tree.
|
|
70
|
+
* If the node is a non-empty group, replace it with an auto-generated group to be able to keep displaying its children.
|
|
71
|
+
* If not, remove it and recursively clean its parent with the following rules:
|
|
72
|
+
* - An empty auto-generated should be removed from the tree
|
|
73
|
+
* - An empty non-auto-generated should be turned into a leaf
|
|
74
|
+
*/
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
export const removeDataRowFromTree = ({
|
|
78
|
+
id,
|
|
79
|
+
tree,
|
|
80
|
+
treeDepths,
|
|
81
|
+
updatedGroupsManager
|
|
82
|
+
}) => {
|
|
83
|
+
const node = tree[id];
|
|
84
|
+
|
|
85
|
+
if (node.type === 'group' && node.children.length > 0) {
|
|
86
|
+
replaceDataGroupWithAutoGeneratedGroup({
|
|
87
|
+
node,
|
|
88
|
+
tree,
|
|
89
|
+
treeDepths,
|
|
90
|
+
updatedGroupsManager
|
|
91
|
+
});
|
|
92
|
+
} else {
|
|
93
|
+
removeNodeAndCleanParent({
|
|
94
|
+
node,
|
|
95
|
+
tree,
|
|
96
|
+
treeDepths,
|
|
97
|
+
updatedGroupsManager
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
};
|
|
@@ -1,59 +1,65 @@
|
|
|
1
|
+
import { GRID_ROOT_GROUP_ID } from '@mui/x-data-grid';
|
|
1
2
|
export const sortRowTree = params => {
|
|
2
3
|
const {
|
|
3
|
-
rowIds,
|
|
4
4
|
rowTree,
|
|
5
5
|
disableChildrenSorting,
|
|
6
|
-
sortRowList
|
|
6
|
+
sortRowList,
|
|
7
|
+
shouldRenderGroupBelowLeaves
|
|
7
8
|
} = params;
|
|
8
|
-
let sortedRows = [];
|
|
9
|
+
let sortedRows = [];
|
|
10
|
+
const sortedGroupedByParentRows = new Map();
|
|
9
11
|
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}]]);
|
|
12
|
+
const sortGroup = node => {
|
|
13
|
+
const shouldSortGroup = !!sortRowList && (!disableChildrenSorting || node.depth === -1);
|
|
14
|
+
let sortedRowIds;
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
let group = groupedByParentRows.get(node.parent);
|
|
16
|
+
if (shouldSortGroup) {
|
|
17
|
+
for (let i = 0; i < node.children.length; i += 1) {
|
|
18
|
+
const childNode = rowTree[node.children[i]];
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
25
|
-
groupedByParentRows.set(node.parent, group);
|
|
26
|
-
}
|
|
20
|
+
if (childNode.type === 'group') {
|
|
21
|
+
sortGroup(childNode);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
27
24
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
} // Apply the sorting to each list of children
|
|
25
|
+
sortedRowIds = sortRowList(node.children.map(childId => rowTree[childId]));
|
|
26
|
+
} else if (shouldRenderGroupBelowLeaves) {
|
|
27
|
+
const childrenLeaves = [];
|
|
28
|
+
const childrenGroups = [];
|
|
34
29
|
|
|
30
|
+
for (let i = 0; i < node.children.length; i += 1) {
|
|
31
|
+
const childId = node.children[i];
|
|
32
|
+
const childNode = rowTree[childId];
|
|
35
33
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
if (childNode.type === 'group') {
|
|
35
|
+
sortGroup(childNode);
|
|
36
|
+
childrenGroups.push(childId);
|
|
37
|
+
} else if (childNode.type === 'leaf') {
|
|
38
|
+
childrenLeaves.push(childId);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
sortedRowIds = [...childrenLeaves, ...childrenGroups];
|
|
40
43
|
} else {
|
|
41
|
-
let
|
|
42
|
-
|
|
44
|
+
for (let i = 0; i < node.children.length; i += 1) {
|
|
45
|
+
const childNode = rowTree[node.children[i]];
|
|
43
46
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
groupSortedRows = sortRowList(group.body);
|
|
47
|
+
if (childNode.type === 'group') {
|
|
48
|
+
sortGroup(childNode);
|
|
49
|
+
}
|
|
48
50
|
}
|
|
49
51
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
52
|
+
sortedRowIds = [...node.children];
|
|
53
|
+
}
|
|
53
54
|
|
|
54
|
-
|
|
55
|
+
if (node.footerId != null) {
|
|
56
|
+
sortedRowIds.push(node.footerId);
|
|
55
57
|
}
|
|
56
|
-
|
|
58
|
+
|
|
59
|
+
sortedGroupedByParentRows.set(node.id, sortedRowIds);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
sortGroup(rowTree[GRID_ROOT_GROUP_ID]); // Flatten the sorted lists to have children just after their parent
|
|
57
63
|
|
|
58
64
|
const insertRowListIntoSortedRows = (startIndex, rowList) => {
|
|
59
65
|
sortedRows = [...sortedRows.slice(0, startIndex), ...rowList, ...sortedRows.slice(startIndex)];
|
|
@@ -70,6 +76,6 @@ export const sortRowTree = params => {
|
|
|
70
76
|
return treeSize;
|
|
71
77
|
};
|
|
72
78
|
|
|
73
|
-
insertRowListIntoSortedRows(0, sortedGroupedByParentRows.get(
|
|
79
|
+
insertRowListIntoSortedRows(0, sortedGroupedByParentRows.get(GRID_ROOT_GROUP_ID));
|
|
74
80
|
return sortedRows;
|
|
75
81
|
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
+
import { GRID_ROOT_GROUP_ID } from '@mui/x-data-grid';
|
|
3
|
+
import { isDeepEqual, getTreeNodeDescendants } from '@mui/x-data-grid/internals';
|
|
4
|
+
import { insertDataRowInTree } from './insertDataRowInTree';
|
|
5
|
+
import { removeDataRowFromTree } from './removeDataRowFromTree';
|
|
6
|
+
import { createUpdatedGroupsManager, getNodePathInTree } from './utils';
|
|
7
|
+
export const updateRowTree = params => {
|
|
8
|
+
const tree = _extends({}, params.previousTree);
|
|
9
|
+
|
|
10
|
+
const treeDepths = _extends({}, params.previousTreeDepth);
|
|
11
|
+
|
|
12
|
+
const updatedGroupsManager = createUpdatedGroupsManager();
|
|
13
|
+
|
|
14
|
+
for (let i = 0; i < params.nodes.inserted.length; i += 1) {
|
|
15
|
+
const {
|
|
16
|
+
id,
|
|
17
|
+
path
|
|
18
|
+
} = params.nodes.inserted[i];
|
|
19
|
+
insertDataRowInTree({
|
|
20
|
+
tree,
|
|
21
|
+
treeDepths,
|
|
22
|
+
updatedGroupsManager,
|
|
23
|
+
id,
|
|
24
|
+
path,
|
|
25
|
+
onDuplicatePath: params.onDuplicatePath,
|
|
26
|
+
isGroupExpandedByDefault: params.isGroupExpandedByDefault,
|
|
27
|
+
defaultGroupingExpansionDepth: params.defaultGroupingExpansionDepth
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
for (let i = 0; i < params.nodes.removed.length; i += 1) {
|
|
32
|
+
const nodeId = params.nodes.removed[i];
|
|
33
|
+
removeDataRowFromTree({
|
|
34
|
+
tree,
|
|
35
|
+
treeDepths,
|
|
36
|
+
updatedGroupsManager,
|
|
37
|
+
id: nodeId
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
for (let i = 0; i < params.nodes.modified.length; i += 1) {
|
|
42
|
+
const {
|
|
43
|
+
id,
|
|
44
|
+
path
|
|
45
|
+
} = params.nodes.modified[i];
|
|
46
|
+
const pathInPreviousTree = getNodePathInTree({
|
|
47
|
+
tree,
|
|
48
|
+
id
|
|
49
|
+
});
|
|
50
|
+
const isInSameGroup = isDeepEqual(pathInPreviousTree, path);
|
|
51
|
+
|
|
52
|
+
if (!isInSameGroup) {
|
|
53
|
+
removeDataRowFromTree({
|
|
54
|
+
tree,
|
|
55
|
+
treeDepths,
|
|
56
|
+
updatedGroupsManager,
|
|
57
|
+
id
|
|
58
|
+
});
|
|
59
|
+
insertDataRowInTree({
|
|
60
|
+
tree,
|
|
61
|
+
treeDepths,
|
|
62
|
+
updatedGroupsManager,
|
|
63
|
+
id,
|
|
64
|
+
path,
|
|
65
|
+
onDuplicatePath: params.onDuplicatePath,
|
|
66
|
+
isGroupExpandedByDefault: params.isGroupExpandedByDefault,
|
|
67
|
+
defaultGroupingExpansionDepth: params.defaultGroupingExpansionDepth
|
|
68
|
+
});
|
|
69
|
+
} else {
|
|
70
|
+
updatedGroupsManager?.addAction(tree[id].parent, 'modifyChildren');
|
|
71
|
+
}
|
|
72
|
+
} // TODO rows v6: Avoid walking the whole tree, we should be able to generate the new list only using slices.
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
const dataRowIds = getTreeNodeDescendants(tree, GRID_ROOT_GROUP_ID, true);
|
|
76
|
+
return {
|
|
77
|
+
tree,
|
|
78
|
+
treeDepths,
|
|
79
|
+
groupingName: params.groupingName,
|
|
80
|
+
dataRowIds,
|
|
81
|
+
updatedGroupsManager
|
|
82
|
+
};
|
|
83
|
+
};
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
|
2
|
+
import _toPropertyKey from "@babel/runtime/helpers/esm/toPropertyKey";
|
|
3
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
4
|
+
import { GRID_ROOT_GROUP_ID } from '@mui/x-data-grid';
|
|
5
|
+
export const getGroupRowIdFromPath = path => {
|
|
6
|
+
const pathStr = path.map(groupingCriteria => `${groupingCriteria.field}/${groupingCriteria.key}`).join('-');
|
|
7
|
+
return `auto-generated-row-${pathStr}`;
|
|
8
|
+
};
|
|
9
|
+
export const getNodePathInTree = ({
|
|
10
|
+
id,
|
|
11
|
+
tree
|
|
12
|
+
}) => {
|
|
13
|
+
const path = [];
|
|
14
|
+
let node = tree[id];
|
|
15
|
+
|
|
16
|
+
while (node.id !== GRID_ROOT_GROUP_ID) {
|
|
17
|
+
path.push({
|
|
18
|
+
field: node.groupingField,
|
|
19
|
+
key: node.groupingKey
|
|
20
|
+
});
|
|
21
|
+
node = tree[node.parent];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return path;
|
|
25
|
+
};
|
|
26
|
+
export const addGroupDefaultExpansion = ({
|
|
27
|
+
node,
|
|
28
|
+
isGroupExpandedByDefault,
|
|
29
|
+
defaultGroupingExpansionDepth
|
|
30
|
+
}) => {
|
|
31
|
+
let childrenExpanded;
|
|
32
|
+
|
|
33
|
+
if (node.id === GRID_ROOT_GROUP_ID) {
|
|
34
|
+
childrenExpanded = true;
|
|
35
|
+
} else if (isGroupExpandedByDefault) {
|
|
36
|
+
childrenExpanded = isGroupExpandedByDefault(node);
|
|
37
|
+
} else {
|
|
38
|
+
childrenExpanded = defaultGroupingExpansionDepth === -1 || defaultGroupingExpansionDepth > node.depth;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return _extends({}, node, {
|
|
42
|
+
childrenExpanded
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Insert a node in the tree
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
export const insertNodeInTree = ({
|
|
50
|
+
node,
|
|
51
|
+
tree,
|
|
52
|
+
treeDepths
|
|
53
|
+
}) => {
|
|
54
|
+
// 1. Insert node in the tree.
|
|
55
|
+
tree[node.id] = node; // 2. Increment the `treeDepths` object for the node's depth.
|
|
56
|
+
|
|
57
|
+
treeDepths[node.depth] = (treeDepths[node.depth] ?? 0) + 1; // 3. Register the new node in its parent.
|
|
58
|
+
|
|
59
|
+
const parentNode = tree[node.parent];
|
|
60
|
+
|
|
61
|
+
if (node.type === 'footer') {
|
|
62
|
+
// For footers,
|
|
63
|
+
// Register the node from its parent `footerId` property.
|
|
64
|
+
tree[node.parent] = _extends({}, parentNode, {
|
|
65
|
+
footerId: node.id
|
|
66
|
+
});
|
|
67
|
+
} else if (node.type === 'group' || node.type === 'leaf') {
|
|
68
|
+
// For groups and leaves,
|
|
69
|
+
// Register the node from its parents `children` and `childrenFromPath` properties.
|
|
70
|
+
const groupingField = node.groupingField ?? '__no_field__';
|
|
71
|
+
const groupingKey = node.groupingKey ?? '__no_key__';
|
|
72
|
+
tree[node.parent] = _extends({}, parentNode, {
|
|
73
|
+
childrenFromPath: _extends({}, parentNode.childrenFromPath, {
|
|
74
|
+
[groupingField]: _extends({}, parentNode.childrenFromPath?.[groupingField], {
|
|
75
|
+
[groupingKey.toString()]: node.id
|
|
76
|
+
})
|
|
77
|
+
}),
|
|
78
|
+
children: [...parentNode.children, node.id]
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Removes a node from the tree
|
|
84
|
+
*/
|
|
85
|
+
|
|
86
|
+
export const removeNodeFromTree = ({
|
|
87
|
+
node,
|
|
88
|
+
tree,
|
|
89
|
+
treeDepths
|
|
90
|
+
}) => {
|
|
91
|
+
// 1. Remove node from the tree.
|
|
92
|
+
delete tree[node.id]; // 2. Decrement the `treeDepths` object for the node's depth.
|
|
93
|
+
|
|
94
|
+
const nodeDepth = node.depth;
|
|
95
|
+
const currentNodeCount = treeDepths[nodeDepth];
|
|
96
|
+
|
|
97
|
+
if (currentNodeCount === 1) {
|
|
98
|
+
delete treeDepths[nodeDepth];
|
|
99
|
+
} else {
|
|
100
|
+
treeDepths[nodeDepth] = currentNodeCount - 1;
|
|
101
|
+
} // 3. Unregister the new node in its parent.
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
const parentNode = tree[node.parent]; // For footers,
|
|
105
|
+
// Unregister the node from its parent `footerId` property.
|
|
106
|
+
|
|
107
|
+
if (node.type === 'footer') {
|
|
108
|
+
tree[parentNode.id] = _extends({}, parentNode, {
|
|
109
|
+
footerId: null
|
|
110
|
+
});
|
|
111
|
+
} // For groups and leaves,
|
|
112
|
+
// Unregister the node from its parents `children` and `childrenFromPath` properties.
|
|
113
|
+
else {
|
|
114
|
+
const groupingField = node.groupingField ?? '__no_field__';
|
|
115
|
+
const groupingKey = node.groupingKey ?? '__no_key__';
|
|
116
|
+
|
|
117
|
+
const _ref = parentNode.childrenFromPath?.[groupingField] ?? {},
|
|
118
|
+
_groupingKey$toString = groupingKey.toString(),
|
|
119
|
+
newChildrenFromPathWithField = _objectWithoutPropertiesLoose(_ref, [_groupingKey$toString].map(_toPropertyKey)); // TODO rows v6: Can we avoid this linear complexity ?
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
const children = parentNode.children.filter(childId => childId !== node.id);
|
|
123
|
+
|
|
124
|
+
const childrenFromPath = _extends({}, parentNode.childrenFromPath);
|
|
125
|
+
|
|
126
|
+
if (Object.keys(newChildrenFromPathWithField).length === 0) {
|
|
127
|
+
delete childrenFromPath[groupingField];
|
|
128
|
+
} else {
|
|
129
|
+
childrenFromPath[groupingField] = newChildrenFromPathWithField;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
tree[parentNode.id] = _extends({}, parentNode, {
|
|
133
|
+
children,
|
|
134
|
+
childrenFromPath
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* Updates the `id` and `isAutoGenerated` properties of a group node.
|
|
140
|
+
*/
|
|
141
|
+
|
|
142
|
+
export const updateGroupNodeIdAndAutoGenerated = ({
|
|
143
|
+
node,
|
|
144
|
+
updatedNode,
|
|
145
|
+
tree,
|
|
146
|
+
treeDepths
|
|
147
|
+
}) => {
|
|
148
|
+
// 1. Set the new parent for all children from the old group
|
|
149
|
+
node.children.forEach(childId => {
|
|
150
|
+
tree[childId] = _extends({}, tree[childId], {
|
|
151
|
+
parent: updatedNode.id
|
|
152
|
+
});
|
|
153
|
+
}); // 2. Remove the old group from the tree
|
|
154
|
+
|
|
155
|
+
removeNodeFromTree({
|
|
156
|
+
node,
|
|
157
|
+
tree,
|
|
158
|
+
treeDepths
|
|
159
|
+
}); // 3. Add the new group in the tree
|
|
160
|
+
|
|
161
|
+
const groupNode = _extends({}, node, updatedNode);
|
|
162
|
+
|
|
163
|
+
insertNodeInTree({
|
|
164
|
+
node: groupNode,
|
|
165
|
+
tree,
|
|
166
|
+
treeDepths
|
|
167
|
+
});
|
|
168
|
+
};
|
|
169
|
+
export const createUpdatedGroupsManager = () => ({
|
|
170
|
+
value: {},
|
|
171
|
+
|
|
172
|
+
addAction(groupId, action) {
|
|
173
|
+
if (!this.value[groupId]) {
|
|
174
|
+
this.value[groupId] = {};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
this.value[groupId][action] = true;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
});
|
|
@@ -461,7 +461,7 @@ DataGridProRaw.propTypes = {
|
|
|
461
461
|
/**
|
|
462
462
|
* Determines if a group should be expanded after its creation.
|
|
463
463
|
* This prop takes priority over the `defaultGroupingExpansionDepth` prop.
|
|
464
|
-
* @param {
|
|
464
|
+
* @param {GridGroupNode} node The node of the group to test.
|
|
465
465
|
* @returns {boolean} A boolean indicating if the group is expanded.
|
|
466
466
|
*/
|
|
467
467
|
isGroupExpandedByDefault: _propTypes.default.func,
|
|
@@ -639,16 +639,6 @@ DataGridProRaw.propTypes = {
|
|
|
639
639
|
*/
|
|
640
640
|
onColumnResize: _propTypes.default.func,
|
|
641
641
|
|
|
642
|
-
/**
|
|
643
|
-
* Callback fired when a column visibility changes.
|
|
644
|
-
* Only works when no `columnVisibilityModel` is provided and if we change the visibility of a single column at a time.
|
|
645
|
-
* @param {GridColumnVisibilityChangeParams} params With all properties from [[GridColumnVisibilityChangeParams]].
|
|
646
|
-
* @param {MuiEvent<{}>} event The event object.
|
|
647
|
-
* @param {GridCallbackDetails} details Additional details for this callback.
|
|
648
|
-
* @deprecated Use `onColumnVisibilityModelChange` instead.
|
|
649
|
-
*/
|
|
650
|
-
onColumnVisibilityChange: _propTypes.default.func,
|
|
651
|
-
|
|
652
642
|
/**
|
|
653
643
|
* Callback fired when the column visibility model changes.
|
|
654
644
|
* @param {GridColumnVisibilityModel} model The new model.
|
|
@@ -900,8 +890,8 @@ DataGridProRaw.propTypes = {
|
|
|
900
890
|
* Rows data to pin on top or bottom.
|
|
901
891
|
*/
|
|
902
892
|
pinnedRows: _propTypes.default.shape({
|
|
903
|
-
bottom: _propTypes.default.
|
|
904
|
-
top: _propTypes.default.
|
|
893
|
+
bottom: _propTypes.default.arrayOf(_propTypes.default.object),
|
|
894
|
+
top: _propTypes.default.arrayOf(_propTypes.default.object)
|
|
905
895
|
}),
|
|
906
896
|
|
|
907
897
|
/**
|
|
@@ -946,7 +936,7 @@ DataGridProRaw.propTypes = {
|
|
|
946
936
|
/**
|
|
947
937
|
* Set of rows of type [[GridRowsProp]].
|
|
948
938
|
*/
|
|
949
|
-
rows: _propTypes.default.
|
|
939
|
+
rows: _propTypes.default.arrayOf(_propTypes.default.object).isRequired,
|
|
950
940
|
|
|
951
941
|
/**
|
|
952
942
|
* Loading rows can be processed on the server or client-side.
|
|
@@ -30,7 +30,7 @@ const DATA_GRID_PRO_PROPS_DEFAULT_VALUES = (0, _extends2.default)({}, _xDataGrid
|
|
|
30
30
|
disableChildrenFiltering: false,
|
|
31
31
|
disableChildrenSorting: false,
|
|
32
32
|
rowReordering: false,
|
|
33
|
-
rowsLoadingMode:
|
|
33
|
+
rowsLoadingMode: 'client',
|
|
34
34
|
getDetailPanelHeight: () => 500
|
|
35
35
|
});
|
|
36
36
|
exports.DATA_GRID_PRO_PROPS_DEFAULT_VALUES = DATA_GRID_PRO_PROPS_DEFAULT_VALUES;
|
|
@@ -327,7 +327,7 @@ const DataGridProVirtualScroller = /*#__PURE__*/React.forwardRef(function DataGr
|
|
|
327
327
|
}
|
|
328
328
|
|
|
329
329
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_internals.GridVirtualScroller, (0, _extends2.default)({}, getRootProps(other), {
|
|
330
|
-
children: [topPinnedRowsData.length > 0 ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(VirtualScrollerPinnedRows, {
|
|
330
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_xDataGrid.GridOverlays, {}), topPinnedRowsData.length > 0 ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(VirtualScrollerPinnedRows, {
|
|
331
331
|
className: classes.topPinnedRows,
|
|
332
332
|
ownerState: {
|
|
333
333
|
position: 'top'
|
|
@@ -138,7 +138,7 @@ process.env.NODE_ENV !== "production" ? GridDetailPanelToggleCell.propTypes = {
|
|
|
138
138
|
/**
|
|
139
139
|
* The row model of the row that the current cell belongs to.
|
|
140
140
|
*/
|
|
141
|
-
row: _propTypes.default.
|
|
141
|
+
row: _propTypes.default.any.isRequired,
|
|
142
142
|
|
|
143
143
|
/**
|
|
144
144
|
* The node of the row that the current cell belongs to.
|