@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.
Files changed (129) hide show
  1. package/CHANGELOG.md +297 -19
  2. package/DataGridPro/DataGridPro.js +4 -14
  3. package/DataGridPro/useDataGridProProps.js +2 -2
  4. package/components/DataGridProVirtualScroller.js +2 -2
  5. package/components/GridDetailPanelToggleCell.js +1 -1
  6. package/components/GridRowReorderCell.js +4 -6
  7. package/components/GridTreeDataGroupingCell.d.ts +2 -2
  8. package/components/GridTreeDataGroupingCell.js +1 -1
  9. package/hooks/features/detailPanel/useGridDetailPanel.js +2 -2
  10. package/hooks/features/detailPanel/useGridDetailPanelCache.js +2 -2
  11. package/hooks/features/infiniteLoader/useGridInfiniteLoader.js +2 -2
  12. package/hooks/features/lazyLoader/useGridLazyLoader.js +20 -9
  13. package/hooks/features/lazyLoader/useGridLazyLoaderPreProcessors.d.ts +1 -1
  14. package/hooks/features/lazyLoader/useGridLazyLoaderPreProcessors.js +20 -6
  15. package/hooks/features/rowPinning/gridRowPinningInterface.d.ts +2 -2
  16. package/hooks/features/rowPinning/useGridRowPinningPreProcessors.d.ts +16 -16
  17. package/hooks/features/rowPinning/useGridRowPinningPreProcessors.js +62 -25
  18. package/hooks/features/rowReorder/useGridRowReorder.js +5 -5
  19. package/hooks/features/treeData/gridTreeDataGroupColDef.js +1 -1
  20. package/hooks/features/treeData/gridTreeDataUtils.js +14 -12
  21. package/hooks/features/treeData/useGridTreeData.js +2 -6
  22. package/hooks/features/treeData/useGridTreeDataPreProcessors.js +35 -18
  23. package/index.js +1 -1
  24. package/internals/index.d.ts +4 -2
  25. package/internals/index.js +4 -2
  26. package/legacy/DataGridPro/DataGridPro.js +4 -14
  27. package/legacy/DataGridPro/useDataGridProProps.js +2 -2
  28. package/legacy/components/DataGridProVirtualScroller.js +2 -2
  29. package/legacy/components/GridDetailPanelToggleCell.js +1 -1
  30. package/legacy/components/GridRowReorderCell.js +4 -6
  31. package/legacy/components/GridTreeDataGroupingCell.js +1 -1
  32. package/legacy/hooks/features/detailPanel/useGridDetailPanel.js +2 -2
  33. package/legacy/hooks/features/detailPanel/useGridDetailPanelCache.js +2 -2
  34. package/legacy/hooks/features/infiniteLoader/useGridInfiniteLoader.js +2 -2
  35. package/legacy/hooks/features/lazyLoader/useGridLazyLoader.js +25 -15
  36. package/legacy/hooks/features/lazyLoader/useGridLazyLoaderPreProcessors.js +21 -7
  37. package/legacy/hooks/features/rowPinning/useGridRowPinningPreProcessors.js +62 -25
  38. package/legacy/hooks/features/rowReorder/useGridRowReorder.js +5 -5
  39. package/legacy/hooks/features/treeData/gridTreeDataGroupColDef.js +1 -1
  40. package/legacy/hooks/features/treeData/gridTreeDataUtils.js +14 -12
  41. package/legacy/hooks/features/treeData/useGridTreeData.js +2 -6
  42. package/legacy/hooks/features/treeData/useGridTreeDataPreProcessors.js +37 -22
  43. package/legacy/index.js +1 -1
  44. package/legacy/internals/index.js +4 -2
  45. package/legacy/utils/tree/createRowTree.js +36 -0
  46. package/legacy/utils/tree/index.js +1 -1
  47. package/legacy/utils/tree/insertDataRowInTree.js +127 -0
  48. package/legacy/utils/tree/models.js +1 -0
  49. package/legacy/utils/tree/removeDataRowFromTree.js +97 -0
  50. package/legacy/utils/tree/sortRowTree.js +49 -43
  51. package/legacy/utils/tree/updateRowTree.js +81 -0
  52. package/legacy/utils/tree/utils.js +184 -0
  53. package/models/dataGridProProps.d.ts +3 -3
  54. package/modern/DataGridPro/DataGridPro.js +4 -14
  55. package/modern/DataGridPro/useDataGridProProps.js +2 -2
  56. package/modern/components/DataGridProVirtualScroller.js +2 -2
  57. package/modern/components/GridDetailPanelToggleCell.js +1 -1
  58. package/modern/components/GridRowReorderCell.js +4 -4
  59. package/modern/components/GridTreeDataGroupingCell.js +1 -1
  60. package/modern/hooks/features/detailPanel/useGridDetailPanel.js +2 -2
  61. package/modern/hooks/features/detailPanel/useGridDetailPanelCache.js +2 -2
  62. package/modern/hooks/features/infiniteLoader/useGridInfiniteLoader.js +2 -2
  63. package/modern/hooks/features/lazyLoader/useGridLazyLoader.js +20 -9
  64. package/modern/hooks/features/lazyLoader/useGridLazyLoaderPreProcessors.js +20 -6
  65. package/modern/hooks/features/rowPinning/useGridRowPinningPreProcessors.js +60 -23
  66. package/modern/hooks/features/rowReorder/useGridRowReorder.js +5 -3
  67. package/modern/hooks/features/treeData/gridTreeDataGroupColDef.js +1 -1
  68. package/modern/hooks/features/treeData/gridTreeDataUtils.js +13 -9
  69. package/modern/hooks/features/treeData/useGridTreeData.js +2 -4
  70. package/modern/hooks/features/treeData/useGridTreeDataPreProcessors.js +35 -18
  71. package/modern/index.js +1 -1
  72. package/modern/internals/index.js +4 -2
  73. package/modern/utils/tree/createRowTree.js +35 -0
  74. package/modern/utils/tree/index.js +1 -1
  75. package/modern/utils/tree/insertDataRowInTree.js +127 -0
  76. package/modern/utils/tree/models.js +1 -0
  77. package/modern/utils/tree/removeDataRowFromTree.js +100 -0
  78. package/modern/utils/tree/sortRowTree.js +46 -40
  79. package/modern/utils/tree/updateRowTree.js +83 -0
  80. package/modern/utils/tree/utils.js +180 -0
  81. package/node/DataGridPro/DataGridPro.js +4 -14
  82. package/node/DataGridPro/useDataGridProProps.js +1 -1
  83. package/node/components/DataGridProVirtualScroller.js +1 -1
  84. package/node/components/GridDetailPanelToggleCell.js +1 -1
  85. package/node/components/GridRowReorderCell.js +3 -5
  86. package/node/components/GridTreeDataGroupingCell.js +1 -1
  87. package/node/hooks/features/detailPanel/useGridDetailPanel.js +1 -1
  88. package/node/hooks/features/detailPanel/useGridDetailPanelCache.js +1 -1
  89. package/node/hooks/features/infiniteLoader/useGridInfiniteLoader.js +1 -1
  90. package/node/hooks/features/lazyLoader/useGridLazyLoader.js +19 -8
  91. package/node/hooks/features/lazyLoader/useGridLazyLoaderPreProcessors.js +18 -5
  92. package/node/hooks/features/rowPinning/useGridRowPinningPreProcessors.js +63 -26
  93. package/node/hooks/features/rowReorder/useGridRowReorder.js +4 -4
  94. package/node/hooks/features/treeData/gridTreeDataGroupColDef.js +1 -1
  95. package/node/hooks/features/treeData/gridTreeDataUtils.js +14 -12
  96. package/node/hooks/features/treeData/useGridTreeData.js +1 -5
  97. package/node/hooks/features/treeData/useGridTreeDataPreProcessors.js +35 -17
  98. package/node/index.js +1 -1
  99. package/node/internals/index.js +35 -10
  100. package/node/utils/tree/createRowTree.js +46 -0
  101. package/node/utils/tree/index.js +2 -2
  102. package/node/utils/tree/insertDataRowInTree.js +139 -0
  103. package/node/utils/tree/models.js +5 -0
  104. package/node/utils/tree/removeDataRowFromTree.js +110 -0
  105. package/node/utils/tree/sortRowTree.js +50 -43
  106. package/node/utils/tree/updateRowTree.js +98 -0
  107. package/node/utils/tree/utils.js +217 -0
  108. package/package.json +5 -5
  109. package/utils/tree/createRowTree.d.ts +15 -0
  110. package/utils/tree/createRowTree.js +35 -0
  111. package/utils/tree/index.d.ts +1 -1
  112. package/utils/tree/index.js +1 -1
  113. package/utils/tree/insertDataRowInTree.d.ts +51 -0
  114. package/utils/tree/insertDataRowInTree.js +129 -0
  115. package/utils/tree/models.d.ts +13 -0
  116. package/utils/tree/models.js +1 -0
  117. package/utils/tree/removeDataRowFromTree.d.ts +40 -0
  118. package/utils/tree/removeDataRowFromTree.js +100 -0
  119. package/utils/tree/sortRowTree.d.ts +6 -1
  120. package/utils/tree/sortRowTree.js +46 -40
  121. package/utils/tree/updateRowTree.d.ts +19 -0
  122. package/utils/tree/updateRowTree.js +83 -0
  123. package/utils/tree/utils.d.ts +66 -0
  124. package/utils/tree/utils.js +186 -0
  125. package/legacy/utils/tree/buildRowTree.js +0 -195
  126. package/modern/utils/tree/buildRowTree.js +0 -174
  127. package/node/utils/tree/buildRowTree.js +0 -195
  128. package/utils/tree/buildRowTree.d.ts +0 -48
  129. 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": "5.17.5",
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.18.9",
35
- "@mui/utils": "^5.10.3",
36
- "@mui/x-data-grid": "5.17.5",
37
- "@mui/x-license-pro": "5.17.0",
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
+ };
@@ -1 +1 @@
1
- export { getGroupRowIdFromPath } from './buildRowTree';
1
+ export { getGroupRowIdFromPath } from './utils';
@@ -1 +1 @@
1
- export { getGroupRowIdFromPath } from './buildRowTree';
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 = []; // Group the rows by parent
9
+ let sortedRows = [];
10
+ const sortedGroupedByParentRows = new Map();
9
11
 
