@mui/x-data-grid-pro 8.19.0 → 8.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/DataGridPro/DataGridPro.js +29 -2
  3. package/components/GridRowReorderCell.js +15 -3
  4. package/components/headerFiltering/GridHeaderFilterCell.js +2 -3
  5. package/esm/DataGridPro/DataGridPro.js +29 -2
  6. package/esm/components/GridRowReorderCell.js +15 -3
  7. package/esm/components/headerFiltering/GridHeaderFilterCell.js +2 -3
  8. package/esm/hooks/features/dataSource/useGridDataSourceBasePro.js +1 -1
  9. package/esm/hooks/features/rowReorder/commonReorderConditions.d.ts +30 -0
  10. package/esm/hooks/features/rowReorder/commonReorderConditions.js +78 -0
  11. package/esm/hooks/features/rowReorder/index.d.ts +2 -1
  12. package/esm/hooks/features/rowReorder/index.js +2 -1
  13. package/esm/hooks/features/rowReorder/models.d.ts +17 -0
  14. package/esm/hooks/features/rowReorder/models.js +1 -0
  15. package/esm/hooks/features/rowReorder/reorderExecutor.d.ts +27 -0
  16. package/esm/hooks/features/rowReorder/reorderExecutor.js +29 -0
  17. package/esm/hooks/features/rowReorder/reorderValidator.d.ts +12 -0
  18. package/esm/hooks/features/rowReorder/reorderValidator.js +14 -0
  19. package/esm/hooks/features/rowReorder/types.d.ts +25 -0
  20. package/esm/hooks/features/rowReorder/types.js +1 -0
  21. package/esm/hooks/features/rowReorder/useGridRowReorder.d.ts +1 -1
  22. package/esm/hooks/features/rowReorder/useGridRowReorder.js +167 -80
  23. package/esm/hooks/features/rowReorder/utils.d.ts +82 -0
  24. package/esm/hooks/features/rowReorder/utils.js +259 -0
  25. package/esm/hooks/features/rows/useGridRowsOverridableMethods.d.ts +7 -0
  26. package/esm/hooks/features/rows/useGridRowsOverridableMethods.js +59 -0
  27. package/esm/hooks/features/treeData/treeDataReorderExecutor.d.ts +11 -0
  28. package/esm/hooks/features/treeData/treeDataReorderExecutor.js +534 -0
  29. package/esm/hooks/features/treeData/treeDataReorderValidator.d.ts +2 -0
  30. package/esm/hooks/features/treeData/treeDataReorderValidator.js +35 -0
  31. package/esm/hooks/features/treeData/useGridTreeData.d.ts +3 -3
  32. package/esm/hooks/features/treeData/useGridTreeData.js +49 -4
  33. package/esm/hooks/features/treeData/utils.d.ts +8 -0
  34. package/esm/hooks/features/treeData/utils.js +96 -0
  35. package/esm/index.js +1 -1
  36. package/esm/internals/index.d.ts +8 -0
  37. package/esm/internals/index.js +6 -0
  38. package/esm/models/dataGridProProps.d.ts +32 -4
  39. package/esm/models/gridRowOrderChangeParams.d.ts +29 -5
  40. package/hooks/features/dataSource/useGridDataSourceBasePro.js +1 -1
  41. package/hooks/features/rowReorder/commonReorderConditions.d.ts +30 -0
  42. package/hooks/features/rowReorder/commonReorderConditions.js +84 -0
  43. package/hooks/features/rowReorder/index.d.ts +2 -1
  44. package/hooks/features/rowReorder/models.d.ts +17 -0
  45. package/hooks/features/rowReorder/models.js +5 -0
  46. package/hooks/features/rowReorder/reorderExecutor.d.ts +27 -0
  47. package/hooks/features/rowReorder/reorderExecutor.js +37 -0
  48. package/hooks/features/rowReorder/reorderValidator.d.ts +12 -0
  49. package/hooks/features/rowReorder/reorderValidator.js +21 -0
  50. package/hooks/features/rowReorder/types.d.ts +25 -0
  51. package/hooks/features/rowReorder/types.js +5 -0
  52. package/hooks/features/rowReorder/useGridRowReorder.d.ts +1 -1
  53. package/hooks/features/rowReorder/useGridRowReorder.js +168 -81
  54. package/hooks/features/rowReorder/utils.d.ts +82 -0
  55. package/hooks/features/rowReorder/utils.js +286 -0
  56. package/hooks/features/rows/useGridRowsOverridableMethods.d.ts +7 -0
  57. package/hooks/features/rows/useGridRowsOverridableMethods.js +67 -0
  58. package/hooks/features/treeData/treeDataReorderExecutor.d.ts +11 -0
  59. package/hooks/features/treeData/treeDataReorderExecutor.js +541 -0
  60. package/hooks/features/treeData/treeDataReorderValidator.d.ts +2 -0
  61. package/hooks/features/treeData/treeDataReorderValidator.js +41 -0
  62. package/hooks/features/treeData/useGridTreeData.d.ts +3 -3
  63. package/hooks/features/treeData/useGridTreeData.js +48 -3
  64. package/hooks/features/treeData/utils.d.ts +8 -0
  65. package/hooks/features/treeData/utils.js +109 -0
  66. package/index.js +1 -1
  67. package/internals/index.d.ts +8 -0
  68. package/internals/index.js +53 -1
  69. package/models/dataGridProProps.d.ts +32 -4
  70. package/models/gridRowOrderChangeParams.d.ts +29 -5
  71. package/package.json +2 -2
