@mui/x-data-grid-premium 8.24.0 → 8.26.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 (68) hide show
  1. package/CHANGELOG.md +196 -6479
  2. package/DataGridPremium/DataGridPremium.js +25 -1
  3. package/DataGridPremium/useDataGridPremiumComponent.js +3 -0
  4. package/DataGridPremium/useDataGridPremiumProps.js +5 -1
  5. package/components/GridAggregationRowOverlay.js +1 -0
  6. package/components/GridEmptyPivotOverlay.js +1 -0
  7. package/components/GridPremiumColumnMenu.js +1 -0
  8. package/components/GridPremiumToolbar.js +55 -3
  9. package/components/columnMenu/menuItems/GridColumnMenuAggregationItem.js +1 -0
  10. package/components/resizablePanel/ResizablePanel.js +1 -0
  11. package/components/resizablePanel/ResizablePanelHandle.js +1 -0
  12. package/esm/DataGridPremium/DataGridPremium.js +25 -1
  13. package/esm/DataGridPremium/useDataGridPremiumComponent.js +3 -0
  14. package/esm/DataGridPremium/useDataGridPremiumProps.js +5 -1
  15. package/esm/components/GridAggregationRowOverlay.js +2 -0
  16. package/esm/components/GridEmptyPivotOverlay.js +2 -0
  17. package/esm/components/GridPremiumColumnMenu.js +2 -0
  18. package/esm/components/GridPremiumToolbar.js +57 -5
  19. package/esm/components/columnMenu/menuItems/GridColumnMenuAggregationItem.js +2 -0
  20. package/esm/components/resizablePanel/ResizablePanel.js +2 -0
  21. package/esm/components/resizablePanel/ResizablePanelHandle.js +2 -0
  22. package/esm/hooks/features/aggregation/useGridAggregationPreProcessors.js +2 -0
  23. package/esm/hooks/features/clipboard/useGridClipboardImport.js +20 -9
  24. package/esm/hooks/features/history/constants.d.ts +2 -0
  25. package/esm/hooks/features/history/constants.js +1 -0
  26. package/esm/hooks/features/history/defaultHistoryHandlers.d.ts +20 -0
  27. package/esm/hooks/features/history/defaultHistoryHandlers.js +365 -0
  28. package/esm/hooks/features/history/gridHistoryInterfaces.d.ts +95 -0
  29. package/esm/hooks/features/history/gridHistoryInterfaces.js +1 -0
  30. package/esm/hooks/features/history/gridHistorySelectors.d.ts +16 -0
  31. package/esm/hooks/features/history/gridHistorySelectors.js +7 -0
  32. package/esm/hooks/features/history/index.d.ts +3 -0
  33. package/esm/hooks/features/history/index.js +2 -0
  34. package/esm/hooks/features/history/useGridHistory.d.ts +6 -0
  35. package/esm/hooks/features/history/useGridHistory.js +294 -0
  36. package/esm/hooks/features/index.d.ts +2 -1
  37. package/esm/hooks/features/index.js +2 -1
  38. package/esm/hooks/utils/useGridChartIntegration.js +2 -0
  39. package/esm/index.js +1 -1
  40. package/esm/models/dataGridPremiumProps.d.ts +26 -1
  41. package/esm/models/gridApiPremium.d.ts +2 -1
  42. package/esm/models/gridStatePremium.d.ts +2 -0
  43. package/esm/typeOverloads/modules.d.ts +25 -2
  44. package/esm/typeOverloads/modules.js +5 -1
  45. package/hooks/features/aggregation/useGridAggregationPreProcessors.js +1 -0
  46. package/hooks/features/clipboard/useGridClipboardImport.js +20 -9
  47. package/hooks/features/history/constants.d.ts +2 -0
  48. package/hooks/features/history/constants.js +7 -0
  49. package/hooks/features/history/defaultHistoryHandlers.d.ts +20 -0
  50. package/hooks/features/history/defaultHistoryHandlers.js +376 -0
  51. package/hooks/features/history/gridHistoryInterfaces.d.ts +95 -0
  52. package/hooks/features/history/gridHistoryInterfaces.js +5 -0
  53. package/hooks/features/history/gridHistorySelectors.d.ts +16 -0
  54. package/hooks/features/history/gridHistorySelectors.js +13 -0
  55. package/hooks/features/history/index.d.ts +3 -0
  56. package/hooks/features/history/index.js +43 -0
  57. package/hooks/features/history/useGridHistory.d.ts +6 -0
  58. package/hooks/features/history/useGridHistory.js +303 -0
  59. package/hooks/features/index.d.ts +2 -1
  60. package/hooks/features/index.js +11 -0
  61. package/hooks/utils/useGridChartIntegration.js +1 -0
  62. package/index.js +1 -1
  63. package/models/dataGridPremiumProps.d.ts +26 -1
  64. package/models/gridApiPremium.d.ts +2 -1
  65. package/models/gridStatePremium.d.ts +2 -0
  66. package/package.json +5 -5
  67. package/typeOverloads/modules.d.ts +25 -2
  68. package/typeOverloads/modules.js +1 -3
