@mui/x-data-grid-premium 7.0.0-beta.7 → 7.1.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 +266 -12
- package/DataGridPremium/DataGridPremium.js +26 -17
- package/README.md +1 -1
- package/esm/DataGridPremium/DataGridPremium.js +26 -17
- package/esm/components/GridAggregationHeader.js +1 -2
- package/esm/components/GridColumnMenuAggregationItem.js +2 -3
- package/esm/components/GridColumnMenuRowGroupItem.js +1 -2
- package/esm/components/GridColumnMenuRowUngroupItem.js +1 -2
- package/esm/components/GridExcelExportMenuItem.js +1 -1
- package/esm/components/GridGroupingColumnLeafCell.js +1 -2
- package/esm/components/GridGroupingCriteriaCell.js +2 -3
- package/esm/hooks/features/aggregation/gridAggregationUtils.js +4 -4
- package/esm/hooks/features/aggregation/useGridAggregation.js +1 -2
- package/esm/hooks/features/aggregation/useGridAggregationPreProcessors.js +1 -2
- package/esm/hooks/features/aggregation/wrapColumnWithAggregation.js +5 -9
- package/esm/hooks/features/cellSelection/useGridCellSelection.js +13 -21
- package/esm/hooks/features/clipboard/useGridClipboardImport.js +21 -8
- package/esm/hooks/features/export/serializer/excelSerializer.js +9 -22
- package/esm/hooks/features/export/useGridExcelExport.js +9 -11
- package/esm/hooks/features/rowGrouping/createGroupingColDef.js +23 -32
- package/esm/hooks/features/rowGrouping/gridRowGroupingUtils.js +4 -7
- package/esm/hooks/features/rowGrouping/useGridRowGrouping.js +5 -9
- package/esm/hooks/utils/useKeepGroupedColumnsHidden.js +7 -9
- package/esm/utils/releaseInfo.js +1 -1
- package/hooks/features/cellSelection/useGridCellSelection.js +2 -1
- package/hooks/features/clipboard/useGridClipboardImport.d.ts +1 -1
- package/hooks/features/clipboard/useGridClipboardImport.js +18 -3
- package/hooks/features/rowGrouping/createGroupingColDef.js +3 -2
- package/index.js +1 -1
- package/models/dataGridPremiumProps.d.ts +12 -2
- package/modern/DataGridPremium/DataGridPremium.js +26 -17
- package/modern/hooks/features/cellSelection/useGridCellSelection.js +2 -1
- package/modern/hooks/features/clipboard/useGridClipboardImport.js +19 -4
- package/modern/hooks/features/rowGrouping/createGroupingColDef.js +3 -2
- package/modern/index.js +1 -1
- package/modern/utils/releaseInfo.js +1 -1
- package/package.json +7 -7
- package/utils/releaseInfo.js +1 -1
|
@@ -18,7 +18,6 @@ const useUtilityClasses = ownerState => {
|
|
|
18
18
|
return composeClasses(slots, getDataGridUtilityClass, classes);
|
|
19
19
|
};
|
|
20
20
|
export function GridGroupingCriteriaCell(props) {
|
|
21
|
-
var _filteredDescendantCo, _rootProps$slotProps;
|
|
22
21
|
const {
|
|
23
22
|
id,
|
|
24
23
|
field,
|
|
@@ -33,7 +32,7 @@ export function GridGroupingCriteriaCell(props) {
|
|
|
33
32
|
};
|
|
34
33
|
const classes = useUtilityClasses(ownerState);
|
|
35
34
|
const filteredDescendantCountLookup = useGridSelector(apiRef, gridFilteredDescendantCountLookupSelector);
|
|
36
|
-
const filteredDescendantCount =
|
|
35
|
+
const filteredDescendantCount = filteredDescendantCountLookup[rowNode.id] ?? 0;
|
|
37
36
|
const Icon = rowNode.childrenExpanded ? rootProps.slots.groupingCriteriaCollapseIcon : rootProps.slots.groupingCriteriaExpandIcon;
|
|
38
37
|
const handleKeyDown = event => {
|
|
39
38
|
if (event.key === ' ') {
|
|
@@ -74,7 +73,7 @@ export function GridGroupingCriteriaCell(props) {
|
|
|
74
73
|
onKeyDown: handleKeyDown,
|
|
75
74
|
tabIndex: -1,
|
|
76
75
|
"aria-label": rowNode.childrenExpanded ? apiRef.current.getLocaleText('treeDataCollapse') : apiRef.current.getLocaleText('treeDataExpand')
|
|
77
|
-
},
|
|
76
|
+
}, rootProps.slotProps?.baseIconButton, {
|
|
78
77
|
children: /*#__PURE__*/_jsx(Icon, {
|
|
79
78
|
fontSize: "inherit"
|
|
80
79
|
})
|
|
@@ -143,18 +143,18 @@ export const addFooterRows = ({
|
|
|
143
143
|
* Compares two sets of aggregation rules to determine if they are equal or not.
|
|
144
144
|
*/
|
|
145
145
|
export const areAggregationRulesEqual = (previousValue, newValue) => {
|
|
146
|
-
const previousFields = Object.keys(previousValue
|
|
146
|
+
const previousFields = Object.keys(previousValue ?? {});
|
|
147
147
|
const newFields = Object.keys(newValue);
|
|
148
148
|
if (!isDeepEqual(previousFields, newFields)) {
|
|
149
149
|
return false;
|
|
150
150
|
}
|
|
151
151
|
return newFields.every(field => {
|
|
152
|
-
const previousRule = previousValue
|
|
152
|
+
const previousRule = previousValue?.[field];
|
|
153
153
|
const newRule = newValue[field];
|
|
154
|
-
if (
|
|
154
|
+
if (previousRule?.aggregationFunction !== newRule?.aggregationFunction) {
|
|
155
155
|
return false;
|
|
156
156
|
}
|
|
157
|
-
if (
|
|
157
|
+
if (previousRule?.aggregationFunctionName !== newRule?.aggregationFunctionName) {
|
|
158
158
|
return false;
|
|
159
159
|
}
|
|
160
160
|
return true;
|
|
@@ -5,14 +5,13 @@ import { gridAggregationModelSelector } from './gridAggregationSelectors';
|
|
|
5
5
|
import { getAggregationRules, mergeStateWithAggregationModel, areAggregationRulesEqual } from './gridAggregationUtils';
|
|
6
6
|
import { createAggregationLookup } from './createAggregationLookup';
|
|
7
7
|
export const aggregationStateInitializer = (state, props, apiRef) => {
|
|
8
|
-
var _ref, _props$aggregationMod, _props$initialState;
|
|
9
8
|
apiRef.current.caches.aggregation = {
|
|
10
9
|
rulesOnLastColumnHydration: {},
|
|
11
10
|
rulesOnLastRowHydration: {}
|
|
12
11
|
};
|
|
13
12
|
return _extends({}, state, {
|
|
14
13
|
aggregation: {
|
|
15
|
-
model:
|
|
14
|
+
model: props.aggregationModel ?? props.initialState?.aggregation?.model ?? {}
|
|
16
15
|
}
|
|
17
16
|
});
|
|
18
17
|
};
|
|
@@ -85,11 +85,10 @@ export const useGridAggregationPreProcessors = (apiRef, props) => {
|
|
|
85
85
|
});
|
|
86
86
|
}, [apiRef, props.disableAggregation]);
|
|
87
87
|
const stateRestorePreProcessing = React.useCallback((params, context) => {
|
|
88
|
-
var _context$stateToResto;
|
|
89
88
|
if (props.disableAggregation) {
|
|
90
89
|
return params;
|
|
91
90
|
}
|
|
92
|
-
const aggregationModel =
|
|
91
|
+
const aggregationModel = context.stateToRestore.aggregation?.model;
|
|
93
92
|
if (aggregationModel != null) {
|
|
94
93
|
apiRef.current.setState(mergeStateWithAggregationModel(aggregationModel));
|
|
95
94
|
}
|
|
@@ -15,8 +15,7 @@ const getAggregationValueWrappedValueGetter = ({
|
|
|
15
15
|
const rowId = apiRef.current.getRowId(row);
|
|
16
16
|
const cellAggregationResult = getCellAggregationResult(rowId, column.field);
|
|
17
17
|
if (cellAggregationResult != null) {
|
|
18
|
-
|
|
19
|
-
return (_cellAggregationResul = cellAggregationResult == null ? void 0 : cellAggregationResult.value) != null ? _cellAggregationResul : null;
|
|
18
|
+
return cellAggregationResult?.value ?? null;
|
|
20
19
|
}
|
|
21
20
|
if (valueGetter) {
|
|
22
21
|
return valueGetter(value, row, column, apiRef);
|
|
@@ -40,8 +39,7 @@ const getAggregationValueWrappedValueFormatter = ({
|
|
|
40
39
|
if (rowId != null) {
|
|
41
40
|
const cellAggregationResult = getCellAggregationResult(rowId, column.field);
|
|
42
41
|
if (cellAggregationResult != null) {
|
|
43
|
-
|
|
44
|
-
return (_aggregationRule$aggr = (_aggregationRule$aggr2 = aggregationRule.aggregationFunction).valueFormatter) == null ? void 0 : _aggregationRule$aggr.call(_aggregationRule$aggr2, {
|
|
42
|
+
return aggregationRule.aggregationFunction.valueFormatter?.({
|
|
45
43
|
id: rowId,
|
|
46
44
|
field: column.field,
|
|
47
45
|
value,
|
|
@@ -64,7 +62,6 @@ const getAggregationValueWrappedRenderCell = ({
|
|
|
64
62
|
const wrappedRenderCell = params => {
|
|
65
63
|
const cellAggregationResult = getCellAggregationResult(params.id, params.field);
|
|
66
64
|
if (cellAggregationResult != null) {
|
|
67
|
-
var _aggregationFunction$;
|
|
68
65
|
if (!renderCell) {
|
|
69
66
|
if (cellAggregationResult.position === 'footer') {
|
|
70
67
|
return /*#__PURE__*/_jsx(GridFooterCell, _extends({}, params));
|
|
@@ -72,7 +69,7 @@ const getAggregationValueWrappedRenderCell = ({
|
|
|
72
69
|
return params.formattedValue;
|
|
73
70
|
}
|
|
74
71
|
const aggregationMeta = {
|
|
75
|
-
hasCellUnit:
|
|
72
|
+
hasCellUnit: aggregationRule.aggregationFunction.hasCellUnit ?? true,
|
|
76
73
|
aggregationFunctionName: aggregationRule.aggregationFunctionName
|
|
77
74
|
};
|
|
78
75
|
return renderCell(_extends({}, params, {
|
|
@@ -140,7 +137,6 @@ export const wrapColumnWithAggregationValue = ({
|
|
|
140
137
|
aggregationRule
|
|
141
138
|
}) => {
|
|
142
139
|
const getCellAggregationResult = (id, field) => {
|
|
143
|
-
var _rowNode$parent, _gridAggregationLooku;
|
|
144
140
|
let cellAggregationPosition = null;
|
|
145
141
|
const rowNode = apiRef.current.getRowNode(id);
|
|
146
142
|
if (rowNode.type === 'group') {
|
|
@@ -153,8 +149,8 @@ export const wrapColumnWithAggregationValue = ({
|
|
|
153
149
|
}
|
|
154
150
|
|
|
155
151
|
// TODO: Add custom root id
|
|
156
|
-
const groupId = cellAggregationPosition === 'inline' ? id :
|
|
157
|
-
const aggregationResult =
|
|
152
|
+
const groupId = cellAggregationPosition === 'inline' ? id : rowNode.parent ?? '';
|
|
153
|
+
const aggregationResult = gridAggregationLookupSelector(apiRef)?.[groupId]?.[field];
|
|
158
154
|
if (!aggregationResult || aggregationResult.position !== cellAggregationPosition) {
|
|
159
155
|
return null;
|
|
160
156
|
}
|
|
@@ -4,12 +4,9 @@ import { ownerDocument, useEventCallback } from '@mui/material/utils';
|
|
|
4
4
|
import { getTotalHeaderHeight, isNavigationKey, serializeCellValue, useGridRegisterPipeProcessor, useGridVisibleRows } from '@mui/x-data-grid-pro/internals';
|
|
5
5
|
import { useGridApiEventHandler, useGridApiMethod, GRID_ACTIONS_COLUMN_TYPE, GRID_CHECKBOX_SELECTION_COL_DEF, GRID_DETAIL_PANEL_TOGGLE_FIELD, gridRowsDataRowIdToIdLookupSelector, gridClasses, gridFocusCellSelector, GRID_REORDER_COL_DEF, useGridSelector, gridSortedRowIdsSelector, gridDimensionsSelector } from '@mui/x-data-grid-pro';
|
|
6
6
|
import { gridCellSelectionStateSelector } from './gridCellSelectionSelector';
|
|
7
|
-
export const cellSelectionStateInitializer = (state, props) => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
cellSelection: _extends({}, (_props$cellSelectionM = props.cellSelectionModel) != null ? _props$cellSelectionM : (_props$initialState = props.initialState) == null ? void 0 : _props$initialState.cellSelection)
|
|
11
|
-
});
|
|
12
|
-
};
|
|
7
|
+
export const cellSelectionStateInitializer = (state, props) => _extends({}, state, {
|
|
8
|
+
cellSelection: _extends({}, props.cellSelectionModel ?? props.initialState?.cellSelection)
|
|
9
|
+
});
|
|
13
10
|
function isKeyboardEvent(event) {
|
|
14
11
|
return !!event.key;
|
|
15
12
|
}
|
|
@@ -26,7 +23,7 @@ export const useGridCellSelection = (apiRef, props) => {
|
|
|
26
23
|
const dimensions = useGridSelector(apiRef, gridDimensionsSelector);
|
|
27
24
|
const totalHeaderHeight = getTotalHeaderHeight(apiRef, props.columnHeaderHeight);
|
|
28
25
|
const ignoreValueFormatterProp = props.ignoreValueFormatterDuringExport;
|
|
29
|
-
const ignoreValueFormatter = (typeof ignoreValueFormatterProp === 'object' ? ignoreValueFormatterProp
|
|
26
|
+
const ignoreValueFormatter = (typeof ignoreValueFormatterProp === 'object' ? ignoreValueFormatterProp?.clipboardExport : ignoreValueFormatterProp) || false;
|
|
30
27
|
const clipboardCopyCellDelimiter = props.clipboardCopyCellDelimiter;
|
|
31
28
|
apiRef.current.registerControlState({
|
|
32
29
|
stateId: 'cellSelection',
|
|
@@ -122,15 +119,13 @@ export const useGridCellSelection = (apiRef, props) => {
|
|
|
122
119
|
return params.rowNode.type !== 'pinnedRow';
|
|
123
120
|
}, [apiRef]);
|
|
124
121
|
const handleMouseUp = useEventCallback(() => {
|
|
125
|
-
var _apiRef$current$rootE;
|
|
126
122
|
lastMouseDownCell.current = null;
|
|
127
|
-
|
|
123
|
+
apiRef.current.rootElementRef?.current?.classList.remove(gridClasses['root--disableUserSelection']);
|
|
128
124
|
|
|
129
125
|
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
130
126
|
stopAutoScroll();
|
|
131
127
|
});
|
|
132
128
|
const handleCellMouseDown = React.useCallback((params, event) => {
|
|
133
|
-
var _apiRef$current$rootE2, _apiRef$current$rootE3;
|
|
134
129
|
// Skip if the click comes from the right-button or, only on macOS, Ctrl is pressed
|
|
135
130
|
// Fix for https://github.com/mui/mui-x/pull/6567#issuecomment-1329155578
|
|
136
131
|
const isMacOs = window.navigator.platform.toUpperCase().indexOf('MAC') >= 0;
|
|
@@ -148,8 +143,8 @@ export const useGridCellSelection = (apiRef, props) => {
|
|
|
148
143
|
id: params.id,
|
|
149
144
|
field: params.field
|
|
150
145
|
};
|
|
151
|
-
|
|
152
|
-
const document = ownerDocument(
|
|
146
|
+
apiRef.current.rootElementRef?.current?.classList.add(gridClasses['root--disableUserSelection']);
|
|
147
|
+
const document = ownerDocument(apiRef.current.rootElementRef?.current);
|
|
153
148
|
document.addEventListener('mouseup', handleMouseUp, {
|
|
154
149
|
once: true
|
|
155
150
|
});
|
|
@@ -167,16 +162,14 @@ export const useGridCellSelection = (apiRef, props) => {
|
|
|
167
162
|
};
|
|
168
163
|
}, []);
|
|
169
164
|
const startAutoScroll = React.useCallback(() => {
|
|
170
|
-
var _apiRef$current$virtu;
|
|
171
165
|
if (autoScrollRAF.current) {
|
|
172
166
|
return;
|
|
173
167
|
}
|
|
174
|
-
if (!
|
|
168
|
+
if (!apiRef.current.virtualScrollerRef?.current) {
|
|
175
169
|
return;
|
|
176
170
|
}
|
|
177
171
|
function autoScroll() {
|
|
178
|
-
|
|
179
|
-
if (!mousePosition.current || !((_apiRef$current$virtu2 = apiRef.current.virtualScrollerRef) != null && _apiRef$current$virtu2.current)) {
|
|
172
|
+
if (!mousePosition.current || !apiRef.current.virtualScrollerRef?.current) {
|
|
180
173
|
return;
|
|
181
174
|
}
|
|
182
175
|
const {
|
|
@@ -222,7 +215,6 @@ export const useGridCellSelection = (apiRef, props) => {
|
|
|
222
215
|
autoScroll();
|
|
223
216
|
}, [apiRef, dimensions]);
|
|
224
217
|
const handleCellMouseOver = React.useCallback((params, event) => {
|
|
225
|
-
var _apiRef$current$virtu3;
|
|
226
218
|
if (!lastMouseDownCell.current) {
|
|
227
219
|
return;
|
|
228
220
|
}
|
|
@@ -234,7 +226,7 @@ export const useGridCellSelection = (apiRef, props) => {
|
|
|
234
226
|
id,
|
|
235
227
|
field
|
|
236
228
|
}, event.ctrlKey || event.metaKey);
|
|
237
|
-
const virtualScrollerRect =
|
|
229
|
+
const virtualScrollerRect = apiRef.current.virtualScrollerRef?.current?.getBoundingClientRect();
|
|
238
230
|
if (!virtualScrollerRect) {
|
|
239
231
|
return;
|
|
240
232
|
}
|
|
@@ -357,8 +349,7 @@ export const useGridCellSelection = (apiRef, props) => {
|
|
|
357
349
|
}
|
|
358
350
|
}, [apiRef, props.cellSelectionModel]);
|
|
359
351
|
React.useEffect(() => {
|
|
360
|
-
|
|
361
|
-
const rootRef = (_apiRef$current$rootE4 = apiRef.current.rootElementRef) == null ? void 0 : _apiRef$current$rootE4.current;
|
|
352
|
+
const rootRef = apiRef.current.rootElementRef?.current;
|
|
362
353
|
return () => {
|
|
363
354
|
stopAutoScroll();
|
|
364
355
|
const document = ownerDocument(rootRef);
|
|
@@ -455,7 +446,8 @@ export const useGridCellSelection = (apiRef, props) => {
|
|
|
455
446
|
const cellParams = apiRef.current.getCellParams(rowId, field);
|
|
456
447
|
cellData = serializeCellValue(cellParams, {
|
|
457
448
|
delimiterCharacter: clipboardCopyCellDelimiter,
|
|
458
|
-
ignoreValueFormatter
|
|
449
|
+
ignoreValueFormatter,
|
|
450
|
+
shouldAppendQuotes: true
|
|
459
451
|
});
|
|
460
452
|
} else {
|
|
461
453
|
cellData = '';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { GRID_CHECKBOX_SELECTION_FIELD, gridFocusCellSelector, gridVisibleColumnFieldsSelector, useGridApiOptionHandler, useGridApiEventHandler, gridPaginatedVisibleSortedGridRowIdsSelector, gridExpandedSortedRowIdsSelector } from '@mui/x-data-grid';
|
|
4
|
-
import { buildWarning, getRowIdFromRowModel, getActiveElement, useGridRegisterPipeProcessor, getPublicApiRef, isPasteShortcut } from '@mui/x-data-grid/internals';
|
|
4
|
+
import { buildWarning, getRowIdFromRowModel, getActiveElement, useGridRegisterPipeProcessor, getPublicApiRef, isPasteShortcut, useGridLogger } from '@mui/x-data-grid/internals';
|
|
5
5
|
import { GRID_DETAIL_PANEL_TOGGLE_FIELD, GRID_REORDER_COL_DEF } from '@mui/x-data-grid-pro';
|
|
6
6
|
import { unstable_debounce as debounce } from '@mui/utils';
|
|
7
|
-
const missingOnProcessRowUpdateErrorWarning = buildWarning(['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,
|
|
7
|
+
const missingOnProcessRowUpdateErrorWarning = buildWarning(['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/#server-side-persistence.'], 'error');
|
|
8
8
|
const columnFieldsToExcludeFromPaste = [GRID_CHECKBOX_SELECTION_FIELD, GRID_REORDER_COL_DEF.field, GRID_DETAIL_PANEL_TOGGLE_FIELD];
|
|
9
9
|
|
|
10
10
|
// Batches rows that are updated during clipboard paste to reduce `updateRows` calls
|
|
@@ -33,9 +33,8 @@ async function getTextFromClipboard(rootEl) {
|
|
|
33
33
|
el.style.top = '0';
|
|
34
34
|
el.style.left = '0';
|
|
35
35
|
const handlePasteEvent = event => {
|
|
36
|
-
var _event$clipboardData;
|
|
37
36
|
el.removeEventListener('paste', handlePasteEvent);
|
|
38
|
-
const text =
|
|
37
|
+
const text = event.clipboardData?.getData('text/plain');
|
|
39
38
|
if (focusedCell instanceof HTMLElement) {
|
|
40
39
|
focusedCell.focus({
|
|
41
40
|
preventScroll: true
|
|
@@ -236,13 +235,17 @@ function defaultPasteResolver({
|
|
|
236
235
|
});
|
|
237
236
|
}
|
|
238
237
|
export const useGridClipboardImport = (apiRef, props) => {
|
|
239
|
-
var _apiRef$current$rootE;
|
|
240
238
|
const processRowUpdate = props.processRowUpdate;
|
|
241
239
|
const onProcessRowUpdateError = props.onProcessRowUpdateError;
|
|
242
240
|
const getRowId = props.getRowId;
|
|
243
241
|
const enableClipboardPaste = !props.disableClipboardPaste;
|
|
244
|
-
const rootEl =
|
|
242
|
+
const rootEl = apiRef.current.rootElementRef?.current;
|
|
243
|
+
const logger = useGridLogger(apiRef, 'useGridClipboardImport');
|
|
245
244
|
const splitClipboardPastedText = props.splitClipboardPastedText;
|
|
245
|
+
const {
|
|
246
|
+
pagination,
|
|
247
|
+
onBeforeClipboardPasteStart
|
|
248
|
+
} = props;
|
|
246
249
|
const handlePaste = React.useCallback(async (params, event) => {
|
|
247
250
|
if (!enableClipboardPaste) {
|
|
248
251
|
return;
|
|
@@ -269,6 +272,16 @@ export const useGridClipboardImport = (apiRef, props) => {
|
|
|
269
272
|
if (!pastedData) {
|
|
270
273
|
return;
|
|
271
274
|
}
|
|
275
|
+
if (onBeforeClipboardPasteStart) {
|
|
276
|
+
try {
|
|
277
|
+
await onBeforeClipboardPasteStart({
|
|
278
|
+
data: pastedData
|
|
279
|
+
});
|
|
280
|
+
} catch (error) {
|
|
281
|
+
logger.debug('Clipboard paste operation cancelled');
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
272
285
|
const cellUpdater = new CellValueUpdater({
|
|
273
286
|
apiRef,
|
|
274
287
|
processRowUpdate,
|
|
@@ -284,10 +297,10 @@ export const useGridClipboardImport = (apiRef, props) => {
|
|
|
284
297
|
updateCell: (...args) => {
|
|
285
298
|
cellUpdater.updateCell(...args);
|
|
286
299
|
},
|
|
287
|
-
pagination
|
|
300
|
+
pagination
|
|
288
301
|
});
|
|
289
302
|
cellUpdater.applyUpdates();
|
|
290
|
-
}, [apiRef, processRowUpdate, onProcessRowUpdateError, getRowId, enableClipboardPaste, rootEl, splitClipboardPastedText,
|
|
303
|
+
}, [apiRef, processRowUpdate, onProcessRowUpdateError, getRowId, enableClipboardPaste, rootEl, splitClipboardPastedText, pagination, onBeforeClipboardPasteStart, logger]);
|
|
291
304
|
const checkIfCanStartEditing = React.useCallback((initialValue, {
|
|
292
305
|
event
|
|
293
306
|
}) => {
|
|
@@ -2,9 +2,8 @@ import _extends from "@babel/runtime/helpers/esm/extends";
|
|
|
2
2
|
import { GRID_DATE_COL_DEF, GRID_DATETIME_COL_DEF } from '@mui/x-data-grid-pro';
|
|
3
3
|
import { buildWarning, isObject, isSingleSelectColDef } from '@mui/x-data-grid/internals';
|
|
4
4
|
const getExcelJs = async () => {
|
|
5
|
-
var _excelJsModule$defaul;
|
|
6
5
|
const excelJsModule = await import('exceljs');
|
|
7
|
-
return
|
|
6
|
+
return excelJsModule.default ?? excelJsModule;
|
|
8
7
|
};
|
|
9
8
|
const warnInvalidFormattedValue = buildWarning(['MUI X: When the value of a field is an object or a `renderCell` is provided, the Excel export might not display the value correctly.', 'You can provide a `valueFormatter` with a string representation to be used.']);
|
|
10
9
|
const getFormattedValueOptions = (colDef, row, valueOptions, api) => {
|
|
@@ -85,7 +84,7 @@ export const serializeRow = (id, columns, api, defaultValueOptionsFormulae) => {
|
|
|
85
84
|
}
|
|
86
85
|
}
|
|
87
86
|
if (isObject(formattedValue)) {
|
|
88
|
-
row[castColumn.field] = formattedValue
|
|
87
|
+
row[castColumn.field] = formattedValue?.label;
|
|
89
88
|
} else {
|
|
90
89
|
row[castColumn.field] = formattedValue;
|
|
91
90
|
}
|
|
@@ -138,28 +137,24 @@ const defaultColumnsStyles = {
|
|
|
138
137
|
}
|
|
139
138
|
};
|
|
140
139
|
export const serializeColumn = (column, columnsStyles) => {
|
|
141
|
-
var _column$headerName;
|
|
142
140
|
const {
|
|
143
141
|
field,
|
|
144
142
|
type
|
|
145
143
|
} = column;
|
|
146
144
|
return {
|
|
147
145
|
key: field,
|
|
148
|
-
headerText:
|
|
146
|
+
headerText: column.headerName ?? column.field,
|
|
149
147
|
// Excel width must stay between 0 and 255 (https://support.microsoft.com/en-us/office/change-the-column-width-and-row-height-72f5e3cc-994d-43e8-ae58-9774a0905f46)
|
|
150
148
|
// From the example of column width behavior (https://docs.microsoft.com/en-US/office/troubleshoot/excel/determine-column-widths#example-of-column-width-behavior)
|
|
151
149
|
// a value of 10 corresponds to 75px. This is an approximation, because column width depends on the font-size
|
|
152
150
|
width: Math.min(255, column.width ? column.width / 7.5 : 8.43),
|
|
153
|
-
style: _extends({}, type &&
|
|
151
|
+
style: _extends({}, type && defaultColumnsStyles?.[type], columnsStyles?.[field])
|
|
154
152
|
};
|
|
155
153
|
};
|
|
156
154
|
const addColumnGroupingHeaders = (worksheet, columns, columnGroupPaths, columnGroupDetails) => {
|
|
157
155
|
const maxDepth = Math.max(...columns.map(({
|
|
158
156
|
key
|
|
159
|
-
}) =>
|
|
160
|
-
var _columnGroupPaths$key, _columnGroupPaths$key2;
|
|
161
|
-
return (_columnGroupPaths$key = (_columnGroupPaths$key2 = columnGroupPaths[key]) == null ? void 0 : _columnGroupPaths$key2.length) != null ? _columnGroupPaths$key : 0;
|
|
162
|
-
}));
|
|
157
|
+
}) => columnGroupPaths[key]?.length ?? 0));
|
|
163
158
|
if (maxDepth === 0) {
|
|
164
159
|
return;
|
|
165
160
|
}
|
|
@@ -178,10 +173,7 @@ const addColumnGroupingHeaders = (worksheet, columns, columnGroupPaths, columnGr
|
|
|
178
173
|
parents: groupingPath.slice(0, rowIndex)
|
|
179
174
|
});
|
|
180
175
|
});
|
|
181
|
-
const newRow = worksheet.addRow(row.map(group =>
|
|
182
|
-
var _group$headerName;
|
|
183
|
-
return group.groupId === null ? null : (_group$headerName = group == null ? void 0 : group.headerName) != null ? _group$headerName : group.groupId;
|
|
184
|
-
}));
|
|
176
|
+
const newRow = worksheet.addRow(row.map(group => group.groupId === null ? null : group?.headerName ?? group.groupId));
|
|
185
177
|
|
|
186
178
|
// use `rowCount`, since worksheet can have additional rows added in `exceljsPreProcess`
|
|
187
179
|
const lastRowIndex = newRow.worksheet.rowCount;
|
|
@@ -226,10 +218,9 @@ export async function getDataForValueOptionsSheet(columns, valueOptionsSheetName
|
|
|
226
218
|
key: column.field
|
|
227
219
|
}));
|
|
228
220
|
return candidateColumns.reduce((acc, column) => {
|
|
229
|
-
var _column$headerName2;
|
|
230
221
|
const singleSelectColumn = column;
|
|
231
222
|
const formattedValueOptions = getFormattedValueOptions(singleSelectColumn, {}, singleSelectColumn.valueOptions, api);
|
|
232
|
-
const header =
|
|
223
|
+
const header = column.headerName ?? column.field;
|
|
233
224
|
const values = [header, ...formattedValueOptions];
|
|
234
225
|
const letter = worksheet.getColumn(column.field).letter;
|
|
235
226
|
const address = `${valueOptionsSheetName}!$${letter}$2:$${letter}$${values.length}`;
|
|
@@ -305,10 +296,7 @@ export async function buildExcel(options, api) {
|
|
|
305
296
|
addColumnGroupingHeaders(worksheet, serializedColumns, columnGroupPaths, api.getAllGroupDetails());
|
|
306
297
|
}
|
|
307
298
|
if (includeHeaders) {
|
|
308
|
-
worksheet.addRow(columns.map(column =>
|
|
309
|
-
var _column$headerName3;
|
|
310
|
-
return (_column$headerName3 = column.headerName) != null ? _column$headerName3 : column.field;
|
|
311
|
-
}));
|
|
299
|
+
worksheet.addRow(columns.map(column => column.headerName ?? column.field));
|
|
312
300
|
}
|
|
313
301
|
const valueOptionsData = await getDataForValueOptionsSheet(columns, valueOptionsSheetName, api);
|
|
314
302
|
createValueOptionsSheetIfNeeded(valueOptionsData, valueOptionsSheetName, workbook);
|
|
@@ -327,7 +315,6 @@ export async function buildExcel(options, api) {
|
|
|
327
315
|
export function setupExcelExportWebWorker(workerOptions = {}) {
|
|
328
316
|
// eslint-disable-next-line no-restricted-globals
|
|
329
317
|
addEventListener('message', async event => {
|
|
330
|
-
var _options$includeHeade;
|
|
331
318
|
const {
|
|
332
319
|
serializedColumns,
|
|
333
320
|
serializedRows,
|
|
@@ -354,7 +341,7 @@ export function setupExcelExportWebWorker(workerOptions = {}) {
|
|
|
354
341
|
if (options.includeColumnGroupsHeaders) {
|
|
355
342
|
addColumnGroupingHeaders(worksheet, serializedColumns, columnGroupPaths, columnGroupDetails);
|
|
356
343
|
}
|
|
357
|
-
const includeHeaders =
|
|
344
|
+
const includeHeaders = options.includeHeaders ?? true;
|
|
358
345
|
if (includeHeaders) {
|
|
359
346
|
worksheet.addRow(serializedColumns.map(column => column.headerText));
|
|
360
347
|
}
|
|
@@ -17,9 +17,8 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
17
17
|
export const useGridExcelExport = (apiRef, props) => {
|
|
18
18
|
const logger = useGridLogger(apiRef, 'useGridExcelExport');
|
|
19
19
|
const getDataAsExcel = React.useCallback((options = {}) => {
|
|
20
|
-
var _options$getRowsToExp, _options$includeHeade, _options$includeColum;
|
|
21
20
|
logger.debug(`Get data as excel`);
|
|
22
|
-
const getRowsToExport =
|
|
21
|
+
const getRowsToExport = options.getRowsToExport ?? defaultGetRowsToExport;
|
|
23
22
|
const exportedRowIds = getRowsToExport({
|
|
24
23
|
apiRef
|
|
25
24
|
});
|
|
@@ -30,12 +29,12 @@ export const useGridExcelExport = (apiRef, props) => {
|
|
|
30
29
|
return buildExcel({
|
|
31
30
|
columns: exportedColumns,
|
|
32
31
|
rowIds: exportedRowIds,
|
|
33
|
-
includeHeaders:
|
|
34
|
-
includeColumnGroupsHeaders:
|
|
35
|
-
valueOptionsSheetName:
|
|
36
|
-
columnsStyles: options
|
|
37
|
-
exceljsPreProcess: options
|
|
38
|
-
exceljsPostProcess: options
|
|
32
|
+
includeHeaders: options.includeHeaders ?? true,
|
|
33
|
+
includeColumnGroupsHeaders: options.includeColumnGroupsHeaders ?? true,
|
|
34
|
+
valueOptionsSheetName: options?.valueOptionsSheetName || 'Options',
|
|
35
|
+
columnsStyles: options?.columnsStyles,
|
|
36
|
+
exceljsPreProcess: options?.exceljsPreProcess,
|
|
37
|
+
exceljsPostProcess: options?.exceljsPostProcess
|
|
39
38
|
}, apiRef.current);
|
|
40
39
|
}, [logger, apiRef]);
|
|
41
40
|
const exportDataAsExcel = React.useCallback(async (options = {}) => {
|
|
@@ -51,7 +50,7 @@ export const useGridExcelExport = (apiRef, props) => {
|
|
|
51
50
|
const blob = new Blob([buffer], {
|
|
52
51
|
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
|
53
52
|
});
|
|
54
|
-
exportAs(blob, 'xlsx', options
|
|
53
|
+
exportAs(blob, 'xlsx', options?.fileName);
|
|
55
54
|
};
|
|
56
55
|
if (!workerFn) {
|
|
57
56
|
apiRef.current.publishEvent('excelExportStateChange', 'pending');
|
|
@@ -114,8 +113,7 @@ export const useGridExcelExport = (apiRef, props) => {
|
|
|
114
113
|
* PRE-PROCESSING
|
|
115
114
|
*/
|
|
116
115
|
const addExportMenuButtons = React.useCallback((initialValue, options) => {
|
|
117
|
-
|
|
118
|
-
if ((_options$excelOptions = options.excelOptions) != null && _options$excelOptions.disableToolbarButton) {
|
|
116
|
+
if (options.excelOptions?.disableToolbarButton) {
|
|
119
117
|
return initialValue;
|
|
120
118
|
}
|
|
121
119
|
return [...initialValue, {
|
|
@@ -26,10 +26,9 @@ const GROUPING_COL_DEF_FORCED_PROPERTIES = {
|
|
|
26
26
|
* TODO: Make this index comparator depth invariant, the logic should not be inverted when sorting in the "desc" direction (but the current return format of `sortComparator` does not support this behavior).
|
|
27
27
|
*/
|
|
28
28
|
const groupingFieldIndexComparator = (v1, v2, cellParams1, cellParams2) => {
|
|
29
|
-
var _groupingField, _groupingField2;
|
|
30
29
|
const model = gridRowGroupingSanitizedModelSelector(cellParams1.api.state, cellParams1.api.instanceId);
|
|
31
|
-
const groupingField1 =
|
|
32
|
-
const groupingField2 =
|
|
30
|
+
const groupingField1 = cellParams1.rowNode.groupingField ?? null;
|
|
31
|
+
const groupingField2 = cellParams2.rowNode.groupingField ?? null;
|
|
33
32
|
if (groupingField1 === groupingField2) {
|
|
34
33
|
return 0;
|
|
35
34
|
}
|
|
@@ -44,23 +43,20 @@ const groupingFieldIndexComparator = (v1, v2, cellParams1, cellParams2) => {
|
|
|
44
43
|
}
|
|
45
44
|
return 1;
|
|
46
45
|
};
|
|
47
|
-
const getLeafProperties = leafColDef => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if (cellParams1.rowNode.type === 'leaf' && cellParams2.rowNode.type === 'leaf') {
|
|
58
|
-
return leafColDef.sortComparator(v1, v2, cellParams1, cellParams2);
|
|
59
|
-
}
|
|
60
|
-
return groupingFieldIndexComparator(v1, v2, cellParams1, cellParams2);
|
|
46
|
+
const getLeafProperties = leafColDef => ({
|
|
47
|
+
headerName: leafColDef.headerName ?? leafColDef.field,
|
|
48
|
+
sortable: leafColDef.sortable,
|
|
49
|
+
filterable: leafColDef.filterable,
|
|
50
|
+
valueOptions: isSingleSelectColDef(leafColDef) ? leafColDef.valueOptions : undefined,
|
|
51
|
+
filterOperators: leafColDef.filterOperators,
|
|
52
|
+
sortComparator: (v1, v2, cellParams1, cellParams2) => {
|
|
53
|
+
// We only want to sort the leaves
|
|
54
|
+
if (cellParams1.rowNode.type === 'leaf' && cellParams2.rowNode.type === 'leaf') {
|
|
55
|
+
return leafColDef.sortComparator(v1, v2, cellParams1, cellParams2);
|
|
61
56
|
}
|
|
62
|
-
|
|
63
|
-
}
|
|
57
|
+
return groupingFieldIndexComparator(v1, v2, cellParams1, cellParams2);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
64
60
|
const getGroupingCriteriaProperties = (groupedByColDef, applyHeaderName) => {
|
|
65
61
|
const properties = {
|
|
66
62
|
sortable: groupedByColDef.sortable,
|
|
@@ -68,16 +64,16 @@ const getGroupingCriteriaProperties = (groupedByColDef, applyHeaderName) => {
|
|
|
68
64
|
valueOptions: isSingleSelectColDef(groupedByColDef) ? groupedByColDef.valueOptions : undefined,
|
|
69
65
|
sortComparator: (v1, v2, cellParams1, cellParams2) => {
|
|
70
66
|
// We only want to sort the groups of the current grouping criteria
|
|
71
|
-
if (cellParams1.rowNode.type === 'group' &&
|
|
72
|
-
|
|
67
|
+
if (cellParams1.rowNode.type === 'group' && cellParams2.rowNode.type === 'group' && cellParams1.rowNode.groupingField === cellParams2.rowNode.groupingField) {
|
|
68
|
+
const colDef = cellParams1.api.getColumn(cellParams1.rowNode.groupingField);
|
|
69
|
+
return colDef.sortComparator(v1, v2, cellParams1, cellParams2);
|
|
73
70
|
}
|
|
74
71
|
return groupingFieldIndexComparator(v1, v2, cellParams1, cellParams2);
|
|
75
72
|
},
|
|
76
73
|
filterOperators: groupedByColDef.filterOperators
|
|
77
74
|
};
|
|
78
75
|
if (applyHeaderName) {
|
|
79
|
-
|
|
80
|
-
properties.headerName = (_groupedByColDef$head = groupedByColDef.headerName) != null ? _groupedByColDef$head : groupedByColDef.field;
|
|
76
|
+
properties.headerName = groupedByColDef.headerName ?? groupedByColDef.field;
|
|
81
77
|
}
|
|
82
78
|
return properties;
|
|
83
79
|
};
|
|
@@ -90,8 +86,7 @@ export const createGroupingColDefForOneGroupingCriteria = ({
|
|
|
90
86
|
groupingCriteria,
|
|
91
87
|
colDefOverride
|
|
92
88
|
}) => {
|
|
93
|
-
|
|
94
|
-
const _ref = colDefOverride != null ? colDefOverride : {},
|
|
89
|
+
const _ref = colDefOverride ?? {},
|
|
95
90
|
{
|
|
96
91
|
leafField,
|
|
97
92
|
mainGroupingCriteria,
|
|
@@ -102,7 +97,7 @@ export const createGroupingColDefForOneGroupingCriteria = ({
|
|
|
102
97
|
|
|
103
98
|
// The properties that do not depend on the presence of a `leafColDef` and that can be overridden by `colDefOverride`
|
|
104
99
|
const commonProperties = {
|
|
105
|
-
width: Math.max((
|
|
100
|
+
width: Math.max((groupedByColDef.width ?? GRID_STRING_COL_DEF.width) + 40, leafColDef?.width ?? 0),
|
|
106
101
|
renderCell: params => {
|
|
107
102
|
// Render footer
|
|
108
103
|
if (params.rowNode.type === 'footer' || params.rowNode.type === 'pinnedRow') {
|
|
@@ -183,8 +178,7 @@ export const createGroupingColDefForAllGroupingCriteria = ({
|
|
|
183
178
|
rowGroupingModel,
|
|
184
179
|
colDefOverride
|
|
185
180
|
}) => {
|
|
186
|
-
|
|
187
|
-
const _ref2 = colDefOverride != null ? colDefOverride : {},
|
|
181
|
+
const _ref2 = colDefOverride ?? {},
|
|
188
182
|
{
|
|
189
183
|
leafField,
|
|
190
184
|
mainGroupingCriteria,
|
|
@@ -196,10 +190,7 @@ export const createGroupingColDefForAllGroupingCriteria = ({
|
|
|
196
190
|
// The properties that do not depend on the presence of a `leafColDef` and that can be overridden by `colDefOverride`
|
|
197
191
|
const commonProperties = {
|
|
198
192
|
headerName: apiRef.current.getLocaleText('groupingColumnHeaderName'),
|
|
199
|
-
width: Math.max(...rowGroupingModel.map(field =>
|
|
200
|
-
var _columnsLookup$field$;
|
|
201
|
-
return ((_columnsLookup$field$ = columnsLookup[field].width) != null ? _columnsLookup$field$ : GRID_STRING_COL_DEF.width) + 40;
|
|
202
|
-
}), (_leafColDef$width2 = leafColDef == null ? void 0 : leafColDef.width) != null ? _leafColDef$width2 : 0),
|
|
193
|
+
width: Math.max(...rowGroupingModel.map(field => (columnsLookup[field].width ?? GRID_STRING_COL_DEF.width) + 40), leafColDef?.width ?? 0),
|
|
203
194
|
renderCell: params => {
|
|
204
195
|
// Render footer
|
|
205
196
|
if (params.rowNode.type === 'footer' || params.rowNode.type === 'pinnedRow') {
|
|
@@ -142,13 +142,10 @@ export const getCellGroupingCriteria = ({
|
|
|
142
142
|
export const getGroupingRules = ({
|
|
143
143
|
sanitizedRowGroupingModel,
|
|
144
144
|
columnsLookup
|
|
145
|
-
}) => sanitizedRowGroupingModel.map(field => {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
groupingValueGetter: (_columnsLookup$field = columnsLookup[field]) == null ? void 0 : _columnsLookup$field.groupingValueGetter
|
|
150
|
-
};
|
|
151
|
-
});
|
|
145
|
+
}) => sanitizedRowGroupingModel.map(field => ({
|
|
146
|
+
field,
|
|
147
|
+
groupingValueGetter: columnsLookup[field]?.groupingValueGetter
|
|
148
|
+
}));
|
|
152
149
|
|
|
153
150
|
/**
|
|
154
151
|
* Compares two sets of grouping rules to determine if they are equal or not.
|