@@ -0,0 +1,541 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.treeDataReorderExecutor = exports.SameParentSwapOperation = void 0;
8
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
+ var _xDataGrid = require("@mui/x-data-grid");
10
+ var _reorderExecutor = require("../rowReorder/reorderExecutor");
11
+ var _utils = require("../rowReorder/utils");
12
+ var _utils2 = require("./utils");
13
+ /**
14
+ * Handles reordering of items within the same parent group.
15
+ */
16
+ class SameParentSwapOperation extends _reorderExecutor.BaseReorderOperation {
17
+ operationType = 'same-parent-swap';
18
+ detectOperation(ctx) {
19
+ if (ctx.dropPosition === 'inside') {
20
+ return null;
21
+ }
22
+ const {
23
+ sourceRowId,
24
+ placeholderIndex,
25
+ sortedFilteredRowIds,
26
+ sortedFilteredRowIndexLookup,
27
+ rowTree,
28
+ apiRef
29
+ } = ctx;
30
+ const sourceNode = (0, _xDataGrid.gridRowNodeSelector)(apiRef, sourceRowId);
31
+ if (!sourceNode || sourceNode.type === 'footer') {
32
+ return null;
33
+ }
34
+ let targetIndex = placeholderIndex;
35
+ const sourceIndex = sortedFilteredRowIndexLookup[sourceRowId];
36
+ if (targetIndex === sortedFilteredRowIds.length && sortedFilteredRowIds.length > 0) {
37
+ targetIndex -= 1;
38
+ }
39
+ let targetNode = (0, _xDataGrid.gridRowNodeSelector)(apiRef, sortedFilteredRowIds[targetIndex]);
40
+ if (placeholderIndex > sourceIndex && sourceNode.parent === targetNode.parent) {
41
+ targetIndex = placeholderIndex - 1;
42
+ targetNode = (0, _xDataGrid.gridRowNodeSelector)(apiRef, sortedFilteredRowIds[targetIndex]);
43
+ if (targetNode && targetNode.depth !== sourceNode.depth) {
44
+ while (targetNode.depth > sourceNode.depth && targetIndex >= 0) {
45
+ targetIndex -= 1;
46
+ targetNode = (0, _xDataGrid.gridRowNodeSelector)(apiRef, sortedFilteredRowIds[targetIndex]);
47
+ }
48
+ }
49
+ if (targetIndex === -1) {
50
+ return null;
51
+ }
52
+ }
53
+ let isLastChild = false;
54
+ if (!targetNode) {
55
+ if (placeholderIndex >= sortedFilteredRowIds.length && sortedFilteredRowIds.length > 0) {
56
+ targetNode = (0, _xDataGrid.gridRowNodeSelector)(apiRef, sortedFilteredRowIds[sortedFilteredRowIds.length - 1]);
57
+ isLastChild = true;
58
+ } else {
59
+ return null;
60
+ }
61
+ }
62
+ let adjustedTargetNode = targetNode;
63
+
64
+ // Case A and B adjustment
65
+ if (targetNode.type === 'group' && sourceNode.parent !== targetNode.parent && sourceNode.depth > targetNode.depth) {
66
+ let i = targetIndex - 1;
67
+ while (i >= 0) {
68
+ const node = (0, _xDataGrid.gridRowNodeSelector)(apiRef, sortedFilteredRowIds[i]);
69
+ if (node && node.depth < sourceNode.depth) {
70
+ return null;
71
+ }
72
+ if (node && node.depth === sourceNode.depth) {
73
+ targetIndex = i;
74
+ adjustedTargetNode = node;
75
+ break;
76
+ }
77
+ i -= 1;
78
+ }
79
+ }
80
+
81
+ // Check if below last node in the same group as source node
82
+ const isBelowPosition = ctx.dropPosition === 'below';
83
+ if (isBelowPosition && sourceNode.parent !== adjustedTargetNode.parent) {
84
+ const unAdjustedTargetIndex = placeholderIndex - 1;
85
+ const unAdjustedTargetNode = (0, _xDataGrid.gridRowNodeSelector)(apiRef, sortedFilteredRowIds[unAdjustedTargetIndex]);
86
+ if (unAdjustedTargetNode && unAdjustedTargetNode.parent === sourceNode.parent) {
87
+ adjustedTargetNode = unAdjustedTargetNode;
88
+ isLastChild = true;
89
+ }
90
+ }
91
+ if (sourceNode.parent !== adjustedTargetNode.parent) {
92
+ return null;
93
+ }
94
+ const actualTargetIndex = (0, _utils.calculateTargetIndex)(sourceNode, adjustedTargetNode, isLastChild, rowTree);
95
+ targetNode = adjustedTargetNode;
96
+ return {
97
+ sourceNode,
98
+ targetNode,
99
+ actualTargetIndex,
100
+ isLastChild,
101
+ operationType: this.operationType
102
+ };
103
+ }
104
+ executeOperation(operation, ctx) {
105
+ const {
106
+ sourceNode,
107
+ actualTargetIndex
108
+ } = operation;
109
+ const {
110
+ apiRef,
111
+ sourceRowId
112
+ } = ctx;
113
+ apiRef.current.setState(state => {
114
+ const group = (0, _xDataGrid.gridRowTreeSelector)(apiRef)[sourceNode.parent];
115
+ const currentChildren = [...group.children];
116
+ const oldIndex = currentChildren.findIndex(row => row === sourceRowId);
117
+ if (oldIndex === -1 || actualTargetIndex === -1 || oldIndex === actualTargetIndex) {
118
+ return state;
119
+ }
120
+ currentChildren.splice(actualTargetIndex, 0, currentChildren.splice(oldIndex, 1)[0]);
121
+ return (0, _extends2.default)({}, state, {
122
+ rows: (0, _extends2.default)({}, state.rows, {
123
+ tree: (0, _extends2.default)({}, state.rows.tree, {
124
+ [sourceNode.parent]: (0, _extends2.default)({}, group, {
125
+ children: currentChildren
126
+ })
127
+ })
128
+ })
129
+ });
130
+ });
131
+ apiRef.current.publishEvent('rowsSet');
132
+ }
133
+ }
134
+
135
+ /**
136
+ * Handles moving leaf nodes between different parents.
137
+ */
138
+ exports.SameParentSwapOperation = SameParentSwapOperation;
139
+ class CrossParentLeafOperation extends _reorderExecutor.BaseReorderOperation {
140
+ operationType = 'cross-parent-leaf';
141
+ detectOperation(ctx) {
142
+ // Fail for "inside" position - let DropOnLeafOperation handle it
143
+ if (ctx.dropPosition === 'inside') {
144
+ return null;
145
+ }
146
+ const {
147
+ sourceRowId,
148
+ placeholderIndex,
149
+ sortedFilteredRowIds,
150
+ rowTree,
151
+ apiRef,
152
+ setTreeDataPath
153
+ } = ctx;
154
+ const sourceNode = (0, _xDataGrid.gridRowNodeSelector)(apiRef, sourceRowId);
155
+ if (!sourceNode || sourceNode.type !== 'leaf') {
156
+ return null;
157
+ }
158
+ if (!setTreeDataPath) {
159
+ (0, _utils2.displaySetTreeDataPathWarning)('Cross-parent reordering');
160
+ }
161
+ let targetIndex = placeholderIndex;
162
+ if (targetIndex === sortedFilteredRowIds.length && sortedFilteredRowIds.length > 0) {
163
+ targetIndex = sortedFilteredRowIds.length - 1;
164
+ }
165
+ if (targetIndex < 0) {
166
+ return null;
167
+ }
168
+ const targetNode = (0, _xDataGrid.gridRowNodeSelector)(apiRef, sortedFilteredRowIds[targetIndex]);
169
+ if (!targetNode) {
170
+ return null;
171
+ }
172
+ if (sourceNode.parent === targetNode.parent) {
173
+ return null;
174
+ }
175
+ const actualTargetIndex = (0, _utils.calculateTargetIndex)(sourceNode, targetNode, placeholderIndex >= sortedFilteredRowIds.length, rowTree);
176
+ return {
177
+ sourceNode,
178
+ targetNode,
179
+ actualTargetIndex,
180
+ isLastChild: placeholderIndex >= sortedFilteredRowIds.length,
181
+ operationType: this.operationType
182
+ };
183
+ }
184
+ async executeOperation(operation, ctx) {
185
+ const {
186
+ sourceNode,
187
+ targetNode,
188
+ actualTargetIndex
189
+ } = operation;
190
+ const {
191
+ apiRef
192
+ } = ctx;
193
+ const rowTree = (0, _xDataGrid.gridRowTreeSelector)(apiRef);
194
+ const targetParentNode = rowTree[targetNode.parent];
195
+ const targetPath = (0, _utils2.buildTreeDataPath)(targetParentNode, rowTree);
196
+ const updatedRow = await (0, _utils2.updateLeafPath)(sourceNode, targetPath, ctx);
197
+ if (!updatedRow) {
198
+ return;
199
+ }
200
+
201
+ // Update tree structure
202
+ apiRef.current.setState(state => {
203
+ const updatedTree = (0, _extends2.default)({}, state.rows.tree);
204
+ (0, _utils2.removeNodeFromSourceParent)(updatedTree, sourceNode);
205
+ const targetParent = updatedTree[targetNode.parent];
206
+ const targetChildren = [...targetParent.children];
207
+ targetChildren.splice(actualTargetIndex, 0, sourceNode.id);
208
+ updatedTree[targetNode.parent] = (0, _extends2.default)({}, targetParent, {
209
+ children: targetChildren
210
+ });
211
+ const parentNode = updatedTree[targetNode.parent];
212
+ (0, _utils2.updateNodeParentAndDepth)(updatedTree, sourceNode, targetNode.parent, parentNode.depth + 1);
213
+ return (0, _extends2.default)({}, state, {
214
+ rows: (0, _extends2.default)({}, state.rows, {
215
+ tree: updatedTree
216
+ })
217
+ });
218
+ });
219
+ apiRef.current.updateRows([updatedRow]);
220
+ apiRef.current.publishEvent('rowsSet');
221
+ }
222
+ }
223
+
224
+ /**
225
+ * Handles dropping any node (leaf or group) "inside" a leaf node.
226
+ * This converts the target leaf into a parent group and makes the dragged node its child.
227
+ */
228
+ class DropOnLeafOperation extends _reorderExecutor.BaseReorderOperation {
229
+ operationType = 'drop-on-leaf';
230
+ detectOperation(ctx) {
231
+ const {
232
+ sourceRowId,
233
+ dropPosition,
234
+ placeholderIndex,
235
+ sortedFilteredRowIds,
236
+ apiRef,
237
+ setTreeDataPath
238
+ } = ctx;
239
+ if (dropPosition !== 'inside') {
240
+ return null;
241
+ }
242
+ const sourceNode = (0, _xDataGrid.gridRowNodeSelector)(apiRef, sourceRowId);
243
+ if (!sourceNode || sourceNode.type === 'footer') {
244
+ return null;
245
+ }
246
+ if (!setTreeDataPath) {
247
+ (0, _utils2.displaySetTreeDataPathWarning)('Drop on leaf reordering');
248
+ }
249
+
250
+ // Find target node
251
+ let targetIndex = placeholderIndex;
252
+ if (targetIndex === sortedFilteredRowIds.length && sortedFilteredRowIds.length > 0) {
253
+ targetIndex = sortedFilteredRowIds.length - 1;
254
+ }
255
+ if (targetIndex < 0) {
256
+ return null;
257
+ }
258
+ const targetNode = (0, _xDataGrid.gridRowNodeSelector)(apiRef, sortedFilteredRowIds[targetIndex]);
259
+ if (!targetNode || targetNode.type !== 'leaf') {
260
+ return null;
261
+ }
262
+
263
+ // Target leaf will become a parent, so the actual target index is 0 (first child)
264
+ const actualTargetIndex = 0;
265
+ return {
266
+ sourceNode,
267
+ targetNode,
268
+ actualTargetIndex,
269
+ isLastChild: false,
270
+ operationType: this.operationType
271
+ };
272
+ }
273
+ async executeOperation(operation, ctx) {
274
+ const {
275
+ sourceNode,
276
+ targetNode
277
+ } = operation;
278
+ const {
279
+ apiRef
280
+ } = ctx;
281
+ const rowTree = (0, _xDataGrid.gridRowTreeSelector)(apiRef);
282
+
283
+ // Build target path for the new structure
284
+ const targetPath = (0, _utils2.buildTreeDataPath)(targetNode, rowTree);
285
+ let rowsToUpdate = [];
286
+
287
+ // Handle source node path updates
288
+ if (sourceNode.type === 'leaf') {
289
+ // Simple leaf move
290
+ const updatedRow = await (0, _utils2.updateLeafPath)(sourceNode, targetPath, ctx);
291
+ if (!updatedRow) {
292
+ return;
293
+ }
294
+ rowsToUpdate.push(updatedRow);
295
+ } else {
296
+ // Group move - update entire hierarchy
297
+ const sourceParentNode = rowTree[sourceNode.parent];
298
+ const sourceBasePath = (0, _utils2.buildTreeDataPath)(sourceParentNode, rowTree);
299
+ rowsToUpdate = await (0, _utils2.updateGroupHierarchyPaths)(sourceNode, sourceBasePath, targetPath, ctx);
300
+ if (rowsToUpdate.length === 0) {
301
+ return;
302
+ }
303
+ }
304
+ apiRef.current.setState(state => {
305
+ const updatedTree = (0, _extends2.default)({}, state.rows.tree);
306
+ (0, _utils2.removeNodeFromSourceParent)(updatedTree, sourceNode);
307
+ updatedTree[targetNode.id] = (0, _extends2.default)({}, targetNode, {
308
+ type: 'group',
309
+ children: [sourceNode.id],
310
+ childrenFromPath: {},
311
+ groupingField: null,
312
+ isAutoGenerated: false,
313
+ childrenExpanded: true
314
+ });
315
+ (0, _utils2.updateNodeParentAndDepth)(updatedTree, sourceNode, targetNode.id, targetNode.depth + 1);
316
+ return (0, _extends2.default)({}, state, {
317
+ rows: (0, _extends2.default)({}, state.rows, {
318
+ tree: updatedTree
319
+ })
320
+ });
321
+ });
322
+
323
+ // Update rows in the grid
324
+ apiRef.current.updateRows(rowsToUpdate);
325
+ apiRef.current.publishEvent('rowsSet');
326
+ }
327
+ }
328
+
329
+ /**
330
+ * Handles dropping any node (leaf or group) "inside" a group node.
331
+ * This makes the dragged node the first child of the target group.
332
+ */
333
+ class DropOnGroupOperation extends _reorderExecutor.BaseReorderOperation {
334
+ operationType = 'drop-on-group';
335
+ detectOperation(ctx) {
336
+ const {
337
+ sourceRowId,
338
+ dropPosition,
339
+ placeholderIndex,
340
+ sortedFilteredRowIds,
341
+ apiRef,
342
+ setTreeDataPath,
343
+ rowTree
344
+ } = ctx;
345
+
346
+ // Only applies to "inside" drop position
347
+ if (dropPosition !== 'inside') {
348
+ return null;
349
+ }
350
+ const sourceNode = (0, _xDataGrid.gridRowNodeSelector)(apiRef, sourceRowId);
351
+ if (!sourceNode || sourceNode.type === 'footer') {
352
+ return null;
353
+ }
354
+ if (!setTreeDataPath) {
355
+ (0, _utils2.displaySetTreeDataPathWarning)('Drop on group reordering');
356
+ }
357
+ let targetIndex = placeholderIndex;
358
+ if (targetIndex === sortedFilteredRowIds.length && sortedFilteredRowIds.length > 0) {
359
+ targetIndex = sortedFilteredRowIds.length - 1;
360
+ }
361
+ if (targetIndex < 0) {
362
+ return null;
363
+ }
364
+ const targetNode = (0, _xDataGrid.gridRowNodeSelector)(apiRef, sortedFilteredRowIds[targetIndex]);
365
+ if (!targetNode || targetNode.type !== 'group') {
366
+ return null;
367
+ }
368
+ if ((0, _utils.isDescendantOf)(targetNode, sourceNode, rowTree)) {
369
+ return null;
370
+ }
371
+ const actualTargetIndex = 0;
372
+ return {
373
+ sourceNode,
374
+ targetNode,
375
+ actualTargetIndex,
376
+ isLastChild: false,
377
+ operationType: this.operationType
378
+ };
379
+ }
380
+ async executeOperation(operation, ctx) {
381
+ const {
382
+ sourceNode,
383
+ targetNode
384
+ } = operation;
385
+ const {
386
+ apiRef
387
+ } = ctx;
388
+ const rowTree = (0, _xDataGrid.gridRowTreeSelector)(apiRef);
389
+
390
+ // Build target path for the new structure
391
+ const targetPath = (0, _utils2.buildTreeDataPath)(targetNode, rowTree);
392
+ let rowsToUpdate = [];
393
+
394
+ // Handle source node path updates
395
+ if (sourceNode.type === 'leaf') {
396
+ // Simple leaf move
397
+ const updatedRow = await (0, _utils2.updateLeafPath)(sourceNode, targetPath, ctx);
398
+ if (!updatedRow) {
399
+ return;
400
+ }
401
+ rowsToUpdate.push(updatedRow);
402
+ } else {
403
+ // Group move - update entire hierarchy
404
+ const sourceParentNode = rowTree[sourceNode.parent];
405
+ const sourceBasePath = (0, _utils2.buildTreeDataPath)(sourceParentNode, rowTree);
406
+ rowsToUpdate = await (0, _utils2.updateGroupHierarchyPaths)(sourceNode, sourceBasePath, targetPath, ctx);
407
+ if (rowsToUpdate.length === 0) {
408
+ return;
409
+ }
410
+ }
411
+
412
+ // Update tree structure
413
+ apiRef.current.setState(state => {
414
+ const updatedTree = (0, _extends2.default)({}, state.rows.tree);
415
+
416
+ // Remove source from its current parent
417
+ (0, _utils2.removeNodeFromSourceParent)(updatedTree, sourceNode);
418
+
419
+ // Add source as first child of target group
420
+ const targetGroup = updatedTree[targetNode.id];
421
+ const targetChildren = [sourceNode.id, ...targetGroup.children];
422
+ updatedTree[targetNode.id] = (0, _extends2.default)({}, targetGroup, {
423
+ children: targetChildren
424
+ });
425
+ (0, _utils2.updateNodeParentAndDepth)(updatedTree, sourceNode, targetNode.id, targetNode.depth + 1);
426
+ return (0, _extends2.default)({}, state, {
427
+ rows: (0, _extends2.default)({}, state.rows, {
428
+ tree: updatedTree
429
+ })
430
+ });
431
+ });
432
+
433
+ // Update rows in the grid
434
+ apiRef.current.updateRows(rowsToUpdate);
435
+ apiRef.current.publishEvent('rowsSet');
436
+ }
437
+ }
438
+
439
+ /**
440
+ * Handles moving group nodes (and all their descendants) between different parents.
441
+ */
442
+ class CrossParentGroupOperation extends _reorderExecutor.BaseReorderOperation {
443
+ operationType = 'cross-parent-group';
444
+ detectOperation(ctx) {
445
+ if (ctx.dropPosition === 'inside') {
446
+ return null;
447
+ }
448
+ const {
449
+ sourceRowId,
450
+ placeholderIndex,
451
+ sortedFilteredRowIds,
452
+ rowTree,
453
+ apiRef,
454
+ setTreeDataPath
455
+ } = ctx;
456
+ const sourceNode = (0, _xDataGrid.gridRowNodeSelector)(apiRef, sourceRowId);
457
+ if (!sourceNode || sourceNode.type !== 'group') {
458
+ return null;
459
+ }
460
+ if (!setTreeDataPath) {
461
+ (0, _utils2.displaySetTreeDataPathWarning)('Cross-parent reordering');
462
+ }
463
+
464
+ // Find target node
465
+ let targetIndex = placeholderIndex;
466
+ if (targetIndex === sortedFilteredRowIds.length && sortedFilteredRowIds.length > 0) {
467
+ targetIndex = sortedFilteredRowIds.length - 1;
468
+ }
469
+ if (targetIndex < 0) {
470
+ return null;
471
+ }
472
+ const targetNode = (0, _xDataGrid.gridRowNodeSelector)(apiRef, sortedFilteredRowIds[targetIndex]);
473
+ if (!targetNode) {
474
+ return null;
475
+ }
476
+ if (sourceNode.parent === targetNode.parent) {
477
+ return null;
478
+ }
479
+ if ((0, _utils.isDescendantOf)(targetNode, sourceNode, rowTree)) {
480
+ return null;
481
+ }
482
+ const actualTargetIndex = (0, _utils.calculateTargetIndex)(sourceNode, targetNode, placeholderIndex >= sortedFilteredRowIds.length, rowTree);
483
+ return {
484
+ sourceNode,
485
+ targetNode,
486
+ actualTargetIndex,
487
+ isLastChild: placeholderIndex >= sortedFilteredRowIds.length,
488
+ operationType: this.operationType
489
+ };
490
+ }
491
+ async executeOperation(operation, ctx) {
492
+ const {
493
+ sourceNode,
494
+ targetNode,
495
+ actualTargetIndex
496
+ } = operation;
497
+ const {
498
+ apiRef
499
+ } = ctx;
500
+ const rowTree = (0, _xDataGrid.gridRowTreeSelector)(apiRef);
501
+
502
+ // Calculate new base path for the moved group
503
+ const targetParentNode = rowTree[targetNode.parent];
504
+ const newBasePath = (0, _utils2.buildTreeDataPath)(targetParentNode, rowTree);
505
+
506
+ // Calculate the original base path depth
507
+ const sourceParentNode = rowTree[sourceNode.parent];
508
+ const sourceBasePath = (0, _utils2.buildTreeDataPath)(sourceParentNode, rowTree);
509
+
510
+ // Update group hierarchy paths
511
+ const updates = await (0, _utils2.updateGroupHierarchyPaths)(sourceNode, sourceBasePath, newBasePath, ctx);
512
+ if (updates.length > 0) {
513
+ // Update tree structure (partial moves are allowed)
514
+ apiRef.current.setState(state => {
515
+ const updatedTree = (0, _extends2.default)({}, state.rows.tree);
516
+
517
+ // Remove from source parent
518
+ (0, _utils2.removeNodeFromSourceParent)(updatedTree, sourceNode);
519
+
520
+ // Add to target parent
521
+ const targetParent = updatedTree[targetNode.parent];
522
+ const targetChildren = [...targetParent.children];
523
+ targetChildren.splice(actualTargetIndex, 0, sourceNode.id);
524
+ updatedTree[targetNode.parent] = (0, _extends2.default)({}, targetParent, {
525
+ children: targetChildren
526
+ });
527
+ const newParentNode = updatedTree[targetNode.parent];
528
+ const newGroupDepth = newParentNode.depth + 1;
529
+ (0, _utils2.updateNodeParentAndDepth)(updatedTree, sourceNode, targetNode.parent, newGroupDepth);
530
+ return (0, _extends2.default)({}, state, {
531
+ rows: (0, _extends2.default)({}, state.rows, {
532
+ tree: updatedTree
533
+ })
534
+ });
535
+ });
536
+ apiRef.current.updateRows(updates);
537
+ apiRef.current.publishEvent('rowsSet');
538
+ }
539
+ }
540
+ }
541
+ const treeDataReorderExecutor = exports.treeDataReorderExecutor = new _reorderExecutor.RowReorderExecutor([new SameParentSwapOperation(), new CrossParentLeafOperation(), new DropOnLeafOperation(), new DropOnGroupOperation(), new CrossParentGroupOperation()]);
@@ -0,0 +1,2 @@
1
+ import { RowReorderValidator } from "../rowReorder/reorderValidator.js";
2
+ export declare const treeDataReorderValidator: RowReorderValidator;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.treeDataReorderValidator = void 0;
7
+ var _xDataGrid = require("@mui/x-data-grid");
8
+ var _reorderValidator = require("../rowReorder/reorderValidator");
9
+ var _commonReorderConditions = require("../rowReorder/commonReorderConditions");
10
+ const validationRules = [{
11
+ name: 'same-position',
12
+ applies: ctx => ctx.sourceNode.id === ctx.targetNode.id,
13
+ isInvalid: () => true,
14
+ message: 'Source and target are the same'
15
+ }, {
16
+ name: 'adjacent-position',
17
+ applies: ctx => _commonReorderConditions.commonReorderConditions.isAdjacentPosition(ctx),
18
+ isInvalid: () => true,
19
+ message: 'Source and target are adjacent'
20
+ }, {
21
+ name: 'to-descendent',
22
+ applies: ctx => _commonReorderConditions.commonReorderConditions.isGroupToLeaf(ctx) || _commonReorderConditions.commonReorderConditions.isGroupToGroup(ctx),
23
+ isInvalid: ctx => {
24
+ let currentNode = ctx.targetNode;
25
+ const rowTree = (0, _xDataGrid.gridRowTreeSelector)(ctx.apiRef);
26
+ while (currentNode.parent) {
27
+ currentNode = rowTree[currentNode.parent];
28
+ if (currentNode.id === ctx.sourceNode.id) {
29
+ return true;
30
+ }
31
+ }
32
+ return false;
33
+ },
34
+ message: 'Cannot drop group on one of its descendents'
35
+ }, {
36
+ name: 'group-to-group-above-leaf-belongs-to-source',
37
+ applies: ctx => _commonReorderConditions.commonReorderConditions.isGroupToGroup(ctx) && _commonReorderConditions.commonReorderConditions.isDropAbove(ctx) && _commonReorderConditions.commonReorderConditions.prevIsLeaf(ctx),
38
+ isInvalid: _commonReorderConditions.commonReorderConditions.prevBelongsToSource,
39
+ message: 'Previous leaf belongs to source group or its descendants'
40
+ }];
41
+ const treeDataReorderValidator = exports.treeDataReorderValidator = new _reorderValidator.RowReorderValidator(validationRules);
@@ -1,4 +1,4 @@
1
1
  import { RefObject } from '@mui/x-internals/types';