10
- const groupedByParentRows = new Map([[null, {
11
- body: [],
12
- footer: null
13
- }]]);
12
+ const sortGroup = node => {
13
+ const shouldSortGroup = !!sortRowList && (!disableChildrenSorting || node.depth === -1);
14
+ let sortedRowIds;
14
15
 
15
- for (let i = 0; i < rowIds.length; i += 1) {
16
- const rowId = rowIds[i];
17
- const node = rowTree[rowId];
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
- if (!group) {
21
- group = {
22
- body: [],
23
- footer: null
24
- };
25
- groupedByParentRows.set(node.parent, group);
26
- }
20
+ if (childNode.type === 'group') {
21
+ sortGroup(childNode);
22
+ }
23
+ }
27
24
 
28
- if (node.position === 'footer') {
29
- group.footer = node;
30
- } else {
31
- group.body.push(node);
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
- const sortedGroupedByParentRows = new Map();
37
- groupedByParentRows.forEach((group, parent) => {
38
- if (group.body.length === 0) {
39
- sortedGroupedByParentRows.set(parent, []);
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 groupSortedRows;
42
- const depth = group.body[0].depth;
44
+ for (let i = 0; i < node.children.length; i += 1) {
45
+ const childNode = rowTree[node.children[i]];
43
46
 
44
- if (depth > 0 && disableChildrenSorting || !sortRowList) {
45
- groupSortedRows = group.body.map(row => row.id);
46
- } else {
47
- groupSortedRows = sortRowList(group.body);
47
+ if (childNode.type === 'group') {
48
+ sortGroup(childNode);
49
+ }
48
50
  }
49
51
 
50
- if (group.footer != null) {
51
- groupSortedRows.push(group.footer.id);
52
- }
52
+ sortedRowIds = [...node.children];
53
+ }
53
54
 
54
- sortedGroupedByParentRows.set(parent, groupSortedRows);
55
+ if (node.footerId != null) {
56
+ sortedRowIds.push(node.footerId);
55
57
  }
56
- }); // Flatten the sorted lists to have children just after their parent
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(null));
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
+ };