@@ -0,0 +1,294 @@
1
+ 'use client';
2
+
3
+ import _extends from "@babel/runtime/helpers/esm/extends";
4
+ import * as React from 'react';
5
+ import { isObjectEmpty } from '@mui/x-internals/isObjectEmpty';
6
+ import debounce from '@mui/utils/debounce';
7
+ import { useGridEvent, useGridApiMethod, isUndoShortcut, isRedoShortcut, runIf, useGridNativeEventListener } from '@mui/x-data-grid-pro/internals';
8
+ import { gridHistoryCurrentPositionSelector, gridHistoryStackSelector, gridHistoryCanUndoSelector, gridHistoryCanRedoSelector } from "./gridHistorySelectors.js";
9
+ import { createDefaultHistoryHandlers } from "./defaultHistoryHandlers.js";
10
+ export const historyStateInitializer = state => {
11
+ return _extends({}, state, {
12
+ history: {
13
+ stack: [],
14
+ currentPosition: -1,
15
+ enabled: false
16
+ }
17
+ });
18
+ };
19
+ export const useGridHistory = (apiRef, props) => {
20
+ const {
21
+ historyStackSize,
22
+ onUndo,
23
+ onRedo,
24
+ historyValidationEvents
25
+ } = props;
26
+
27
+ // Use default history events if none provided
28
+ const historyEventHandlers = React.useMemo(() => {
29
+ if (props.historyEventHandlers && !isObjectEmpty(props.historyEventHandlers)) {
30
+ return props.historyEventHandlers;
31
+ }
32
+ return createDefaultHistoryHandlers(apiRef, {
33
+ dataSource: props.dataSource,
34
+ columns: props.columns,
35
+ isCellEditable: props.isCellEditable
36
+ });
37
+ }, [apiRef, props.columns, props.isCellEditable, props.dataSource, props.historyEventHandlers]);
38
+ const isEnabled = React.useMemo(() => historyStackSize > 0 && !isObjectEmpty(historyEventHandlers), [historyStackSize, historyEventHandlers]);
39
+ const isValidationNeeded = React.useMemo(() => isEnabled && historyValidationEvents.length > 0 && Object.values(historyEventHandlers).some(handler => handler.validate), [isEnabled, historyEventHandlers, historyValidationEvents]);
40
+
41
+ // Internal ref to track undo/redo operation state
42
+ // - 'idle': everything is done
43
+ // - 'in-progress': during async undo/redo handler execution (skip validation and prevent the state change by other events)
44
+ // - 'waiting-replay': after undo/redo handler is done, the validation event is triggered again (as undo/redo is changing the state).
45
+ // In this hook we want to skip the replayed event.
46
+ const operationStateRef = React.useRef('idle');
47
+
48
+ // History event unsubscribers
49
+ const eventUnsubscribersRef = React.useRef([]);
50
+ // Validation event unsubscribers
51
+ const validationEventUnsubscribersRef = React.useRef([]);
52
+ const updateHistoryState = React.useCallback(newState => {
53
+ apiRef.current.setState(state => _extends({}, state, {
54
+ history: _extends({}, state.history, newState)
55
+ }));
56
+ }, [apiRef]);
57
+ const addToStack = React.useCallback(item => {
58
+ const currentPosition = gridHistoryCurrentPositionSelector(apiRef);
59
+ let newStack = [...gridHistoryStackSelector(apiRef)];
60
+
61
+ // If we're not at the end of the stack, truncate forward history
62
+ if (currentPosition < newStack.length - 1) {
63
+ newStack = newStack.slice(0, currentPosition + 1);
64
+ }
65
+
66
+ // Add the new item
67
+ newStack.push(item);
68
+
69
+ // If stack exceeds size, remove oldest items
70
+ if (newStack.length > historyStackSize) {
71
+ newStack = newStack.slice(newStack.length - historyStackSize);
72
+ }
73
+ updateHistoryState({
74
+ stack: newStack,
75
+ currentPosition: newStack.length - 1
76
+ });
77
+ }, [apiRef, updateHistoryState, historyStackSize]);
78
+ const clear = React.useCallback(() => {
79
+ updateHistoryState({
80
+ stack: [],
81
+ currentPosition: -1
82
+ });
83
+ }, [updateHistoryState]);
84
+ const clearUndoItems = React.useCallback(() => {
85
+ const stack = gridHistoryStackSelector(apiRef);
86
+ const currentPosition = gridHistoryCurrentPositionSelector(apiRef);
87
+
88
+ // If we're at the end of the stack (no redo items), clear everything
89
+ if (currentPosition >= stack.length - 1) {
90
+ clear();
91
+ } else {
92
+ updateHistoryState({
93
+ stack: stack.slice(currentPosition + 1),
94
+ currentPosition: -1
95
+ });
96
+ }
97
+ }, [apiRef, clear, updateHistoryState]);
98
+ const clearRedoItems = React.useCallback(() => {
99
+ const stack = gridHistoryStackSelector(apiRef);
100
+ const currentPosition = gridHistoryCurrentPositionSelector(apiRef);
101
+ updateHistoryState({
102
+ stack: stack.slice(0, currentPosition + 1)
103
+ });
104
+ }, [apiRef, updateHistoryState]);
105
+ const canUndo = React.useCallback(() => gridHistoryCanUndoSelector(apiRef), [apiRef]);
106
+ const canRedo = React.useCallback(() => gridHistoryCanRedoSelector(apiRef), [apiRef]);
107
+ const validateStackItems = React.useCallback(() => {
108
+ /**
109
+ * When:
110
+ * - idle: continue with the validation
111
+ * - in-progress: skip the validation and don't change the state
112
+ * - waiting-replay: skip the validation this time and reset the state to idle
113
+ */
114
+ if (operationStateRef.current !== 'idle') {
115
+ if (operationStateRef.current === 'waiting-replay') {
116
+ operationStateRef.current = 'idle';
117
+ }
118
+ return;
119
+ }
120
+ const stack = gridHistoryStackSelector(apiRef);
121
+ const currentPosition = gridHistoryCurrentPositionSelector(apiRef);
122
+ if (historyStackSize === 0) {
123
+ if (stack.length > 0) {
124
+ clear();
125
+ }
126
+ return;
127
+ }
128
+ if (stack.length === 0) {
129
+ return;
130
+ }
131
+ const newStack = [...stack];
132
+
133
+ // Redo check
134
+ if (currentPosition + 1 < newStack.length) {
135
+ const item = newStack[currentPosition + 1];
136
+ const handler = historyEventHandlers[item.eventName];
137
+ if (!handler) {
138
+ clearRedoItems();
139
+ } else {
140
+ const isValid = handler.validate ? handler.validate(item.data, 'redo') : true;
141
+ if (!isValid) {
142
+ clearRedoItems();
143
+ }
144
+ }
145
+ }
146
+
147
+ // Undo check
148
+ if (currentPosition >= 0) {
149
+ const item = newStack[currentPosition];
150
+ const handler = historyEventHandlers[item.eventName];
151
+ if (!handler) {
152
+ clearUndoItems();
153
+ } else {
154
+ const isValid = handler.validate ? handler.validate(item.data, 'undo') : true;
155
+ if (!isValid) {
156
+ clearUndoItems();
157
+ }
158
+ }
159
+ }
160
+ }, [apiRef, historyEventHandlers, historyStackSize, clear, clearUndoItems, clearRedoItems]);
161
+ const debouncedValidateStackItems = React.useMemo(() => debounce(validateStackItems, 0), [validateStackItems]);
162
+ const apply = React.useCallback(async (item, operation) => {
163
+ const currentPosition = gridHistoryCurrentPositionSelector(apiRef);
164
+ const clearMethod = operation === 'undo' ? clearUndoItems : clearRedoItems;
165
+ const {
166
+ eventName,
167
+ data
168
+ } = item;
169
+ const handler = historyEventHandlers[eventName];
170
+ if (!handler) {
171
+ // If the handler is not found, it means tha we are updating the handlers map, so we can igore this request
172
+ return false;
173
+ }
174
+ const isValid = handler.validate ? handler.validate(data, operation) : true;
175
+
176
+ // The data is validated every time state change event happens.
177
+ // We can get into a situation where the operation is not valid at this point only with the direct state updates.
178
+ if (!isValid) {
179
+ // Clear history and return false
180
+ clearMethod();
181
+ return false;
182
+ }
183
+
184
+ // Execute the operation
185
+ operationStateRef.current = 'in-progress';
186
+ await handler[operation](data);
187
+ operationStateRef.current = 'waiting-replay';
188
+ updateHistoryState({
189
+ currentPosition: operation === 'undo' ? currentPosition - 1 : currentPosition + 1
190
+ });
191
+ apiRef.current.publishEvent(operation, {
192
+ eventName,
193
+ data
194
+ });
195
+ // If there are no validations in the current setup, skip calling it and change the operation state to idle
196
+ if (isValidationNeeded) {
197
+ validateStackItems();
198
+ } else {
199
+ operationStateRef.current = 'idle';
200
+ }
201
+ return true;
202
+ }, [apiRef, isValidationNeeded, historyEventHandlers, clearUndoItems, clearRedoItems, updateHistoryState, validateStackItems]);
203
+ const undo = React.useCallback(async () => {
204
+ if (!canUndo()) {
205
+ return false;
206
+ }
207
+ const stack = gridHistoryStackSelector(apiRef);
208
+ const currentPosition = gridHistoryCurrentPositionSelector(apiRef);
209
+ return apply(stack[currentPosition], 'undo');
210
+ }, [apiRef, apply, canUndo]);
211
+ const redo = React.useCallback(async () => {
212
+ if (!canRedo()) {
213
+ return false;
214
+ }
215
+ const stack = gridHistoryStackSelector(apiRef);
216
+ const currentPosition = gridHistoryCurrentPositionSelector(apiRef);
217
+ return apply(stack[currentPosition + 1], 'redo');
218
+ }, [apiRef, apply, canRedo]);
219
+ const historyApi = {
220
+ undo,
221
+ redo,
222
+ clear,
223
+ canUndo,
224
+ canRedo
225
+ };
226
+ useGridApiMethod(apiRef, {
227
+ history: historyApi
228
+ }, 'public');
229
+ const handleKeyDown = React.useCallback(async event => {
230
+ if (!isUndoShortcut(event) && !isRedoShortcut(event)) {
231
+ return;
232
+ }
233
+ const action = isUndoShortcut(event) ? apiRef.current.history.undo : apiRef.current.history.redo;
234
+ event.preventDefault();
235
+ event.stopPropagation();
236
+ await action();
237
+ }, [apiRef]);
238
+ useGridNativeEventListener(apiRef, () => apiRef.current.rootElementRef.current, 'keydown', runIf(isEnabled, handleKeyDown));
239
+ useGridEvent(apiRef, 'undo', onUndo);
240
+ useGridEvent(apiRef, 'redo', onRedo);
241
+ React.useEffect(() => {
242
+ updateHistoryState({
243
+ enabled: isEnabled
244
+ });
245
+ }, [isEnabled, updateHistoryState]);
246
+ React.useEffect(() => {
247
+ if (!isValidationNeeded) {
248
+ return () => {};
249
+ }
250
+ historyValidationEvents.forEach(eventName => {
251
+ validationEventUnsubscribersRef.current.push(apiRef.current.subscribeEvent(eventName, debouncedValidateStackItems));
252
+ });
253
+ return () => {
254
+ validationEventUnsubscribersRef.current.forEach(unsubscribe => unsubscribe());
255
+ validationEventUnsubscribersRef.current = [];
256
+ };
257
+ }, [apiRef, isValidationNeeded, historyValidationEvents, debouncedValidateStackItems]);
258
+ React.useEffect(() => {
259
+ if (historyStackSize === 0) {
260
+ return () => {};
261
+ }
262
+ const events = Object.keys(historyEventHandlers);
263
+ // Subscribe to all events in the map
264
+ events.forEach(eventName => {
265
+ const handler = historyEventHandlers[eventName];
266
+ const unsubscribe = apiRef.current.subscribeEvent(eventName, (...params) => {
267
+ // Don't store if the event was triggered by undo/redo
268
+ if (operationStateRef.current !== 'idle') {
269
+ return;
270
+ }
271
+ const data = handler.store(...params);
272
+ if (data !== null) {
273
+ addToStack({
274
+ eventName,
275
+ data
276
+ });
277
+ }
278
+ });
279
+ eventUnsubscribersRef.current.push(unsubscribe);
280
+ });
281
+ return () => {
282
+ eventUnsubscribersRef.current.forEach(unsubscribe => unsubscribe());
283
+ eventUnsubscribersRef.current = [];
284
+ };
285
+ }, [apiRef, historyEventHandlers, historyStackSize, addToStack]);
286
+
287
+ // If the stack size is changed and it is smaller than the current stack size, clear the stack
288
+ React.useEffect(() => {
289
+ const currentStackSize = gridHistoryStackSelector(apiRef).length;
290
+ if (currentStackSize > historyStackSize) {
291
+ clear();
292
+ }
293
+ }, [apiRef, historyStackSize, clear]);
294
+ };
@@ -4,4 +4,5 @@ export * from "./export/index.js";
4
4
  export * from "./cellSelection/index.js";