2
- import { GridApiPro } from "../../../models/gridApiPro.js";
3
- import { DataGridProProcessedProps } from "../../../models/dataGridProProps.js";
4
- export declare const useGridTreeData: (apiRef: RefObject<GridApiPro>, props: Pick<DataGridProProcessedProps, "dataSource">) => void;
2
+ import type { GridPrivateApiPro } from "../../../models/gridApiPro.js";
3
+ import type { DataGridProProcessedProps } from "../../../models/dataGridProProps.js";
4
+ export declare const useGridTreeData: (apiRef: RefObject<GridPrivateApiPro>, props: Pick<DataGridProProcessedProps, "treeData" | "dataSource" | "isValidRowReorder">) => void;
@@ -7,11 +7,10 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.useGridTreeData = void 0;
8
8
  var React = _interopRequireWildcard(require("react"));
9
9
  var _xDataGrid = require("@mui/x-data-grid");
10
+ var _internals = require("@mui/x-data-grid/internals");
10
11
  var _gridTreeDataGroupColDef = require("./gridTreeDataGroupColDef");
12
+ var _treeDataReorderValidator = require("./treeDataReorderValidator");
11
13
  const useGridTreeData = (apiRef, props) => {
12
- /**
13
- * EVENTS
14
- */
15
14
  const handleCellKeyDown = React.useCallback((params, event) => {
16
15
  const cellParams = apiRef.current.getCellParams(params.id, params.field);
17
16
  if (cellParams.colDef.field === _gridTreeDataGroupColDef.GRID_TREE_DATA_GROUPING_FIELD && (event.key === ' ' || event.key === 'Enter') && !event.shiftKey) {
@@ -25,6 +24,52 @@ const useGridTreeData = (apiRef, props) => {
25
24
  apiRef.current.setRowChildrenExpansion(params.id, !params.rowNode.childrenExpanded);
26
25
  }
27
26
  }, [apiRef, props.dataSource]);
27
+ const isValidRowReorderProp = props.isValidRowReorder;
28
+ const isRowReorderValid = React.useCallback((initialValue, {
29
+ sourceRowId,
30
+ targetRowId,
31
+ dropPosition,
32
+ dragDirection
33
+ }) => {
34
+ if ((0, _xDataGrid.gridRowMaximumTreeDepthSelector)(apiRef) === 1 || !props.treeData) {
35
+ return initialValue;
36
+ }
37
+ const expandedSortedRowIndexLookup = (0, _xDataGrid.gridExpandedSortedRowIndexLookupSelector)(apiRef);
38
+ const expandedSortedRowIds = (0, _xDataGrid.gridExpandedSortedRowIdsSelector)(apiRef);
39
+ const rowTree = (0, _xDataGrid.gridRowTreeSelector)(apiRef);
40
+ const targetRowIndex = expandedSortedRowIndexLookup[targetRowId];
41
+ const sourceNode = rowTree[sourceRowId];
42
+ const targetNode = rowTree[targetRowId];
43
+ const prevNode = targetRowIndex > 0 ? rowTree[expandedSortedRowIds[targetRowIndex - 1]] : null;
44
+ const nextNode = targetRowIndex < expandedSortedRowIds.length - 1 ? rowTree[expandedSortedRowIds[targetRowIndex + 1]] : null;
45
+
46
+ // Basic validity checks
47
+ if (!sourceNode || !targetNode) {
48
+ return false;
49
+ }
50
+
51
+ // Create context object
52
+ const context = {
53
+ apiRef,
54
+ sourceNode,
55
+ targetNode,
56
+ prevNode,
57
+ nextNode,
58
+ dropPosition,
59
+ dragDirection
60
+ };
61
+
62
+ // First apply internal validation
63
+ let isValid = _treeDataReorderValidator.treeDataReorderValidator.validate(context);
64
+
65
+ // If internal validation passes AND user provided additional validation
66
+ if (isValid && isValidRowReorderProp) {
67
+ // Apply additional user restrictions
68
+ isValid = isValidRowReorderProp(context);
69
+ }
70
+ return isValid;
71
+ }, [apiRef, props.treeData, isValidRowReorderProp]);
72
+ (0, _internals.useGridRegisterPipeProcessor)(apiRef, 'isRowReorderValid', isRowReorderValid);
28
73
  (0, _xDataGrid.useGridEvent)(apiRef, 'cellKeyDown', handleCellKeyDown);
29
74
  };
30
75
  exports.useGridTreeData = useGridTreeData;
@@ -0,0 +1,8 @@
1
+ import { type GridRowId, type GridTreeNode, type GridGroupNode, type GridValidRowModel, type GridRowTreeConfig } from '@mui/x-data-grid';
2
+ import type { ReorderExecutionContext } from "../rowReorder/types.js";
3
+ export declare const buildTreeDataPath: (node: GridTreeNode, tree: GridRowTreeConfig) => string[];
4
+ export declare function displaySetTreeDataPathWarning(operationName: string): void;
5
+ export declare function removeNodeFromSourceParent(updatedTree: Record<string, GridTreeNode>, sourceNode: GridTreeNode): void;
6
+ export declare function updateLeafPath(sourceNode: GridTreeNode, targetPath: string[], ctx: ReorderExecutionContext): Promise<GridValidRowModel | null>;
7
+ export declare function updateGroupHierarchyPaths(sourceNode: GridGroupNode, sourceBasePath: string[], targetPath: string[], ctx: ReorderExecutionContext): Promise<GridValidRowModel[]>;
8
+ export declare function updateNodeParentAndDepth(updatedTree: Record<string, GridTreeNode>, node: GridTreeNode, newParentId: GridRowId, newDepth: number): void;