@mui/x-data-grid 6.9.1 → 6.10.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 +287 -107
- package/DataGrid/DataGrid.js +5 -1
- package/README.md +1 -1
- package/components/GridPagination.js +16 -3
- package/components/cell/GridEditDateCell.js +1 -1
- package/components/cell/GridEditInputCell.js +3 -3
- package/components/toolbar/GridToolbarQuickFilter.d.ts +1 -1
- package/components/toolbar/GridToolbarQuickFilter.js +12 -9
- package/hooks/core/pipeProcessing/useGridPipeProcessing.js +4 -1
- package/hooks/core/useGridApiInitialization.d.ts +1 -0
- package/hooks/core/useGridApiInitialization.js +59 -36
- package/hooks/features/columns/gridColumnsUtils.js +2 -1
- package/hooks/features/dimensions/useGridDimensions.js +3 -3
- package/hooks/features/editing/useGridEditing.js +2 -1
- package/hooks/features/export/serializers/csvSerializer.d.ts +9 -6
- package/hooks/features/export/serializers/csvSerializer.js +78 -15
- package/hooks/features/export/useGridCsvExport.js +4 -3
- package/hooks/features/filter/gridFilterUtils.js +6 -5
- package/hooks/features/filter/useGridFilter.js +14 -2
- package/hooks/features/rows/gridRowsUtils.js +1 -1
- package/hooks/features/rows/useGridParamsApi.js +4 -4
- package/hooks/utils/useGridApiMethod.js +7 -23
- package/index.js +1 -1
- package/internals/index.d.ts +1 -0
- package/internals/index.js +1 -0
- package/joy/joySlots.js +17 -5
- package/legacy/DataGrid/DataGrid.js +5 -1
- package/legacy/components/GridPagination.js +16 -3
- package/legacy/components/cell/GridEditDateCell.js +1 -1
- package/legacy/components/cell/GridEditInputCell.js +3 -3
- package/legacy/components/toolbar/GridToolbarQuickFilter.js +12 -12
- package/legacy/hooks/core/pipeProcessing/useGridPipeProcessing.js +4 -1
- package/legacy/hooks/core/useGridApiInitialization.js +62 -39
- package/legacy/hooks/features/columns/gridColumnsUtils.js +4 -1
- package/legacy/hooks/features/dimensions/useGridDimensions.js +3 -3
- package/legacy/hooks/features/editing/useGridEditing.js +2 -1
- package/legacy/hooks/features/export/serializers/csvSerializer.js +84 -11
- package/legacy/hooks/features/export/useGridCsvExport.js +4 -3
- package/legacy/hooks/features/filter/gridFilterUtils.js +6 -5
- package/legacy/hooks/features/filter/useGridFilter.js +12 -2
- package/legacy/hooks/features/rows/gridRowsUtils.js +1 -1
- package/legacy/hooks/features/rows/useGridParamsApi.js +4 -4
- package/legacy/hooks/utils/useGridApiMethod.js +7 -25
- package/legacy/index.js +1 -1
- package/legacy/internals/index.js +1 -0
- package/legacy/joy/joySlots.js +17 -5
- package/legacy/locales/esES.js +3 -3
- package/legacy/locales/plPL.js +7 -7
- package/locales/esES.js +3 -3
- package/locales/plPL.js +7 -7
- package/models/api/gridEditingApi.d.ts +1 -1
- package/models/events/gridEventLookup.d.ts +0 -1
- package/models/gridExport.d.ts +8 -1
- package/models/gridFilterModel.d.ts +5 -0
- package/models/props/DataGridProps.d.ts +4 -1
- package/modern/DataGrid/DataGrid.js +5 -1
- package/modern/components/GridPagination.js +16 -2
- package/modern/components/cell/GridEditDateCell.js +1 -1
- package/modern/components/cell/GridEditInputCell.js +3 -3
- package/modern/components/toolbar/GridToolbarQuickFilter.js +12 -9
- package/modern/hooks/core/pipeProcessing/useGridPipeProcessing.js +4 -1
- package/modern/hooks/core/useGridApiInitialization.js +58 -36
- package/modern/hooks/features/columns/gridColumnsUtils.js +2 -1
- package/modern/hooks/features/dimensions/useGridDimensions.js +3 -3
- package/modern/hooks/features/editing/useGridEditing.js +1 -1
- package/modern/hooks/features/export/serializers/csvSerializer.js +78 -15
- package/modern/hooks/features/export/useGridCsvExport.js +3 -2
- package/modern/hooks/features/filter/gridFilterUtils.js +3 -2
- package/modern/hooks/features/filter/useGridFilter.js +14 -2
- package/modern/hooks/features/rows/gridRowsUtils.js +1 -1
- package/modern/hooks/features/rows/useGridParamsApi.js +1 -1
- package/modern/hooks/utils/useGridApiMethod.js +7 -23
- package/modern/index.js +1 -1
- package/modern/internals/index.js +1 -0
- package/modern/joy/joySlots.js +17 -4
- package/modern/locales/esES.js +3 -3
- package/modern/locales/plPL.js +7 -7
- package/node/DataGrid/DataGrid.js +5 -1
- package/node/components/GridPagination.js +16 -2
- package/node/components/cell/GridEditDateCell.js +1 -1
- package/node/components/cell/GridEditInputCell.js +3 -3
- package/node/components/toolbar/GridToolbarQuickFilter.js +12 -9
- package/node/hooks/core/pipeProcessing/useGridPipeProcessing.js +4 -1
- package/node/hooks/core/useGridApiInitialization.js +59 -36
- package/node/hooks/features/columns/gridColumnsUtils.js +2 -1
- package/node/hooks/features/dimensions/useGridDimensions.js +3 -3
- package/node/hooks/features/editing/useGridEditing.js +1 -1
- package/node/hooks/features/export/serializers/csvSerializer.js +78 -15
- package/node/hooks/features/export/useGridCsvExport.js +3 -2
- package/node/hooks/features/filter/gridFilterUtils.js +2 -1
- package/node/hooks/features/filter/useGridFilter.js +14 -2
- package/node/hooks/features/rows/gridRowsUtils.js +1 -1
- package/node/hooks/features/rows/useGridParamsApi.js +1 -1
- package/node/hooks/utils/useGridApiMethod.js +7 -23
- package/node/index.js +1 -1
- package/node/internals/index.js +8 -0
- package/node/joy/joySlots.js +17 -4
- package/node/locales/esES.js +3 -3
- package/node/locales/plPL.js +7 -7
- package/package.json +1 -1
|
@@ -3,58 +3,79 @@ import { Store } from '../../utils/Store';
|
|
|
3
3
|
import { useGridApiMethod } from '../utils/useGridApiMethod';
|
|
4
4
|
import { GridSignature } from '../utils/useGridApiEventHandler';
|
|
5
5
|
import { EventManager } from '../../utils/EventManager';
|
|
6
|
+
const SYMBOL_API_PRIVATE = Symbol('mui.api_private');
|
|
6
7
|
const isSyntheticEvent = event => {
|
|
7
8
|
return event.isPropagationStopped !== undefined;
|
|
8
9
|
};
|
|
10
|
+
export function unwrapPrivateAPI(publicApi) {
|
|
11
|
+
return publicApi[SYMBOL_API_PRIVATE];
|
|
12
|
+
}
|
|
9
13
|
let globalId = 0;
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
function createPrivateAPI(publicApiRef) {
|
|
15
|
+
const existingPrivateApi = publicApiRef.current?.[SYMBOL_API_PRIVATE];
|
|
16
|
+
if (existingPrivateApi) {
|
|
17
|
+
return existingPrivateApi;
|
|
18
|
+
}
|
|
19
|
+
const state = {};
|
|
20
|
+
const privateApi = {
|
|
21
|
+
state,
|
|
22
|
+
store: Store.create(state),
|
|
23
|
+
instanceId: {
|
|
24
|
+
id: globalId
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
globalId += 1;
|
|
28
|
+
privateApi.getPublicApi = () => publicApiRef.current;
|
|
29
|
+
privateApi.register = (visibility, methods) => {
|
|
14
30
|
Object.keys(methods).forEach(methodName => {
|
|
15
|
-
|
|
16
|
-
|
|
31
|
+
const method = methods[methodName];
|
|
32
|
+
const currentPrivateMethod = privateApi[methodName];
|
|
33
|
+
if (currentPrivateMethod?.spying === true) {
|
|
34
|
+
currentPrivateMethod.target = method;
|
|
17
35
|
} else {
|
|
18
|
-
|
|
36
|
+
privateApi[methodName] = method;
|
|
37
|
+
}
|
|
38
|
+
if (visibility === 'public') {
|
|
39
|
+
const publicApi = publicApiRef.current;
|
|
40
|
+
const currentPublicMethod = publicApi[methodName];
|
|
41
|
+
if (currentPublicMethod?.spying === true) {
|
|
42
|
+
currentPublicMethod.target = method;
|
|
43
|
+
} else {
|
|
44
|
+
publicApi[methodName] = method;
|
|
45
|
+
}
|
|
19
46
|
}
|
|
20
47
|
});
|
|
21
48
|
};
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
49
|
+
privateApi.register('private', {
|
|
50
|
+
caches: {},
|
|
51
|
+
eventManager: new EventManager()
|
|
52
|
+
});
|
|
53
|
+
return privateApi;
|
|
54
|
+
}
|
|
55
|
+
function createPublicAPI(privateApiRef) {
|
|
56
|
+
const publicApi = {
|
|
57
|
+
get state() {
|
|
58
|
+
return privateApiRef.current.state;
|
|
28
59
|
},
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
60
|
+
get store() {
|
|
61
|
+
return privateApiRef.current.store;
|
|
62
|
+
},
|
|
63
|
+
get instanceId() {
|
|
64
|
+
return privateApiRef.current.instanceId;
|
|
65
|
+
},
|
|
66
|
+
[SYMBOL_API_PRIVATE]: privateApiRef.current
|
|
33
67
|
};
|
|
34
|
-
return
|
|
35
|
-
}
|
|
68
|
+
return publicApi;
|
|
69
|
+
}
|
|
36
70
|
export function useGridApiInitialization(inputApiRef, props) {
|
|
37
71
|
const publicApiRef = React.useRef();
|
|
38
|
-
if (!publicApiRef.current) {
|
|
39
|
-
const state = {};
|
|
40
|
-
publicApiRef.current = {
|
|
41
|
-
state,
|
|
42
|
-
store: Store.create(state),
|
|
43
|
-
instanceId: {
|
|
44
|
-
id: globalId
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
globalId += 1;
|
|
48
|
-
}
|
|
49
72
|
const privateApiRef = React.useRef();
|
|
50
73
|
if (!privateApiRef.current) {
|
|
51
|
-
privateApiRef.current =
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
});
|
|
74
|
+
privateApiRef.current = createPrivateAPI(publicApiRef);
|
|
75
|
+
}
|
|
76
|
+
if (!publicApiRef.current) {
|
|
77
|
+
publicApiRef.current = createPublicAPI(privateApiRef);
|
|
56
78
|
}
|
|
57
|
-
React.useImperativeHandle(inputApiRef, () => publicApiRef.current, [publicApiRef]);
|
|
58
79
|
const publishEvent = React.useCallback((...args) => {
|
|
59
80
|
const [name, params, event = {}] = args;
|
|
60
81
|
event.defaultMuiPrevented = false;
|
|
@@ -77,6 +98,7 @@ export function useGridApiInitialization(inputApiRef, props) {
|
|
|
77
98
|
subscribeEvent,
|
|
78
99
|
publishEvent
|
|
79
100
|
}, 'public');
|
|
101
|
+
React.useImperativeHandle(inputApiRef, () => publicApiRef.current, [publicApiRef]);
|
|
80
102
|
React.useEffect(() => {
|
|
81
103
|
const api = privateApiRef.current;
|
|
82
104
|
return () => {
|
|
@@ -15,6 +15,7 @@ export function computeFlexColumnsWidth({
|
|
|
15
15
|
totalFlexUnits,
|
|
16
16
|
flexColumns
|
|
17
17
|
}) {
|
|
18
|
+
const uniqueFlexColumns = new Set(flexColumns.map(col => col.field));
|
|
18
19
|
const flexColumnsLookup = {
|
|
19
20
|
all: {},
|
|
20
21
|
frozenFields: [],
|
|
@@ -30,7 +31,7 @@ export function computeFlexColumnsWidth({
|
|
|
30
31
|
// Step 5 of https://drafts.csswg.org/css-flexbox-1/#resolve-flexible-lengths
|
|
31
32
|
function loopOverFlexItems() {
|
|
32
33
|
// 5a: If all the flex items on the line are frozen, free space has been distributed.
|
|
33
|
-
if (flexColumnsLookup.frozenFields.length ===
|
|
34
|
+
if (flexColumnsLookup.frozenFields.length === uniqueFlexColumns.size) {
|
|
34
35
|
return;
|
|
35
36
|
}
|
|
36
37
|
const violationsLookup = {
|
|
@@ -72,7 +72,7 @@ export function useGridDimensions(apiRef, props) {
|
|
|
72
72
|
let hasScrollY;
|
|
73
73
|
if (props.autoHeight) {
|
|
74
74
|
hasScrollY = false;
|
|
75
|
-
hasScrollX = columnsTotalWidth > rootDimensionsRef.current.width;
|
|
75
|
+
hasScrollX = Math.round(columnsTotalWidth) > Math.round(rootDimensionsRef.current.width);
|
|
76
76
|
viewportOuterSize = {
|
|
77
77
|
width: rootDimensionsRef.current.width,
|
|
78
78
|
height: rowsMeta.currentPageTotalHeight + (hasScrollX ? scrollBarSize : 0)
|
|
@@ -84,11 +84,11 @@ export function useGridDimensions(apiRef, props) {
|
|
|
84
84
|
};
|
|
85
85
|
const scrollInformation = hasScroll({
|
|
86
86
|
content: {
|
|
87
|
-
width: columnsTotalWidth,
|
|
87
|
+
width: Math.round(columnsTotalWidth),
|
|
88
88
|
height: rowsMeta.currentPageTotalHeight
|
|
89
89
|
},
|
|
90
90
|
container: {
|
|
91
|
-
width: viewportOuterSize.width,
|
|
91
|
+
width: Math.round(viewportOuterSize.width),
|
|
92
92
|
height: viewportOuterSize.height - pinnedRowsHeight.top - pinnedRowsHeight.bottom
|
|
93
93
|
},
|
|
94
94
|
scrollBarSize
|
|
@@ -107,7 +107,7 @@ export const useGridEditing = (apiRef, props) => {
|
|
|
107
107
|
}, [apiRef, props.editMode]);
|
|
108
108
|
const getEditCellMeta = React.useCallback((id, field) => {
|
|
109
109
|
const editingState = gridEditRowsStateSelector(apiRef.current.state);
|
|
110
|
-
return editingState[id][field];
|
|
110
|
+
return editingState[id]?.[field] ?? null;
|
|
111
111
|
}, [apiRef]);
|
|
112
112
|
const editingSharedApi = {
|
|
113
113
|
isCellEditable,
|
|
@@ -35,43 +35,106 @@ export const serializeCellValue = (cellParams, options) => {
|
|
|
35
35
|
return sanitizeCellValue(value, delimiterCharacter);
|
|
36
36
|
};
|
|
37
37
|
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
|
+
class CSVRow {
|
|
39
|
+
constructor(options) {
|
|
40
|
+
this.options = void 0;
|
|
41
|
+
this.rowString = '';
|
|
42
|
+
this.isEmpty = true;
|
|
43
|
+
this.options = options;
|
|
44
|
+
}
|
|
45
|
+
addValue(value) {
|
|
46
|
+
if (!this.isEmpty) {
|
|
47
|
+
this.rowString += this.options.delimiterCharacter;
|
|
48
|
+
}
|
|
49
|
+
if (value === null || value === undefined) {
|
|
50
|
+
this.rowString += '';
|
|
51
|
+
} else if (typeof this.options.sanitizeCellValue === 'function') {
|
|
52
|
+
this.rowString += this.options.sanitizeCellValue(value, this.options.delimiterCharacter);
|
|
53
|
+
} else {
|
|
54
|
+
this.rowString += value;
|
|
55
|
+
}
|
|
56
|
+
this.isEmpty = false;
|
|
57
|
+
}
|
|
58
|
+
getRowString() {
|
|
59
|
+
return this.rowString;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
38
62
|
const serializeRow = ({
|
|
39
63
|
id,
|
|
40
64
|
columns,
|
|
41
65
|
getCellParams,
|
|
42
66
|
delimiterCharacter,
|
|
43
67
|
ignoreValueFormatter
|
|
44
|
-
}) =>
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
68
|
+
}) => {
|
|
69
|
+
const row = new CSVRow({
|
|
70
|
+
delimiterCharacter
|
|
71
|
+
});
|
|
72
|
+
columns.forEach(column => {
|
|
73
|
+
const cellParams = getCellParams(id, column.field);
|
|
74
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
75
|
+
if (String(cellParams.formattedValue) === '[object Object]') {
|
|
76
|
+
objectFormattedValueWarning();
|
|
77
|
+
}
|
|
49
78
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
79
|
+
row.addValue(serializeCellValue(cellParams, {
|
|
80
|
+
delimiterCharacter,
|
|
81
|
+
ignoreValueFormatter
|
|
82
|
+
}));
|
|
54
83
|
});
|
|
55
|
-
|
|
84
|
+
return row.getRowString();
|
|
85
|
+
};
|
|
56
86
|
export function buildCSV(options) {
|
|
57
87
|
const {
|
|
58
88
|
columns,
|
|
59
89
|
rowIds,
|
|
60
|
-
getCellParams,
|
|
61
90
|
delimiterCharacter,
|
|
62
91
|
includeHeaders,
|
|
63
|
-
|
|
92
|
+
includeColumnGroupsHeaders,
|
|
93
|
+
ignoreValueFormatter,
|
|
94
|
+
apiRef
|
|
64
95
|
} = options;
|
|
65
96
|
const CSVBody = rowIds.reduce((acc, id) => `${acc}${serializeRow({
|
|
66
97
|
id,
|
|
67
98
|
columns,
|
|
68
|
-
getCellParams,
|
|
99
|
+
getCellParams: apiRef.current.getCellParams,
|
|
69
100
|
delimiterCharacter,
|
|
70
101
|
ignoreValueFormatter
|
|
71
|
-
})
|
|
102
|
+
})}\r\n`, '').trim();
|
|
72
103
|
if (!includeHeaders) {
|
|
73
104
|
return CSVBody;
|
|
74
105
|
}
|
|
75
|
-
const
|
|
106
|
+
const filteredColumns = columns.filter(column => column.field !== GRID_CHECKBOX_SELECTION_COL_DEF.field);
|
|
107
|
+
const headerRows = [];
|
|
108
|
+
if (includeColumnGroupsHeaders) {
|
|
109
|
+
const columnGroupLookup = apiRef.current.unstable_getAllGroupDetails();
|
|
110
|
+
let maxColumnGroupsDepth = 0;
|
|
111
|
+
const columnGroupPathsLookup = filteredColumns.reduce((acc, column) => {
|
|
112
|
+
const columnGroupPath = apiRef.current.unstable_getColumnGroupPath(column.field);
|
|
113
|
+
acc[column.field] = columnGroupPath;
|
|
114
|
+
maxColumnGroupsDepth = Math.max(maxColumnGroupsDepth, columnGroupPath.length);
|
|
115
|
+
return acc;
|
|
116
|
+
}, {});
|
|
117
|
+
for (let i = 0; i < maxColumnGroupsDepth; i += 1) {
|
|
118
|
+
const headerGroupRow = new CSVRow({
|
|
119
|
+
delimiterCharacter,
|
|
120
|
+
sanitizeCellValue
|
|
121
|
+
});
|
|
122
|
+
headerRows.push(headerGroupRow);
|
|
123
|
+
filteredColumns.forEach(column => {
|
|
124
|
+
const columnGroupId = (columnGroupPathsLookup[column.field] || [])[i];
|
|
125
|
+
const columnGroup = columnGroupLookup[columnGroupId];
|
|
126
|
+
headerGroupRow.addValue(columnGroup ? columnGroup.headerName || columnGroup.groupId : '');
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
const mainHeaderRow = new CSVRow({
|
|
131
|
+
delimiterCharacter,
|
|
132
|
+
sanitizeCellValue
|
|
133
|
+
});
|
|
134
|
+
filteredColumns.forEach(column => {
|
|
135
|
+
mainHeaderRow.addValue(column.headerName || column.field);
|
|
136
|
+
});
|
|
137
|
+
headerRows.push(mainHeaderRow);
|
|
138
|
+
const CSVHead = `${headerRows.map(row => row.getRowString()).join('\r\n')}\r\n`;
|
|
76
139
|
return `${CSVHead}${CSVBody}`.trim();
|
|
77
140
|
}
|
|
@@ -31,10 +31,11 @@ export const useGridCsvExport = (apiRef, props) => {
|
|
|
31
31
|
return buildCSV({
|
|
32
32
|
columns: exportedColumns,
|
|
33
33
|
rowIds: exportedRowIds,
|
|
34
|
-
getCellParams: apiRef.current.getCellParams,
|
|
35
34
|
delimiterCharacter: options.delimiter || ',',
|
|
36
35
|
includeHeaders: options.includeHeaders ?? true,
|
|
37
|
-
|
|
36
|
+
includeColumnGroupsHeaders: options.includeColumnGroupsHeaders ?? true,
|
|
37
|
+
ignoreValueFormatter,
|
|
38
|
+
apiRef
|
|
38
39
|
});
|
|
39
40
|
}, [logger, apiRef, ignoreValueFormatter]);
|
|
40
41
|
const exportDataAsCsv = React.useCallback(options => {
|
|
@@ -3,7 +3,7 @@ import { GridLogicOperator } from '../../../models';
|
|
|
3
3
|
import { GLOBAL_API_REF, isInternalFilter } from '../../../colDef/utils';
|
|
4
4
|
import { getDefaultGridFilterModel } from './gridFilterState';
|
|
5
5
|
import { buildWarning } from '../../../utils/warning';
|
|
6
|
-
import { gridColumnFieldsSelector, gridColumnLookupSelector } from '../columns';
|
|
6
|
+
import { gridColumnFieldsSelector, gridColumnLookupSelector, gridVisibleColumnFieldsSelector } from '../columns';
|
|
7
7
|
/**
|
|
8
8
|
* Adds default values to the optional fields of a filter items.
|
|
9
9
|
* @param {GridFilterItem} item The raw filter item.
|
|
@@ -157,7 +157,8 @@ export const buildAggregatedQuickFilterApplier = (getRowId, filterModel, apiRef)
|
|
|
157
157
|
if (quickFilterValues.length === 0) {
|
|
158
158
|
return null;
|
|
159
159
|
}
|
|
160
|
-
const
|
|
160
|
+
const quickFilterExcludeHiddenColumns = filterModel.quickFilterExcludeHiddenColumns ?? false;
|
|
161
|
+
const columnFields = quickFilterExcludeHiddenColumns ? gridVisibleColumnFieldsSelector(apiRef) : gridColumnFieldsSelector(apiRef);
|
|
161
162
|
const appliersPerField = [];
|
|
162
163
|
columnFields.forEach(field => {
|
|
163
164
|
const column = apiRef.current.getColumn(field);
|
|
@@ -20,6 +20,7 @@ export const filterStateInitializer = (state, props, apiRef) => {
|
|
|
20
20
|
return _extends({}, state, {
|
|
21
21
|
filter: {
|
|
22
22
|
filterModel: sanitizeFilterModel(filterModel, props.disableMultipleColumnsFiltering, apiRef),
|
|
23
|
+
filteredRowsLookup: {},
|
|
23
24
|
filteredDescendantCountLookup: {}
|
|
24
25
|
},
|
|
25
26
|
visibleRowsLookup: {}
|
|
@@ -252,6 +253,9 @@ export const useGridFilter = (apiRef, props) => {
|
|
|
252
253
|
}, [props.slots.filterPanel, props.slotProps?.filterPanel]);
|
|
253
254
|
const dataRowIdToIdLookup = apiRef.current.state.rows.dataRowIdToModelLookup;
|
|
254
255
|
const rows = React.useMemo(() => Object.values(dataRowIdToIdLookup), [dataRowIdToIdLookup]);
|
|
256
|
+
const {
|
|
257
|
+
getRowId
|
|
258
|
+
} = props;
|
|
255
259
|
const flatFilteringMethod = React.useCallback(params => {
|
|
256
260
|
if (props.filterMode !== 'client' || !params.isRowMatchingFilters) {
|
|
257
261
|
return {
|
|
@@ -271,9 +275,10 @@ export const useGridFilter = (apiRef, props) => {
|
|
|
271
275
|
};
|
|
272
276
|
for (let i = 0; i < rows.length; i += 1) {
|
|
273
277
|
const row = rows[i];
|
|
278
|
+
const id = getRowId ? getRowId(row) : row.id;
|
|
274
279
|
isRowMatchingFilters(row, undefined, result);
|
|
275
280
|
const isRowPassing = passFilterLogic([result.passingFilterItems], [result.passingQuickFilterValues], params.filterModel, apiRef, filterCache);
|
|
276
|
-
filteredRowsLookup[
|
|
281
|
+
filteredRowsLookup[id] = isRowPassing;
|
|
277
282
|
}
|
|
278
283
|
const footerId = 'auto-generated-group-footer-root';
|
|
279
284
|
const footer = dataRowIdToModelLookup[footerId];
|
|
@@ -284,7 +289,7 @@ export const useGridFilter = (apiRef, props) => {
|
|
|
284
289
|
filteredRowsLookup,
|
|
285
290
|
filteredDescendantCountLookup: {}
|
|
286
291
|
};
|
|
287
|
-
}, [apiRef, props.filterMode,
|
|
292
|
+
}, [apiRef, rows, props.filterMode, getRowId]);
|
|
288
293
|
useGridRegisterPipeProcessor(apiRef, 'columnMenu', addColumnMenuItem);
|
|
289
294
|
useGridRegisterPipeProcessor(apiRef, 'exportState', stateExportPreProcessing);
|
|
290
295
|
useGridRegisterPipeProcessor(apiRef, 'restoreState', stateRestorePreProcessing);
|
|
@@ -326,6 +331,13 @@ export const useGridFilter = (apiRef, props) => {
|
|
|
326
331
|
useGridApiEventHandler(apiRef, 'columnsChange', handleColumnsChange);
|
|
327
332
|
useGridApiEventHandler(apiRef, 'activeStrategyProcessorChange', handleStrategyProcessorChange);
|
|
328
333
|
useGridApiEventHandler(apiRef, 'rowExpansionChange', updateVisibleRowsLookupState);
|
|
334
|
+
useGridApiEventHandler(apiRef, 'columnVisibilityModelChange', () => {
|
|
335
|
+
const filterModel = gridFilterModelSelector(apiRef);
|
|
336
|
+
if (filterModel.quickFilterValues && filterModel.quickFilterExcludeHiddenColumns) {
|
|
337
|
+
// re-apply filters because the quick filter results may have changed
|
|
338
|
+
apiRef.current.unstable_applyFilters();
|
|
339
|
+
}
|
|
340
|
+
});
|
|
329
341
|
|
|
330
342
|
/**
|
|
331
343
|
* 1ST RENDER
|
|
@@ -2,7 +2,7 @@ import _extends from "@babel/runtime/helpers/esm/extends";
|
|
|
2
2
|
import { gridPinnedRowsSelector } from './gridRowsSelector';
|
|
3
3
|
import { gridDensityFactorSelector } from '../density/densitySelector';
|
|
4
4
|
export const GRID_ROOT_GROUP_ID = `auto-generated-group-node-root`;
|
|
5
|
-
export const GRID_ID_AUTOGENERATED = Symbol('mui
|
|
5
|
+
export const GRID_ID_AUTOGENERATED = Symbol('mui.id_autogenerated');
|
|
6
6
|
export const buildRootGroup = () => ({
|
|
7
7
|
type: 'group',
|
|
8
8
|
id: GRID_ROOT_GROUP_ID,
|
|
@@ -101,7 +101,7 @@ export function useGridParamsApi(apiRef, props) {
|
|
|
101
101
|
return colDef.valueGetter(getBaseCellParams(id, field));
|
|
102
102
|
}, [apiRef, getBaseCellParams]);
|
|
103
103
|
const getRowValue = React.useCallback((row, colDef) => {
|
|
104
|
-
const id =
|
|
104
|
+
const id = GRID_ID_AUTOGENERATED in row ? row[GRID_ID_AUTOGENERATED] : getRowId?.(row) ?? row.id;
|
|
105
105
|
const field = colDef.field;
|
|
106
106
|
if (!colDef || !colDef.valueGetter) {
|
|
107
107
|
return row[field];
|
|
@@ -1,27 +1,11 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
export function useGridApiMethod(privateApiRef, apiMethods, visibility) {
|
|
3
|
-
const
|
|
4
|
-
const [apiMethodsNames] = React.useState(Object.keys(apiMethods));
|
|
5
|
-
const installMethods = React.useCallback(() => {
|
|
6
|
-
if (!privateApiRef.current) {
|
|
7
|
-
return;
|
|
8
|
-
}
|
|
9
|
-
apiMethodsNames.forEach(methodName => {
|
|
10
|
-
if (!privateApiRef.current.hasOwnProperty(methodName)) {
|
|
11
|
-
privateApiRef.current.register(visibility, {
|
|
12
|
-
[methodName]: (...args) => {
|
|
13
|
-
const fn = apiMethodsRef.current[methodName];
|
|
14
|
-
return fn(...args);
|
|
15
|
-
}
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
}, [apiMethodsNames, privateApiRef, visibility]);
|
|
3
|
+
const isFirstRender = React.useRef(true);
|
|
20
4
|
React.useEffect(() => {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
5
|
+
isFirstRender.current = false;
|
|
6
|
+
privateApiRef.current.register(visibility, apiMethods);
|
|
7
|
+
}, [privateApiRef, visibility, apiMethods]);
|
|
8
|
+
if (isFirstRender.current) {
|
|
9
|
+
privateApiRef.current.register(visibility, apiMethods);
|
|
10
|
+
}
|
|
27
11
|
}
|
package/modern/index.js
CHANGED
|
@@ -8,6 +8,7 @@ export { getGridFilter } from '../components/panel/filterPanel/GridFilterPanel';
|
|
|
8
8
|
export { useGridRegisterPipeProcessor } from '../hooks/core/pipeProcessing';
|
|
9
9
|
export { useGridRegisterStrategyProcessor, GRID_DEFAULT_STRATEGY } from '../hooks/core/strategyProcessing';
|
|
10
10
|
export { useGridInitialization } from '../hooks/core/useGridInitialization';
|
|
11
|
+
export { unwrapPrivateAPI } from '../hooks/core/useGridApiInitialization';
|
|
11
12
|
export { useGridClipboard } from '../hooks/features/clipboard/useGridClipboard';
|
|
12
13
|
export { useGridColumnHeaders } from '../hooks/features/columnHeaders/useGridColumnHeaders';
|
|
13
14
|
export { unstable_gridHeaderFilteringEditFieldSelector, unstable_gridHeaderFilteringMenuSelector } from '../hooks/features/headerFiltering/gridHeaderFilteringSelectors';
|
package/modern/joy/joySlots.js
CHANGED
|
@@ -299,7 +299,20 @@ const Pagination = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
299
299
|
}, [apiRef]);
|
|
300
300
|
const page = paginationModel.page <= lastPage ? paginationModel.page : lastPage;
|
|
301
301
|
const pageSize = paginationModel.pageSize;
|
|
302
|
-
const
|
|
302
|
+
const isPageSizeIncludedInPageSizeOptions = () => {
|
|
303
|
+
for (let i = 0; i < rootProps.pageSizeOptions.length; i += 1) {
|
|
304
|
+
const option = rootProps.pageSizeOptions[i];
|
|
305
|
+
if (typeof option === 'number') {
|
|
306
|
+
if (option === pageSize) {
|
|
307
|
+
return true;
|
|
308
|
+
}
|
|
309
|
+
} else if (option.value === pageSize) {
|
|
310
|
+
return true;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
return false;
|
|
314
|
+
};
|
|
315
|
+
const pageSizeOptions = isPageSizeIncludedInPageSizeOptions() ? rootProps.pageSizeOptions : [];
|
|
303
316
|
const handleChangeRowsPerPage = (event, newValue) => {
|
|
304
317
|
const newPageSize = Number(newValue);
|
|
305
318
|
apiRef.current.setPageSize(newPageSize);
|
|
@@ -323,9 +336,9 @@ const Pagination = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
323
336
|
value: pageSize,
|
|
324
337
|
children: pageSizeOptions.map(option => {
|
|
325
338
|
return /*#__PURE__*/_jsx(Option, {
|
|
326
|
-
value: option,
|
|
327
|
-
children: option
|
|
328
|
-
}, option);
|
|
339
|
+
value: typeof option !== 'number' && option.value ? option.value : option,
|
|
340
|
+
children: typeof option !== 'number' && option.label ? option.label : `${option}`
|
|
341
|
+
}, typeof option !== 'number' && option.label ? option.label : `${option}`);
|
|
329
342
|
})
|
|
330
343
|
})]
|
|
331
344
|
}), /*#__PURE__*/_jsx(JoyTypography, {
|
package/modern/locales/esES.js
CHANGED
|
@@ -8,8 +8,8 @@ const esESGrid = {
|
|
|
8
8
|
toolbarDensity: 'Densidad',
|
|
9
9
|
toolbarDensityLabel: 'Densidad',
|
|
10
10
|
toolbarDensityCompact: 'Compacta',
|
|
11
|
-
toolbarDensityStandard: '
|
|
12
|
-
toolbarDensityComfortable: '
|
|
11
|
+
toolbarDensityStandard: 'Estándar',
|
|
12
|
+
toolbarDensityComfortable: 'Cómoda',
|
|
13
13
|
// Columns selector toolbar button text
|
|
14
14
|
toolbarColumns: 'Columnas',
|
|
15
15
|
toolbarColumnsLabel: 'Seleccionar columnas',
|
|
@@ -37,7 +37,7 @@ const esESGrid = {
|
|
|
37
37
|
columnsPanelHideAllButton: 'Ocultar todo',
|
|
38
38
|
// Filter panel text
|
|
39
39
|
filterPanelAddFilter: 'Agregar filtro',
|
|
40
|
-
|
|
40
|
+
filterPanelRemoveAll: 'Remover todos',
|
|
41
41
|
filterPanelDeleteIconLabel: 'Borrar',
|
|
42
42
|
filterPanelLogicOperator: 'Operador lógico',
|
|
43
43
|
filterPanelOperator: 'Operadores',
|
package/modern/locales/plPL.js
CHANGED
|
@@ -37,7 +37,7 @@ const plPLGrid = {
|
|
|
37
37
|
columnsPanelHideAllButton: 'Ukryj wszystko',
|
|
38
38
|
// Filter panel text
|
|
39
39
|
filterPanelAddFilter: 'Dodaj filtr',
|
|
40
|
-
|
|
40
|
+
filterPanelRemoveAll: 'Usuń wszystkie',
|
|
41
41
|
filterPanelDeleteIconLabel: 'Usuń',
|
|
42
42
|
filterPanelLogicOperator: 'Operator logiczny',
|
|
43
43
|
filterPanelOperator: 'Operator',
|
|
@@ -68,12 +68,12 @@ const plPLGrid = {
|
|
|
68
68
|
// 'filterOperator<=': '<=',
|
|
69
69
|
|
|
70
70
|
// Header filter operators text
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
headerFilterOperatorContains: 'Zawiera',
|
|
72
|
+
headerFilterOperatorEquals: 'Równa się',
|
|
73
|
+
headerFilterOperatorStartsWith: 'Zaczyna się od',
|
|
74
|
+
headerFilterOperatorEndsWith: 'Kończy się na',
|
|
75
75
|
// headerFilterOperatorIs: 'Is',
|
|
76
|
-
|
|
76
|
+
headerFilterOperatorNot: 'Niepuste',
|
|
77
77
|
// headerFilterOperatorAfter: 'Is after',
|
|
78
78
|
// headerFilterOperatorOnOrAfter: 'Is on or after',
|
|
79
79
|
// headerFilterOperatorBefore: 'Is before',
|
|
@@ -95,7 +95,7 @@ const plPLGrid = {
|
|
|
95
95
|
// Column menu text
|
|
96
96
|
columnMenuLabel: 'Menu',
|
|
97
97
|
columnMenuShowColumns: 'Pokaż wszystkie kolumny',
|
|
98
|
-
|
|
98
|
+
columnMenuManageColumns: 'Zarządzaj kolumnami',
|
|
99
99
|
columnMenuFilter: 'Filtr',
|
|
100
100
|
columnMenuHideColumn: 'Ukryj',
|
|
101
101
|
columnMenuUnsort: 'Anuluj sortowanie',
|
|
@@ -190,6 +190,7 @@ DataGridRaw.propTypes = {
|
|
|
190
190
|
value: _propTypes.default.any
|
|
191
191
|
})).isRequired,
|
|
192
192
|
logicOperator: _propTypes.default.oneOf(['and', 'or']),
|
|
193
|
+
quickFilterExcludeHiddenColumns: _propTypes.default.bool,
|
|
193
194
|
quickFilterLogicOperator: _propTypes.default.oneOf(['and', 'or']),
|
|
194
195
|
quickFilterValues: _propTypes.default.array
|
|
195
196
|
}),
|
|
@@ -522,7 +523,10 @@ DataGridRaw.propTypes = {
|
|
|
522
523
|
* Select the pageSize dynamically using the component UI.
|
|
523
524
|
* @default [25, 50, 100]
|
|
524
525
|
*/
|
|
525
|
-
pageSizeOptions: _propTypes.default.arrayOf(_propTypes.default.number
|
|
526
|
+
pageSizeOptions: _propTypes.default.arrayOf(_propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.shape({
|
|
527
|
+
label: _propTypes.default.string.isRequired,
|
|
528
|
+
value: _propTypes.default.number.isRequired
|
|
529
|
+
})]).isRequired),
|
|
526
530
|
pagination: props => {
|
|
527
531
|
if (props.pagination === false) {
|
|
528
532
|
return new Error(['MUI: `<DataGrid pagination={false} />` is not a valid prop.', 'Infinite scrolling is not available in the MIT version.', '', 'You need to upgrade to DataGridPro or DataGridPremium component to disable the pagination.'].join('\n'));
|
|
@@ -47,21 +47,35 @@ const GridPagination = /*#__PURE__*/React.forwardRef(function GridPagination(pro
|
|
|
47
47
|
const handlePageChange = React.useCallback((_, page) => {
|
|
48
48
|
apiRef.current.setPage(page);
|
|
49
49
|
}, [apiRef]);
|
|
50
|
+
const isPageSizeIncludedInPageSizeOptions = pageSize => {
|
|
51
|
+
for (let i = 0; i < rootProps.pageSizeOptions.length; i += 1) {
|
|
52
|
+
const option = rootProps.pageSizeOptions[i];
|
|
53
|
+
if (typeof option === 'number') {
|
|
54
|
+
if (option === pageSize) {
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
} else if (option.value === pageSize) {
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return false;
|
|
62
|
+
};
|
|
50
63
|
if (process.env.NODE_ENV !== 'production') {
|
|
51
64
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
52
65
|
const warnedOnceMissingInPageSizeOptions = React.useRef(false);
|
|
53
66
|
const pageSize = rootProps.paginationModel?.pageSize ?? paginationModel.pageSize;
|
|
54
|
-
if (!warnedOnceMissingInPageSizeOptions.current && !rootProps.autoPageSize && !
|
|
67
|
+
if (!warnedOnceMissingInPageSizeOptions.current && !rootProps.autoPageSize && !isPageSizeIncludedInPageSizeOptions(pageSize)) {
|
|
55
68
|
console.warn([`MUI: The page size \`${paginationModel.pageSize}\` is not preset in the \`pageSizeOptions\``, `Add it to show the pagination select.`].join('\n'));
|
|
56
69
|
warnedOnceMissingInPageSizeOptions.current = true;
|
|
57
70
|
}
|
|
58
71
|
}
|
|
72
|
+
const pageSizeOptions = isPageSizeIncludedInPageSizeOptions(paginationModel.pageSize) ? rootProps.pageSizeOptions : [];
|
|
59
73
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(GridPaginationRoot, (0, _extends2.default)({
|
|
60
74
|
ref: ref,
|
|
61
75
|
component: "div",
|
|
62
76
|
count: rowCount,
|
|
63
77
|
page: paginationModel.page <= lastPage ? paginationModel.page : lastPage,
|
|
64
|
-
rowsPerPageOptions:
|
|
78
|
+
rowsPerPageOptions: pageSizeOptions,
|
|
65
79
|
rowsPerPage: paginationModel.pageSize,
|
|
66
80
|
onPageChange: handlePageChange,
|
|
67
81
|
onRowsPerPageChange: handlePageSizeChange
|
|
@@ -121,7 +121,7 @@ function GridEditDateCell(props) {
|
|
|
121
121
|
const meta = apiRef.current.unstable_getEditCellMeta(id, field);
|
|
122
122
|
const handleInputRef = el => {
|
|
123
123
|
inputRef.current = el;
|
|
124
|
-
if (meta
|
|
124
|
+
if (meta?.unstable_updateValueOnRender && !hasUpdatedEditValueOnMount.current) {
|
|
125
125
|
const inputValue = inputRef.current.value;
|
|
126
126
|
const parsedDate = parseValueToDate(inputValue);
|
|
127
127
|
setValueState({
|
|
@@ -77,12 +77,12 @@ const GridEditInputCell = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
77
77
|
unstable_skipValueParser: true
|
|
78
78
|
}, event);
|
|
79
79
|
}, [apiRef, debounceMs, field, id, onValueChange]);
|
|
80
|
-
const meta = apiRef.current.unstable_getEditCellMeta
|
|
80
|
+
const meta = apiRef.current.unstable_getEditCellMeta(id, field);
|
|
81
81
|
React.useEffect(() => {
|
|
82
|
-
if (meta
|
|
82
|
+
if (meta?.changeReason !== 'debouncedSetEditCellValue') {
|
|
83
83
|
setValueState(value);
|
|
84
84
|
}
|
|
85
|
-
}, [meta
|
|
85
|
+
}, [meta, value]);
|
|
86
86
|
(0, _utils.unstable_useEnhancedEffect)(() => {
|
|
87
87
|
if (hasFocus) {
|
|
88
88
|
inputRef.current.focus();
|