5
5
  export * from "./aiAssistant/index.js";
6
6
  export * from "./sidebar/index.js";
7
- export * from "./pivoting/index.js";
7
+ export * from "./pivoting/index.js";
8
+ export * from "./history/index.js";
@@ -5,4 +5,5 @@ export * from "./export/index.js";
5
5
  export * from "./cellSelection/index.js";
6
6
  export * from "./aiAssistant/index.js";
7
7
  export * from "./sidebar/index.js";
8
- export * from "./pivoting/index.js";
8
+ export * from "./pivoting/index.js";
9
+ export * from "./history/index.js";
@@ -1,3 +1,5 @@
1
+ 'use client';
2
+
1
3
  import * as React from 'react';
2
4
  import { GridChartsIntegrationContext } from "../../components/chartsIntegration/GridChartsIntegrationContext.js";
3
5
  export const useGridChartsIntegrationContext = (ignoreError = false) => {
package/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid-premium v8.24.0
2
+ * @mui/x-data-grid-premium v8.26.0
3
3
  *
4
4
  * @license SEE LICENSE IN LICENSE
5
5
  * This source code is licensed under the SEE LICENSE IN LICENSE license found in the
@@ -1,5 +1,5 @@
1
1
  import { RefObject } from '@mui/x-internals/types';
2
- import { GridCallbackDetails, GridValidRowModel, GridGroupNode, GridEventListener, GridGetRowsError, GridUpdateRowError, type GridColDef, GridLocaleTextApi } from '@mui/x-data-grid-pro';
2
+ import { GridCallbackDetails, GridValidRowModel, GridGroupNode, GridEventListener, GridGetRowsError, GridUpdateRowError, type GridColDef, GridLocaleTextApi, type GridEvents } from '@mui/x-data-grid-pro';
3
3
  import { GridExperimentalProFeatures, DataGridProPropsWithDefaultValue, DataGridProPropsWithoutDefaultValue, DataGridPropsWithComplexDefaultValueAfterProcessing, DataGridPropsWithComplexDefaultValueBeforeProcessing, DataGridPremiumSharedPropsWithDefaultValue } from '@mui/x-data-grid-pro/internals';
4
4
  import type { GridRowGroupingModel } from "../hooks/features/rowGrouping/index.js";
5
5
  import type { GridAggregationModel, GridAggregationFunction, GridAggregationFunctionDataSource, GridAggregationPosition } from "../hooks/features/aggregation/index.js";
@@ -11,6 +11,7 @@ import { GridCellSelectionModel } from "../hooks/features/cellSelection/index.js
11
11
  import type { GridPivotingColDefOverrides, PivotingColDefCallback, GridPivotModel } from "../hooks/features/pivoting/gridPivotingInterfaces.js";
12
12
  import { GridDataSourcePremium as GridDataSource, GridGetRowsParamsPremium as GridGetRowsParams } from "../hooks/features/dataSource/models.js";
13
13
  import { Conversation, PromptResponse, PromptSuggestion } from "../hooks/features/aiAssistant/gridAiAssistantInterfaces.js";
14
+ import type { GridHistoryEventHandler } from "../hooks/features/history/gridHistoryInterfaces.js";
14
15
  export interface GridExperimentalPremiumFeatures extends GridExperimentalProFeatures {
15
16
  charts?: boolean;
16
17
  }
@@ -101,6 +102,22 @@ export interface DataGridPremiumPropsWithDefaultValue<R extends GridValidRowMode
101
102
  * @default false
102
103
  */
103
104
  chartsIntegration: boolean;
105
+ /**
106
+ * The maximum size of the history stack.
107
+ * Set to 0 to disable the undo/redo feature.
108
+ * @default 30
109
+ */
110
+ historyStackSize: number;
111
+ /**
112
+ * Map of grid events to their undo/redo handlers.
113
+ * @default Handlers for `rowEditStop`, `cellEditStop` and `clipboardPasteEnd` events
114
+ */
115
+ historyEventHandlers: Record<GridEvents, GridHistoryEventHandler<any>>;
116
+ /**
117
+ * List of grid events after which the history stack items should be re-validated.
118
+ * @default ['columnsChange', 'rowsSet', 'sortedRowsSet', 'filteredRowsSet', 'paginationModelChange']
119
+ */
120
+ historyValidationEvents: GridEvents[];
104
121
  }
