@mui/x-data-grid-premium 8.10.1 → 8.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +221 -8
- package/DataGridPremium/DataGridPremium.js +6 -4
- package/DataGridPremium/useDataGridPremiumComponent.d.ts +2 -1
- package/DataGridPremium/useDataGridPremiumComponent.js +2 -2
- package/esm/DataGridPremium/DataGridPremium.js +6 -4
- package/esm/DataGridPremium/useDataGridPremiumComponent.d.ts +2 -1
- package/esm/DataGridPremium/useDataGridPremiumComponent.js +2 -2
- package/esm/hooks/features/aggregation/wrapColumnWithAggregation.d.ts +1 -0
- package/esm/hooks/features/clipboard/useGridClipboardImport.js +1 -1
- package/esm/hooks/features/export/serializer/setupExcelExportWebWorker.js +1 -2
- package/esm/hooks/features/rowGrouping/createGroupingColDef.d.ts +2 -1
- package/esm/hooks/features/rowGrouping/createGroupingColDef.js +31 -7
- package/esm/hooks/features/rowGrouping/gridRowGroupingInterfaces.d.ts +1 -0
- package/esm/hooks/features/rowGrouping/gridRowGroupingUtils.js +5 -1
- package/esm/hooks/features/rowGrouping/useGridRowGrouping.d.ts +1 -1
- package/esm/hooks/features/rowGrouping/useGridRowGrouping.js +48 -2
- package/esm/hooks/features/rowReorder/operations.d.ts +40 -0
- package/esm/hooks/features/rowReorder/operations.js +535 -0
- package/esm/hooks/features/rowReorder/reorderExecutor.d.ts +15 -0
- package/esm/hooks/features/rowReorder/reorderExecutor.js +25 -0
- package/esm/hooks/features/rowReorder/reorderValidator.d.ts +16 -0
- package/esm/hooks/features/rowReorder/reorderValidator.js +116 -0
- package/esm/hooks/features/rowReorder/types.d.ts +42 -0
- package/esm/hooks/features/rowReorder/types.js +1 -0
- package/esm/hooks/features/rowReorder/utils.d.ts +127 -0
- package/esm/hooks/features/rowReorder/utils.js +343 -0
- package/esm/hooks/features/rows/useGridRowsOverridableMethods.d.ts +7 -0
- package/esm/hooks/features/rows/useGridRowsOverridableMethods.js +52 -0
- package/esm/index.js +1 -1
- package/esm/models/gridGroupingValueSetter.d.ts +14 -0
- package/esm/models/gridGroupingValueSetter.js +1 -0
- package/esm/models/index.d.ts +1 -0
- package/esm/models/index.js +1 -0
- package/esm/typeOverloads/modules.d.ts +7 -1
- package/hooks/features/aggregation/wrapColumnWithAggregation.d.ts +1 -0
- package/hooks/features/clipboard/useGridClipboardImport.js +1 -1
- package/hooks/features/export/serializer/setupExcelExportWebWorker.js +1 -2
- package/hooks/features/rowGrouping/createGroupingColDef.d.ts +2 -1
- package/hooks/features/rowGrouping/createGroupingColDef.js +31 -7
- package/hooks/features/rowGrouping/gridRowGroupingInterfaces.d.ts +1 -0
- package/hooks/features/rowGrouping/gridRowGroupingUtils.js +5 -1
- package/hooks/features/rowGrouping/useGridRowGrouping.d.ts +1 -1
- package/hooks/features/rowGrouping/useGridRowGrouping.js +46 -0
- package/hooks/features/rowReorder/operations.d.ts +40 -0
- package/hooks/features/rowReorder/operations.js +546 -0
- package/hooks/features/rowReorder/reorderExecutor.d.ts +15 -0
- package/hooks/features/rowReorder/reorderExecutor.js +31 -0
- package/hooks/features/rowReorder/reorderValidator.d.ts +16 -0
- package/hooks/features/rowReorder/reorderValidator.js +122 -0
- package/hooks/features/rowReorder/types.d.ts +42 -0
- package/hooks/features/rowReorder/types.js +5 -0
- package/hooks/features/rowReorder/utils.d.ts +127 -0
- package/hooks/features/rowReorder/utils.js +360 -0
- package/hooks/features/rows/useGridRowsOverridableMethods.d.ts +7 -0
- package/hooks/features/rows/useGridRowsOverridableMethods.js +60 -0
- package/index.js +1 -1
- package/models/gridGroupingValueSetter.d.ts +14 -0
- package/models/gridGroupingValueSetter.js +5 -0
- package/models/index.d.ts +1 -0
- package/models/index.js +11 -0
- package/package.json +5 -5
- package/typeOverloads/modules.d.ts +7 -1
|
@@ -0,0 +1,546 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.SameParentSwapOperation = exports.CrossParentLeafOperation = exports.CrossParentGroupOperation = exports.BaseReorderOperation = void 0;
|
|
8
|
+
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
9
|
+
var _xDataGridPro = require("@mui/x-data-grid-pro");
|
|
10
|
+
var _warning = require("@mui/x-internals/warning");
|
|
11
|
+
var _isDeepEqual = require("@mui/x-internals/isDeepEqual");
|
|
12
|
+
var _rowGrouping = require("../rowGrouping");
|
|
13
|
+
var _gridRowGroupingUtils = require("../rowGrouping/gridRowGroupingUtils");
|
|
14
|
+
var _utils = require("./utils");
|
|
15
|
+
/**
|
|
16
|
+
* Base class for all reorder operations.
|
|
17
|
+
* Provides abstract methods for operation detection and execution.
|
|
18
|
+
*/
|
|
19
|
+
class BaseReorderOperation {}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Handles reordering of items within the same parent group.
|
|
23
|
+
*/
|
|
24
|
+
exports.BaseReorderOperation = BaseReorderOperation;
|
|
25
|
+
class SameParentSwapOperation extends BaseReorderOperation {
|
|
26
|
+
operationType = 'same-parent-swap';
|
|
27
|
+
detectOperation(ctx) {
|
|
28
|
+
const {
|
|
29
|
+
sourceRowId,
|
|
30
|
+
placeholderIndex,
|
|
31
|
+
sortedFilteredRowIds,
|
|
32
|
+
sortedFilteredRowIndexLookup,
|
|
33
|
+
rowTree,
|
|
34
|
+
apiRef
|
|
35
|
+
} = ctx;
|
|
36
|
+
const sourceNode = (0, _xDataGridPro.gridRowNodeSelector)(apiRef, sourceRowId);
|
|
37
|
+
if (!sourceNode || sourceNode.type === 'footer') {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
let targetIndex = placeholderIndex;
|
|
41
|
+
const sourceIndex = sortedFilteredRowIndexLookup[sourceRowId];
|
|
42
|
+
if (targetIndex === sortedFilteredRowIds.length && sortedFilteredRowIds.length > 0) {
|
|
43
|
+
targetIndex -= 1;
|
|
44
|
+
}
|
|
45
|
+
let targetNode = (0, _xDataGridPro.gridRowNodeSelector)(apiRef, sortedFilteredRowIds[targetIndex]);
|
|
46
|
+
if (placeholderIndex > sourceIndex && sourceNode.parent === targetNode.parent) {
|
|
47
|
+
targetIndex = placeholderIndex - 1;
|
|
48
|
+
targetNode = (0, _xDataGridPro.gridRowNodeSelector)(apiRef, sortedFilteredRowIds[targetIndex]);
|
|
49
|
+
if (targetNode && targetNode.depth !== sourceNode.depth) {
|
|
50
|
+
while (targetNode.depth > sourceNode.depth && targetIndex >= 0) {
|
|
51
|
+
targetIndex -= 1;
|
|
52
|
+
targetNode = (0, _xDataGridPro.gridRowNodeSelector)(apiRef, sortedFilteredRowIds[targetIndex]);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (targetIndex === -1) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
let isLastChild = false;
|
|
60
|
+
if (!targetNode) {
|
|
61
|
+
if (placeholderIndex >= sortedFilteredRowIds.length && sortedFilteredRowIds.length > 0) {
|
|
62
|
+
targetNode = (0, _xDataGridPro.gridRowNodeSelector)(apiRef, sortedFilteredRowIds[sortedFilteredRowIds.length - 1]);
|
|
63
|
+
isLastChild = true;
|
|
64
|
+
} else {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
let adjustedTargetNode = targetNode;
|
|
69
|
+
|
|
70
|
+
// Case A and B adjustment
|
|
71
|
+
if (targetNode.type === 'group' && sourceNode.parent !== targetNode.parent && sourceNode.depth > targetNode.depth) {
|
|
72
|
+
let i = targetIndex - 1;
|
|
73
|
+
while (i >= 0) {
|
|
74
|
+
const node = (0, _xDataGridPro.gridRowNodeSelector)(apiRef, sortedFilteredRowIds[i]);
|
|
75
|
+
if (node && node.depth < sourceNode.depth) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
if (node && node.depth === sourceNode.depth) {
|
|
79
|
+
targetIndex = i;
|
|
80
|
+
adjustedTargetNode = node;
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
i -= 1;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const operationType = (0, _utils.determineOperationType)(sourceNode, adjustedTargetNode);
|
|
87
|
+
if (operationType !== 'same-parent-swap') {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
const actualTargetIndex = (0, _utils.calculateTargetIndex)(sourceNode, adjustedTargetNode, isLastChild, rowTree);
|
|
91
|
+
targetNode = adjustedTargetNode;
|
|
92
|
+
if (sourceNode.type !== targetNode.type) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
sourceNode,
|
|
97
|
+
targetNode,
|
|
98
|
+
actualTargetIndex,
|
|
99
|
+
isLastChild,
|
|
100
|
+
operationType
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
executeOperation(operation, ctx) {
|
|
104
|
+
const {
|
|
105
|
+
sourceNode,
|
|
106
|
+
actualTargetIndex
|
|
107
|
+
} = operation;
|
|
108
|
+
const {
|
|
109
|
+
apiRef,
|
|
110
|
+
sourceRowId
|
|
111
|
+
} = ctx;
|
|
112
|
+
apiRef.current.setState(state => {
|
|
113
|
+
const group = (0, _xDataGridPro.gridRowTreeSelector)(apiRef)[sourceNode.parent];
|
|
114
|
+
const currentChildren = [...group.children];
|
|
115
|
+
const oldIndex = currentChildren.findIndex(row => row === sourceRowId);
|
|
116
|
+
if (oldIndex === -1 || actualTargetIndex === -1 || oldIndex === actualTargetIndex) {
|
|
117
|
+
return state;
|
|
118
|
+
}
|
|
119
|
+
currentChildren.splice(actualTargetIndex, 0, currentChildren.splice(oldIndex, 1)[0]);
|
|
120
|
+
return (0, _extends2.default)({}, state, {
|
|
121
|
+
rows: (0, _extends2.default)({}, state.rows, {
|
|
122
|
+
tree: (0, _extends2.default)({}, state.rows.tree, {
|
|
123
|
+
[sourceNode.parent]: (0, _extends2.default)({}, group, {
|
|
124
|
+
children: currentChildren
|
|
125
|
+
})
|
|
126
|
+
})
|
|
127
|
+
})
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
apiRef.current.publishEvent('rowsSet');
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Handles moving leaf nodes between different parent groups.
|
|
136
|
+
*/
|
|
137
|
+
exports.SameParentSwapOperation = SameParentSwapOperation;
|
|
138
|
+
class CrossParentLeafOperation extends BaseReorderOperation {
|
|
139
|
+
operationType = 'cross-parent-leaf';
|
|
140
|
+
detectOperation(ctx) {
|
|
141
|
+
const {
|
|
142
|
+
sourceRowId,
|
|
143
|
+
placeholderIndex,
|
|
144
|
+
sortedFilteredRowIds,
|
|
145
|
+
rowTree,
|
|
146
|
+
apiRef
|
|
147
|
+
} = ctx;
|
|
148
|
+
const sourceNode = (0, _xDataGridPro.gridRowNodeSelector)(apiRef, sourceRowId);
|
|
149
|
+
if (!sourceNode || sourceNode.type === 'footer') {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
let targetNode = (0, _xDataGridPro.gridRowNodeSelector)(apiRef, sortedFilteredRowIds[placeholderIndex]);
|
|
153
|
+
let isLastChild = false;
|
|
154
|
+
if (!targetNode) {
|
|
155
|
+
if (placeholderIndex >= sortedFilteredRowIds.length && sortedFilteredRowIds.length > 0) {
|
|
156
|
+
targetNode = (0, _xDataGridPro.gridRowNodeSelector)(apiRef, sortedFilteredRowIds[sortedFilteredRowIds.length - 1]);
|
|
157
|
+
isLastChild = true;
|
|
158
|
+
} else {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
let adjustedTargetNode = targetNode;
|
|
163
|
+
|
|
164
|
+
// Case D adjustment
|
|
165
|
+
if (sourceNode.type === 'leaf' && targetNode.type === 'group' && targetNode.depth < sourceNode.depth) {
|
|
166
|
+
const prevIndex = placeholderIndex - 1;
|
|
167
|
+
if (prevIndex >= 0) {
|
|
168
|
+
const prevRowId = sortedFilteredRowIds[prevIndex];
|
|
169
|
+
const leafTargetNode = (0, _xDataGridPro.gridRowNodeSelector)(apiRef, prevRowId);
|
|
170
|
+
if (leafTargetNode && leafTargetNode.type === 'leaf') {
|
|
171
|
+
adjustedTargetNode = leafTargetNode;
|
|
172
|
+
isLastChild = true;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
const operationType = (0, _utils.determineOperationType)(sourceNode, adjustedTargetNode);
|
|
177
|
+
if (operationType !== 'cross-parent-leaf') {
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
const actualTargetIndex = (0, _utils.calculateTargetIndex)(sourceNode, adjustedTargetNode, isLastChild, rowTree);
|
|
181
|
+
targetNode = adjustedTargetNode;
|
|
182
|
+
|
|
183
|
+
// Validate depth constraints
|
|
184
|
+
if (sourceNode.type === 'leaf' && targetNode.type === 'leaf') {
|
|
185
|
+
if (sourceNode.depth !== targetNode.depth) {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
} else if (sourceNode.type === 'leaf' && targetNode.type === 'group') {
|
|
189
|
+
if (targetNode.depth >= sourceNode.depth) {
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return {
|
|
194
|
+
sourceNode,
|
|
195
|
+
targetNode: adjustedTargetNode,
|
|
196
|
+
actualTargetIndex,
|
|
197
|
+
isLastChild,
|
|
198
|
+
operationType
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
async executeOperation(operation, ctx) {
|
|
202
|
+
const {
|
|
203
|
+
sourceNode,
|
|
204
|
+
targetNode,
|
|
205
|
+
isLastChild
|
|
206
|
+
} = operation;
|
|
207
|
+
const {
|
|
208
|
+
apiRef,
|
|
209
|
+
sourceRowId,
|
|
210
|
+
processRowUpdate,
|
|
211
|
+
onProcessRowUpdateError
|
|
212
|
+
} = ctx;
|
|
213
|
+
let target = targetNode;
|
|
214
|
+
if (targetNode.type === 'group') {
|
|
215
|
+
const prevIndex = ctx.placeholderIndex - 1;
|
|
216
|
+
if (prevIndex >= 0) {
|
|
217
|
+
const prevRowId = ctx.sortedFilteredRowIds[prevIndex];
|
|
218
|
+
const prevNode = (0, _xDataGridPro.gridRowNodeSelector)(apiRef, prevRowId);
|
|
219
|
+
if (prevNode && prevNode.type === 'leaf') {
|
|
220
|
+
target = prevNode;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
const rowTree = (0, _xDataGridPro.gridRowTreeSelector)(apiRef);
|
|
225
|
+
const sourceGroup = rowTree[sourceNode.parent];
|
|
226
|
+
const targetGroup = rowTree[target.parent];
|
|
227
|
+
const sourceChildren = sourceGroup.children;
|
|
228
|
+
const targetChildren = targetGroup.children;
|
|
229
|
+
const sourceIndex = sourceChildren.findIndex(row => row === sourceRowId);
|
|
230
|
+
const targetIndex = targetChildren.findIndex(row => row === target.id);
|
|
231
|
+
if (sourceIndex === -1 || targetIndex === -1) {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
const dataRowIdToModelLookup = (0, _xDataGridPro.gridRowsLookupSelector)(apiRef);
|
|
235
|
+
const columnsLookup = (0, _xDataGridPro.gridColumnLookupSelector)(apiRef);
|
|
236
|
+
const sanitizedRowGroupingModel = (0, _rowGrouping.gridRowGroupingSanitizedModelSelector)(apiRef);
|
|
237
|
+
const originalSourceRow = dataRowIdToModelLookup[sourceRowId];
|
|
238
|
+
let updatedSourceRow = (0, _extends2.default)({}, originalSourceRow);
|
|
239
|
+
const targetRow = dataRowIdToModelLookup[target.id];
|
|
240
|
+
const groupingRules = (0, _gridRowGroupingUtils.getGroupingRules)({
|
|
241
|
+
sanitizedRowGroupingModel,
|
|
242
|
+
columnsLookup
|
|
243
|
+
});
|
|
244
|
+
for (const groupingRule of groupingRules) {
|
|
245
|
+
const colDef = columnsLookup[groupingRule.field];
|
|
246
|
+
if (groupingRule.groupingValueSetter && colDef) {
|
|
247
|
+
const targetGroupingValue = (0, _gridRowGroupingUtils.getCellGroupingCriteria)({
|
|
248
|
+
row: targetRow,
|
|
249
|
+
colDef,
|
|
250
|
+
groupingRule,
|
|
251
|
+
apiRef
|
|
252
|
+
}).key;
|
|
253
|
+
updatedSourceRow = groupingRule.groupingValueSetter(targetGroupingValue, updatedSourceRow, colDef, apiRef);
|
|
254
|
+
} else {
|
|
255
|
+
updatedSourceRow[groupingRule.field] = targetRow[groupingRule.field];
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
const commitStateUpdate = finalSourceRow => {
|
|
259
|
+
apiRef.current.setState(state => {
|
|
260
|
+
const updatedSourceChildren = sourceChildren.filter(rowId => rowId !== sourceRowId);
|
|
261
|
+
const updatedTree = (0, _extends2.default)({}, state.rows.tree);
|
|
262
|
+
const removedGroups = new Set();
|
|
263
|
+
let rootLevelRemovals = 0;
|
|
264
|
+
if (updatedSourceChildren.length === 0) {
|
|
265
|
+
removedGroups.add(sourceGroup.id);
|
|
266
|
+
rootLevelRemovals = (0, _utils.removeEmptyAncestors)(sourceGroup.parent, updatedTree, removedGroups);
|
|
267
|
+
}
|
|
268
|
+
removedGroups.forEach(groupId => {
|
|
269
|
+
const group = updatedTree[groupId];
|
|
270
|
+
if (group && group.parent && updatedTree[group.parent]) {
|
|
271
|
+
const parent = updatedTree[group.parent];
|
|
272
|
+
updatedTree[group.parent] = (0, _extends2.default)({}, parent, {
|
|
273
|
+
children: parent.children.filter(childId => childId !== groupId)
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
delete updatedTree[groupId];
|
|
277
|
+
});
|
|
278
|
+
if (!removedGroups.has(sourceGroup.id)) {
|
|
279
|
+
updatedTree[sourceNode.parent] = (0, _extends2.default)({}, sourceGroup, {
|
|
280
|
+
children: updatedSourceChildren
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
const updatedTargetChildren = isLastChild ? [...targetChildren, sourceRowId] : [...targetChildren.slice(0, targetIndex), sourceRowId, ...targetChildren.slice(targetIndex)];
|
|
284
|
+
updatedTree[target.parent] = (0, _extends2.default)({}, targetGroup, {
|
|
285
|
+
children: updatedTargetChildren
|
|
286
|
+
});
|
|
287
|
+
updatedTree[sourceNode.id] = (0, _extends2.default)({}, sourceNode, {
|
|
288
|
+
parent: target.parent
|
|
289
|
+
});
|
|
290
|
+
return (0, _extends2.default)({}, state, {
|
|
291
|
+
rows: (0, _extends2.default)({}, state.rows, {
|
|
292
|
+
totalTopLevelRowCount: state.rows.totalTopLevelRowCount - rootLevelRemovals,
|
|
293
|
+
tree: updatedTree
|
|
294
|
+
})
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
apiRef.current.updateRows([finalSourceRow]);
|
|
298
|
+
apiRef.current.publishEvent('rowsSet');
|
|
299
|
+
};
|
|
300
|
+
if (processRowUpdate && !(0, _isDeepEqual.isDeepEqual)(originalSourceRow, updatedSourceRow)) {
|
|
301
|
+
const params = {
|
|
302
|
+
rowId: sourceRowId,
|
|
303
|
+
previousRow: originalSourceRow,
|
|
304
|
+
updatedRow: updatedSourceRow
|
|
305
|
+
};
|
|
306
|
+
apiRef.current.setLoading(true);
|
|
307
|
+
try {
|
|
308
|
+
const processedRow = await processRowUpdate(updatedSourceRow, originalSourceRow, params);
|
|
309
|
+
const finalRow = processedRow || updatedSourceRow;
|
|
310
|
+
commitStateUpdate(finalRow);
|
|
311
|
+
} catch (error) {
|
|
312
|
+
apiRef.current.setLoading(false);
|
|
313
|
+
if (onProcessRowUpdateError) {
|
|
314
|
+
onProcessRowUpdateError(error);
|
|
315
|
+
} else if (process.env.NODE_ENV !== 'production') {
|
|
316
|
+
(0, _warning.warnOnce)(['MUI X: A call to `processRowUpdate()` threw an error which was not handled because `onProcessRowUpdateError()` is missing.', 'To handle the error pass a callback to the `onProcessRowUpdateError()` prop, for example `<DataGrid onProcessRowUpdateError={(error) => ...} />`.', 'For more detail, see https://mui.com/x/react-data-grid/editing/persistence/.'], 'error');
|
|
317
|
+
}
|
|
318
|
+
} finally {
|
|
319
|
+
apiRef.current.setLoading(false);
|
|
320
|
+
}
|
|
321
|
+
} else {
|
|
322
|
+
commitStateUpdate(updatedSourceRow);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Handles moving entire groups between different parents.
|
|
329
|
+
*/
|
|
330
|
+
exports.CrossParentLeafOperation = CrossParentLeafOperation;
|
|
331
|
+
class CrossParentGroupOperation extends BaseReorderOperation {
|
|
332
|
+
operationType = 'cross-parent-group';
|
|
333
|
+
detectOperation(ctx) {
|
|
334
|
+
const {
|
|
335
|
+
sourceRowId,
|
|
336
|
+
placeholderIndex,
|
|
337
|
+
sortedFilteredRowIds,
|
|
338
|
+
rowTree,
|
|
339
|
+
apiRef
|
|
340
|
+
} = ctx;
|
|
341
|
+
const sourceNode = (0, _xDataGridPro.gridRowNodeSelector)(apiRef, sourceRowId);
|
|
342
|
+
if (!sourceNode || sourceNode.type === 'footer') {
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
let targetIndex = placeholderIndex;
|
|
346
|
+
let targetNode = (0, _xDataGridPro.gridRowNodeSelector)(apiRef, sortedFilteredRowIds[placeholderIndex]);
|
|
347
|
+
let isLastChild = false;
|
|
348
|
+
if (!targetNode) {
|
|
349
|
+
if (placeholderIndex >= sortedFilteredRowIds.length && sortedFilteredRowIds.length > 0) {
|
|
350
|
+
targetNode = (0, _xDataGridPro.gridRowNodeSelector)(apiRef, sortedFilteredRowIds[sortedFilteredRowIds.length - 1]);
|
|
351
|
+
targetIndex = sortedFilteredRowIds.length - 1;
|
|
352
|
+
isLastChild = true;
|
|
353
|
+
} else {
|
|
354
|
+
return null;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
let adjustedTargetNode = targetNode;
|
|
358
|
+
|
|
359
|
+
// Case G adjustment
|
|
360
|
+
if (sourceNode.type === 'group' && targetNode.type === 'group' && sourceNode.parent !== targetNode.parent && sourceNode.depth > targetNode.depth) {
|
|
361
|
+
let prevIndex = targetIndex - 1;
|
|
362
|
+
if (prevIndex < 0) {
|
|
363
|
+
return null;
|
|
364
|
+
}
|
|
365
|
+
let prevNode = (0, _xDataGridPro.gridRowNodeSelector)(apiRef, sortedFilteredRowIds[prevIndex]);
|
|
366
|
+
if (prevNode && prevNode.depth !== sourceNode.depth) {
|
|
367
|
+
while (prevNode.depth > sourceNode.depth && prevIndex >= 0) {
|
|
368
|
+
prevIndex -= 1;
|
|
369
|
+
prevNode = (0, _xDataGridPro.gridRowNodeSelector)(apiRef, sortedFilteredRowIds[prevIndex]);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
if (!prevNode || prevNode.type !== 'group' || prevNode.depth !== sourceNode.depth) {
|
|
373
|
+
return null;
|
|
374
|
+
}
|
|
375
|
+
isLastChild = true;
|
|
376
|
+
adjustedTargetNode = prevNode;
|
|
377
|
+
}
|
|
378
|
+
const operationType = (0, _utils.determineOperationType)(sourceNode, adjustedTargetNode);
|
|
379
|
+
if (operationType !== 'cross-parent-group') {
|
|
380
|
+
return null;
|
|
381
|
+
}
|
|
382
|
+
const actualTargetIndex = (0, _utils.calculateTargetIndex)(sourceNode, adjustedTargetNode, isLastChild, rowTree);
|
|
383
|
+
const operation = {
|
|
384
|
+
sourceNode,
|
|
385
|
+
targetNode: adjustedTargetNode,
|
|
386
|
+
actualTargetIndex,
|
|
387
|
+
isLastChild,
|
|
388
|
+
operationType
|
|
389
|
+
};
|
|
390
|
+
targetNode = adjustedTargetNode;
|
|
391
|
+
if (sourceNode.depth !== targetNode.depth) {
|
|
392
|
+
return null;
|
|
393
|
+
}
|
|
394
|
+
return operation;
|
|
395
|
+
}
|
|
396
|
+
async executeOperation(operation, ctx) {
|
|
397
|
+
const {
|
|
398
|
+
sourceNode,
|
|
399
|
+
targetNode,
|
|
400
|
+
isLastChild
|
|
401
|
+
} = operation;
|
|
402
|
+
const {
|
|
403
|
+
apiRef,
|
|
404
|
+
processRowUpdate,
|
|
405
|
+
onProcessRowUpdateError
|
|
406
|
+
} = ctx;
|
|
407
|
+
const tree = (0, _xDataGridPro.gridRowTreeSelector)(apiRef);
|
|
408
|
+
const dataRowIdToModelLookup = (0, _xDataGridPro.gridRowsLookupSelector)(apiRef);
|
|
409
|
+
const columnsLookup = (0, _xDataGridPro.gridColumnLookupSelector)(apiRef);
|
|
410
|
+
const sanitizedRowGroupingModel = (0, _rowGrouping.gridRowGroupingSanitizedModelSelector)(apiRef);
|
|
411
|
+
const allLeafIds = (0, _utils.collectAllLeafDescendants)(sourceNode, tree);
|
|
412
|
+
if (allLeafIds.length === 0) {
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
const updater = new _utils.BatchRowUpdater(processRowUpdate, onProcessRowUpdateError);
|
|
416
|
+
const groupingRules = (0, _gridRowGroupingUtils.getGroupingRules)({
|
|
417
|
+
sanitizedRowGroupingModel,
|
|
418
|
+
columnsLookup
|
|
419
|
+
});
|
|
420
|
+
const targetParentPath = (0, _utils.getNodePathInTree)({
|
|
421
|
+
id: targetNode.parent,
|
|
422
|
+
tree
|
|
423
|
+
});
|
|
424
|
+
for (const leafId of allLeafIds) {
|
|
425
|
+
const originalRow = dataRowIdToModelLookup[leafId];
|
|
426
|
+
let updatedRow = (0, _extends2.default)({}, originalRow);
|
|
427
|
+
for (let depth = 0; depth < targetParentPath.length; depth += 1) {
|
|
428
|
+
const pathItem = targetParentPath[depth];
|
|
429
|
+
if (pathItem.field) {
|
|
430
|
+
const groupingRule = groupingRules.find(rule => rule.field === pathItem.field);
|
|
431
|
+
if (groupingRule) {
|
|
432
|
+
const colDef = columnsLookup[groupingRule.field];
|
|
433
|
+
if (groupingRule.groupingValueSetter && colDef) {
|
|
434
|
+
updatedRow = groupingRule.groupingValueSetter(pathItem.key, updatedRow, colDef, apiRef);
|
|
435
|
+
} else {
|
|
436
|
+
updatedRow[groupingRule.field] = pathItem.key;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
updater.queueUpdate(leafId, originalRow, updatedRow);
|
|
442
|
+
}
|
|
443
|
+
apiRef.current.setLoading(true);
|
|
444
|
+
try {
|
|
445
|
+
const {
|
|
446
|
+
successful,
|
|
447
|
+
failed,
|
|
448
|
+
updates
|
|
449
|
+
} = await updater.executeAll();
|
|
450
|
+
if (successful.length > 0) {
|
|
451
|
+
apiRef.current.setState(state => {
|
|
452
|
+
const updatedTree = (0, _extends2.default)({}, state.rows.tree);
|
|
453
|
+
const treeDepths = (0, _extends2.default)({}, state.rows.treeDepths);
|
|
454
|
+
let rootLevelRemovals = 0;
|
|
455
|
+
if (failed.length === 0) {
|
|
456
|
+
const sourceParentNode = updatedTree[sourceNode.parent];
|
|
457
|
+
if (!sourceParentNode) {
|
|
458
|
+
const targetParentNode = updatedTree[targetNode.parent];
|
|
459
|
+
const targetIndex = targetParentNode.children.indexOf(targetNode.id);
|
|
460
|
+
const newTargetChildren = [...targetParentNode.children];
|
|
461
|
+
if (isLastChild) {
|
|
462
|
+
newTargetChildren.push(sourceNode.id);
|
|
463
|
+
} else {
|
|
464
|
+
newTargetChildren.splice(targetIndex, 0, sourceNode.id);
|
|
465
|
+
}
|
|
466
|
+
updatedTree[targetNode.parent] = (0, _extends2.default)({}, targetParentNode, {
|
|
467
|
+
children: newTargetChildren
|
|
468
|
+
});
|
|
469
|
+
updatedTree[sourceNode.id] = (0, _extends2.default)({}, sourceNode, {
|
|
470
|
+
parent: targetNode.parent
|
|
471
|
+
});
|
|
472
|
+
} else {
|
|
473
|
+
const updatedSourceParentChildren = sourceParentNode.children.filter(id => id !== sourceNode.id);
|
|
474
|
+
if (updatedSourceParentChildren.length === 0) {
|
|
475
|
+
const removedGroups = new Set();
|
|
476
|
+
removedGroups.add(sourceNode.parent);
|
|
477
|
+
const parentOfSourceParent = updatedTree[sourceNode.parent].parent;
|
|
478
|
+
if (parentOfSourceParent) {
|
|
479
|
+
rootLevelRemovals = (0, _utils.removeEmptyAncestors)(parentOfSourceParent, updatedTree, removedGroups);
|
|
480
|
+
}
|
|
481
|
+
removedGroups.forEach(groupId => {
|
|
482
|
+
const group = updatedTree[groupId];
|
|
483
|
+
if (group && group.parent && updatedTree[group.parent]) {
|
|
484
|
+
const parent = updatedTree[group.parent];
|
|
485
|
+
updatedTree[group.parent] = (0, _extends2.default)({}, parent, {
|
|
486
|
+
children: parent.children.filter(childId => childId !== groupId)
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
delete updatedTree[groupId];
|
|
490
|
+
});
|
|
491
|
+
} else {
|
|
492
|
+
updatedTree[sourceNode.parent] = (0, _extends2.default)({}, sourceParentNode, {
|
|
493
|
+
children: updatedSourceParentChildren
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
const targetParentNode = updatedTree[targetNode.parent];
|
|
497
|
+
const sourceGroupNode = sourceNode;
|
|
498
|
+
const existingGroup = sourceGroupNode.groupingKey !== null && sourceGroupNode.groupingField !== null ? (0, _utils.findExistingGroupWithSameKey)(targetParentNode, sourceGroupNode.groupingKey, sourceGroupNode.groupingField, updatedTree) : null;
|
|
499
|
+
if (existingGroup) {
|
|
500
|
+
const updatedExistingGroup = (0, _extends2.default)({}, existingGroup, {
|
|
501
|
+
children: [...existingGroup.children, ...sourceGroupNode.children]
|
|
502
|
+
});
|
|
503
|
+
updatedTree[existingGroup.id] = updatedExistingGroup;
|
|
504
|
+
sourceGroupNode.children.forEach(childId => {
|
|
505
|
+
const childNode = updatedTree[childId];
|
|
506
|
+
if (childNode) {
|
|
507
|
+
updatedTree[childId] = (0, _extends2.default)({}, childNode, {
|
|
508
|
+
parent: existingGroup.id
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
});
|
|
512
|
+
delete updatedTree[sourceNode.id];
|
|
513
|
+
} else {
|
|
514
|
+
const targetIndex = targetParentNode.children.indexOf(targetNode.id);
|
|
515
|
+
const newTargetChildren = [...targetParentNode.children];
|
|
516
|
+
if (isLastChild) {
|
|
517
|
+
newTargetChildren.push(sourceNode.id);
|
|
518
|
+
} else {
|
|
519
|
+
newTargetChildren.splice(targetIndex, 0, sourceNode.id);
|
|
520
|
+
}
|
|
521
|
+
updatedTree[targetNode.parent] = (0, _extends2.default)({}, targetParentNode, {
|
|
522
|
+
children: newTargetChildren
|
|
523
|
+
});
|
|
524
|
+
updatedTree[sourceNode.id] = (0, _extends2.default)({}, sourceNode, {
|
|
525
|
+
parent: targetNode.parent
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
return (0, _extends2.default)({}, state, {
|
|
531
|
+
rows: (0, _extends2.default)({}, state.rows, {
|
|
532
|
+
totalTopLevelRowCount: state.rows.totalTopLevelRowCount - rootLevelRemovals,
|
|
533
|
+
tree: updatedTree,
|
|
534
|
+
treeDepths
|
|
535
|
+
})
|
|
536
|
+
});
|
|
537
|
+
});
|
|
538
|
+
apiRef.current.updateRows(updates);
|
|
539
|
+
apiRef.current.publishEvent('rowsSet');
|
|
540
|
+
}
|
|
541
|
+
} finally {
|
|
542
|
+
apiRef.current.setLoading(false);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
exports.CrossParentGroupOperation = CrossParentGroupOperation;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BaseReorderOperation } from "./operations.js";
|
|
2
|
+
import type { ReorderExecutionContext } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Executor class for handling row reorder operations in grouped data grids.
|
|
5
|
+
*
|
|
6
|
+
* This class coordinates the execution of different reorder operation types,
|
|
7
|
+
* trying each operation in order until one succeeds or all fail.
|
|
8
|
+
*/
|
|
9
|
+
declare class RowReorderExecutor {
|
|
10
|
+
private operations;
|
|
11
|
+
constructor(operations: BaseReorderOperation[]);
|
|
12
|
+
execute(ctx: ReorderExecutionContext): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
export declare const rowGroupingReorderExecutor: RowReorderExecutor;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.rowGroupingReorderExecutor = void 0;
|
|
7
|
+
var _warning = require("@mui/x-internals/warning");
|
|
8
|
+
var _operations = require("./operations");
|
|
9
|
+
/**
|
|
10
|
+
* Executor class for handling row reorder operations in grouped data grids.
|
|
11
|
+
*
|
|
12
|
+
* This class coordinates the execution of different reorder operation types,
|
|
13
|
+
* trying each operation in order until one succeeds or all fail.
|
|
14
|
+
*/
|
|
15
|
+
class RowReorderExecutor {
|
|
16
|
+
constructor(operations) {
|
|
17
|
+
this.operations = operations;
|
|
18
|
+
}
|
|
19
|
+
async execute(ctx) {
|
|
20
|
+
for (const operation of this.operations) {
|
|
21
|
+
const detectedOperation = operation.detectOperation(ctx);
|
|
22
|
+
if (detectedOperation) {
|
|
23
|
+
// eslint-disable-next-line no-await-in-loop
|
|
24
|
+
await operation.executeOperation(detectedOperation, ctx);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
(0, _warning.warnOnce)(['MUI X: The parameters provided to the `setRowIndex()` resulted in a no-op.', 'Consider looking at the documentation at https://mui.com/x/react-data-grid/row-grouping/'], 'warning');
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const rowGroupingReorderExecutor = exports.rowGroupingReorderExecutor = new RowReorderExecutor([new _operations.SameParentSwapOperation(), new _operations.CrossParentLeafOperation(), new _operations.CrossParentGroupOperation()]);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ReorderValidationContext } from "./types.js";
|
|
2
|
+
interface ValidationRule {
|
|
3
|
+
name: string;
|
|
4
|
+
applies: (ctx: ReorderValidationContext) => boolean;
|
|
5
|
+
isInvalid: (ctx: ReorderValidationContext) => boolean;
|
|
6
|
+
message?: string;
|
|
7
|
+
}
|
|
8
|
+
declare class RowReorderValidator {
|
|
9
|
+
private rules;
|
|
10
|
+
constructor(rules?: ValidationRule[]);
|
|
11
|
+
addRule(rule: ValidationRule): void;
|
|
12
|
+
removeRule(ruleName: string): void;
|
|
13
|
+
validate(context: ReorderValidationContext): boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare const rowGroupingReorderValidator: RowReorderValidator;
|
|
16
|
+
export {};
|