@mui/x-data-grid 6.19.6 → 6.19.8
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 +48 -0
- package/components/GridPagination.d.ts +6 -5
- package/components/GridPagination.js +12 -3
- package/components/cell/GridActionsCellItem.d.ts +8 -25
- package/components/cell/GridActionsCellItem.js +4 -0
- package/hooks/features/clipboard/useGridClipboard.js +4 -2
- package/hooks/features/export/serializers/csvSerializer.d.ts +2 -0
- package/hooks/features/export/serializers/csvSerializer.js +23 -12
- package/hooks/features/export/useGridCsvExport.js +3 -2
- package/hooks/features/rowSelection/useGridRowSelection.js +3 -2
- package/index.js +1 -1
- package/legacy/components/GridPagination.js +12 -3
- package/legacy/components/cell/GridActionsCellItem.js +4 -0
- package/legacy/hooks/features/clipboard/useGridClipboard.js +4 -2
- package/legacy/hooks/features/export/serializers/csvSerializer.js +23 -12
- package/legacy/hooks/features/export/useGridCsvExport.js +3 -2
- package/legacy/hooks/features/rowSelection/useGridRowSelection.js +3 -2
- package/legacy/index.js +1 -1
- package/models/gridExport.d.ts +6 -0
- package/modern/components/GridPagination.js +12 -3
- package/modern/components/cell/GridActionsCellItem.js +4 -0
- package/modern/hooks/features/clipboard/useGridClipboard.js +4 -2
- package/modern/hooks/features/export/serializers/csvSerializer.js +23 -12
- package/modern/hooks/features/export/useGridCsvExport.js +2 -1
- package/modern/hooks/features/rowSelection/useGridRowSelection.js +3 -2
- package/modern/index.js +1 -1
- package/node/components/GridPagination.js +10 -2
- package/node/components/cell/GridActionsCellItem.js +4 -0
- package/node/hooks/features/clipboard/useGridClipboard.js +4 -2
- package/node/hooks/features/export/serializers/csvSerializer.js +23 -12
- package/node/hooks/features/export/useGridCsvExport.js +2 -1
- package/node/hooks/features/rowSelection/useGridRowSelection.js +2 -1
- package/node/index.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,54 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## 6.19.8
|
|
7
|
+
|
|
8
|
+
_Mar 20, 2024_
|
|
9
|
+
|
|
10
|
+
We'd like to offer a big thanks to the 3 contributors who made this release possible.
|
|
11
|
+
|
|
12
|
+
### Data Grid
|
|
13
|
+
|
|
14
|
+
#### `@mui/x-data-grid@6.19.8`
|
|
15
|
+
|
|
16
|
+
- [DataGrid] Fix `ElementType` usage (#12505) @cherniavskii
|
|
17
|
+
- [DataGrid] Fix cell value formatting on copy (#12483) @sai6855
|
|
18
|
+
- [DataGrid] Fix checkbox selection when filtering (#12485) @g1mishra
|
|
19
|
+
|
|
20
|
+
#### `@mui/x-data-grid-pro@6.19.8` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
21
|
+
|
|
22
|
+
Same changes as in `@mui/x-data-grid@6.19.8`.
|
|
23
|
+
|
|
24
|
+
#### `@mui/x-data-grid-premium@6.19.8` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
25
|
+
|
|
26
|
+
Same changes as in `@mui/x-data-grid-pro@6.19.8`, plus:
|
|
27
|
+
|
|
28
|
+
- [DataGridPremium] Add support for confirmation before clipboard paste (#12466) @cherniavskii
|
|
29
|
+
|
|
30
|
+
### Docs
|
|
31
|
+
|
|
32
|
+
- [docs] Update links to v7 (#12495) @cherniavskii
|
|
33
|
+
|
|
34
|
+
## 6.19.7
|
|
35
|
+
|
|
36
|
+
_Mar 14, 2024_
|
|
37
|
+
|
|
38
|
+
We'd like to offer a big thanks to @LukasTy who made this release possible.
|
|
39
|
+
|
|
40
|
+
### Date Pickers
|
|
41
|
+
|
|
42
|
+
#### `@mui/x-date-pickers@6.19.7`
|
|
43
|
+
|
|
44
|
+
- [pickers] Keep the existing time when looking for closest enabled date (#12410) @LukasTy
|
|
45
|
+
|
|
46
|
+
#### `@mui/x-date-pickers-pro@6.19.7` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
47
|
+
|
|
48
|
+
Same changes as in `@mui/x-date-pickers@6.19.7`.
|
|
49
|
+
|
|
50
|
+
### Docs
|
|
51
|
+
|
|
52
|
+
- [docs] Add Pickers custom start of week section (#12425) @LukasTy
|
|
53
|
+
|
|
6
54
|
## 6.19.6
|
|
7
55
|
|
|
8
56
|
_Mar 1, 2024_
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
import { TablePaginationProps } from '@mui/material/TablePagination';
|
|
3
|
+
interface GridPaginationOwnProps {
|
|
4
|
+
component?: React.ElementType;
|
|
5
|
+
}
|
|
6
|
+
declare const GridPagination: React.ForwardRefExoticComponent<Omit<Partial<Omit<TablePaginationProps, "component">> & GridPaginationOwnProps, "ref"> & React.RefAttributes<unknown>>;
|
|
7
|
+
export { GridPagination };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
2
|
import * as React from 'react';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
3
4
|
import TablePagination, { tablePaginationClasses } from '@mui/material/TablePagination';
|
|
4
5
|
import { styled } from '@mui/material/styles';
|
|
5
6
|
import { useGridSelector } from '../hooks/utils/useGridSelector';
|
|
@@ -27,7 +28,7 @@ const GridPaginationRoot = styled(TablePagination)(({
|
|
|
27
28
|
|
|
28
29
|
// A mutable version of a readonly array.
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
const GridPagination = /*#__PURE__*/React.forwardRef(function GridPagination(props, ref) {
|
|
31
32
|
const apiRef = useGridApiContext();
|
|
32
33
|
const rootProps = useGridRootProps();
|
|
33
34
|
const paginationModel = useGridSelector(apiRef, gridPaginationModelSelector);
|
|
@@ -63,7 +64,7 @@ export const GridPagination = /*#__PURE__*/React.forwardRef(function GridPaginat
|
|
|
63
64
|
const warnedOnceMissingInPageSizeOptions = React.useRef(false);
|
|
64
65
|
const pageSize = (_rootProps$pagination = (_rootProps$pagination2 = rootProps.paginationModel) == null ? void 0 : _rootProps$pagination2.pageSize) != null ? _rootProps$pagination : paginationModel.pageSize;
|
|
65
66
|
if (!warnedOnceMissingInPageSizeOptions.current && !rootProps.autoPageSize && !isPageSizeIncludedInPageSizeOptions(pageSize)) {
|
|
66
|
-
console.warn([`MUI: The page size \`${paginationModel.pageSize}\` is not preset in the \`pageSizeOptions
|
|
67
|
+
console.warn([`MUI X: The page size \`${paginationModel.pageSize}\` is not preset in the \`pageSizeOptions\`.`, `Add it to show the pagination select.`].join('\n'));
|
|
67
68
|
warnedOnceMissingInPageSizeOptions.current = true;
|
|
68
69
|
}
|
|
69
70
|
}
|
|
@@ -82,4 +83,12 @@ export const GridPagination = /*#__PURE__*/React.forwardRef(function GridPaginat
|
|
|
82
83
|
onPageChange: handlePageChange,
|
|
83
84
|
onRowsPerPageChange: handlePageSizeChange
|
|
84
85
|
}, apiRef.current.getLocaleText('MuiTablePagination'), props));
|
|
85
|
-
});
|
|
86
|
+
});
|
|
87
|
+
process.env.NODE_ENV !== "production" ? GridPagination.propTypes = {
|
|
88
|
+
// ----------------------------- Warning --------------------------------
|
|
89
|
+
// | These PropTypes are generated from the TypeScript type definitions |
|
|
90
|
+
// | To update them edit the TypeScript types and run "yarn proptypes" |
|
|
91
|
+
// ----------------------------------------------------------------------
|
|
92
|
+
component: PropTypes.elementType
|
|
93
|
+
} : void 0;
|
|
94
|
+
export { GridPagination };
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { IconButtonProps } from '@mui/material/IconButton';
|
|
3
3
|
import { MenuItemProps } from '@mui/material/MenuItem';
|
|
4
|
-
|
|
4
|
+
interface GridActionsCellItemCommonProps {
|
|
5
5
|
label: string;
|
|
6
6
|
icon?: React.ReactElement;
|
|
7
7
|
/** from https://mui.com/material-ui/api/button-base/#ButtonBase-prop-component */
|
|
8
8
|
component?: React.ElementType;
|
|
9
|
-
}
|
|
9
|
+
}
|
|
10
|
+
export type GridActionsCellItemProps = GridActionsCellItemCommonProps & (({
|
|
10
11
|
showInMenu?: false;
|
|
11
12
|
icon: React.ReactElement;
|
|
12
|
-
} & IconButtonProps) | ({
|
|
13
|
+
} & Omit<IconButtonProps, 'component'>) | ({
|
|
13
14
|
showInMenu: true;
|
|
14
15
|
/**
|
|
15
16
|
* If false, the menu will not close when this item is clicked.
|
|
@@ -17,25 +18,11 @@ export type GridActionsCellItemProps = {
|
|
|
17
18
|
*/
|
|
18
19
|
closeMenuOnClick?: boolean;
|
|
19
20
|
closeMenu?: () => void;
|
|
20
|
-
} & MenuItemProps));
|
|
21
|
-
declare const GridActionsCellItem: React.ForwardRefExoticComponent<(Omit<{
|
|
22
|
-
label: string;
|
|
23
|
-
icon?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined;
|
|
24
|
-
/** from https://mui.com/material-ui/api/button-base/#ButtonBase-prop-component */
|
|
25
|
-
component?: React.ElementType<any, keyof React.JSX.IntrinsicElements> | undefined;
|
|
26
|
-
} & {
|
|
21
|
+
} & Omit<MenuItemProps, 'component'>));
|
|
22
|
+
declare const GridActionsCellItem: React.ForwardRefExoticComponent<(Omit<GridActionsCellItemCommonProps & {
|
|
27
23
|
showInMenu?: false | undefined;
|
|
28
24
|
icon: React.ReactElement;
|
|
29
|
-
} &
|
|
30
|
-
ref?: ((instance: HTMLButtonElement | null) => void) | React.RefObject<HTMLButtonElement> | null | undefined;
|
|
31
|
-
}, "color" | "size" | "style" | "disabled" | "action" | "className" | "tabIndex" | "children" | "sx" | "classes" | "centerRipple" | "disableRipple" | "disableTouchRipple" | "focusRipple" | "focusVisibleClassName" | "LinkComponent" | "onFocusVisible" | "TouchRippleProps" | "touchRippleRef" | "disableFocusRipple" | "edge"> & {
|
|
32
|
-
component?: React.ElementType<any, keyof React.JSX.IntrinsicElements> | undefined;
|
|
33
|
-
}, "ref"> | Omit<{
|
|
34
|
-
label: string;
|
|
35
|
-
icon?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined;
|
|
36
|
-
/** from https://mui.com/material-ui/api/button-base/#ButtonBase-prop-component */
|
|
37
|
-
component?: React.ElementType<any, keyof React.JSX.IntrinsicElements> | undefined;
|
|
38
|
-
} & {
|
|
25
|
+
} & Omit<IconButtonProps, "component">, "ref"> | Omit<GridActionsCellItemCommonProps & {
|
|
39
26
|
showInMenu: true;
|
|
40
27
|
/**
|
|
41
28
|
* If false, the menu will not close when this item is clicked.
|
|
@@ -43,9 +30,5 @@ declare const GridActionsCellItem: React.ForwardRefExoticComponent<(Omit<{
|
|
|
43
30
|
*/
|
|
44
31
|
closeMenuOnClick?: boolean | undefined;
|
|
45
32
|
closeMenu?: (() => void) | undefined;
|
|
46
|
-
} &
|
|
47
|
-
ref?: ((instance: HTMLLIElement | null) => void) | React.RefObject<HTMLLIElement> | null | undefined;
|
|
48
|
-
}, "style" | "dense" | "disabled" | "action" | "selected" | "autoFocus" | "className" | "tabIndex" | "children" | "sx" | "classes" | "disableGutters" | "divider" | "centerRipple" | "disableRipple" | "disableTouchRipple" | "focusRipple" | "focusVisibleClassName" | "LinkComponent" | "onFocusVisible" | "TouchRippleProps" | "touchRippleRef"> & {
|
|
49
|
-
component?: React.ElementType<any, keyof React.JSX.IntrinsicElements> | undefined;
|
|
50
|
-
}, "ref">) & React.RefAttributes<HTMLElement>>;
|
|
33
|
+
} & Omit<MenuItemProps, "component">, "ref">) & React.RefAttributes<HTMLElement>>;
|
|
51
34
|
export { GridActionsCellItem };
|
|
@@ -63,6 +63,10 @@ process.env.NODE_ENV !== "production" ? GridActionsCellItem.propTypes = {
|
|
|
63
63
|
// | These PropTypes are generated from the TypeScript type definitions |
|
|
64
64
|
// | To update them edit the TypeScript types and run "yarn proptypes" |
|
|
65
65
|
// ----------------------------------------------------------------------
|
|
66
|
+
/**
|
|
67
|
+
* from https://mui.com/material-ui/api/button-base/#ButtonBase-prop-component
|
|
68
|
+
*/
|
|
69
|
+
component: PropTypes.elementType,
|
|
66
70
|
icon: PropTypes.element,
|
|
67
71
|
label: PropTypes.string.isRequired,
|
|
68
72
|
showInMenu: PropTypes.bool
|
|
@@ -68,7 +68,8 @@ export const useGridClipboard = (apiRef, props) => {
|
|
|
68
68
|
textToCopy = apiRef.current.getDataAsCsv({
|
|
69
69
|
includeHeaders: false,
|
|
70
70
|
// TODO: make it configurable
|
|
71
|
-
delimiter: clipboardCopyCellDelimiter
|
|
71
|
+
delimiter: clipboardCopyCellDelimiter,
|
|
72
|
+
shouldAppendQuotes: false
|
|
72
73
|
});
|
|
73
74
|
} else {
|
|
74
75
|
const focusedCell = gridFocusCellSelector(apiRef);
|
|
@@ -76,7 +77,8 @@ export const useGridClipboard = (apiRef, props) => {
|
|
|
76
77
|
const cellParams = apiRef.current.getCellParams(focusedCell.id, focusedCell.field);
|
|
77
78
|
textToCopy = serializeCellValue(cellParams, {
|
|
78
79
|
delimiterCharacter: clipboardCopyCellDelimiter,
|
|
79
|
-
ignoreValueFormatter
|
|
80
|
+
ignoreValueFormatter,
|
|
81
|
+
shouldAppendQuotes: false
|
|
80
82
|
});
|
|
81
83
|
}
|
|
82
84
|
}
|
|
@@ -6,6 +6,7 @@ import type { GridApiCommunity } from '../../../../models/api/gridApiCommunity';
|
|
|
6
6
|
export declare const serializeCellValue: (cellParams: GridCellParams, options: {
|
|
7
7
|
delimiterCharacter: string;
|
|
8
8
|
ignoreValueFormatter: boolean;
|
|
9
|
+
shouldAppendQuotes: boolean;
|
|
9
10
|
}) => any;
|
|
10
11
|
interface BuildCSVOptions {
|
|
11
12
|
columns: GridStateColDef[];
|
|
@@ -15,6 +16,7 @@ interface BuildCSVOptions {
|
|
|
15
16
|
includeColumnGroupsHeaders: NonNullable<GridCsvExportOptions['includeColumnGroupsHeaders']>;
|
|
16
17
|
ignoreValueFormatter: boolean;
|
|
17
18
|
apiRef: React.MutableRefObject<GridApiCommunity>;
|
|
19
|
+
shouldAppendQuotes: boolean;
|
|
18
20
|
}
|
|
19
21
|
export declare function buildCSV(options: BuildCSVOptions): string;
|
|
20
22
|
export {};
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { GRID_CHECKBOX_SELECTION_COL_DEF } from '../../../../colDef';
|
|
2
2
|
import { buildWarning } from '../../../../utils/warning';
|
|
3
|
-
function sanitizeCellValue(value, delimiterCharacter) {
|
|
3
|
+
function sanitizeCellValue(value, delimiterCharacter, shouldAppendQuotes) {
|
|
4
4
|
if (typeof value === 'string') {
|
|
5
5
|
// Make sure value containing delimiter or line break won't be split into multiple rows
|
|
6
6
|
if ([delimiterCharacter, '\n', '\r', '"'].some(delimiter => value.includes(delimiter))) {
|
|
7
|
-
|
|
7
|
+
if (shouldAppendQuotes) {
|
|
8
|
+
return `"${value.replace(/"/g, '""')}"`;
|
|
9
|
+
}
|
|
10
|
+
return `${value.replace(/"/g, '""')}`;
|
|
8
11
|
}
|
|
9
12
|
return value;
|
|
10
13
|
}
|
|
@@ -13,7 +16,8 @@ function sanitizeCellValue(value, delimiterCharacter) {
|
|
|
13
16
|
export const serializeCellValue = (cellParams, options) => {
|
|
14
17
|
const {
|
|
15
18
|
delimiterCharacter,
|
|
16
|
-
ignoreValueFormatter
|
|
19
|
+
ignoreValueFormatter,
|
|
20
|
+
shouldAppendQuotes
|
|
17
21
|
} = options;
|
|
18
22
|
let value;
|
|
19
23
|
if (ignoreValueFormatter) {
|
|
@@ -32,7 +36,7 @@ export const serializeCellValue = (cellParams, options) => {
|
|
|
32
36
|
} else {
|
|
33
37
|
value = cellParams.formattedValue;
|
|
34
38
|
}
|
|
35
|
-
return sanitizeCellValue(value, delimiterCharacter);
|
|
39
|
+
return sanitizeCellValue(value, delimiterCharacter, shouldAppendQuotes);
|
|
36
40
|
};
|
|
37
41
|
const objectFormattedValueWarning = buildWarning(['MUI: When the value of a field is an object or a `renderCell` is provided, the CSV export might not display the value correctly.', 'You can provide a `valueFormatter` with a string representation to be used.']);
|
|
38
42
|
class CSVRow {
|
|
@@ -49,7 +53,7 @@ class CSVRow {
|
|
|
49
53
|
if (value === null || value === undefined) {
|
|
50
54
|
this.rowString += '';
|
|
51
55
|
} else if (typeof this.options.sanitizeCellValue === 'function') {
|
|
52
|
-
this.rowString += this.options.sanitizeCellValue(value, this.options.delimiterCharacter);
|
|
56
|
+
this.rowString += this.options.sanitizeCellValue(value, this.options.delimiterCharacter, this.options.shouldAppendQuotes);
|
|
53
57
|
} else {
|
|
54
58
|
this.rowString += value;
|
|
55
59
|
}
|
|
@@ -64,10 +68,12 @@ const serializeRow = ({
|
|
|
64
68
|
columns,
|
|
65
69
|
getCellParams,
|
|
66
70
|
delimiterCharacter,
|
|
67
|
-
ignoreValueFormatter
|
|
71
|
+
ignoreValueFormatter,
|
|
72
|
+
shouldAppendQuotes
|
|
68
73
|
}) => {
|
|
69
74
|
const row = new CSVRow({
|
|
70
|
-
delimiterCharacter
|
|
75
|
+
delimiterCharacter,
|
|
76
|
+
shouldAppendQuotes
|
|
71
77
|
});
|
|
72
78
|
columns.forEach(column => {
|
|
73
79
|
const cellParams = getCellParams(id, column.field);
|
|
@@ -78,7 +84,8 @@ const serializeRow = ({
|
|
|
78
84
|
}
|
|
79
85
|
row.addValue(serializeCellValue(cellParams, {
|
|
80
86
|
delimiterCharacter,
|
|
81
|
-
ignoreValueFormatter
|
|
87
|
+
ignoreValueFormatter,
|
|
88
|
+
shouldAppendQuotes
|
|
82
89
|
}));
|
|
83
90
|
});
|
|
84
91
|
return row.getRowString();
|
|
@@ -91,14 +98,16 @@ export function buildCSV(options) {
|
|
|
91
98
|
includeHeaders,
|
|
92
99
|
includeColumnGroupsHeaders,
|
|
93
100
|
ignoreValueFormatter,
|
|
94
|
-
apiRef
|
|
101
|
+
apiRef,
|
|
102
|
+
shouldAppendQuotes
|
|
95
103
|
} = options;
|
|
96
104
|
const CSVBody = rowIds.reduce((acc, id) => `${acc}${serializeRow({
|
|
97
105
|
id,
|
|
98
106
|
columns,
|
|
99
107
|
getCellParams: apiRef.current.getCellParams,
|
|
100
108
|
delimiterCharacter,
|
|
101
|
-
ignoreValueFormatter
|
|
109
|
+
ignoreValueFormatter,
|
|
110
|
+
shouldAppendQuotes
|
|
102
111
|
})}\r\n`, '').trim();
|
|
103
112
|
if (!includeHeaders) {
|
|
104
113
|
return CSVBody;
|
|
@@ -117,7 +126,8 @@ export function buildCSV(options) {
|
|
|
117
126
|
for (let i = 0; i < maxColumnGroupsDepth; i += 1) {
|
|
118
127
|
const headerGroupRow = new CSVRow({
|
|
119
128
|
delimiterCharacter,
|
|
120
|
-
sanitizeCellValue
|
|
129
|
+
sanitizeCellValue,
|
|
130
|
+
shouldAppendQuotes
|
|
121
131
|
});
|
|
122
132
|
headerRows.push(headerGroupRow);
|
|
123
133
|
filteredColumns.forEach(column => {
|
|
@@ -129,7 +139,8 @@ export function buildCSV(options) {
|
|
|
129
139
|
}
|
|
130
140
|
const mainHeaderRow = new CSVRow({
|
|
131
141
|
delimiterCharacter,
|
|
132
|
-
sanitizeCellValue
|
|
142
|
+
sanitizeCellValue,
|
|
143
|
+
shouldAppendQuotes
|
|
133
144
|
});
|
|
134
145
|
filteredColumns.forEach(column => {
|
|
135
146
|
mainHeaderRow.addValue(column.headerName || column.field);
|
|
@@ -19,7 +19,7 @@ export const useGridCsvExport = (apiRef, props) => {
|
|
|
19
19
|
const ignoreValueFormatterProp = props.unstable_ignoreValueFormatterDuringExport;
|
|
20
20
|
const ignoreValueFormatter = (typeof ignoreValueFormatterProp === 'object' ? ignoreValueFormatterProp == null ? void 0 : ignoreValueFormatterProp.csvExport : ignoreValueFormatterProp) || false;
|
|
21
21
|
const getDataAsCsv = React.useCallback((options = {}) => {
|
|
22
|
-
var _options$getRowsToExp, _options$includeHeade, _options$includeColum;
|
|
22
|
+
var _options$getRowsToExp, _options$includeHeade, _options$includeColum, _options$shouldAppend;
|
|
23
23
|
logger.debug(`Get data as CSV`);
|
|
24
24
|
const exportedColumns = getColumnsToExport({
|
|
25
25
|
apiRef,
|
|
@@ -36,7 +36,8 @@ export const useGridCsvExport = (apiRef, props) => {
|
|
|
36
36
|
includeHeaders: (_options$includeHeade = options.includeHeaders) != null ? _options$includeHeade : true,
|
|
37
37
|
includeColumnGroupsHeaders: (_options$includeColum = options.includeColumnGroupsHeaders) != null ? _options$includeColum : true,
|
|
38
38
|
ignoreValueFormatter,
|
|
39
|
-
apiRef
|
|
39
|
+
apiRef,
|
|
40
|
+
shouldAppendQuotes: (_options$shouldAppend = options.shouldAppendQuotes) != null ? _options$shouldAppend : true
|
|
40
41
|
});
|
|
41
42
|
}, [logger, apiRef, ignoreValueFormatter]);
|
|
42
43
|
const exportDataAsCsv = React.useCallback(options => {
|
|
@@ -7,7 +7,7 @@ import { gridRowsLookupSelector } from '../rows/gridRowsSelector';
|
|
|
7
7
|
import { gridRowSelectionStateSelector, selectedGridRowsSelector, selectedIdsLookupSelector } from './gridRowSelectionSelector';
|
|
8
8
|
import { gridPaginatedVisibleSortedGridRowIdsSelector } from '../pagination';
|
|
9
9
|
import { gridFocusCellSelector } from '../focus/gridFocusStateSelector';
|
|
10
|
-
import { gridExpandedSortedRowIdsSelector } from '../filter/gridFilterSelector';
|
|
10
|
+
import { gridExpandedSortedRowIdsSelector, gridFilterModelSelector } from '../filter/gridFilterSelector';
|
|
11
11
|
import { GRID_CHECKBOX_SELECTION_COL_DEF, GRID_ACTIONS_COLUMN_TYPE } from '../../../colDef';
|
|
12
12
|
import { GridCellModes } from '../../../models/gridEditRowModel';
|
|
13
13
|
import { isKeyboardEvent, isNavigationKey } from '../../../utils/keyboardUtils';
|
|
@@ -280,7 +280,8 @@ export const useGridRowSelection = (apiRef, props) => {
|
|
|
280
280
|
const handleHeaderSelectionCheckboxChange = React.useCallback(params => {
|
|
281
281
|
const shouldLimitSelectionToCurrentPage = props.checkboxSelectionVisibleOnly && props.pagination;
|
|
282
282
|
const rowsToBeSelected = shouldLimitSelectionToCurrentPage ? gridPaginatedVisibleSortedGridRowIdsSelector(apiRef) : gridExpandedSortedRowIdsSelector(apiRef);
|
|
283
|
-
apiRef
|
|
283
|
+
const filterModel = gridFilterModelSelector(apiRef);
|
|
284
|
+
apiRef.current.selectRows(rowsToBeSelected, params.value, (filterModel == null ? void 0 : filterModel.items.length) > 0);
|
|
284
285
|
}, [apiRef, props.checkboxSelectionVisibleOnly, props.pagination]);
|
|
285
286
|
const handleCellKeyDown = React.useCallback((params, event) => {
|
|
286
287
|
// Get the most recent cell mode because it may have been changed by another listener
|
package/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
2
|
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
3
3
|
import * as React from 'react';
|
|
4
|
+
import PropTypes from 'prop-types';
|
|
4
5
|
import TablePagination, { tablePaginationClasses } from '@mui/material/TablePagination';
|
|
5
6
|
import { styled } from '@mui/material/styles';
|
|
6
7
|
import { useGridSelector } from '../hooks/utils/useGridSelector';
|
|
@@ -24,7 +25,7 @@ var GridPaginationRoot = styled(TablePagination)(function (_ref) {
|
|
|
24
25
|
|
|
25
26
|
// A mutable version of a readonly array.
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
var GridPagination = /*#__PURE__*/React.forwardRef(function GridPagination(props, ref) {
|
|
28
29
|
var apiRef = useGridApiContext();
|
|
29
30
|
var rootProps = useGridRootProps();
|
|
30
31
|
var paginationModel = useGridSelector(apiRef, gridPaginationModelSelector);
|
|
@@ -62,7 +63,7 @@ export var GridPagination = /*#__PURE__*/React.forwardRef(function GridPaginatio
|
|
|
62
63
|
var warnedOnceMissingInPageSizeOptions = React.useRef(false);
|
|
63
64
|
var pageSize = (_rootProps$pagination = (_rootProps$pagination2 = rootProps.paginationModel) == null ? void 0 : _rootProps$pagination2.pageSize) != null ? _rootProps$pagination : paginationModel.pageSize;
|
|
64
65
|
if (!warnedOnceMissingInPageSizeOptions.current && !rootProps.autoPageSize && !isPageSizeIncludedInPageSizeOptions(pageSize)) {
|
|
65
|
-
console.warn(["MUI: The page size `".concat(paginationModel.pageSize, "` is not preset in the `pageSizeOptions
|
|
66
|
+
console.warn(["MUI X: The page size `".concat(paginationModel.pageSize, "` is not preset in the `pageSizeOptions`."), "Add it to show the pagination select."].join('\n'));
|
|
66
67
|
warnedOnceMissingInPageSizeOptions.current = true;
|
|
67
68
|
}
|
|
68
69
|
}
|
|
@@ -81,4 +82,12 @@ export var GridPagination = /*#__PURE__*/React.forwardRef(function GridPaginatio
|
|
|
81
82
|
onPageChange: handlePageChange,
|
|
82
83
|
onRowsPerPageChange: handlePageSizeChange
|
|
83
84
|
}, apiRef.current.getLocaleText('MuiTablePagination'), props));
|
|
84
|
-
});
|
|
85
|
+
});
|
|
86
|
+
process.env.NODE_ENV !== "production" ? GridPagination.propTypes = {
|
|
87
|
+
// ----------------------------- Warning --------------------------------
|
|
88
|
+
// | These PropTypes are generated from the TypeScript type definitions |
|
|
89
|
+
// | To update them edit the TypeScript types and run "yarn proptypes" |
|
|
90
|
+
// ----------------------------------------------------------------------
|
|
91
|
+
component: PropTypes.elementType
|
|
92
|
+
} : void 0;
|
|
93
|
+
export { GridPagination };
|
|
@@ -62,6 +62,10 @@ process.env.NODE_ENV !== "production" ? GridActionsCellItem.propTypes = {
|
|
|
62
62
|
// | These PropTypes are generated from the TypeScript type definitions |
|
|
63
63
|
// | To update them edit the TypeScript types and run "yarn proptypes" |
|
|
64
64
|
// ----------------------------------------------------------------------
|
|
65
|
+
/**
|
|
66
|
+
* from https://mui.com/material-ui/api/button-base/#ButtonBase-prop-component
|
|
67
|
+
*/
|
|
68
|
+
component: PropTypes.elementType,
|
|
65
69
|
icon: PropTypes.element,
|
|
66
70
|
label: PropTypes.string.isRequired,
|
|
67
71
|
showInMenu: PropTypes.bool
|
|
@@ -69,7 +69,8 @@ export var useGridClipboard = function useGridClipboard(apiRef, props) {
|
|
|
69
69
|
textToCopy = apiRef.current.getDataAsCsv({
|
|
70
70
|
includeHeaders: false,
|
|
71
71
|
// TODO: make it configurable
|
|
72
|
-
delimiter: clipboardCopyCellDelimiter
|
|
72
|
+
delimiter: clipboardCopyCellDelimiter,
|
|
73
|
+
shouldAppendQuotes: false
|
|
73
74
|
});
|
|
74
75
|
} else {
|
|
75
76
|
var focusedCell = gridFocusCellSelector(apiRef);
|
|
@@ -77,7 +78,8 @@ export var useGridClipboard = function useGridClipboard(apiRef, props) {
|
|
|
77
78
|
var cellParams = apiRef.current.getCellParams(focusedCell.id, focusedCell.field);
|
|
78
79
|
textToCopy = serializeCellValue(cellParams, {
|
|
79
80
|
delimiterCharacter: clipboardCopyCellDelimiter,
|
|
80
|
-
ignoreValueFormatter: ignoreValueFormatter
|
|
81
|
+
ignoreValueFormatter: ignoreValueFormatter,
|
|
82
|
+
shouldAppendQuotes: false
|
|
81
83
|
});
|
|
82
84
|
}
|
|
83
85
|
}
|
|
@@ -2,13 +2,16 @@ import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
|
|
|
2
2
|
import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
3
3
|
import { GRID_CHECKBOX_SELECTION_COL_DEF } from '../../../../colDef';
|
|
4
4
|
import { buildWarning } from '../../../../utils/warning';
|
|
5
|
-
function sanitizeCellValue(value, delimiterCharacter) {
|
|
5
|
+
function sanitizeCellValue(value, delimiterCharacter, shouldAppendQuotes) {
|
|
6
6
|
if (typeof value === 'string') {
|
|
7
7
|
// Make sure value containing delimiter or line break won't be split into multiple rows
|
|
8
8
|
if ([delimiterCharacter, '\n', '\r', '"'].some(function (delimiter) {
|
|
9
9
|
return value.includes(delimiter);
|
|
10
10
|
})) {
|
|
11
|
-
|
|
11
|
+
if (shouldAppendQuotes) {
|
|
12
|
+
return "\"".concat(value.replace(/"/g, '""'), "\"");
|
|
13
|
+
}
|
|
14
|
+
return "".concat(value.replace(/"/g, '""'));
|
|
12
15
|
}
|
|
13
16
|
return value;
|
|
14
17
|
}
|
|
@@ -16,7 +19,8 @@ function sanitizeCellValue(value, delimiterCharacter) {
|
|
|
16
19
|
}
|
|
17
20
|
export var serializeCellValue = function serializeCellValue(cellParams, options) {
|
|
18
21
|
var delimiterCharacter = options.delimiterCharacter,
|
|
19
|
-
ignoreValueFormatter = options.ignoreValueFormatter
|
|
22
|
+
ignoreValueFormatter = options.ignoreValueFormatter,
|
|
23
|
+
shouldAppendQuotes = options.shouldAppendQuotes;
|
|
20
24
|
var value;
|
|
21
25
|
if (ignoreValueFormatter) {
|
|
22
26
|
var _cellParams$value2;
|
|
@@ -34,7 +38,7 @@ export var serializeCellValue = function serializeCellValue(cellParams, options)
|
|
|
34
38
|
} else {
|
|
35
39
|
value = cellParams.formattedValue;
|
|
36
40
|
}
|
|
37
|
-
return sanitizeCellValue(value, delimiterCharacter);
|
|
41
|
+
return sanitizeCellValue(value, delimiterCharacter, shouldAppendQuotes);
|
|
38
42
|
};
|
|
39
43
|
var objectFormattedValueWarning = buildWarning(['MUI: When the value of a field is an object or a `renderCell` is provided, the CSV export might not display the value correctly.', 'You can provide a `valueFormatter` with a string representation to be used.']);
|
|
40
44
|
var CSVRow = /*#__PURE__*/function () {
|
|
@@ -54,7 +58,7 @@ var CSVRow = /*#__PURE__*/function () {
|
|
|
54
58
|
if (value === null || value === undefined) {
|
|
55
59
|
this.rowString += '';
|
|
56
60
|
} else if (typeof this.options.sanitizeCellValue === 'function') {
|
|
57
|
-
this.rowString += this.options.sanitizeCellValue(value, this.options.delimiterCharacter);
|
|
61
|
+
this.rowString += this.options.sanitizeCellValue(value, this.options.delimiterCharacter, this.options.shouldAppendQuotes);
|
|
58
62
|
} else {
|
|
59
63
|
this.rowString += value;
|
|
60
64
|
}
|
|
@@ -73,9 +77,11 @@ var serializeRow = function serializeRow(_ref) {
|
|
|
73
77
|
columns = _ref.columns,
|
|
74
78
|
getCellParams = _ref.getCellParams,
|
|
75
79
|
delimiterCharacter = _ref.delimiterCharacter,
|
|
76
|
-
ignoreValueFormatter = _ref.ignoreValueFormatter
|
|
80
|
+
ignoreValueFormatter = _ref.ignoreValueFormatter,
|
|
81
|
+
shouldAppendQuotes = _ref.shouldAppendQuotes;
|
|
77
82
|
var row = new CSVRow({
|
|
78
|
-
delimiterCharacter: delimiterCharacter
|
|
83
|
+
delimiterCharacter: delimiterCharacter,
|
|
84
|
+
shouldAppendQuotes: shouldAppendQuotes
|
|
79
85
|
});
|
|
80
86
|
columns.forEach(function (column) {
|
|
81
87
|
var cellParams = getCellParams(id, column.field);
|
|
@@ -86,7 +92,8 @@ var serializeRow = function serializeRow(_ref) {
|
|
|
86
92
|
}
|
|
87
93
|
row.addValue(serializeCellValue(cellParams, {
|
|
88
94
|
delimiterCharacter: delimiterCharacter,
|
|
89
|
-
ignoreValueFormatter: ignoreValueFormatter
|
|
95
|
+
ignoreValueFormatter: ignoreValueFormatter,
|
|
96
|
+
shouldAppendQuotes: shouldAppendQuotes
|
|
90
97
|
}));
|
|
91
98
|
});
|
|
92
99
|
return row.getRowString();
|
|
@@ -98,14 +105,16 @@ export function buildCSV(options) {
|
|
|
98
105
|
includeHeaders = options.includeHeaders,
|
|
99
106
|
includeColumnGroupsHeaders = options.includeColumnGroupsHeaders,
|
|
100
107
|
ignoreValueFormatter = options.ignoreValueFormatter,
|
|
101
|
-
apiRef = options.apiRef
|
|
108
|
+
apiRef = options.apiRef,
|
|
109
|
+
shouldAppendQuotes = options.shouldAppendQuotes;
|
|
102
110
|
var CSVBody = rowIds.reduce(function (acc, id) {
|
|
103
111
|
return "".concat(acc).concat(serializeRow({
|
|
104
112
|
id: id,
|
|
105
113
|
columns: columns,
|
|
106
114
|
getCellParams: apiRef.current.getCellParams,
|
|
107
115
|
delimiterCharacter: delimiterCharacter,
|
|
108
|
-
ignoreValueFormatter: ignoreValueFormatter
|
|
116
|
+
ignoreValueFormatter: ignoreValueFormatter,
|
|
117
|
+
shouldAppendQuotes: shouldAppendQuotes
|
|
109
118
|
}), "\r\n");
|
|
110
119
|
}, '').trim();
|
|
111
120
|
if (!includeHeaders) {
|
|
@@ -127,7 +136,8 @@ export function buildCSV(options) {
|
|
|
127
136
|
var _loop = function _loop(i) {
|
|
128
137
|
var headerGroupRow = new CSVRow({
|
|
129
138
|
delimiterCharacter: delimiterCharacter,
|
|
130
|
-
sanitizeCellValue: sanitizeCellValue
|
|
139
|
+
sanitizeCellValue: sanitizeCellValue,
|
|
140
|
+
shouldAppendQuotes: shouldAppendQuotes
|
|
131
141
|
});
|
|
132
142
|
headerRows.push(headerGroupRow);
|
|
133
143
|
filteredColumns.forEach(function (column) {
|
|
@@ -142,7 +152,8 @@ export function buildCSV(options) {
|
|
|
142
152
|
}
|
|
143
153
|
var mainHeaderRow = new CSVRow({
|
|
144
154
|
delimiterCharacter: delimiterCharacter,
|
|
145
|
-
sanitizeCellValue: sanitizeCellValue
|
|
155
|
+
sanitizeCellValue: sanitizeCellValue,
|
|
156
|
+
shouldAppendQuotes: shouldAppendQuotes
|
|
146
157
|
});
|
|
147
158
|
filteredColumns.forEach(function (column) {
|
|
148
159
|
mainHeaderRow.addValue(column.headerName || column.field);
|
|
@@ -21,7 +21,7 @@ export var useGridCsvExport = function useGridCsvExport(apiRef, props) {
|
|
|
21
21
|
var ignoreValueFormatterProp = props.unstable_ignoreValueFormatterDuringExport;
|
|
22
22
|
var ignoreValueFormatter = (_typeof(ignoreValueFormatterProp) === 'object' ? ignoreValueFormatterProp == null ? void 0 : ignoreValueFormatterProp.csvExport : ignoreValueFormatterProp) || false;
|
|
23
23
|
var getDataAsCsv = React.useCallback(function () {
|
|
24
|
-
var _options$getRowsToExp, _options$includeHeade, _options$includeColum;
|
|
24
|
+
var _options$getRowsToExp, _options$includeHeade, _options$includeColum, _options$shouldAppend;
|
|
25
25
|
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
26
26
|
logger.debug("Get data as CSV");
|
|
27
27
|
var exportedColumns = getColumnsToExport({
|
|
@@ -39,7 +39,8 @@ export var useGridCsvExport = function useGridCsvExport(apiRef, props) {
|
|
|
39
39
|
includeHeaders: (_options$includeHeade = options.includeHeaders) != null ? _options$includeHeade : true,
|
|
40
40
|
includeColumnGroupsHeaders: (_options$includeColum = options.includeColumnGroupsHeaders) != null ? _options$includeColum : true,
|
|
41
41
|
ignoreValueFormatter: ignoreValueFormatter,
|
|
42
|
-
apiRef: apiRef
|
|
42
|
+
apiRef: apiRef,
|
|
43
|
+
shouldAppendQuotes: (_options$shouldAppend = options.shouldAppendQuotes) != null ? _options$shouldAppend : true
|
|
43
44
|
});
|
|
44
45
|
}, [logger, apiRef, ignoreValueFormatter]);
|
|
45
46
|
var exportDataAsCsv = React.useCallback(function (options) {
|
|
@@ -8,7 +8,7 @@ import { gridRowsLookupSelector } from '../rows/gridRowsSelector';
|
|
|
8
8
|
import { gridRowSelectionStateSelector, selectedGridRowsSelector, selectedIdsLookupSelector } from './gridRowSelectionSelector';
|
|
9
9
|
import { gridPaginatedVisibleSortedGridRowIdsSelector } from '../pagination';
|
|
10
10
|
import { gridFocusCellSelector } from '../focus/gridFocusStateSelector';
|
|
11
|
-
import { gridExpandedSortedRowIdsSelector } from '../filter/gridFilterSelector';
|
|
11
|
+
import { gridExpandedSortedRowIdsSelector, gridFilterModelSelector } from '../filter/gridFilterSelector';
|
|
12
12
|
import { GRID_CHECKBOX_SELECTION_COL_DEF, GRID_ACTIONS_COLUMN_TYPE } from '../../../colDef';
|
|
13
13
|
import { GridCellModes } from '../../../models/gridEditRowModel';
|
|
14
14
|
import { isKeyboardEvent, isNavigationKey } from '../../../utils/keyboardUtils';
|
|
@@ -303,7 +303,8 @@ export var useGridRowSelection = function useGridRowSelection(apiRef, props) {
|
|
|
303
303
|
var handleHeaderSelectionCheckboxChange = React.useCallback(function (params) {
|
|
304
304
|
var shouldLimitSelectionToCurrentPage = props.checkboxSelectionVisibleOnly && props.pagination;
|
|
305
305
|
var rowsToBeSelected = shouldLimitSelectionToCurrentPage ? gridPaginatedVisibleSortedGridRowIdsSelector(apiRef) : gridExpandedSortedRowIdsSelector(apiRef);
|
|
306
|
-
apiRef
|
|
306
|
+
var filterModel = gridFilterModelSelector(apiRef);
|
|
307
|
+
apiRef.current.selectRows(rowsToBeSelected, params.value, (filterModel == null ? void 0 : filterModel.items.length) > 0);
|
|
307
308
|
}, [apiRef, props.checkboxSelectionVisibleOnly, props.pagination]);
|
|
308
309
|
var handleCellKeyDown = React.useCallback(function (params, event) {
|
|
309
310
|
// Get the most recent cell mode because it may have been changed by another listener
|
package/legacy/index.js
CHANGED
package/models/gridExport.d.ts
CHANGED
|
@@ -88,6 +88,12 @@ export interface GridCsvExportOptions extends GridFileExportOptions {
|
|
|
88
88
|
* @returns {GridRowId[]} The list of row ids to export.
|
|
89
89
|
*/
|
|
90
90
|
getRowsToExport?: (params: GridCsvGetRowsToExportParams) => GridRowId[];
|
|
91
|
+
/**
|
|
92
|
+
* @ignore
|
|
93
|
+
* If `false`, the quotes will not be appended to the cell value.
|
|
94
|
+
* @default true
|
|
95
|
+
*/
|
|
96
|
+
shouldAppendQuotes?: boolean;
|
|
91
97
|
}
|
|
92
98
|
/**
|
|
93
99
|
* The options to apply on the Print export.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
2
|
import * as React from 'react';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
3
4
|
import TablePagination, { tablePaginationClasses } from '@mui/material/TablePagination';
|
|
4
5
|
import { styled } from '@mui/material/styles';
|
|
5
6
|
import { useGridSelector } from '../hooks/utils/useGridSelector';
|
|
@@ -27,7 +28,7 @@ const GridPaginationRoot = styled(TablePagination)(({
|
|
|
27
28
|
|
|
28
29
|
// A mutable version of a readonly array.
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
const GridPagination = /*#__PURE__*/React.forwardRef(function GridPagination(props, ref) {
|
|
31
32
|
const apiRef = useGridApiContext();
|
|
32
33
|
const rootProps = useGridRootProps();
|
|
33
34
|
const paginationModel = useGridSelector(apiRef, gridPaginationModelSelector);
|
|
@@ -59,7 +60,7 @@ export const GridPagination = /*#__PURE__*/React.forwardRef(function GridPaginat
|
|
|
59
60
|
const warnedOnceMissingInPageSizeOptions = React.useRef(false);
|
|
60
61
|
const pageSize = rootProps.paginationModel?.pageSize ?? paginationModel.pageSize;
|
|
61
62
|
if (!warnedOnceMissingInPageSizeOptions.current && !rootProps.autoPageSize && !isPageSizeIncludedInPageSizeOptions(pageSize)) {
|
|
62
|
-
console.warn([`MUI: The page size \`${paginationModel.pageSize}\` is not preset in the \`pageSizeOptions
|
|
63
|
+
console.warn([`MUI X: The page size \`${paginationModel.pageSize}\` is not preset in the \`pageSizeOptions\`.`, `Add it to show the pagination select.`].join('\n'));
|
|
63
64
|
warnedOnceMissingInPageSizeOptions.current = true;
|
|
64
65
|
}
|
|
65
66
|
}
|
|
@@ -78,4 +79,12 @@ export const GridPagination = /*#__PURE__*/React.forwardRef(function GridPaginat
|
|
|
78
79
|
onPageChange: handlePageChange,
|
|
79
80
|
onRowsPerPageChange: handlePageSizeChange
|
|
80
81
|
}, apiRef.current.getLocaleText('MuiTablePagination'), props));
|
|
81
|
-
});
|
|
82
|
+
});
|
|
83
|
+
process.env.NODE_ENV !== "production" ? GridPagination.propTypes = {
|
|
84
|
+
// ----------------------------- Warning --------------------------------
|
|
85
|
+
// | These PropTypes are generated from the TypeScript type definitions |
|
|
86
|
+
// | To update them edit the TypeScript types and run "yarn proptypes" |
|
|
87
|
+
// ----------------------------------------------------------------------
|
|
88
|
+
component: PropTypes.elementType
|
|
89
|
+
} : void 0;
|
|
90
|
+
export { GridPagination };
|
|
@@ -62,6 +62,10 @@ process.env.NODE_ENV !== "production" ? GridActionsCellItem.propTypes = {
|
|
|
62
62
|
// | These PropTypes are generated from the TypeScript type definitions |
|
|
63
63
|
// | To update them edit the TypeScript types and run "yarn proptypes" |
|
|
64
64
|
// ----------------------------------------------------------------------
|
|
65
|
+
/**
|
|
66
|
+
* from https://mui.com/material-ui/api/button-base/#ButtonBase-prop-component
|
|
67
|
+
*/
|
|
68
|
+
component: PropTypes.elementType,
|
|
65
69
|
icon: PropTypes.element,
|
|
66
70
|
label: PropTypes.string.isRequired,
|
|
67
71
|
showInMenu: PropTypes.bool
|
|
@@ -67,7 +67,8 @@ export const useGridClipboard = (apiRef, props) => {
|
|
|
67
67
|
textToCopy = apiRef.current.getDataAsCsv({
|
|
68
68
|
includeHeaders: false,
|
|
69
69
|
// TODO: make it configurable
|
|
70
|
-
delimiter: clipboardCopyCellDelimiter
|
|
70
|
+
delimiter: clipboardCopyCellDelimiter,
|
|
71
|
+
shouldAppendQuotes: false
|
|
71
72
|
});
|
|
72
73
|
} else {
|
|
73
74
|
const focusedCell = gridFocusCellSelector(apiRef);
|
|
@@ -75,7 +76,8 @@ export const useGridClipboard = (apiRef, props) => {
|
|
|
75
76
|
const cellParams = apiRef.current.getCellParams(focusedCell.id, focusedCell.field);
|
|
76
77
|
textToCopy = serializeCellValue(cellParams, {
|
|
77
78
|
delimiterCharacter: clipboardCopyCellDelimiter,
|
|
78
|
-
ignoreValueFormatter
|
|
79
|
+
ignoreValueFormatter,
|
|
80
|
+
shouldAppendQuotes: false
|
|
79
81
|
});
|
|
80
82
|
}
|
|
81
83
|
}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { GRID_CHECKBOX_SELECTION_COL_DEF } from '../../../../colDef';
|
|
2
2
|
import { buildWarning } from '../../../../utils/warning';
|
|
3
|
-
function sanitizeCellValue(value, delimiterCharacter) {
|
|
3
|
+
function sanitizeCellValue(value, delimiterCharacter, shouldAppendQuotes) {
|
|
4
4
|
if (typeof value === 'string') {
|
|
5
5
|
// Make sure value containing delimiter or line break won't be split into multiple rows
|
|
6
6
|
if ([delimiterCharacter, '\n', '\r', '"'].some(delimiter => value.includes(delimiter))) {
|
|
7
|
-
|
|
7
|
+
if (shouldAppendQuotes) {
|
|
8
|
+
return `"${value.replace(/"/g, '""')}"`;
|
|
9
|
+
}
|
|
10
|
+
return `${value.replace(/"/g, '""')}`;
|
|
8
11
|
}
|
|
9
12
|
return value;
|
|
10
13
|
}
|
|
@@ -13,7 +16,8 @@ function sanitizeCellValue(value, delimiterCharacter) {
|
|
|
13
16
|
export const serializeCellValue = (cellParams, options) => {
|
|
14
17
|
const {
|
|
15
18
|
delimiterCharacter,
|
|
16
|
-
ignoreValueFormatter
|
|
19
|
+
ignoreValueFormatter,
|
|
20
|
+
shouldAppendQuotes
|
|
17
21
|
} = options;
|
|
18
22
|
let value;
|
|
19
23
|
if (ignoreValueFormatter) {
|
|
@@ -30,7 +34,7 @@ export const serializeCellValue = (cellParams, options) => {
|
|
|
30
34
|
} else {
|
|
31
35
|
value = cellParams.formattedValue;
|
|
32
36
|
}
|
|
33
|
-
return sanitizeCellValue(value, delimiterCharacter);
|
|
37
|
+
return sanitizeCellValue(value, delimiterCharacter, shouldAppendQuotes);
|
|
34
38
|
};
|
|
35
39
|
const objectFormattedValueWarning = buildWarning(['MUI: When the value of a field is an object or a `renderCell` is provided, the CSV export might not display the value correctly.', 'You can provide a `valueFormatter` with a string representation to be used.']);
|
|
36
40
|
class CSVRow {
|
|
@@ -47,7 +51,7 @@ class CSVRow {
|
|
|
47
51
|
if (value === null || value === undefined) {
|
|
48
52
|
this.rowString += '';
|
|
49
53
|
} else if (typeof this.options.sanitizeCellValue === 'function') {
|
|
50
|
-
this.rowString += this.options.sanitizeCellValue(value, this.options.delimiterCharacter);
|
|
54
|
+
this.rowString += this.options.sanitizeCellValue(value, this.options.delimiterCharacter, this.options.shouldAppendQuotes);
|
|
51
55
|
} else {
|
|
52
56
|
this.rowString += value;
|
|
53
57
|
}
|
|
@@ -62,10 +66,12 @@ const serializeRow = ({
|
|
|
62
66
|
columns,
|
|
63
67
|
getCellParams,
|
|
64
68
|
delimiterCharacter,
|
|
65
|
-
ignoreValueFormatter
|
|
69
|
+
ignoreValueFormatter,
|
|
70
|
+
shouldAppendQuotes
|
|
66
71
|
}) => {
|
|
67
72
|
const row = new CSVRow({
|
|
68
|
-
delimiterCharacter
|
|
73
|
+
delimiterCharacter,
|
|
74
|
+
shouldAppendQuotes
|
|
69
75
|
});
|
|
70
76
|
columns.forEach(column => {
|
|
71
77
|
const cellParams = getCellParams(id, column.field);
|
|
@@ -76,7 +82,8 @@ const serializeRow = ({
|
|
|
76
82
|
}
|
|
77
83
|
row.addValue(serializeCellValue(cellParams, {
|
|
78
84
|
delimiterCharacter,
|
|
79
|
-
ignoreValueFormatter
|
|
85
|
+
ignoreValueFormatter,
|
|
86
|
+
shouldAppendQuotes
|
|
80
87
|
}));
|
|
81
88
|
});
|
|
82
89
|
return row.getRowString();
|
|
@@ -89,14 +96,16 @@ export function buildCSV(options) {
|
|
|
89
96
|
includeHeaders,
|
|
90
97
|
includeColumnGroupsHeaders,
|
|
91
98
|
ignoreValueFormatter,
|
|
92
|
-
apiRef
|
|
99
|
+
apiRef,
|
|
100
|
+
shouldAppendQuotes
|
|
93
101
|
} = options;
|
|
94
102
|
const CSVBody = rowIds.reduce((acc, id) => `${acc}${serializeRow({
|
|
95
103
|
id,
|
|
96
104
|
columns,
|
|
97
105
|
getCellParams: apiRef.current.getCellParams,
|
|
98
106
|
delimiterCharacter,
|
|
99
|
-
ignoreValueFormatter
|
|
107
|
+
ignoreValueFormatter,
|
|
108
|
+
shouldAppendQuotes
|
|
100
109
|
})}\r\n`, '').trim();
|
|
101
110
|
if (!includeHeaders) {
|
|
102
111
|
return CSVBody;
|
|
@@ -115,7 +124,8 @@ export function buildCSV(options) {
|
|
|
115
124
|
for (let i = 0; i < maxColumnGroupsDepth; i += 1) {
|
|
116
125
|
const headerGroupRow = new CSVRow({
|
|
117
126
|
delimiterCharacter,
|
|
118
|
-
sanitizeCellValue
|
|
127
|
+
sanitizeCellValue,
|
|
128
|
+
shouldAppendQuotes
|
|
119
129
|
});
|
|
120
130
|
headerRows.push(headerGroupRow);
|
|
121
131
|
filteredColumns.forEach(column => {
|
|
@@ -127,7 +137,8 @@ export function buildCSV(options) {
|
|
|
127
137
|
}
|
|
128
138
|
const mainHeaderRow = new CSVRow({
|
|
129
139
|
delimiterCharacter,
|
|
130
|
-
sanitizeCellValue
|
|
140
|
+
sanitizeCellValue,
|
|
141
|
+
shouldAppendQuotes
|
|
131
142
|
});
|
|
132
143
|
filteredColumns.forEach(column => {
|
|
133
144
|
mainHeaderRow.addValue(column.headerName || column.field);
|
|
@@ -35,7 +35,8 @@ export const useGridCsvExport = (apiRef, props) => {
|
|
|
35
35
|
includeHeaders: options.includeHeaders ?? true,
|
|
36
36
|
includeColumnGroupsHeaders: options.includeColumnGroupsHeaders ?? true,
|
|
37
37
|
ignoreValueFormatter,
|
|
38
|
-
apiRef
|
|
38
|
+
apiRef,
|
|
39
|
+
shouldAppendQuotes: options.shouldAppendQuotes ?? true
|
|
39
40
|
});
|
|
40
41
|
}, [logger, apiRef, ignoreValueFormatter]);
|
|
41
42
|
const exportDataAsCsv = React.useCallback(options => {
|
|
@@ -7,7 +7,7 @@ import { gridRowsLookupSelector } from '../rows/gridRowsSelector';
|
|
|
7
7
|
import { gridRowSelectionStateSelector, selectedGridRowsSelector, selectedIdsLookupSelector } from './gridRowSelectionSelector';
|
|
8
8
|
import { gridPaginatedVisibleSortedGridRowIdsSelector } from '../pagination';
|
|
9
9
|
import { gridFocusCellSelector } from '../focus/gridFocusStateSelector';
|
|
10
|
-
import { gridExpandedSortedRowIdsSelector } from '../filter/gridFilterSelector';
|
|
10
|
+
import { gridExpandedSortedRowIdsSelector, gridFilterModelSelector } from '../filter/gridFilterSelector';
|
|
11
11
|
import { GRID_CHECKBOX_SELECTION_COL_DEF, GRID_ACTIONS_COLUMN_TYPE } from '../../../colDef';
|
|
12
12
|
import { GridCellModes } from '../../../models/gridEditRowModel';
|
|
13
13
|
import { isKeyboardEvent, isNavigationKey } from '../../../utils/keyboardUtils';
|
|
@@ -274,7 +274,8 @@ export const useGridRowSelection = (apiRef, props) => {
|
|
|
274
274
|
const handleHeaderSelectionCheckboxChange = React.useCallback(params => {
|
|
275
275
|
const shouldLimitSelectionToCurrentPage = props.checkboxSelectionVisibleOnly && props.pagination;
|
|
276
276
|
const rowsToBeSelected = shouldLimitSelectionToCurrentPage ? gridPaginatedVisibleSortedGridRowIdsSelector(apiRef) : gridExpandedSortedRowIdsSelector(apiRef);
|
|
277
|
-
apiRef
|
|
277
|
+
const filterModel = gridFilterModelSelector(apiRef);
|
|
278
|
+
apiRef.current.selectRows(rowsToBeSelected, params.value, filterModel?.items.length > 0);
|
|
278
279
|
}, [apiRef, props.checkboxSelectionVisibleOnly, props.pagination]);
|
|
279
280
|
const handleCellKeyDown = React.useCallback((params, event) => {
|
|
280
281
|
// Get the most recent cell mode because it may have been changed by another listener
|
package/modern/index.js
CHANGED
|
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
exports.GridPagination = void 0;
|
|
8
8
|
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
9
9
|
var React = _interopRequireWildcard(require("react"));
|
|
10
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
10
11
|
var _TablePagination = _interopRequireWildcard(require("@mui/material/TablePagination"));
|
|
11
12
|
var _styles = require("@mui/material/styles");
|
|
12
13
|
var _useGridSelector = require("../hooks/utils/useGridSelector");
|
|
@@ -68,7 +69,7 @@ const GridPagination = exports.GridPagination = /*#__PURE__*/React.forwardRef(fu
|
|
|
68
69
|
const warnedOnceMissingInPageSizeOptions = React.useRef(false);
|
|
69
70
|
const pageSize = rootProps.paginationModel?.pageSize ?? paginationModel.pageSize;
|
|
70
71
|
if (!warnedOnceMissingInPageSizeOptions.current && !rootProps.autoPageSize && !isPageSizeIncludedInPageSizeOptions(pageSize)) {
|
|
71
|
-
console.warn([`MUI: The page size \`${paginationModel.pageSize}\` is not preset in the \`pageSizeOptions
|
|
72
|
+
console.warn([`MUI X: The page size \`${paginationModel.pageSize}\` is not preset in the \`pageSizeOptions\`.`, `Add it to show the pagination select.`].join('\n'));
|
|
72
73
|
warnedOnceMissingInPageSizeOptions.current = true;
|
|
73
74
|
}
|
|
74
75
|
}
|
|
@@ -87,4 +88,11 @@ const GridPagination = exports.GridPagination = /*#__PURE__*/React.forwardRef(fu
|
|
|
87
88
|
onPageChange: handlePageChange,
|
|
88
89
|
onRowsPerPageChange: handlePageSizeChange
|
|
89
90
|
}, apiRef.current.getLocaleText('MuiTablePagination'), props));
|
|
90
|
-
});
|
|
91
|
+
});
|
|
92
|
+
process.env.NODE_ENV !== "production" ? GridPagination.propTypes = {
|
|
93
|
+
// ----------------------------- Warning --------------------------------
|
|
94
|
+
// | These PropTypes are generated from the TypeScript type definitions |
|
|
95
|
+
// | To update them edit the TypeScript types and run "yarn proptypes" |
|
|
96
|
+
// ----------------------------------------------------------------------
|
|
97
|
+
component: _propTypes.default.elementType
|
|
98
|
+
} : void 0;
|
|
@@ -70,6 +70,10 @@ process.env.NODE_ENV !== "production" ? GridActionsCellItem.propTypes = {
|
|
|
70
70
|
// | These PropTypes are generated from the TypeScript type definitions |
|
|
71
71
|
// | To update them edit the TypeScript types and run "yarn proptypes" |
|
|
72
72
|
// ----------------------------------------------------------------------
|
|
73
|
+
/**
|
|
74
|
+
* from https://mui.com/material-ui/api/button-base/#ButtonBase-prop-component
|
|
75
|
+
*/
|
|
76
|
+
component: _propTypes.default.elementType,
|
|
73
77
|
icon: _propTypes.default.element,
|
|
74
78
|
label: _propTypes.default.string.isRequired,
|
|
75
79
|
showInMenu: _propTypes.default.bool
|
|
@@ -75,7 +75,8 @@ const useGridClipboard = (apiRef, props) => {
|
|
|
75
75
|
textToCopy = apiRef.current.getDataAsCsv({
|
|
76
76
|
includeHeaders: false,
|
|
77
77
|
// TODO: make it configurable
|
|
78
|
-
delimiter: clipboardCopyCellDelimiter
|
|
78
|
+
delimiter: clipboardCopyCellDelimiter,
|
|
79
|
+
shouldAppendQuotes: false
|
|
79
80
|
});
|
|
80
81
|
} else {
|
|
81
82
|
const focusedCell = (0, _gridFocusStateSelector.gridFocusCellSelector)(apiRef);
|
|
@@ -83,7 +84,8 @@ const useGridClipboard = (apiRef, props) => {
|
|
|
83
84
|
const cellParams = apiRef.current.getCellParams(focusedCell.id, focusedCell.field);
|
|
84
85
|
textToCopy = (0, _csvSerializer.serializeCellValue)(cellParams, {
|
|
85
86
|
delimiterCharacter: clipboardCopyCellDelimiter,
|
|
86
|
-
ignoreValueFormatter
|
|
87
|
+
ignoreValueFormatter,
|
|
88
|
+
shouldAppendQuotes: false
|
|
87
89
|
});
|
|
88
90
|
}
|
|
89
91
|
}
|
|
@@ -7,11 +7,14 @@ exports.buildCSV = buildCSV;
|
|
|
7
7
|
exports.serializeCellValue = void 0;
|
|
8
8
|
var _colDef = require("../../../../colDef");
|
|
9
9
|
var _warning = require("../../../../utils/warning");
|
|
10
|
-
function sanitizeCellValue(value, delimiterCharacter) {
|
|
10
|
+
function sanitizeCellValue(value, delimiterCharacter, shouldAppendQuotes) {
|
|
11
11
|
if (typeof value === 'string') {
|
|
12
12
|
// Make sure value containing delimiter or line break won't be split into multiple rows
|
|
13
13
|
if ([delimiterCharacter, '\n', '\r', '"'].some(delimiter => value.includes(delimiter))) {
|
|
14
|
-
|
|
14
|
+
if (shouldAppendQuotes) {
|
|
15
|
+
return `"${value.replace(/"/g, '""')}"`;
|
|
16
|
+
}
|
|
17
|
+
return `${value.replace(/"/g, '""')}`;
|
|
15
18
|
}
|
|
16
19
|
return value;
|
|
17
20
|
}
|
|
@@ -20,7 +23,8 @@ function sanitizeCellValue(value, delimiterCharacter) {
|
|
|
20
23
|
const serializeCellValue = (cellParams, options) => {
|
|
21
24
|
const {
|
|
22
25
|
delimiterCharacter,
|
|
23
|
-
ignoreValueFormatter
|
|
26
|
+
ignoreValueFormatter,
|
|
27
|
+
shouldAppendQuotes
|
|
24
28
|
} = options;
|
|
25
29
|
let value;
|
|
26
30
|
if (ignoreValueFormatter) {
|
|
@@ -37,7 +41,7 @@ const serializeCellValue = (cellParams, options) => {
|
|
|
37
41
|
} else {
|
|
38
42
|
value = cellParams.formattedValue;
|
|
39
43
|
}
|
|
40
|
-
return sanitizeCellValue(value, delimiterCharacter);
|
|
44
|
+
return sanitizeCellValue(value, delimiterCharacter, shouldAppendQuotes);
|
|
41
45
|
};
|
|
42
46
|
exports.serializeCellValue = serializeCellValue;
|
|
43
47
|
const objectFormattedValueWarning = (0, _warning.buildWarning)(['MUI: When the value of a field is an object or a `renderCell` is provided, the CSV export might not display the value correctly.', 'You can provide a `valueFormatter` with a string representation to be used.']);
|
|
@@ -55,7 +59,7 @@ class CSVRow {
|
|
|
55
59
|
if (value === null || value === undefined) {
|
|
56
60
|
this.rowString += '';
|
|
57
61
|
} else if (typeof this.options.sanitizeCellValue === 'function') {
|
|
58
|
-
this.rowString += this.options.sanitizeCellValue(value, this.options.delimiterCharacter);
|
|
62
|
+
this.rowString += this.options.sanitizeCellValue(value, this.options.delimiterCharacter, this.options.shouldAppendQuotes);
|
|
59
63
|
} else {
|
|
60
64
|
this.rowString += value;
|
|
61
65
|
}
|
|
@@ -70,10 +74,12 @@ const serializeRow = ({
|
|
|
70
74
|
columns,
|
|
71
75
|
getCellParams,
|
|
72
76
|
delimiterCharacter,
|
|
73
|
-
ignoreValueFormatter
|
|
77
|
+
ignoreValueFormatter,
|
|
78
|
+
shouldAppendQuotes
|
|
74
79
|
}) => {
|
|
75
80
|
const row = new CSVRow({
|
|
76
|
-
delimiterCharacter
|
|
81
|
+
delimiterCharacter,
|
|
82
|
+
shouldAppendQuotes
|
|
77
83
|
});
|
|
78
84
|
columns.forEach(column => {
|
|
79
85
|
const cellParams = getCellParams(id, column.field);
|
|
@@ -84,7 +90,8 @@ const serializeRow = ({
|
|
|
84
90
|
}
|
|
85
91
|
row.addValue(serializeCellValue(cellParams, {
|
|
86
92
|
delimiterCharacter,
|
|
87
|
-
ignoreValueFormatter
|
|
93
|
+
ignoreValueFormatter,
|
|
94
|
+
shouldAppendQuotes
|
|
88
95
|
}));
|
|
89
96
|
});
|
|
90
97
|
return row.getRowString();
|
|
@@ -97,14 +104,16 @@ function buildCSV(options) {
|
|
|
97
104
|
includeHeaders,
|
|
98
105
|
includeColumnGroupsHeaders,
|
|
99
106
|
ignoreValueFormatter,
|
|
100
|
-
apiRef
|
|
107
|
+
apiRef,
|
|
108
|
+
shouldAppendQuotes
|
|
101
109
|
} = options;
|
|
102
110
|
const CSVBody = rowIds.reduce((acc, id) => `${acc}${serializeRow({
|
|
103
111
|
id,
|
|
104
112
|
columns,
|
|
105
113
|
getCellParams: apiRef.current.getCellParams,
|
|
106
114
|
delimiterCharacter,
|
|
107
|
-
ignoreValueFormatter
|
|
115
|
+
ignoreValueFormatter,
|
|
116
|
+
shouldAppendQuotes
|
|
108
117
|
})}\r\n`, '').trim();
|
|
109
118
|
if (!includeHeaders) {
|
|
110
119
|
return CSVBody;
|
|
@@ -123,7 +132,8 @@ function buildCSV(options) {
|
|
|
123
132
|
for (let i = 0; i < maxColumnGroupsDepth; i += 1) {
|
|
124
133
|
const headerGroupRow = new CSVRow({
|
|
125
134
|
delimiterCharacter,
|
|
126
|
-
sanitizeCellValue
|
|
135
|
+
sanitizeCellValue,
|
|
136
|
+
shouldAppendQuotes
|
|
127
137
|
});
|
|
128
138
|
headerRows.push(headerGroupRow);
|
|
129
139
|
filteredColumns.forEach(column => {
|
|
@@ -135,7 +145,8 @@ function buildCSV(options) {
|
|
|
135
145
|
}
|
|
136
146
|
const mainHeaderRow = new CSVRow({
|
|
137
147
|
delimiterCharacter,
|
|
138
|
-
sanitizeCellValue
|
|
148
|
+
sanitizeCellValue,
|
|
149
|
+
shouldAppendQuotes
|
|
139
150
|
});
|
|
140
151
|
filteredColumns.forEach(column => {
|
|
141
152
|
mainHeaderRow.addValue(column.headerName || column.field);
|
|
@@ -43,7 +43,8 @@ const useGridCsvExport = (apiRef, props) => {
|
|
|
43
43
|
includeHeaders: options.includeHeaders ?? true,
|
|
44
44
|
includeColumnGroupsHeaders: options.includeColumnGroupsHeaders ?? true,
|
|
45
45
|
ignoreValueFormatter,
|
|
46
|
-
apiRef
|
|
46
|
+
apiRef,
|
|
47
|
+
shouldAppendQuotes: options.shouldAppendQuotes ?? true
|
|
47
48
|
});
|
|
48
49
|
}, [logger, apiRef, ignoreValueFormatter]);
|
|
49
50
|
const exportDataAsCsv = React.useCallback(options => {
|
|
@@ -284,7 +284,8 @@ const useGridRowSelection = (apiRef, props) => {
|
|
|
284
284
|
const handleHeaderSelectionCheckboxChange = React.useCallback(params => {
|
|
285
285
|
const shouldLimitSelectionToCurrentPage = props.checkboxSelectionVisibleOnly && props.pagination;
|
|
286
286
|
const rowsToBeSelected = shouldLimitSelectionToCurrentPage ? (0, _pagination.gridPaginatedVisibleSortedGridRowIdsSelector)(apiRef) : (0, _gridFilterSelector.gridExpandedSortedRowIdsSelector)(apiRef);
|
|
287
|
-
|
|
287
|
+
const filterModel = (0, _gridFilterSelector.gridFilterModelSelector)(apiRef);
|
|
288
|
+
apiRef.current.selectRows(rowsToBeSelected, params.value, filterModel?.items.length > 0);
|
|
288
289
|
}, [apiRef, props.checkboxSelectionVisibleOnly, props.pagination]);
|
|
289
290
|
const handleCellKeyDown = React.useCallback((params, event) => {
|
|
290
291
|
// Get the most recent cell mode because it may have been changed by another listener
|
package/node/index.js
CHANGED