105
122
  export interface DataGridPremiumPropsWithoutDefaultValue<R extends GridValidRowModel = any> extends Omit<DataGridProPropsWithoutDefaultValue<R>, 'initialState' | 'apiRef' | 'dataSource' | 'onDataSourceError'> {
106
123
  /**
@@ -292,4 +309,12 @@ export interface DataGridPremiumPropsWithoutDefaultValue<R extends GridValidRowM
292
309
  * @param {string} activeChartId The new active chart id.
293
310
  */
294
311
  onActiveChartIdChange?: (activeChartId: string) => void;
312
+ /**
313
+ * Callback fired when an undo operation is executed.
314
+ */
315
+ onUndo?: GridEventListener<'undo'>;
316
+ /**
317
+ * Callback fired when a redo operation is executed.
318
+ */
319
+ onRedo?: GridEventListener<'redo'>;
295
320
  }
@@ -11,9 +11,10 @@ import type { GridPivotingApi, GridPivotingPrivateApi } from "../hooks/features/
11
11
  import { GridAiAssistantApi } from "../hooks/features/aiAssistant/gridAiAssistantInterfaces.js";
12
12
  import { GridSidebarApi } from "../hooks/features/sidebar/gridSidebarInterfaces.js";
13
13
  import { GridChartsIntegrationApi, GridChartsIntegrationPrivateApi } from "../hooks/features/chartsIntegration/gridChartsIntegrationInterfaces.js";
