@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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mui/x-data-grid-pro",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0-alpha.1",
|
|
4
4
|
"description": "The Pro plan edition of the data grid component (MUI X).",
|
|
5
5
|
"author": "MUI Team",
|
|
6
6
|
"main": "./node/index.js",
|
|
@@ -31,10 +31,10 @@
|
|
|
31
31
|
"directory": "packages/grid/x-data-grid-pro"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@babel/runtime": "^7.
|
|
35
|
-
"@mui/utils": "^5.10.
|
|
36
|
-
"@mui/x-data-grid": "
|
|
37
|
-
"@mui/x-license-pro": "
|
|
34
|
+
"@babel/runtime": "^7.19.0",
|
|
35
|
+
"@mui/utils": "^5.10.6",
|
|
36
|
+
"@mui/x-data-grid": "6.0.0-alpha.1",
|
|
37
|
+
"@mui/x-license-pro": "6.0.0-alpha.0",
|
|
38
38
|
"@types/format-util": "^1.0.2",
|
|
39
39
|
"clsx": "^1.2.1",
|
|
40
40
|
"prop-types": "^15.8.1",
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { GridRowTreeCreationValue } from '@mui/x-data-grid/internals';
|
|
2
|
+
import { RowTreeBuilderNode, GridTreePathDuplicateHandler } from './models';
|
|
3
|
+
import { DataGridProProps } from '../../models/dataGridProProps';
|
|
4
|
+
interface CreateRowTreeParams {
|
|
5
|
+
nodes: RowTreeBuilderNode[];
|
|
6
|
+
defaultGroupingExpansionDepth: number;
|
|
7
|
+
isGroupExpandedByDefault?: DataGridProProps['isGroupExpandedByDefault'];
|
|
8
|
+
groupingName: string;
|
|
9
|
+
onDuplicatePath?: GridTreePathDuplicateHandler;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Transform a list of rows into a tree structure where each row references its parent and children.
|
|
13
|
+
*/
|
|
14
|
+
export declare const createRowTree: (params: CreateRowTreeParams) => GridRowTreeCreationValue;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { GRID_ROOT_GROUP_ID } from '@mui/x-data-grid';
|
|
2
|
+
import { buildRootGroup } from '@mui/x-data-grid/internals';
|
|
3
|
+
import { insertDataRowInTree } from './insertDataRowInTree';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Transform a list of rows into a tree structure where each row references its parent and children.
|
|
7
|
+
*/
|
|
8
|
+
export const createRowTree = params => {
|
|
9
|
+
const dataRowIds = [];
|
|
10
|
+
const tree = {
|
|
11
|
+
[GRID_ROOT_GROUP_ID]: buildRootGroup()
|
|
12
|
+
};
|
|
13
|
+
const treeDepths = {};
|
|
14
|
+
|
|
15
|
+
for (let i = 0; i < params.nodes.length; i += 1) {
|
|
16
|
+
const node = params.nodes[i];
|
|
17
|
+
dataRowIds.push(node.id);
|
|
18
|
+
insertDataRowInTree({
|
|
19
|
+
tree,
|
|
20
|
+
id: node.id,
|
|
21
|
+
path: node.path,
|
|
22
|
+
onDuplicatePath: params.onDuplicatePath,
|
|
23
|
+
treeDepths,
|
|
24
|
+
isGroupExpandedByDefault: params.isGroupExpandedByDefault,
|
|
25
|
+
defaultGroupingExpansionDepth: params.defaultGroupingExpansionDepth
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
tree,
|
|
31
|
+
treeDepths,
|
|
32
|
+
groupingName: params.groupingName,
|
|
33
|
+
dataRowIds
|
|
34
|
+
};
|
|
35
|
+
};
|
package/utils/tree/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { getGroupRowIdFromPath } from './
|
|
1
|
+
export { getGroupRowIdFromPath } from './utils';
|
package/utils/tree/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { getGroupRowIdFromPath } from './
|
|
1
|
+
export { getGroupRowIdFromPath } from './utils';
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { GridRowId, GridRowTreeConfig } from '@mui/x-data-grid';
|
|
2
|
+
import { GridTreeDepths, GridRowTreeUpdatedGroupsManager } from '@mui/x-data-grid/internals';
|
|
3
|
+
import { GridTreePathDuplicateHandler, RowTreeBuilderGroupingCriterion } from './models';
|
|
4
|
+
import { DataGridProProps } from '../../models/dataGridProProps';
|
|
5
|
+
interface InsertDataRowInTreeParams {
|
|
6
|
+
/**
|
|
7
|
+
* ID of the data row to insert in the tree.
|
|
8
|
+
*/
|
|
9
|
+
id: GridRowId;
|
|
10
|
+
/**
|
|
11
|
+
* Path of the data row to insert in the tree.
|
|
12
|
+
*/
|
|
13
|
+
path: RowTreeBuilderGroupingCriterion[];
|
|
14
|
+
/**
|
|
15
|
+
* Tree in which to insert the data row.
|
|
16
|
+
* This tree can be mutated but it's children should not.
|
|
17
|
+
* For instance:
|
|
18
|
+
*
|
|
19
|
+
* - `tree[nodeId] = newNode` => valid
|
|
20
|
+
* - `tree[nodeId].children.push(newNodeId)` => invalid
|
|
21
|
+
*/
|
|
22
|
+
tree: GridRowTreeConfig;
|
|
23
|
+
/**
|
|
24
|
+
* Amount of nodes at each depth of the tree.
|
|
25
|
+
* This object can be mutated.
|
|
26
|
+
* For instance:
|
|
27
|
+
*
|
|
28
|
+
* - `treeDepths[nodeDepth] = treeDepth[nodeDepth] + 1` => valid
|
|
29
|
+
*/
|
|
30
|
+
treeDepths: GridTreeDepths;
|
|
31
|
+
/**
|
|
32
|
+
* Object tracking the action performed on each group.
|
|
33
|
+
* Used to decide which groups to refresh on sorting, filtering, aggregation, ...
|
|
34
|
+
* If not defined, then the tracking will be skipped.
|
|
35
|
+
*/
|
|
36
|
+
updatedGroupsManager?: GridRowTreeUpdatedGroupsManager;
|
|
37
|
+
/**
|
|
38
|
+
* Callback fired when trying to insert a data row for a path already populated by another data row.
|
|
39
|
+
*/
|
|
40
|
+
onDuplicatePath?: GridTreePathDuplicateHandler;
|
|
41
|
+
isGroupExpandedByDefault?: DataGridProProps['isGroupExpandedByDefault'];
|
|
42
|
+
defaultGroupingExpansionDepth: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Inserts a data row in a tree.
|
|
46
|
+
* For each steps of its path:
|
|
47
|
+
* - if a node exists with the same partial path, it will register this node as the ancestor of the data row.
|
|
48
|
+
* - if not, it will create an auto-generated node and register it as ancestor of the data row.
|
|
49
|
+
*/
|
|
50
|
+
export declare const insertDataRowInTree: ({ id, path, updatedGroupsManager, tree, treeDepths, onDuplicatePath, isGroupExpandedByDefault, defaultGroupingExpansionDepth, }: InsertDataRowInTreeParams) => void;
|
|
51
|
+
export {};
|
|
@@ -0,0 +1,129 @@
|
|
|
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
|
+
var _childrenFromPath, _childrenFromPath$fie;
|
|
24
|
+
|
|
25
|
+
const {
|
|
26
|
+
key,
|
|
27
|
+
field
|
|
28
|
+
} = path[depth];
|
|
29
|
+
const fieldWithDefaultValue = field != null ? field : '__no_field__';
|
|
30
|
+
const keyWithDefaultValue = key != null ? key : '__no_key__';
|
|
31
|
+
const existingNodeIdWithPartialPath = (_childrenFromPath = tree[parentNodeId].childrenFromPath) == null ? void 0 : (_childrenFromPath$fie = _childrenFromPath[fieldWithDefaultValue]) == null ? void 0 : _childrenFromPath$fie[keyWithDefaultValue.toString()]; // When we reach the last step of the path,
|
|
32
|
+
// We need to create a node for the row passed to `insertNodeInTree`
|
|
33
|
+
|
|
34
|
+
if (depth === path.length - 1) {
|
|
35
|
+
// If no node matches the full path,
|
|
36
|
+
// We create a leaf node for the data row.
|
|
37
|
+
if (existingNodeIdWithPartialPath == null) {
|
|
38
|
+
const leafNode = {
|
|
39
|
+
type: 'leaf',
|
|
40
|
+
id,
|
|
41
|
+
depth,
|
|
42
|
+
parent: parentNodeId,
|
|
43
|
+
groupingKey: key
|
|
44
|
+
};
|
|
45
|
+
updatedGroupsManager == null ? void 0 : updatedGroupsManager.addAction(parentNodeId, 'insertChildren');
|
|
46
|
+
insertNodeInTree({
|
|
47
|
+
node: leafNode,
|
|
48
|
+
tree,
|
|
49
|
+
treeDepths
|
|
50
|
+
});
|
|
51
|
+
} else {
|
|
52
|
+
const existingNodeWithPartialPath = tree[existingNodeIdWithPartialPath]; // If we already have an auto-generated group matching the partial path,
|
|
53
|
+
// We replace it with the node from of data row passed to `insertNodeInTree`
|
|
54
|
+
|
|
55
|
+
if (existingNodeWithPartialPath.type === 'group' && existingNodeWithPartialPath.isAutoGenerated) {
|
|
56
|
+
updatedGroupsManager == null ? void 0 : updatedGroupsManager.addAction(parentNodeId, 'removeChildren');
|
|
57
|
+
updatedGroupsManager == null ? void 0 : updatedGroupsManager.addAction(parentNodeId, 'insertChildren');
|
|
58
|
+
updateGroupNodeIdAndAutoGenerated({
|
|
59
|
+
tree,
|
|
60
|
+
treeDepths,
|
|
61
|
+
node: existingNodeWithPartialPath,
|
|
62
|
+
updatedNode: {
|
|
63
|
+
id,
|
|
64
|
+
isAutoGenerated: false
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
} else {
|
|
68
|
+
// If we have another row matching the partial path, then there is a duplicate in the dataset.
|
|
69
|
+
// We warn the user and skip the current row.
|
|
70
|
+
onDuplicatePath == null ? void 0 : onDuplicatePath(existingNodeIdWithPartialPath, id, path);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
} // For the intermediary steps of the path,
|
|
74
|
+
// We need to make sure that there is a node matching the partial path.
|
|
75
|
+
//
|
|
76
|
+
// If no node matches the partial path,
|
|
77
|
+
// We create an auto-generated group node.
|
|
78
|
+
else if (existingNodeIdWithPartialPath == null) {
|
|
79
|
+
const nodeId = getGroupRowIdFromPath(path.slice(0, depth + 1));
|
|
80
|
+
const autoGeneratedGroupNode = {
|
|
81
|
+
type: 'group',
|
|
82
|
+
id: nodeId,
|
|
83
|
+
parent: parentNodeId,
|
|
84
|
+
depth,
|
|
85
|
+
isAutoGenerated: true,
|
|
86
|
+
groupingKey: key,
|
|
87
|
+
groupingField: field,
|
|
88
|
+
children: [],
|
|
89
|
+
childrenFromPath: {}
|
|
90
|
+
};
|
|
91
|
+
updatedGroupsManager == null ? void 0 : updatedGroupsManager.addAction(parentNodeId, 'insertChildren');
|
|
92
|
+
insertNodeInTree({
|
|
93
|
+
node: addGroupDefaultExpansion({
|
|
94
|
+
node: autoGeneratedGroupNode,
|
|
95
|
+
defaultGroupingExpansionDepth,
|
|
96
|
+
isGroupExpandedByDefault
|
|
97
|
+
}),
|
|
98
|
+
tree,
|
|
99
|
+
treeDepths
|
|
100
|
+
});
|
|
101
|
+
parentNodeId = nodeId;
|
|
102
|
+
} // For the intermediary steps of the path
|
|
103
|
+
// If a node matches the partial path, we use it as parent for the next step
|
|
104
|
+
else {
|
|
105
|
+
const currentGroupNode = tree[existingNodeIdWithPartialPath]; // If the node matching the partial path is not a group, we turn it into a group
|
|
106
|
+
|
|
107
|
+
if (currentGroupNode.type !== 'group') {
|
|
108
|
+
const groupNode = {
|
|
109
|
+
type: 'group',
|
|
110
|
+
id: currentGroupNode.id,
|
|
111
|
+
parent: currentGroupNode.parent,
|
|
112
|
+
depth: currentGroupNode.depth,
|
|
113
|
+
isAutoGenerated: false,
|
|
114
|
+
groupingKey: key,
|
|
115
|
+
groupingField: field,
|
|
116
|
+
children: [],
|
|
117
|
+
childrenFromPath: {}
|
|
118
|
+
};
|
|
119
|
+
tree[existingNodeIdWithPartialPath] = addGroupDefaultExpansion({
|
|
120
|
+
node: groupNode,
|
|
121
|
+
defaultGroupingExpansionDepth,
|
|
122
|
+
isGroupExpandedByDefault
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
parentNodeId = currentGroupNode.id;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { GridKeyValue, GridRowId } from '@mui/x-data-grid';
|
|
2
|
+
export interface RowTreeBuilderGroupingCriterion {
|
|
3
|
+
field: string | null;
|
|
4
|
+
key: GridKeyValue | null;
|
|
5
|
+
}
|
|
6
|
+
export interface RowTreeBuilderNode {
|
|
7
|
+
id: GridRowId;
|
|
8
|
+
path: RowTreeBuilderGroupingCriterion[];
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Callback called when trying to insert a data row in the tree in place of an already existing data row.
|
|
12
|
+
*/
|
|
13
|
+
export declare type GridTreePathDuplicateHandler = (firstId: GridRowId, secondId: GridRowId, path: RowTreeBuilderGroupingCriterion[]) => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { GridRowId, GridRowTreeConfig } from '@mui/x-data-grid';
|
|
2
|
+
import { GridTreeDepths, GridRowTreeUpdatedGroupsManager } from '@mui/x-data-grid/internals';
|
|
3
|
+
interface RemoveDataRowFromTreeParams {
|
|
4
|
+
/**
|
|
5
|
+
* ID of the data row to remove from the tree.
|
|
6
|
+
*/
|
|
7
|
+
id: GridRowId;
|
|
8
|
+
/**
|
|
9
|
+
* Tree from which to remove the data row.
|
|
10
|
+
* This tree can be mutated but it's children should not.
|
|
11
|
+
* For instance:
|
|
12
|
+
*
|
|
13
|
+
* - `tree[nodeId] = newNode` => valid
|
|
14
|
+
* - `tree[nodeId].children.push(newNodeId)` => invalid
|
|
15
|
+
*/
|
|
16
|
+
tree: GridRowTreeConfig;
|
|
17
|
+
/**
|
|
18
|
+
* Amount of nodes at each depth of the tree.
|
|
19
|
+
* This object can be mutated.
|
|
20
|
+
* For instance:
|
|
21
|
+
*
|
|
22
|
+
* - `treeDepths[nodeDepth] = treeDepth[nodeDepth] + 1` => valid
|
|
23
|
+
*/
|
|
24
|
+
treeDepths: GridTreeDepths;
|
|
25
|
+
/**
|
|
26
|
+
* Object tracking the action performed on each group.
|
|
27
|
+
* Used to decide which groups to refresh on sorting, filtering, aggregation, ...
|
|
28
|
+
* If not defined, then the tracking will be skipped.
|
|
29
|
+
*/
|
|
30
|
+
updatedGroupsManager?: GridRowTreeUpdatedGroupsManager;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Removed a data row from the tree.
|
|
34
|
+
* If the node is a non-empty group, replace it with an auto-generated group to be able to keep displaying its children.
|
|
35
|
+
* If not, remove it and recursively clean its parent with the following rules:
|
|
36
|
+
* - An empty auto-generated should be removed from the tree
|
|
37
|
+
* - An empty non-auto-generated should be turned into a leaf
|
|
38
|
+
*/
|
|
39
|
+
export declare const removeDataRowFromTree: ({ id, tree, treeDepths, updatedGroupsManager, }: RemoveDataRowFromTreeParams) => void;
|
|
40
|
+
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 == null ? void 0 : 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 == null ? void 0 : updatedGroupsManager.addAction(node.parent, 'removeChildren');
|
|
54
|
+
updatedGroupsManager == null ? void 0 : 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,10 +1,15 @@
|
|
|
1
1
|
import { GridRowId, GridRowTreeConfig } from '@mui/x-data-grid';
|
|
2
2
|
import { GridSortingModelApplier } from '@mui/x-data-grid/internals';
|
|
3
3
|
interface SortRowTreeParams {
|
|
4
|
-
rowIds: GridRowId[];
|
|
5
4
|
rowTree: GridRowTreeConfig;
|
|
6
5
|
disableChildrenSorting: boolean;
|
|
7
6
|
sortRowList: GridSortingModelApplier | null;
|
|
7
|
+
/**
|
|
8
|
+
* Defines where the groups are placed relative to the leaves of same depth when no sorting rule is applied.
|
|
9
|
+
* If `true` the groups will be rendered below the leaves.
|
|
10
|
+
* If `false`, the groups will be rendered on their creation order.
|
|
11
|
+
*/
|
|
12
|
+
shouldRenderGroupBelowLeaves: boolean;
|
|
8
13
|
}
|
|
9
14
|
export declare const sortRowTree: (params: SortRowTreeParams) => GridRowId[];
|
|
10
15
|
export {};
|
|
@@ -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,19 @@
|
|
|
1
|
+
import { GridGroupNode, GridRowId, GridRowTreeConfig } from '@mui/x-data-grid';
|
|
2
|
+
import { GridRowTreeCreationValue, GridTreeDepths } from '@mui/x-data-grid/internals';
|
|
3
|
+
import { GridTreePathDuplicateHandler, RowTreeBuilderNode } from './models';
|
|
4
|
+
export interface UpdateRowTreeNodes {
|
|
5
|
+
inserted: RowTreeBuilderNode[];
|
|
6
|
+
modified: RowTreeBuilderNode[];
|
|
7
|
+
removed: GridRowId[];
|
|
8
|
+
}
|
|
9
|
+
interface UpdateRowTreeParams {
|
|
10
|
+
previousTree: GridRowTreeConfig;
|
|
11
|
+
previousTreeDepth: GridTreeDepths;
|
|
12
|
+
nodes: UpdateRowTreeNodes;
|
|
13
|
+
defaultGroupingExpansionDepth: number;
|
|
14
|
+
isGroupExpandedByDefault?: (node: GridGroupNode) => boolean;
|
|
15
|
+
groupingName: string;
|
|
16
|
+
onDuplicatePath?: GridTreePathDuplicateHandler;
|
|
17
|
+
}
|
|
18
|
+
export declare const updateRowTree: (params: UpdateRowTreeParams) => GridRowTreeCreationValue;
|
|
19
|
+
export {};
|
|
@@ -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 == null ? void 0 : 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
|
+
};
|