@mui/x-data-grid-premium 7.5.0 → 7.6.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 +148 -5418
- package/DataGridPremium/DataGridPremium.js +2 -2
- package/components/GridColumnMenuAggregationItem.js +1 -1
- package/components/GridColumnMenuRowGroupItem.d.ts +1 -5
- package/components/GridColumnMenuRowGroupItem.js +1 -10
- package/components/GridColumnMenuRowUngroupItem.d.ts +1 -5
- package/components/GridColumnMenuRowUngroupItem.js +1 -10
- package/components/GridExcelExportMenuItem.js +2 -1
- package/components/GridPremiumColumnMenu.d.ts +1 -2
- package/components/GridPremiumColumnMenu.js +1 -11
- package/esm/DataGridPremium/DataGridPremium.js +2 -2
- package/esm/components/GridColumnMenuAggregationItem.js +1 -1
- package/esm/components/GridColumnMenuRowGroupItem.js +2 -12
- package/esm/components/GridColumnMenuRowUngroupItem.js +2 -12
- package/esm/components/GridExcelExportMenuItem.js +2 -1
- package/esm/components/GridPremiumColumnMenu.js +2 -13
- package/esm/hooks/features/cellSelection/useGridCellSelection.js +6 -3
- package/esm/hooks/features/export/serializer/excelSerializer.js +43 -23
- package/esm/hooks/features/export/useGridExcelExport.js +9 -4
- package/esm/utils/releaseInfo.js +1 -1
- package/hooks/features/cellSelection/useGridCellSelection.js +6 -3
- package/hooks/features/export/serializer/excelSerializer.d.ts +12 -10
- package/hooks/features/export/serializer/excelSerializer.js +44 -24
- package/hooks/features/export/useGridExcelExport.js +8 -3
- package/index.d.ts +1 -0
- package/index.js +1 -1
- package/modern/DataGridPremium/DataGridPremium.js +2 -2
- package/modern/components/GridColumnMenuAggregationItem.js +1 -1
- package/modern/components/GridColumnMenuRowGroupItem.js +2 -12
- package/modern/components/GridColumnMenuRowUngroupItem.js +2 -12
- package/modern/components/GridExcelExportMenuItem.js +2 -1
- package/modern/components/GridPremiumColumnMenu.js +2 -13
- package/modern/hooks/features/cellSelection/useGridCellSelection.js +6 -3
- package/modern/hooks/features/export/serializer/excelSerializer.js +43 -23
- package/modern/hooks/features/export/useGridExcelExport.js +9 -4
- package/modern/index.js +1 -1
- package/modern/utils/releaseInfo.js +1 -1
- package/package.json +6 -6
- package/utils/releaseInfo.js +1 -1
|
@@ -8,7 +8,7 @@ exports.buildExcel = buildExcel;
|
|
|
8
8
|
exports.getDataForValueOptionsSheet = getDataForValueOptionsSheet;
|
|
9
9
|
exports.serializeColumn = void 0;
|
|
10
10
|
exports.serializeColumns = serializeColumns;
|
|
11
|
-
exports.
|
|
11
|
+
exports.serializeRowUnsafe = void 0;
|
|
12
12
|
exports.setupExcelExportWebWorker = setupExcelExportWebWorker;
|
|
13
13
|
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
14
14
|
var _xDataGridPro = require("@mui/x-data-grid-pro");
|
|
@@ -37,22 +37,30 @@ const getFormattedValueOptions = (colDef, row, valueOptions, api) => {
|
|
|
37
37
|
}
|
|
38
38
|
return valueOptionsFormatted.map(option => typeof option === 'object' ? option.label : option);
|
|
39
39
|
};
|
|
40
|
-
|
|
40
|
+
/**
|
|
41
|
+
* FIXME: This function mutates the colspan info, but colspan info assumes that the columns
|
|
42
|
+
* passed to it are always consistent. In this case, the exported columns may differ from the
|
|
43
|
+
* actual rendered columns.
|
|
44
|
+
* The caller of this function MUST call `resetColSpan()` before and after usage.
|
|
45
|
+
*/
|
|
46
|
+
const serializeRowUnsafe = (id, columns, apiRef, defaultValueOptionsFormulae, options) => {
|
|
41
47
|
const row = {};
|
|
42
48
|
const dataValidation = {};
|
|
43
49
|
const mergedCells = [];
|
|
44
|
-
const firstCellParams =
|
|
50
|
+
const firstCellParams = apiRef.current.getCellParams(id, columns[0].field);
|
|
45
51
|
const outlineLevel = firstCellParams.rowNode.depth;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
const hasColSpan = (0, _internals.gridHasColSpanSelector)(apiRef);
|
|
53
|
+
if (hasColSpan) {
|
|
54
|
+
// `colSpan` is only calculated for rendered rows, so we need to calculate it during export for every row
|
|
55
|
+
apiRef.current.calculateColSpan({
|
|
56
|
+
rowId: id,
|
|
57
|
+
minFirstColumn: 0,
|
|
58
|
+
maxLastColumn: columns.length,
|
|
59
|
+
columns
|
|
60
|
+
});
|
|
61
|
+
}
|
|
54
62
|
columns.forEach((column, colIndex) => {
|
|
55
|
-
const colSpanInfo =
|
|
63
|
+
const colSpanInfo = hasColSpan ? apiRef.current.unstable_getCellColSpanInfo(id, colIndex) : undefined;
|
|
56
64
|
if (colSpanInfo && colSpanInfo.spannedByColSpan) {
|
|
57
65
|
return;
|
|
58
66
|
}
|
|
@@ -62,7 +70,8 @@ const serializeRow = (id, columns, api, defaultValueOptionsFormulae) => {
|
|
|
62
70
|
rightIndex: colIndex + colSpanInfo.cellProps.colSpan
|
|
63
71
|
});
|
|
64
72
|
}
|
|
65
|
-
const cellParams =
|
|
73
|
+
const cellParams = apiRef.current.getCellParams(id, column.field);
|
|
74
|
+
let cellValue;
|
|
66
75
|
switch (cellParams.colDef.type) {
|
|
67
76
|
case 'singleSelect':
|
|
68
77
|
{
|
|
@@ -75,7 +84,7 @@ const serializeRow = (id, columns, api, defaultValueOptionsFormulae) => {
|
|
|
75
84
|
row,
|
|
76
85
|
field: cellParams.field
|
|
77
86
|
});
|
|
78
|
-
const formattedValueOptions = getFormattedValueOptions(castColumn, row, valueOptions,
|
|
87
|
+
const formattedValueOptions = getFormattedValueOptions(castColumn, row, valueOptions, apiRef.current);
|
|
79
88
|
dataValidation[castColumn.field] = {
|
|
80
89
|
type: 'list',
|
|
81
90
|
allowBlank: true,
|
|
@@ -91,7 +100,7 @@ const serializeRow = (id, columns, api, defaultValueOptionsFormulae) => {
|
|
|
91
100
|
formulae: [address]
|
|
92
101
|
};
|
|
93
102
|
}
|
|
94
|
-
const formattedValue =
|
|
103
|
+
const formattedValue = apiRef.current.getCellParams(id, castColumn.field).formattedValue;
|
|
95
104
|
if (process.env.NODE_ENV !== 'production') {
|
|
96
105
|
if (String(cellParams.formattedValue) === '[object Object]') {
|
|
97
106
|
warnInvalidFormattedValue();
|
|
@@ -106,7 +115,7 @@ const serializeRow = (id, columns, api, defaultValueOptionsFormulae) => {
|
|
|
106
115
|
}
|
|
107
116
|
case 'boolean':
|
|
108
117
|
case 'number':
|
|
109
|
-
|
|
118
|
+
cellValue = apiRef.current.getCellParams(id, column.field).value;
|
|
110
119
|
break;
|
|
111
120
|
case 'date':
|
|
112
121
|
case 'dateTime':
|
|
@@ -114,7 +123,7 @@ const serializeRow = (id, columns, api, defaultValueOptionsFormulae) => {
|
|
|
114
123
|
// Excel does not do any timezone conversion, so we create a date using UTC instead of local timezone
|
|
115
124
|
// Solution from: https://github.com/exceljs/exceljs/issues/486#issuecomment-432557582
|
|
116
125
|
// About Date.UTC(): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC#exemples
|
|
117
|
-
const value =
|
|
126
|
+
const value = apiRef.current.getCellParams(id, column.field).value;
|
|
118
127
|
// value may be `undefined` in auto-generated grouping rows
|
|
119
128
|
if (!value) {
|
|
120
129
|
break;
|
|
@@ -126,7 +135,7 @@ const serializeRow = (id, columns, api, defaultValueOptionsFormulae) => {
|
|
|
126
135
|
case 'actions':
|
|
127
136
|
break;
|
|
128
137
|
default:
|
|
129
|
-
|
|
138
|
+
cellValue = apiRef.current.getCellParams(id, column.field).formattedValue;
|
|
130
139
|
if (process.env.NODE_ENV !== 'production') {
|
|
131
140
|
if (String(cellParams.formattedValue) === '[object Object]') {
|
|
132
141
|
warnInvalidFormattedValue();
|
|
@@ -134,6 +143,15 @@ const serializeRow = (id, columns, api, defaultValueOptionsFormulae) => {
|
|
|
134
143
|
}
|
|
135
144
|
break;
|
|
136
145
|
}
|
|
146
|
+
if (typeof cellValue === 'string' && options.escapeFormulas) {
|
|
147
|
+
// See https://owasp.org/www-community/attacks/CSV_Injection
|
|
148
|
+
if (['=', '+', '-', '@', '\t', '\r'].includes(cellValue[0])) {
|
|
149
|
+
cellValue = `'${cellValue}`;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (typeof cellValue !== 'undefined') {
|
|
153
|
+
row[column.field] = cellValue;
|
|
154
|
+
}
|
|
137
155
|
});
|
|
138
156
|
return {
|
|
139
157
|
row,
|
|
@@ -142,7 +160,7 @@ const serializeRow = (id, columns, api, defaultValueOptionsFormulae) => {
|
|
|
142
160
|
mergedCells
|
|
143
161
|
};
|
|
144
162
|
};
|
|
145
|
-
exports.
|
|
163
|
+
exports.serializeRowUnsafe = serializeRowUnsafe;
|
|
146
164
|
const defaultColumnsStyles = {
|
|
147
165
|
[_xDataGridPro.GRID_DATE_COL_DEF.type]: {
|
|
148
166
|
numFmt: 'dd.mm.yyyy'
|
|
@@ -282,7 +300,7 @@ async function createValueOptionsSheetIfNeeded(valueOptionsData, sheetName, work
|
|
|
282
300
|
valueOptionsWorksheet.getColumn(field).values = values;
|
|
283
301
|
});
|
|
284
302
|
}
|
|
285
|
-
async function buildExcel(options,
|
|
303
|
+
async function buildExcel(options, apiRef) {
|
|
286
304
|
const {
|
|
287
305
|
columns,
|
|
288
306
|
rowIds,
|
|
@@ -306,20 +324,22 @@ async function buildExcel(options, api) {
|
|
|
306
324
|
}
|
|
307
325
|
if (includeColumnGroupsHeaders) {
|
|
308
326
|
const columnGroupPaths = columns.reduce((acc, column) => {
|
|
309
|
-
acc[column.field] =
|
|
327
|
+
acc[column.field] = apiRef.current.getColumnGroupPath(column.field);
|
|
310
328
|
return acc;
|
|
311
329
|
}, {});
|
|
312
|
-
addColumnGroupingHeaders(worksheet, serializedColumns, columnGroupPaths,
|
|
330
|
+
addColumnGroupingHeaders(worksheet, serializedColumns, columnGroupPaths, apiRef.current.getAllGroupDetails());
|
|
313
331
|
}
|
|
314
332
|
if (includeHeaders) {
|
|
315
333
|
worksheet.addRow(columns.map(column => column.headerName ?? column.field));
|
|
316
334
|
}
|
|
317
|
-
const valueOptionsData = await getDataForValueOptionsSheet(columns, valueOptionsSheetName,
|
|
335
|
+
const valueOptionsData = await getDataForValueOptionsSheet(columns, valueOptionsSheetName, apiRef.current);
|
|
318
336
|
createValueOptionsSheetIfNeeded(valueOptionsData, valueOptionsSheetName, workbook);
|
|
337
|
+
apiRef.current.resetColSpan();
|
|
319
338
|
rowIds.forEach(id => {
|
|
320
|
-
const serializedRow =
|
|
339
|
+
const serializedRow = serializeRowUnsafe(id, columns, apiRef, valueOptionsData, options);
|
|
321
340
|
addSerializedRowToWorksheet(serializedRow, worksheet);
|
|
322
341
|
});
|
|
342
|
+
apiRef.current.resetColSpan();
|
|
323
343
|
if (exceljsPostProcess) {
|
|
324
344
|
await exceljsPostProcess({
|
|
325
345
|
workbook,
|
|
@@ -42,8 +42,9 @@ const useGridExcelExport = (apiRef, props) => {
|
|
|
42
42
|
valueOptionsSheetName: options?.valueOptionsSheetName || 'Options',
|
|
43
43
|
columnsStyles: options?.columnsStyles,
|
|
44
44
|
exceljsPreProcess: options?.exceljsPreProcess,
|
|
45
|
-
exceljsPostProcess: options?.exceljsPostProcess
|
|
46
|
-
|
|
45
|
+
exceljsPostProcess: options?.exceljsPostProcess,
|
|
46
|
+
escapeFormulas: options.escapeFormulas ?? true
|
|
47
|
+
}, apiRef);
|
|
47
48
|
}, [logger, apiRef]);
|
|
48
49
|
const exportDataAsExcel = React.useCallback(async (options = {}) => {
|
|
49
50
|
const {
|
|
@@ -95,7 +96,11 @@ const useGridExcelExport = (apiRef, props) => {
|
|
|
95
96
|
});
|
|
96
97
|
const valueOptionsData = await (0, _excelSerializer.getDataForValueOptionsSheet)(exportedColumns, valueOptionsSheetName, apiRef.current);
|
|
97
98
|
const serializedColumns = (0, _excelSerializer.serializeColumns)(exportedColumns, options.columnsStyles || {});
|
|
98
|
-
|
|
99
|
+
apiRef.current.resetColSpan();
|
|
100
|
+
const serializedRows = exportedRowIds.map(id => (0, _excelSerializer.serializeRowUnsafe)(id, exportedColumns, apiRef, valueOptionsData, {
|
|
101
|
+
escapeFormulas: options.escapeFormulas ?? true
|
|
102
|
+
}));
|
|
103
|
+
apiRef.current.resetColSpan();
|
|
99
104
|
const columnGroupPaths = exportedColumns.reduce((acc, column) => {
|
|
100
105
|
acc[column.field] = apiRef.current.getColumnGroupPath(column.field);
|
|
101
106
|
return acc;
|
package/index.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export * from './hooks';
|
|
|
22
22
|
export * from './models';
|
|
23
23
|
export * from './components';
|
|
24
24
|
export { GridColumnHeaders } from '@mui/x-data-grid-pro';
|
|
25
|
+
export type { GridColumnHeadersProps } from '@mui/x-data-grid-pro';
|
|
25
26
|
export type { DataGridPremiumProps, GridExperimentalPremiumFeatures, } from './models/dataGridPremiumProps';
|
|
26
27
|
export { useGridApiContext, useGridApiRef, useGridRootProps } from './typeOverloads/reexports';
|
|
27
28
|
export type { GridApi, GridInitialState, GridState } from './typeOverloads/reexports';
|
package/index.js
CHANGED
|
@@ -51,7 +51,7 @@ export const DataGridPremium = /*#__PURE__*/React.memo(DataGridPremiumRaw);
|
|
|
51
51
|
process.env.NODE_ENV !== "production" ? DataGridPremiumRaw.propTypes = {
|
|
52
52
|
// ----------------------------- Warning --------------------------------
|
|
53
53
|
// | These PropTypes are generated from the TypeScript type definitions |
|
|
54
|
-
// | To update them edit the TypeScript types and run "
|
|
54
|
+
// | To update them edit the TypeScript types and run "pnpm proptypes" |
|
|
55
55
|
// ----------------------------------------------------------------------
|
|
56
56
|
/**
|
|
57
57
|
* Aggregation functions available on the grid.
|
|
@@ -84,7 +84,7 @@ process.env.NODE_ENV !== "production" ? DataGridPremiumRaw.propTypes = {
|
|
|
84
84
|
*/
|
|
85
85
|
'aria-labelledby': PropTypes.string,
|
|
86
86
|
/**
|
|
87
|
-
* If `true`, the Data Grid height is dynamic and
|
|
87
|
+
* If `true`, the Data Grid height is dynamic and follows the number of rows in the Data Grid.
|
|
88
88
|
* @default false
|
|
89
89
|
*/
|
|
90
90
|
autoHeight: PropTypes.bool,
|
|
@@ -100,7 +100,7 @@ function GridColumnMenuAggregationItem(props) {
|
|
|
100
100
|
process.env.NODE_ENV !== "production" ? GridColumnMenuAggregationItem.propTypes = {
|
|
101
101
|
// ----------------------------- Warning --------------------------------
|
|
102
102
|
// | These PropTypes are generated from the TypeScript type definitions |
|
|
103
|
-
// | To update them edit the TypeScript types and run "
|
|
103
|
+
// | To update them edit the TypeScript types and run "pnpm proptypes" |
|
|
104
104
|
// ----------------------------------------------------------------------
|
|
105
105
|
colDef: PropTypes.object.isRequired,
|
|
106
106
|
onClick: PropTypes.func.isRequired
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
2
|
import MenuItem from '@mui/material/MenuItem';
|
|
4
3
|
import ListItemIcon from '@mui/material/ListItemIcon';
|
|
5
4
|
import ListItemText from '@mui/material/ListItemText';
|
|
@@ -9,7 +8,7 @@ import { gridRowGroupingSanitizedModelSelector } from '../hooks/features/rowGrou
|
|
|
9
8
|
import { getRowGroupingCriteriaFromGroupingField, GRID_ROW_GROUPING_SINGLE_GROUPING_FIELD, isGroupingColumn } from '../hooks/features/rowGrouping/gridRowGroupingUtils';
|
|
10
9
|
import { useGridRootProps } from '../hooks/utils/useGridRootProps';
|
|
11
10
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
12
|
-
function GridColumnMenuRowGroupItem(props) {
|
|
11
|
+
export function GridColumnMenuRowGroupItem(props) {
|
|
13
12
|
const {
|
|
14
13
|
colDef,
|
|
15
14
|
onClick
|
|
@@ -46,13 +45,4 @@ function GridColumnMenuRowGroupItem(props) {
|
|
|
46
45
|
});
|
|
47
46
|
}
|
|
48
47
|
return renderUnGroupingMenuItem(getRowGroupingCriteriaFromGroupingField(colDef.field));
|
|
49
|
-
}
|
|
50
|
-
process.env.NODE_ENV !== "production" ? GridColumnMenuRowGroupItem.propTypes = {
|
|
51
|
-
// ----------------------------- Warning --------------------------------
|
|
52
|
-
// | These PropTypes are generated from the TypeScript type definitions |
|
|
53
|
-
// | To update them edit the TypeScript types and run "yarn proptypes" |
|
|
54
|
-
// ----------------------------------------------------------------------
|
|
55
|
-
colDef: PropTypes.object.isRequired,
|
|
56
|
-
onClick: PropTypes.func.isRequired
|
|
57
|
-
} : void 0;
|
|
58
|
-
export { GridColumnMenuRowGroupItem };
|
|
48
|
+
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
2
|
import MenuItem from '@mui/material/MenuItem';
|
|
4
3
|
import ListItemIcon from '@mui/material/ListItemIcon';
|
|
5
4
|
import ListItemText from '@mui/material/ListItemText';
|
|
@@ -8,7 +7,7 @@ import { useGridApiContext } from '../hooks/utils/useGridApiContext';
|
|
|
8
7
|
import { gridRowGroupingSanitizedModelSelector } from '../hooks/features/rowGrouping/gridRowGroupingSelector';
|
|
9
8
|
import { useGridRootProps } from '../hooks/utils/useGridRootProps';
|
|
10
9
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
|
-
function GridColumnMenuRowUngroupItem(props) {
|
|
10
|
+
export function GridColumnMenuRowUngroupItem(props) {
|
|
12
11
|
const {
|
|
13
12
|
colDef,
|
|
14
13
|
onClick
|
|
@@ -51,13 +50,4 @@ function GridColumnMenuRowUngroupItem(props) {
|
|
|
51
50
|
children: apiRef.current.getLocaleText('groupColumn')(name)
|
|
52
51
|
})]
|
|
53
52
|
});
|
|
54
|
-
}
|
|
55
|
-
process.env.NODE_ENV !== "production" ? GridColumnMenuRowUngroupItem.propTypes = {
|
|
56
|
-
// ----------------------------- Warning --------------------------------
|
|
57
|
-
// | These PropTypes are generated from the TypeScript type definitions |
|
|
58
|
-
// | To update them edit the TypeScript types and run "yarn proptypes" |
|
|
59
|
-
// ----------------------------------------------------------------------
|
|
60
|
-
colDef: PropTypes.object.isRequired,
|
|
61
|
-
onClick: PropTypes.func.isRequired
|
|
62
|
-
} : void 0;
|
|
63
|
-
export { GridColumnMenuRowUngroupItem };
|
|
53
|
+
}
|
|
@@ -25,13 +25,14 @@ function GridExcelExportMenuItem(props) {
|
|
|
25
25
|
process.env.NODE_ENV !== "production" ? GridExcelExportMenuItem.propTypes = {
|
|
26
26
|
// ----------------------------- Warning --------------------------------
|
|
27
27
|
// | These PropTypes are generated from the TypeScript type definitions |
|
|
28
|
-
// | To update them edit the TypeScript types and run "
|
|
28
|
+
// | To update them edit the TypeScript types and run "pnpm proptypes" |
|
|
29
29
|
// ----------------------------------------------------------------------
|
|
30
30
|
hideMenu: PropTypes.func,
|
|
31
31
|
options: PropTypes.shape({
|
|
32
32
|
allColumns: PropTypes.bool,
|
|
33
33
|
columnsStyles: PropTypes.object,
|
|
34
34
|
disableToolbarButton: PropTypes.bool,
|
|
35
|
+
escapeFormulas: PropTypes.bool,
|
|
35
36
|
exceljsPostProcess: PropTypes.func,
|
|
36
37
|
exceljsPreProcess: PropTypes.func,
|
|
37
38
|
fields: PropTypes.arrayOf(PropTypes.string),
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import PropTypes from 'prop-types';
|
|
4
3
|
import { GridGenericColumnMenu, GRID_COLUMN_MENU_SLOTS, GRID_COLUMN_MENU_SLOT_PROPS } from '@mui/x-data-grid-pro';
|
|
5
4
|
import { GridColumnMenuAggregationItem } from './GridColumnMenuAggregationItem';
|
|
6
5
|
import { isGroupingColumn } from '../hooks/features/rowGrouping';
|
|
@@ -28,21 +27,11 @@ export const GRID_COLUMN_MENU_SLOT_PROPS_PREMIUM = _extends({}, GRID_COLUMN_MENU
|
|
|
28
27
|
displayOrder: 27
|
|
29
28
|
}
|
|
30
29
|
});
|
|
31
|
-
const GridPremiumColumnMenu = /*#__PURE__*/React.forwardRef(function GridPremiumColumnMenuSimple(props, ref) {
|
|
30
|
+
export const GridPremiumColumnMenu = /*#__PURE__*/React.forwardRef(function GridPremiumColumnMenuSimple(props, ref) {
|
|
32
31
|
return /*#__PURE__*/_jsx(GridGenericColumnMenu, _extends({
|
|
33
32
|
ref: ref
|
|
34
33
|
}, props, {
|
|
35
34
|
defaultSlots: GRID_COLUMN_MENU_SLOTS_PREMIUM,
|
|
36
35
|
defaultSlotProps: GRID_COLUMN_MENU_SLOT_PROPS_PREMIUM
|
|
37
36
|
}));
|
|
38
|
-
});
|
|
39
|
-
process.env.NODE_ENV !== "production" ? GridPremiumColumnMenu.propTypes = {
|
|
40
|
-
// ----------------------------- Warning --------------------------------
|
|
41
|
-
// | These PropTypes are generated from the TypeScript type definitions |
|
|
42
|
-
// | To update them edit the TypeScript types and run "yarn proptypes" |
|
|
43
|
-
// ----------------------------------------------------------------------
|
|
44
|
-
colDef: PropTypes.object.isRequired,
|
|
45
|
-
hideMenu: PropTypes.func.isRequired,
|
|
46
|
-
open: PropTypes.bool.isRequired
|
|
47
|
-
} : void 0;
|
|
48
|
-
export { GridPremiumColumnMenu };
|
|
37
|
+
});
|
|
@@ -445,9 +445,12 @@ export const useGridCellSelection = (apiRef, props) => {
|
|
|
445
445
|
if (fieldsMap[field]) {
|
|
446
446
|
const cellParams = apiRef.current.getCellParams(rowId, field);
|
|
447
447
|
cellData = serializeCellValue(cellParams, {
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
448
|
+
csvOptions: {
|
|
449
|
+
delimiter: clipboardCopyCellDelimiter,
|
|
450
|
+
shouldAppendQuotes: false,
|
|
451
|
+
escapeFormulas: false
|
|
452
|
+
},
|
|
453
|
+
ignoreValueFormatter
|
|
451
454
|
});
|
|
452
455
|
} else {
|
|
453
456
|
cellData = '';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
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
|
-
import { buildWarning, isObject, isSingleSelectColDef } from '@mui/x-data-grid/internals';
|
|
3
|
+
import { buildWarning, isObject, isSingleSelectColDef, gridHasColSpanSelector } from '@mui/x-data-grid/internals';
|
|
4
4
|
const getExcelJs = async () => {
|
|
5
5
|
const excelJsModule = await import('exceljs');
|
|
6
6
|
return excelJsModule.default ?? excelJsModule;
|
|
@@ -23,22 +23,30 @@ const getFormattedValueOptions = (colDef, row, valueOptions, api) => {
|
|
|
23
23
|
}
|
|
24
24
|
return valueOptionsFormatted.map(option => typeof option === 'object' ? option.label : option);
|
|
25
25
|
};
|
|
26
|
-
|
|
26
|
+
/**
|
|
27
|
+
* FIXME: This function mutates the colspan info, but colspan info assumes that the columns
|
|
28
|
+
* passed to it are always consistent. In this case, the exported columns may differ from the
|
|
29
|
+
* actual rendered columns.
|
|
30
|
+
* The caller of this function MUST call `resetColSpan()` before and after usage.
|
|
31
|
+
*/
|
|
32
|
+
export const serializeRowUnsafe = (id, columns, apiRef, defaultValueOptionsFormulae, options) => {
|
|
27
33
|
const row = {};
|
|
28
34
|
const dataValidation = {};
|
|
29
35
|
const mergedCells = [];
|
|
30
|
-
const firstCellParams =
|
|
36
|
+
const firstCellParams = apiRef.current.getCellParams(id, columns[0].field);
|
|
31
37
|
const outlineLevel = firstCellParams.rowNode.depth;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
const hasColSpan = gridHasColSpanSelector(apiRef);
|
|
39
|
+
if (hasColSpan) {
|
|
40
|
+
// `colSpan` is only calculated for rendered rows, so we need to calculate it during export for every row
|
|
41
|
+
apiRef.current.calculateColSpan({
|
|
42
|
+
rowId: id,
|
|
43
|
+
minFirstColumn: 0,
|
|
44
|
+
maxLastColumn: columns.length,
|
|
45
|
+
columns
|
|
46
|
+
});
|
|
47
|
+
}
|
|
40
48
|
columns.forEach((column, colIndex) => {
|
|
41
|
-
const colSpanInfo =
|
|
49
|
+
const colSpanInfo = hasColSpan ? apiRef.current.unstable_getCellColSpanInfo(id, colIndex) : undefined;
|
|
42
50
|
if (colSpanInfo && colSpanInfo.spannedByColSpan) {
|
|
43
51
|
return;
|
|
44
52
|
}
|
|
@@ -48,7 +56,8 @@ export const serializeRow = (id, columns, api, defaultValueOptionsFormulae) => {
|
|
|
48
56
|
rightIndex: colIndex + colSpanInfo.cellProps.colSpan
|
|
49
57
|
});
|
|
50
58
|
}
|
|
51
|
-
const cellParams =
|
|
59
|
+
const cellParams = apiRef.current.getCellParams(id, column.field);
|
|
60
|
+
let cellValue;
|
|
52
61
|
switch (cellParams.colDef.type) {
|
|
53
62
|
case 'singleSelect':
|
|
54
63
|
{
|
|
@@ -61,7 +70,7 @@ export const serializeRow = (id, columns, api, defaultValueOptionsFormulae) => {
|
|
|
61
70
|
row,
|
|
62
71
|
field: cellParams.field
|
|
63
72
|
});
|
|
64
|
-
const formattedValueOptions = getFormattedValueOptions(castColumn, row, valueOptions,
|
|
73
|
+
const formattedValueOptions = getFormattedValueOptions(castColumn, row, valueOptions, apiRef.current);
|
|
65
74
|
dataValidation[castColumn.field] = {
|
|
66
75
|
type: 'list',
|
|
67
76
|
allowBlank: true,
|
|
@@ -77,7 +86,7 @@ export const serializeRow = (id, columns, api, defaultValueOptionsFormulae) => {
|
|
|
77
86
|
formulae: [address]
|
|
78
87
|
};
|
|
79
88
|
}
|
|
80
|
-
const formattedValue =
|
|
89
|
+
const formattedValue = apiRef.current.getCellParams(id, castColumn.field).formattedValue;
|
|
81
90
|
if (process.env.NODE_ENV !== 'production') {
|
|
82
91
|
if (String(cellParams.formattedValue) === '[object Object]') {
|
|
83
92
|
warnInvalidFormattedValue();
|
|
@@ -92,7 +101,7 @@ export const serializeRow = (id, columns, api, defaultValueOptionsFormulae) => {
|
|
|
92
101
|
}
|
|
93
102
|
case 'boolean':
|
|
94
103
|
case 'number':
|
|
95
|
-
|
|
104
|
+
cellValue = apiRef.current.getCellParams(id, column.field).value;
|
|
96
105
|
break;
|
|
97
106
|
case 'date':
|
|
98
107
|
case 'dateTime':
|
|
@@ -100,7 +109,7 @@ export const serializeRow = (id, columns, api, defaultValueOptionsFormulae) => {
|
|
|
100
109
|
// Excel does not do any timezone conversion, so we create a date using UTC instead of local timezone
|
|
101
110
|
// Solution from: https://github.com/exceljs/exceljs/issues/486#issuecomment-432557582
|
|
102
111
|
// About Date.UTC(): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC#exemples
|
|
103
|
-
const value =
|
|
112
|
+
const value = apiRef.current.getCellParams(id, column.field).value;
|
|
104
113
|
// value may be `undefined` in auto-generated grouping rows
|
|
105
114
|
if (!value) {
|
|
106
115
|
break;
|
|
@@ -112,7 +121,7 @@ export const serializeRow = (id, columns, api, defaultValueOptionsFormulae) => {
|
|
|
112
121
|
case 'actions':
|
|
113
122
|
break;
|
|
114
123
|
default:
|
|
115
|
-
|
|
124
|
+
cellValue = apiRef.current.getCellParams(id, column.field).formattedValue;
|
|
116
125
|
if (process.env.NODE_ENV !== 'production') {
|
|
117
126
|
if (String(cellParams.formattedValue) === '[object Object]') {
|
|
118
127
|
warnInvalidFormattedValue();
|
|
@@ -120,6 +129,15 @@ export const serializeRow = (id, columns, api, defaultValueOptionsFormulae) => {
|
|
|
120
129
|
}
|
|
121
130
|
break;
|
|
122
131
|
}
|
|
132
|
+
if (typeof cellValue === 'string' && options.escapeFormulas) {
|
|
133
|
+
// See https://owasp.org/www-community/attacks/CSV_Injection
|
|
134
|
+
if (['=', '+', '-', '@', '\t', '\r'].includes(cellValue[0])) {
|
|
135
|
+
cellValue = `'${cellValue}`;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (typeof cellValue !== 'undefined') {
|
|
139
|
+
row[column.field] = cellValue;
|
|
140
|
+
}
|
|
123
141
|
});
|
|
124
142
|
return {
|
|
125
143
|
row,
|
|
@@ -266,7 +284,7 @@ async function createValueOptionsSheetIfNeeded(valueOptionsData, sheetName, work
|
|
|
266
284
|
valueOptionsWorksheet.getColumn(field).values = values;
|
|
267
285
|
});
|
|
268
286
|
}
|
|
269
|
-
export async function buildExcel(options,
|
|
287
|
+
export async function buildExcel(options, apiRef) {
|
|
270
288
|
const {
|
|
271
289
|
columns,
|
|
272
290
|
rowIds,
|
|
@@ -290,20 +308,22 @@ export async function buildExcel(options, api) {
|
|
|
290
308
|
}
|
|
291
309
|
if (includeColumnGroupsHeaders) {
|
|
292
310
|
const columnGroupPaths = columns.reduce((acc, column) => {
|
|
293
|
-
acc[column.field] =
|
|
311
|
+
acc[column.field] = apiRef.current.getColumnGroupPath(column.field);
|
|
294
312
|
return acc;
|
|
295
313
|
}, {});
|
|
296
|
-
addColumnGroupingHeaders(worksheet, serializedColumns, columnGroupPaths,
|
|
314
|
+
addColumnGroupingHeaders(worksheet, serializedColumns, columnGroupPaths, apiRef.current.getAllGroupDetails());
|
|
297
315
|
}
|
|
298
316
|
if (includeHeaders) {
|
|
299
317
|
worksheet.addRow(columns.map(column => column.headerName ?? column.field));
|
|
300
318
|
}
|
|
301
|
-
const valueOptionsData = await getDataForValueOptionsSheet(columns, valueOptionsSheetName,
|
|
319
|
+
const valueOptionsData = await getDataForValueOptionsSheet(columns, valueOptionsSheetName, apiRef.current);
|
|
302
320
|
createValueOptionsSheetIfNeeded(valueOptionsData, valueOptionsSheetName, workbook);
|
|
321
|
+
apiRef.current.resetColSpan();
|
|
303
322
|
rowIds.forEach(id => {
|
|
304
|
-
const serializedRow =
|
|
323
|
+
const serializedRow = serializeRowUnsafe(id, columns, apiRef, valueOptionsData, options);
|
|
305
324
|
addSerializedRowToWorksheet(serializedRow, worksheet);
|
|
306
325
|
});
|
|
326
|
+
apiRef.current.resetColSpan();
|
|
307
327
|
if (exceljsPostProcess) {
|
|
308
328
|
await exceljsPostProcess({
|
|
309
329
|
workbook,
|
|
@@ -3,7 +3,7 @@ const _excluded = ["worker", "exceljsPostProcess", "exceljsPreProcess", "columns
|
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { useGridApiMethod, useGridLogger, useGridApiOptionHandler } from '@mui/x-data-grid';
|
|
5
5
|
import { useGridRegisterPipeProcessor, exportAs, getColumnsToExport, defaultGetRowsToExport } from '@mui/x-data-grid/internals';
|
|
6
|
-
import { buildExcel, getDataForValueOptionsSheet, serializeColumns,
|
|
6
|
+
import { buildExcel, getDataForValueOptionsSheet, serializeColumns, serializeRowUnsafe } from './serializer/excelSerializer';
|
|
7
7
|
import { GridExcelExportMenuItem } from '../../../components';
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -34,8 +34,9 @@ export const useGridExcelExport = (apiRef, props) => {
|
|
|
34
34
|
valueOptionsSheetName: options?.valueOptionsSheetName || 'Options',
|
|
35
35
|
columnsStyles: options?.columnsStyles,
|
|
36
36
|
exceljsPreProcess: options?.exceljsPreProcess,
|
|
37
|
-
exceljsPostProcess: options?.exceljsPostProcess
|
|
38
|
-
|
|
37
|
+
exceljsPostProcess: options?.exceljsPostProcess,
|
|
38
|
+
escapeFormulas: options.escapeFormulas ?? true
|
|
39
|
+
}, apiRef);
|
|
39
40
|
}, [logger, apiRef]);
|
|
40
41
|
const exportDataAsExcel = React.useCallback(async (options = {}) => {
|
|
41
42
|
const {
|
|
@@ -87,7 +88,11 @@ export const useGridExcelExport = (apiRef, props) => {
|
|
|
87
88
|
});
|
|
88
89
|
const valueOptionsData = await getDataForValueOptionsSheet(exportedColumns, valueOptionsSheetName, apiRef.current);
|
|
89
90
|
const serializedColumns = serializeColumns(exportedColumns, options.columnsStyles || {});
|
|
90
|
-
|
|
91
|
+
apiRef.current.resetColSpan();
|
|
92
|
+
const serializedRows = exportedRowIds.map(id => serializeRowUnsafe(id, exportedColumns, apiRef, valueOptionsData, {
|
|
93
|
+
escapeFormulas: options.escapeFormulas ?? true
|
|
94
|
+
}));
|
|
95
|
+
apiRef.current.resetColSpan();
|
|
91
96
|
const columnGroupPaths = exportedColumns.reduce((acc, column) => {
|
|
92
97
|
acc[column.field] = apiRef.current.getColumnGroupPath(column.field);
|
|
93
98
|
return acc;
|
package/modern/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ponyfillGlobal } from '@mui/utils';
|
|
2
2
|
export const getReleaseInfo = () => {
|
|
3
|
-
const releaseInfo = "
|
|
3
|
+
const releaseInfo = "MTcxNzAxNjQwMDAwMA==";
|
|
4
4
|
if (process.env.NODE_ENV !== 'production') {
|
|
5
5
|
// A simple hack to set the value in the test environment (has no build step).
|
|
6
6
|
// eslint-disable-next-line no-useless-concat
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mui/x-data-grid-premium",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.6.0",
|
|
4
4
|
"description": "The Premium plan edition of the Data Grid Components (MUI X).",
|
|
5
5
|
"author": "MUI Team",
|
|
6
6
|
"main": "./index.js",
|
|
@@ -33,17 +33,17 @@
|
|
|
33
33
|
"directory": "packages/x-data-grid-premium"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@babel/runtime": "^7.24.
|
|
37
|
-
"@mui/system": "^5.15.
|
|
36
|
+
"@babel/runtime": "^7.24.6",
|
|
37
|
+
"@mui/system": "^5.15.15",
|
|
38
38
|
"@mui/utils": "^5.15.14",
|
|
39
39
|
"@types/format-util": "^1.0.4",
|
|
40
40
|
"clsx": "^2.1.1",
|
|
41
41
|
"exceljs": "^4.4.0",
|
|
42
42
|
"prop-types": "^15.8.1",
|
|
43
43
|
"reselect": "^4.1.8",
|
|
44
|
-
"@mui/x-data-grid": "7.
|
|
45
|
-
"@mui/x-data-grid
|
|
46
|
-
"@mui/x-license": "7.
|
|
44
|
+
"@mui/x-data-grid-pro": "7.6.0",
|
|
45
|
+
"@mui/x-data-grid": "7.6.0",
|
|
46
|
+
"@mui/x-license": "7.6.0"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"@mui/material": "^5.15.14",
|
package/utils/releaseInfo.js
CHANGED
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.getReleaseInfo = void 0;
|
|
7
7
|
var _utils = require("@mui/utils");
|
|
8
8
|
const getReleaseInfo = () => {
|
|
9
|
-
const releaseInfo = "
|
|
9
|
+
const releaseInfo = "MTcxNzAxNjQwMDAwMA==";
|
|
10
10
|
if (process.env.NODE_ENV !== 'production') {
|
|
11
11
|
// A simple hack to set the value in the test environment (has no build step).
|
|
12
12
|
// eslint-disable-next-line no-useless-concat
|