14
+ import type { GridHistoryApi } from "../hooks/features/history/gridHistoryInterfaces.js";
14
15
  /**
15
16
  * The api of Data Grid Premium.
16
17
  * TODO: Do not redefine manually the pro features
17
18
  */
18
- export interface GridApiPremium extends GridApiCommon<GridStatePremium, GridInitialStatePremium>, GridRowProApi, GridColumnPinningApi, GridDetailPanelApi, GridRowGroupingApi, GridExcelExportApi, GridAggregationApi, GridRowPinningApi, GridDataSourceApiPremium, GridCellSelectionApi, GridPivotingApi, GridAiAssistantApi, GridSidebarApi, GridChartsIntegrationApi, GridRowMultiSelectionApi, GridColumnReorderApi {}
19
+ export interface GridApiPremium extends GridApiCommon<GridStatePremium, GridInitialStatePremium>, GridRowProApi, GridColumnPinningApi, GridDetailPanelApi, GridRowGroupingApi, GridExcelExportApi, GridAggregationApi, GridRowPinningApi, GridDataSourceApiPremium, GridCellSelectionApi, GridPivotingApi, GridAiAssistantApi, GridSidebarApi, GridChartsIntegrationApi, GridHistoryApi, GridRowMultiSelectionApi, GridColumnReorderApi {}
19
20
  export interface GridPrivateApiPremium extends GridApiPremium, GridPrivateOnlyApiCommon<GridApiPremium, GridPrivateApiPremium, DataGridPremiumProcessedProps>, GridDataSourcePremiumPrivateApi, GridAggregationPrivateApi, GridDetailPanelPrivateApi, GridRowReorderPrivateApi, GridPivotingPrivateApi, GridChartsIntegrationPrivateApi {}
@@ -4,6 +4,7 @@ import type { GridPivotingInitialState, GridPivotingState } from "../hooks/featu
4
4
  import type { GridAiAssistantInitialState, GridAiAssistantState } from "../hooks/features/aiAssistant/gridAiAssistantInterfaces.js";
5
5
  import type { GridSidebarInitialState, GridSidebarState } from "../hooks/features/sidebar/gridSidebarState.js";
6
6
  import type { GridChartsIntegrationState, GridChartsIntegrationInitialState } from "../hooks/features/chartsIntegration/gridChartsIntegrationInterfaces.js";
7
+ import type { GridHistoryState } from "../hooks/features/history/gridHistoryInterfaces.js";
7
8
  /**
8
9
  * The state of Data Grid Premium.
9
10
  */
@@ -15,6 +16,7 @@ export interface GridStatePremium extends GridStatePro {
15
16
  aiAssistant: GridAiAssistantState;
16
17
  sidebar: GridSidebarState;
17
18
  chartsIntegration: GridChartsIntegrationState;
19
+ history: GridHistoryState;
18
20
  }
19
21
  /**
20
22
  * The initial state of Data Grid Premium.
@@ -1,4 +1,4 @@
1
- import type { GridExportDisplayOptions, GridValidRowModel } from '@mui/x-data-grid-pro';
1
+ import { GridEventLookup, GridExportDisplayOptions, GridRowId, GridValidRowModel } from '@mui/x-data-grid-pro';
2
2
  import type { GridAggregationCellMeta } from '@mui/x-data-grid-pro/internals';
3
3
  import type { GridPipeProcessingLookupPro, GridControlledStateEventLookupPro, GridApiCachesPro, GridEventLookupPro } from '@mui/x-data-grid-pro/typeOverloads';
4
4
  import type { GridGroupingValueGetter, GridGroupingValueSetter, GridPastedValueParser } from "../models/index.js";
@@ -79,7 +79,12 @@ interface GridEventLookupPremium extends GridEventLookupPro {
79
79
  /**
80
80
  * Fired when the clipboard paste operation ends.
81
81
  */
82
- clipboardPasteEnd: {};
82
+ clipboardPasteEnd: {
83
+ params: {
84
+ oldRows: Map<GridRowId, GridValidRowModel>;
85
+ newRows: Map<GridRowId, GridValidRowModel>;
86
+ };
87
+ };
83
88
  /**
84
89
  * Fired when the sidebar is opened.
85
90
  */
@@ -105,6 +110,24 @@ interface GridEventLookupPremium extends GridEventLookupPro {
105
110
  synced: boolean;
106
111
  };
107
112
  };
113
+ /**
114
+ * Fired when an undo operation is executed.
115
+ */
116
+ undo: {
117
+ params: {
118
+ eventName: keyof GridEventLookup;
119
+ data: any;
120
+ };
121
+ };
122
+ /**
123
+ * Fired when a redo operation is executed.
124
+ */
125
+ redo: {
126
+ params: {
127
+ eventName: keyof GridEventLookup;
128
+ data: any;
129
+ };
130
+ };
108
131
  }
109
132
  export interface GridColDefPremium<R extends GridValidRowModel = any, V = any, F = V> {
110
133
  /**
@@ -1 +1,5 @@
1
- export {};
1
+ import { GridEventLookup } from '@mui/x-data-grid-pro';
2
+
3
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
4
+
5
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -1,4 +1,5 @@
1
1
  "use strict";
2
+ 'use client';
2
3
 
3
4
  var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
4
5
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
@@ -61,7 +61,7 @@ async function getTextFromClipboard(rootEl) {
61
61
 
62
62
  // Keeps track of updated rows during clipboard paste
63
63
  class CellValueUpdater {
64
- rowsToUpdate = {};
64
+ rowsToUpdate = new Map();
65
65
  constructor(options) {
66
66
  this.options = options;
67
67
  this.updateRow = batchRowUpdates(options.apiRef.current.updateRows, 50);
@@ -82,7 +82,7 @@ class CellValueUpdater {
82
82
  if (!colDef || !colDef.editable) {
83
83
  return;
84
84
  }
85
- const row = this.rowsToUpdate[rowId] || (0, _extends2.default)({}, apiRef.current.getRow(rowId));
85
+ const row = this.rowsToUpdate.get(rowId) || (0, _extends2.default)({}, apiRef.current.getRow(rowId));
86
86
  if (!row) {
87
87
  return;
88
88
  }
@@ -112,7 +112,7 @@ class CellValueUpdater {
112
112
  // We cannot update row id, so this cell value update should be ignored
113
113
  return;
114
114
  }
115
- this.rowsToUpdate[rowId] = rowCopy;
115
+ this.rowsToUpdate.set(rowId, rowCopy);
116
116
  }
117
117
  applyUpdates() {
118
118
  const {
@@ -121,13 +121,20 @@ class CellValueUpdater {
121
121
  onProcessRowUpdateError
122
122
  } = this.options;
123
123
  const rowsToUpdate = this.rowsToUpdate;
124
- const rowIdsToUpdate = Object.keys(rowsToUpdate);
124
+ const rowIdsToUpdate = Array.from(rowsToUpdate.keys());
125
125
  if (rowIdsToUpdate.length === 0) {
126
- apiRef.current.publishEvent('clipboardPasteEnd');
126
+ apiRef.current.publishEvent('clipboardPasteEnd', {
127
+ oldRows: new Map(),
128
+ newRows: new Map()
129
+ });
127
130
  return;
128
131
  }
132
+ const oldRows = new Map();
133
+ const newRows = new Map();
129
134
  const handleRowUpdate = async rowId => {
130
- const newRow = rowsToUpdate[rowId];
135
+ const oldRow = apiRef.current.getRow(rowId);
136
+ const newRow = rowsToUpdate.get(rowId);
137
+ oldRows.set(rowId, oldRow);
131
138
  if (typeof processRowUpdate === 'function') {
132
139
  const handleError = errorThrown => {
133
140
  if (onProcessRowUpdateError) {
@@ -137,15 +144,16 @@ class CellValueUpdater {
137
144
  }
138
145
  };
139
146
  try {
140
- const oldRow = apiRef.current.getRow(rowId);
141
147
  const finalRowUpdate = await processRowUpdate(newRow, oldRow, {
142
148
  rowId
143
149
  });
150
+ newRows.set(rowId, finalRowUpdate);
144
151
  this.updateRow(finalRowUpdate);
145
152
  } catch (error) {
146
153
  handleError(error);
147
154
  }
148
155
  } else {
156
+ newRows.set(rowId, newRow);
149
157
  this.updateRow(newRow);
150
158
  }
151
159
  };
@@ -157,8 +165,11 @@ class CellValueUpdater {
157
165
  });
158
166
  });
159
167
  Promise.all(promises).then(() => {
160
- this.rowsToUpdate = {};
161
- apiRef.current.publishEvent('clipboardPasteEnd');
168
+ apiRef.current.publishEvent('clipboardPasteEnd', {
169
+ oldRows,
170
+ newRows
171
+ });
172
+ this.rowsToUpdate.clear();
162
173
  });
163
174
  }
164
175
  }
@@ -0,0 +1,2 @@
1
+ import type { GridEvents } from '@mui/x-data-grid-pro';
2
+ export declare const DEFAULT_HISTORY_VALIDATION_EVENTS: GridEvents[];
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.DEFAULT_HISTORY_VALIDATION_EVENTS = void 0;
7
+ const DEFAULT_HISTORY_VALIDATION_EVENTS = exports.DEFAULT_HISTORY_VALIDATION_EVENTS = ['columnsChange', 'rowsSet', 'sortedRowsSet', 'filteredRowsSet', 'paginationModelChange'];
@@ -0,0 +1,20 @@
1
+ import { RefObject } from '@mui/x-internals/types';
2
+ import type { GridApiPremium } from "../../../models/gridApiPremium.js";
3
+ import type { DataGridPremiumProcessedProps } from "../../../models/dataGridPremiumProps.js";
4
+ import type { GridHistoryEventHandler, GridCellEditHistoryData, GridRowEditHistoryData, GridClipboardPasteHistoryData } from "./gridHistoryInterfaces.js";
5
+ /**
6
+ * Create the default handler for cellEditStop events.
7
+ */
8
+ export declare const createCellEditHistoryHandler: (apiRef: RefObject<GridApiPremium>) => GridHistoryEventHandler<GridCellEditHistoryData>;
9
+ /**
10
+ * Create the default handler for rowEditStop events.
11
+ */
12
+ export declare const createRowEditHistoryHandler: (apiRef: RefObject<GridApiPremium>) => GridHistoryEventHandler<GridRowEditHistoryData>;
13
+ /**
14
+ * Create the default handler for clipboardPasteEnd events.
15
+ */
16
+ export declare const createClipboardPasteHistoryHandler: (apiRef: RefObject<GridApiPremium>) => GridHistoryEventHandler<GridClipboardPasteHistoryData>;
17
+ /**
18
+ * Create the default history events map.
19
+ */
20
+ export declare const createDefaultHistoryHandlers: (apiRef: RefObject<GridApiPremium>, props: Pick<DataGridPremiumProcessedProps, "columns" | "isCellEditable" | "dataSource">) => Record<keyof import("@mui/x-data-grid").GridEventLookup, GridHistoryEventHandler<GridCellEditHistoryData> | GridHistoryEventHandler<GridRowEditHistoryData> | GridHistoryEventHandler<GridClipboardPasteHistoryData>>;