@mui/x-data-grid 5.15.1 → 5.15.2
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 +44 -0
- package/DataGrid/DataGrid.js +1 -1
- package/hooks/features/editRows/useGridCellEditing.new.js +15 -7
- package/hooks/features/editRows/useGridRowEditing.new.js +9 -2
- package/hooks/features/filter/gridFilterState.d.ts +12 -1
- package/hooks/features/filter/gridFilterUtils.d.ts +8 -5
- package/hooks/features/filter/gridFilterUtils.js +74 -43
- package/hooks/features/filter/useGridFilter.js +16 -3
- package/hooks/features/focus/useGridFocus.js +11 -6
- package/hooks/features/rows/useGridRows.js +5 -2
- package/hooks/features/statePersistence/gridStatePersistenceInterface.d.ts +3 -0
- package/index.js +1 -1
- package/internals/index.d.ts +1 -0
- package/internals/index.js +1 -0
- package/legacy/DataGrid/DataGrid.js +1 -1
- package/legacy/hooks/features/editRows/useGridCellEditing.new.js +16 -8
- package/legacy/hooks/features/editRows/useGridRowEditing.new.js +9 -2
- package/legacy/hooks/features/filter/gridFilterUtils.js +84 -55
- package/legacy/hooks/features/filter/useGridFilter.js +16 -3
- package/legacy/hooks/features/focus/useGridFocus.js +11 -6
- package/legacy/hooks/features/rows/useGridRows.js +5 -2
- package/legacy/index.js +1 -1
- package/legacy/internals/index.js +1 -0
- package/models/props/DataGridProps.d.ts +3 -3
- package/modern/DataGrid/DataGrid.js +1 -1
- package/modern/hooks/features/editRows/useGridCellEditing.new.js +15 -7
- package/modern/hooks/features/editRows/useGridRowEditing.new.js +9 -2
- package/modern/hooks/features/filter/gridFilterUtils.js +73 -42
- package/modern/hooks/features/filter/useGridFilter.js +16 -3
- package/modern/hooks/features/focus/useGridFocus.js +11 -6
- package/modern/hooks/features/rows/useGridRows.js +5 -2
- package/modern/index.js +1 -1
- package/modern/internals/index.js +1 -0
- package/node/DataGrid/DataGrid.js +1 -1
- package/node/hooks/features/editRows/useGridCellEditing.new.js +15 -7
- package/node/hooks/features/editRows/useGridRowEditing.new.js +9 -2
- package/node/hooks/features/filter/gridFilterUtils.js +81 -47
- package/node/hooks/features/filter/useGridFilter.js +15 -2
- package/node/hooks/features/focus/useGridFocus.js +11 -6
- package/node/hooks/features/rows/useGridRows.js +5 -2
- package/node/index.js +1 -1
- package/node/internals/index.js +8 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,50 @@
|
|
|
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
|
+
## 5.15.2
|
|
7
|
+
|
|
8
|
+
_Aug 11, 2022_
|
|
9
|
+
|
|
10
|
+
We'd like to offer a big thanks to the 7 contributors who made this release possible. Here are some highlights ✨:
|
|
11
|
+
|
|
12
|
+
- ✨ Improve quick filtering with row grouping (#5701) @alexfauquette
|
|
13
|
+
- 📚 Documentation improvements
|
|
14
|
+
- 🐞 Bugfixes
|
|
15
|
+
|
|
16
|
+
### `@mui/x-data-grid@5.15.2` / `@mui/x-data-grid-pro@5.15.2` / `@mui/x-data-grid-premium@5.15.2`
|
|
17
|
+
|
|
18
|
+
#### Changes
|
|
19
|
+
|
|
20
|
+
- [DataGrid] Catch errors if rows freezing is not supported (#5711) @cherniavskii
|
|
21
|
+
- [DataGrid] Preserve cell mode when entering edit mode while commiting (#5686) @m4theushw
|
|
22
|
+
- [DataGridPremium] Let quick filter search in row grouping children (#5701) @alexfauquette
|
|
23
|
+
|
|
24
|
+
### `@mui/x-date-pickers@v5.0.0-beta.5` / `@mui/x-date-picker-pro@5.0.0-beta.5`
|
|
25
|
+
|
|
26
|
+
#### Changes
|
|
27
|
+
|
|
28
|
+
- [pickers] Add `react-dom` to peerDependencies (#5752) @cherniavskii
|
|
29
|
+
- [TimePicker] Set clock focus outline to `none` (#5758) @LukasTy
|
|
30
|
+
- [pickers] Fix theme augmentation with TypeScript (#5596) @alexfauquette
|
|
31
|
+
- [pickers] Reset input value when locale is modified (#5310) @alexfauquette
|
|
32
|
+
- [pickers] Support `disableHighlightToday` on `MonthPicker` and `YearPicker` (#5562) @flaviendelangle
|
|
33
|
+
- [pickers] Fallback to desktop mode when `matchMedia` is unavailable (#5684) @LukasTy
|
|
34
|
+
- [pickers] Trigger `onChange` when clearing or accepting `Invalid date` (#5740) @LukasTy
|
|
35
|
+
|
|
36
|
+
### Docs
|
|
37
|
+
|
|
38
|
+
- [docs] Add RFC GH issue template (#5739) @bytasv
|
|
39
|
+
- [docs] Add description to the `GridExportStateParams` page (#5654) @oliviertassinari
|
|
40
|
+
- [docs] Improve the Events page (#5413) @flaviendelangle
|
|
41
|
+
- [docs] Use new editing API in the introduction demos (#5728) @oliviertassinari
|
|
42
|
+
|
|
43
|
+
### Core
|
|
44
|
+
|
|
45
|
+
- [core] Remove duplicated `FUNDING.yml` file (#5656) @oliviertassinari
|
|
46
|
+
- [core] Remove outdated Next.js options (#5727) @oliviertassinari
|
|
47
|
+
- [core] Update tooling to run with React 18 (#4155) @m4theushw
|
|
48
|
+
- [test] Fix failing dynamic row height tests on Edge (#5707) @m4theushw
|
|
49
|
+
|
|
6
50
|
## 5.15.1
|
|
7
51
|
|
|
8
52
|
_Aug 4, 2022_
|
package/DataGrid/DataGrid.js
CHANGED
|
@@ -645,7 +645,7 @@ DataGridRaw.propTypes = {
|
|
|
645
645
|
* @param {GridState} state The new state.
|
|
646
646
|
* @param {MuiEvent<{}>} event The event object.
|
|
647
647
|
* @param {GridCallbackDetails} details Additional details for this callback.
|
|
648
|
-
* @
|
|
648
|
+
* @ignore - do not document.
|
|
649
649
|
*/
|
|
650
650
|
onStateChange: PropTypes.func,
|
|
651
651
|
|
|
@@ -15,6 +15,7 @@ import { GridCellEditStartReasons, GridCellEditStopReasons } from '../../../mode
|
|
|
15
15
|
const missingOnProcessRowUpdateErrorWarning = buildWarning(['MUI: A call to `processRowUpdate` threw an error which was not handled because `onProcessRowUpdateError` is missing.', 'To handle the error pass a callback to the `onProcessRowUpdateError` prop, e.g. `<DataGrid onProcessRowUpdateError={(error) => ...} />`.', 'For more detail, see http://mui.com/components/data-grid/editing/#persistence.'], 'error');
|
|
16
16
|
export const useGridCellEditing = (apiRef, props) => {
|
|
17
17
|
const [cellModesModel, setCellModesModel] = React.useState({});
|
|
18
|
+
const cellModesModelRef = React.useRef(cellModesModel);
|
|
18
19
|
const prevCellModesModel = React.useRef({});
|
|
19
20
|
const {
|
|
20
21
|
processRowUpdate,
|
|
@@ -62,6 +63,10 @@ export const useGridCellEditing = (apiRef, props) => {
|
|
|
62
63
|
return;
|
|
63
64
|
}
|
|
64
65
|
|
|
66
|
+
if (apiRef.current.getCellMode(params.id, params.field) === GridCellModes.View) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
65
70
|
const newParams = _extends({}, params, {
|
|
66
71
|
reason: GridCellEditStopReasons.cellFocusOut
|
|
67
72
|
});
|
|
@@ -194,18 +199,21 @@ export const useGridCellEditing = (apiRef, props) => {
|
|
|
194
199
|
}
|
|
195
200
|
|
|
196
201
|
setCellModesModel(newModel);
|
|
202
|
+
cellModesModelRef.current = newModel;
|
|
197
203
|
apiRef.current.publishEvent('cellModesModelChange', newModel);
|
|
198
204
|
}, [apiRef, onCellModesModelChange, props.cellModesModel, signature]);
|
|
199
205
|
const updateFieldInCellModesModel = React.useCallback((id, field, newProps) => {
|
|
200
|
-
|
|
206
|
+
// We use the ref because it always contain the up-to-date value, different from the state
|
|
207
|
+
// that needs a rerender to reflect the new value
|
|
208
|
+
const newModel = _extends({}, cellModesModelRef.current);
|
|
201
209
|
|
|
202
210
|
if (newProps !== null) {
|
|
203
211
|
newModel[id] = _extends({}, newModel[id], {
|
|
204
212
|
[field]: _extends({}, newProps)
|
|
205
213
|
});
|
|
206
214
|
} else {
|
|
207
|
-
const
|
|
208
|
-
otherFields = _objectWithoutPropertiesLoose(
|
|
215
|
+
const _newModel$id = newModel[id],
|
|
216
|
+
otherFields = _objectWithoutPropertiesLoose(_newModel$id, [field].map(_toPropertyKey)); // Ensure that we have a new object, not a reference
|
|
209
217
|
|
|
210
218
|
|
|
211
219
|
newModel[id] = otherFields;
|
|
@@ -216,7 +224,7 @@ export const useGridCellEditing = (apiRef, props) => {
|
|
|
216
224
|
}
|
|
217
225
|
|
|
218
226
|
updateCellModesModel(newModel);
|
|
219
|
-
}, [
|
|
227
|
+
}, [updateCellModesModel]);
|
|
220
228
|
const updateOrDeleteFieldState = React.useCallback((id, field, newProps) => {
|
|
221
229
|
apiRef.current.setState(state => {
|
|
222
230
|
const newEditingState = _extends({}, state.editRows);
|
|
@@ -289,12 +297,12 @@ export const useGridCellEditing = (apiRef, props) => {
|
|
|
289
297
|
apiRef.current.unstable_runPendingEditCellValueMutation(id, field);
|
|
290
298
|
|
|
291
299
|
const finishCellEditMode = () => {
|
|
300
|
+
updateOrDeleteFieldState(id, field, null);
|
|
301
|
+
updateFieldInCellModesModel(id, field, null);
|
|
302
|
+
|
|
292
303
|
if (cellToFocusAfter !== 'none') {
|
|
293
304
|
apiRef.current.unstable_moveFocusToRelativeCell(id, field, cellToFocusAfter);
|
|
294
305
|
}
|
|
295
|
-
|
|
296
|
-
updateOrDeleteFieldState(id, field, null);
|
|
297
|
-
updateFieldInCellModesModel(id, field, null);
|
|
298
306
|
};
|
|
299
307
|
|
|
300
308
|
if (ignoreModifications) {
|
|
@@ -16,6 +16,7 @@ import { GridRowEditStopReasons, GridRowEditStartReasons } from '../../../models
|
|
|
16
16
|
const missingOnProcessRowUpdateErrorWarning = buildWarning(['MUI: A call to `processRowUpdate` threw an error which was not handled because `onProcessRowUpdateError` is missing.', 'To handle the error pass a callback to the `onProcessRowUpdateError` prop, e.g. `<DataGrid onProcessRowUpdateError={(error) => ...} />`.', 'For more detail, see http://mui.com/components/data-grid/editing/#persistence.'], 'error');
|
|
17
17
|
export const useGridRowEditing = (apiRef, props) => {
|
|
18
18
|
const [rowModesModel, setRowModesModel] = React.useState({});
|
|
19
|
+
const rowModesModelRef = React.useRef(rowModesModel);
|
|
19
20
|
const prevRowModesModel = React.useRef({});
|
|
20
21
|
const focusTimeout = React.useRef(null);
|
|
21
22
|
const nextFocusedCell = React.useRef(null);
|
|
@@ -90,6 +91,11 @@ export const useGridRowEditing = (apiRef, props) => {
|
|
|
90
91
|
// The row might have been deleted during the click
|
|
91
92
|
if (!apiRef.current.getRow(params.id)) {
|
|
92
93
|
return;
|
|
94
|
+
} // The row may already changed its mode
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
if (apiRef.current.getRowMode(params.id) === GridRowModes.View) {
|
|
98
|
+
return;
|
|
93
99
|
}
|
|
94
100
|
|
|
95
101
|
const rowParams = apiRef.current.getRowParams(params.id);
|
|
@@ -260,10 +266,11 @@ export const useGridRowEditing = (apiRef, props) => {
|
|
|
260
266
|
}
|
|
261
267
|
|
|
262
268
|
setRowModesModel(newModel);
|
|
269
|
+
rowModesModelRef.current = newModel;
|
|
263
270
|
apiRef.current.publishEvent('rowModesModelChange', newModel);
|
|
264
271
|
}, [apiRef, onRowModesModelChange, props.rowModesModel, signature]);
|
|
265
272
|
const updateRowInRowModesModel = React.useCallback((id, newProps) => {
|
|
266
|
-
const newModel = _extends({},
|
|
273
|
+
const newModel = _extends({}, rowModesModelRef.current);
|
|
267
274
|
|
|
268
275
|
if (newProps !== null) {
|
|
269
276
|
newModel[id] = _extends({}, newProps);
|
|
@@ -272,7 +279,7 @@ export const useGridRowEditing = (apiRef, props) => {
|
|
|
272
279
|
}
|
|
273
280
|
|
|
274
281
|
updateRowModesModel(newModel);
|
|
275
|
-
}, [
|
|
282
|
+
}, [updateRowModesModel]);
|
|
276
283
|
const updateOrDeleteRowState = React.useCallback((id, newProps) => {
|
|
277
284
|
apiRef.current.setState(state => {
|
|
278
285
|
const newEditingState = _extends({}, state.editRows);
|
|
@@ -1,5 +1,12 @@
|
|
|
1
|
+
import { GridFilterItem } from '../../../models/gridFilterItem';
|
|
1
2
|
import { GridFilterModel } from '../../../models/gridFilterModel';
|
|
2
3
|
import { GridRowId } from '../../../models/gridRows';
|
|
4
|
+
export declare type GridFilterItemResult = {
|
|
5
|
+
[key: Required<GridFilterItem>['id']]: boolean;
|
|
6
|
+
};
|
|
7
|
+
export declare type GridQuickFilterValueResult = {
|
|
8
|
+
[key: string]: boolean;
|
|
9
|
+
};
|
|
3
10
|
export declare const getDefaultGridFilterModel: () => GridFilterModel;
|
|
4
11
|
export interface GridFilterState {
|
|
5
12
|
filterModel: GridFilterModel;
|
|
@@ -31,8 +38,12 @@ export interface GridFilterInitialState {
|
|
|
31
38
|
* @param {GridRowId} rowId The id of the row we want to filter.
|
|
32
39
|
* @param {(filterItem: GridFilterItem) => boolean} shouldApplyItem An optional callback to allow the filtering engine to only apply some items.
|
|
33
40
|
*/
|
|
34
|
-
export declare type GridAggregatedFilterItemApplier = (rowId: GridRowId, shouldApplyItem?: (columnField: string) => boolean) =>
|
|
41
|
+
export declare type GridAggregatedFilterItemApplier = (rowId: GridRowId, shouldApplyItem?: (columnField: string) => boolean) => {
|
|
42
|
+
passingFilterItems: null | GridFilterItemResult;
|
|
43
|
+
passingQuickFilterValues: null | GridQuickFilterValueResult;
|
|
44
|
+
};
|
|
35
45
|
export interface GridFilteringMethodParams {
|
|
36
46
|
isRowMatchingFilters: GridAggregatedFilterItemApplier | null;
|
|
47
|
+
filterModel: GridFilterModel;
|
|
37
48
|
}
|
|
38
49
|
export declare type GridFilteringMethodValue = Omit<GridFilterState, 'filterModel'>;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { GridFilterItem, GridFilterModel } from '../../../models';
|
|
2
|
+
import { GridFilterItem, GridFilterModel, GridRowId } from '../../../models';
|
|
3
3
|
import { GridApiCommunity } from '../../../models/api/gridApiCommunity';
|
|
4
4
|
import { GridStateCommunity } from '../../../models/gridStateCommunity';
|
|
5
|
-
import { GridAggregatedFilterItemApplier } from './gridFilterState';
|
|
5
|
+
import { GridAggregatedFilterItemApplier, GridFilterItemResult, GridQuickFilterValueResult } from './gridFilterState';
|
|
6
|
+
declare type GridFilterItemApplierNotAggregated = (rowId: GridRowId, shouldApplyItem?: (columnField: string) => boolean) => GridFilterItemResult;
|
|
6
7
|
/**
|
|
7
8
|
* Adds default values to the optional fields of a filter items.
|
|
8
9
|
* @param {GridFilterItem} item The raw filter item.
|
|
@@ -19,12 +20,14 @@ export declare const mergeStateWithFilterModel: (filterModel: GridFilterModel, d
|
|
|
19
20
|
* @param {React.MutableRefObject<GridApiCommunity>} apiRef The API of the grid.
|
|
20
21
|
* @returns {GridAggregatedFilterItemApplier | null} A method that checks if a row is matching the current filter model. If `null`, we consider that all the rows are matching the filters.
|
|
21
22
|
*/
|
|
22
|
-
export declare const buildAggregatedFilterItemsApplier: (filterModel: GridFilterModel, apiRef: React.MutableRefObject<GridApiCommunity>) =>
|
|
23
|
+
export declare const buildAggregatedFilterItemsApplier: (filterModel: GridFilterModel, apiRef: React.MutableRefObject<GridApiCommunity>) => GridFilterItemApplierNotAggregated | null;
|
|
23
24
|
/**
|
|
24
25
|
* Generates a method to easily check if a row is matching the current quick filter.
|
|
25
26
|
* @param {any[]} values The model with which we want to filter the rows.
|
|
26
27
|
* @param {React.MutableRefObject<GridApiCommunity>} apiRef The API of the grid.
|
|
27
28
|
* @returns {GridAggregatedFilterItemApplier | null} A method that checks if a row is matching the current filter model. If `null`, we consider that all the rows are matching the filters.
|
|
28
29
|
*/
|
|
29
|
-
export declare const buildAggregatedQuickFilterApplier: (filterModel: GridFilterModel, apiRef: React.MutableRefObject<GridApiCommunity>) =>
|
|
30
|
-
export declare const buildAggregatedFilterApplier: (filterModel: GridFilterModel, apiRef: React.MutableRefObject<GridApiCommunity>) => GridAggregatedFilterItemApplier
|
|
30
|
+
export declare const buildAggregatedQuickFilterApplier: (filterModel: GridFilterModel, apiRef: React.MutableRefObject<GridApiCommunity>) => GridFilterItemApplierNotAggregated | null;
|
|
31
|
+
export declare const buildAggregatedFilterApplier: (filterModel: GridFilterModel, apiRef: React.MutableRefObject<GridApiCommunity>) => GridAggregatedFilterItemApplier;
|
|
32
|
+
export declare const passFilterLogic: (allFilterItemResults: (null | GridFilterItemResult)[], allQuickFilterResults: (null | GridQuickFilterValueResult)[], filterModel: GridFilterModel) => boolean;
|
|
33
|
+
export {};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
2
|
import { GridLinkOperator } from '../../../models';
|
|
3
|
+
import { getDefaultGridFilterModel } from './gridFilterState';
|
|
3
4
|
import { buildWarning } from '../../../utils/warning';
|
|
4
5
|
import { gridColumnFieldsSelector, gridColumnLookupSelector } from '../columns';
|
|
5
|
-
import { gridRowTreeSelector } from '../rows/gridRowsSelector';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Adds default values to the optional fields of a filter items.
|
|
@@ -78,10 +78,8 @@ export const mergeStateWithFilterModel = (filterModel, disableMultipleColumnsFil
|
|
|
78
78
|
|
|
79
79
|
export const buildAggregatedFilterItemsApplier = (filterModel, apiRef) => {
|
|
80
80
|
const {
|
|
81
|
-
items
|
|
82
|
-
linkOperator = GridLinkOperator.And
|
|
81
|
+
items
|
|
83
82
|
} = filterModel;
|
|
84
|
-
const tree = gridRowTreeSelector(apiRef);
|
|
85
83
|
|
|
86
84
|
const getFilterCallbackFromItem = filterItem => {
|
|
87
85
|
if (!filterItem.columnField || !filterItem.operatorValue) {
|
|
@@ -145,18 +143,12 @@ export const buildAggregatedFilterItemsApplier = (filterModel, apiRef) => {
|
|
|
145
143
|
}
|
|
146
144
|
|
|
147
145
|
return (rowId, shouldApplyFilter) => {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
if (linkOperator === GridLinkOperator.And) {
|
|
155
|
-
return filteredAppliers.every(applier => applier.fn(rowId));
|
|
156
|
-
} // Return `true` as soon as we have a passing filter
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
return filteredAppliers.some(applier => applier.fn(rowId));
|
|
146
|
+
const resultPerItemId = {};
|
|
147
|
+
const filteredAppliers = shouldApplyFilter ? appliers.filter(applier => shouldApplyFilter(applier.item.columnField)) : appliers;
|
|
148
|
+
filteredAppliers.forEach(applier => {
|
|
149
|
+
resultPerItemId[applier.item.id] = applier.fn(rowId);
|
|
150
|
+
});
|
|
151
|
+
return resultPerItemId;
|
|
160
152
|
};
|
|
161
153
|
};
|
|
162
154
|
/**
|
|
@@ -168,8 +160,7 @@ export const buildAggregatedFilterItemsApplier = (filterModel, apiRef) => {
|
|
|
168
160
|
|
|
169
161
|
export const buildAggregatedQuickFilterApplier = (filterModel, apiRef) => {
|
|
170
162
|
const {
|
|
171
|
-
quickFilterValues = []
|
|
172
|
-
quickFilterLogicOperator = GridLinkOperator.And
|
|
163
|
+
quickFilterValues = []
|
|
173
164
|
} = filterModel;
|
|
174
165
|
|
|
175
166
|
if (quickFilterValues.length === 0) {
|
|
@@ -190,6 +181,11 @@ export const buildAggregatedQuickFilterApplier = (filterModel, apiRef) => {
|
|
|
190
181
|
}); // If some value does not have an applier we ignore them
|
|
191
182
|
|
|
192
183
|
const sanitizedQuickFilterValues = quickFilterValues.filter((value, index) => Object.keys(appliersPerColumnField).some(field => appliersPerColumnField[field][index] != null));
|
|
184
|
+
|
|
185
|
+
if (sanitizedQuickFilterValues.length === 0) {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
|
|
193
189
|
return (rowId, shouldApplyFilter) => {
|
|
194
190
|
const usedCellParams = {};
|
|
195
191
|
const columnsFieldsToFilter = [];
|
|
@@ -198,10 +194,10 @@ export const buildAggregatedQuickFilterApplier = (filterModel, apiRef) => {
|
|
|
198
194
|
usedCellParams[columnField] = apiRef.current.getCellParams(rowId, columnField);
|
|
199
195
|
columnsFieldsToFilter.push(columnField);
|
|
200
196
|
}
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
197
|
+
});
|
|
198
|
+
const quickFilterValueResult = {};
|
|
199
|
+
sanitizedQuickFilterValues.forEach((value, index) => {
|
|
200
|
+
const isPassing = columnsFieldsToFilter.some(field => {
|
|
205
201
|
var _appliersPerColumnFie, _appliersPerColumnFie2;
|
|
206
202
|
|
|
207
203
|
if (appliersPerColumnField[field][index] == null) {
|
|
@@ -209,36 +205,71 @@ export const buildAggregatedQuickFilterApplier = (filterModel, apiRef) => {
|
|
|
209
205
|
}
|
|
210
206
|
|
|
211
207
|
return (_appliersPerColumnFie = (_appliersPerColumnFie2 = appliersPerColumnField[field])[index]) == null ? void 0 : _appliersPerColumnFie.call(_appliersPerColumnFie2, usedCellParams[field]);
|
|
212
|
-
})
|
|
213
|
-
|
|
208
|
+
});
|
|
209
|
+
quickFilterValueResult[value] = isPassing;
|
|
210
|
+
});
|
|
211
|
+
return quickFilterValueResult;
|
|
212
|
+
};
|
|
213
|
+
};
|
|
214
|
+
export const buildAggregatedFilterApplier = (filterModel, apiRef) => {
|
|
215
|
+
const isRowMatchingFilterItems = buildAggregatedFilterItemsApplier(filterModel, apiRef);
|
|
216
|
+
const isRowMatchingQuickFilter = buildAggregatedQuickFilterApplier(filterModel, apiRef);
|
|
217
|
+
return (rowId, shouldApplyFilter) => ({
|
|
218
|
+
passingFilterItems: isRowMatchingFilterItems && isRowMatchingFilterItems(rowId, shouldApplyFilter),
|
|
219
|
+
passingQuickFilterValues: isRowMatchingQuickFilter && isRowMatchingQuickFilter(rowId, shouldApplyFilter)
|
|
220
|
+
});
|
|
221
|
+
};
|
|
222
|
+
export const passFilterLogic = (allFilterItemResults, allQuickFilterResults, filterModel) => {
|
|
223
|
+
var _filterModel$quickFil, _filterModel$linkOper;
|
|
214
224
|
|
|
225
|
+
const cleanedAllFilterItemResults = allFilterItemResults.filter(result => result != null);
|
|
226
|
+
const cleanedAllQuickFilterResults = allQuickFilterResults.filter(result => result != null); // Defaultize operators
|
|
215
227
|
|
|
216
|
-
|
|
217
|
-
|
|
228
|
+
const quickFilterLogicOperator = (_filterModel$quickFil = filterModel.quickFilterLogicOperator) != null ? _filterModel$quickFil : getDefaultGridFilterModel().quickFilterLogicOperator;
|
|
229
|
+
const linkOperator = (_filterModel$linkOper = filterModel.linkOperator) != null ? _filterModel$linkOper : getDefaultGridFilterModel().linkOperator; // get result for filter items model
|
|
218
230
|
|
|
219
|
-
|
|
231
|
+
if (cleanedAllFilterItemResults.length > 0) {
|
|
232
|
+
// Return true if the item pass with one of the rows
|
|
233
|
+
const filterItemPredicate = item => {
|
|
234
|
+
return cleanedAllFilterItemResults.some(filterItemResult => filterItemResult[item.id]);
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
if (linkOperator === GridLinkOperator.And) {
|
|
238
|
+
const passesAllFilters = filterModel.items.every(filterItemPredicate);
|
|
239
|
+
|
|
240
|
+
if (!passesAllFilters) {
|
|
220
241
|
return false;
|
|
221
242
|
}
|
|
243
|
+
} else {
|
|
244
|
+
const passesSomeFilters = filterModel.items.some(filterItemPredicate);
|
|
222
245
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
const isRowMatchingFilterItems = buildAggregatedFilterItemsApplier(filterModel, apiRef);
|
|
229
|
-
const isRowMatchingQuickFilter = buildAggregatedQuickFilterApplier(filterModel, apiRef);
|
|
246
|
+
if (!passesSomeFilters) {
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
} // get result for quick filter model
|
|
230
251
|
|
|
231
|
-
if (isRowMatchingFilterItems == null && isRowMatchingQuickFilter == null) {
|
|
232
|
-
return null;
|
|
233
|
-
}
|
|
234
252
|
|
|
235
|
-
if (
|
|
236
|
-
|
|
237
|
-
|
|
253
|
+
if (cleanedAllQuickFilterResults.length > 0 && filterModel.quickFilterValues != null) {
|
|
254
|
+
// Return true if the item pass with one of the rows
|
|
255
|
+
const quickFilterValuePredicate = value => {
|
|
256
|
+
return cleanedAllQuickFilterResults.some(quickFilterValueResult => quickFilterValueResult[value]);
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
if (quickFilterLogicOperator === GridLinkOperator.And) {
|
|
260
|
+
const passesAllQuickFilterValues = filterModel.quickFilterValues.every(quickFilterValuePredicate);
|
|
238
261
|
|
|
239
|
-
|
|
240
|
-
|
|
262
|
+
if (!passesAllQuickFilterValues) {
|
|
263
|
+
return false;
|
|
264
|
+
}
|
|
265
|
+
} else {
|
|
266
|
+
const passesSomeQuickFilterValues = filterModel.quickFilterValues.some(quickFilterValuePredicate);
|
|
267
|
+
|
|
268
|
+
if (!passesSomeQuickFilterValues) {
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
241
272
|
}
|
|
242
273
|
|
|
243
|
-
return
|
|
274
|
+
return true;
|
|
244
275
|
};
|
|
@@ -12,7 +12,7 @@ import { useFirstRender } from '../../utils/useFirstRender';
|
|
|
12
12
|
import { gridRowIdsSelector } from '../rows';
|
|
13
13
|
import { useGridRegisterPipeProcessor } from '../../core/pipeProcessing';
|
|
14
14
|
import { GRID_DEFAULT_STRATEGY, useGridRegisterStrategyProcessor } from '../../core/strategyProcessing';
|
|
15
|
-
import { buildAggregatedFilterApplier, sanitizeFilterModel, mergeStateWithFilterModel, cleanFilterItem } from './gridFilterUtils';
|
|
15
|
+
import { buildAggregatedFilterApplier, sanitizeFilterModel, mergeStateWithFilterModel, cleanFilterItem, passFilterLogic } from './gridFilterUtils';
|
|
16
16
|
import { isDeepEqual } from '../../../utils/utils';
|
|
17
17
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
18
18
|
export const filterStateInitializer = (state, props, apiRef) => {
|
|
@@ -49,7 +49,8 @@ export const useGridFilter = (apiRef, props) => {
|
|
|
49
49
|
const filterModel = gridFilterModelSelector(state, apiRef.current.instanceId);
|
|
50
50
|
const isRowMatchingFilters = props.filterMode === GridFeatureModeConstant.client ? buildAggregatedFilterApplier(filterModel, apiRef) : null;
|
|
51
51
|
const filteringResult = apiRef.current.unstable_applyStrategyProcessor('filtering', {
|
|
52
|
-
isRowMatchingFilters
|
|
52
|
+
isRowMatchingFilters,
|
|
53
|
+
filterModel: filterModel != null ? filterModel : getDefaultGridFilterModel()
|
|
53
54
|
});
|
|
54
55
|
return _extends({}, state, {
|
|
55
56
|
filter: _extends({}, state.filter, filteringResult)
|
|
@@ -261,7 +262,19 @@ export const useGridFilter = (apiRef, props) => {
|
|
|
261
262
|
|
|
262
263
|
for (let i = 0; i < rowIds.length; i += 1) {
|
|
263
264
|
const rowId = rowIds[i];
|
|
264
|
-
|
|
265
|
+
let isRowPassing;
|
|
266
|
+
|
|
267
|
+
if (typeof rowId === 'string' && rowId.startsWith('auto-generated-group-footer')) {
|
|
268
|
+
isRowPassing = true;
|
|
269
|
+
} else {
|
|
270
|
+
const {
|
|
271
|
+
passingFilterItems,
|
|
272
|
+
passingQuickFilterValues
|
|
273
|
+
} = params.isRowMatchingFilters(rowId);
|
|
274
|
+
isRowPassing = passFilterLogic([passingFilterItems], [passingQuickFilterValues], params.filterModel);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
filteredRowsLookup[rowId] = isRowPassing;
|
|
265
278
|
}
|
|
266
279
|
|
|
267
280
|
return {
|
|
@@ -60,6 +60,12 @@ export const useGridFocus = (apiRef, props) => {
|
|
|
60
60
|
return;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
+
if (focusedCell) {
|
|
64
|
+
// There's a focused cell but another cell was clicked
|
|
65
|
+
// Publishes an event to notify that the focus was lost
|
|
66
|
+
apiRef.current.publishEvent('cellFocusOut', apiRef.current.getCellParams(focusedCell.id, focusedCell.field));
|
|
67
|
+
}
|
|
68
|
+
|
|
63
69
|
apiRef.current.publishEvent('cellFocusIn', apiRef.current.getCellParams(id, field));
|
|
64
70
|
}, [apiRef, logger]);
|
|
65
71
|
const setColumnHeaderFocus = React.useCallback((field, event = {}) => {
|
|
@@ -191,11 +197,7 @@ export const useGridFocus = (apiRef, props) => {
|
|
|
191
197
|
|
|
192
198
|
if (!apiRef.current.getRow(focusedCell.id)) {
|
|
193
199
|
return;
|
|
194
|
-
}
|
|
195
|
-
// Publishes an event to notify that the focus was lost
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
apiRef.current.publishEvent('cellFocusOut', apiRef.current.getCellParams(focusedCell.id, focusedCell.field), event);
|
|
200
|
+
}
|
|
199
201
|
|
|
200
202
|
if (cellParams) {
|
|
201
203
|
apiRef.current.setCellFocus(cellParams.id, cellParams.field);
|
|
@@ -206,7 +208,10 @@ export const useGridFocus = (apiRef, props) => {
|
|
|
206
208
|
columnHeader: null
|
|
207
209
|
}
|
|
208
210
|
}));
|
|
209
|
-
apiRef.current.forceUpdate();
|
|
211
|
+
apiRef.current.forceUpdate(); // There's a focused cell but another element (not a cell) was clicked
|
|
212
|
+
// Publishes an event to notify that the focus was lost
|
|
213
|
+
|
|
214
|
+
apiRef.current.publishEvent('cellFocusOut', apiRef.current.getCellParams(focusedCell.id, focusedCell.field), event);
|
|
210
215
|
}
|
|
211
216
|
}, [apiRef]);
|
|
212
217
|
const handleCellModeChange = React.useCallback(params => {
|
|
@@ -26,8 +26,11 @@ export const rowsStateInitializer = (state, props, apiRef) => {
|
|
|
26
26
|
};
|
|
27
27
|
export const useGridRows = (apiRef, props) => {
|
|
28
28
|
if (process.env.NODE_ENV !== 'production') {
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
try {
|
|
30
|
+
// Freeze the `rows` prop so developers have a fast failure if they try to use Array.prototype.push().
|
|
31
|
+
Object.freeze(props.rows);
|
|
32
|
+
} catch (error) {// Sometimes, it's impossible to freeze, so we give up on it.
|
|
33
|
+
}
|
|
31
34
|
}
|
|
32
35
|
|
|
33
36
|
const logger = useGridLogger(apiRef, 'useGridRows');
|
|
@@ -20,6 +20,9 @@ export interface GridRestoreStatePreProcessingValue {
|
|
|
20
20
|
*/
|
|
21
21
|
callbacks: (() => void)[];
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Object passed as parameter in the `exportState()` grid API method.
|
|
25
|
+
*/
|
|
23
26
|
export interface GridExportStateParams {
|
|
24
27
|
/**
|
|
25
28
|
* By default, the grid exports all the models.
|
package/index.js
CHANGED
package/internals/index.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export { useGridDensity, densityStateInitializer } from '../hooks/features/densi
|
|
|
18
18
|
export { useGridCsvExport } from '../hooks/features/export/useGridCsvExport';
|
|
19
19
|
export { useGridPrintExport } from '../hooks/features/export/useGridPrintExport';
|
|
20
20
|
export { useGridFilter, filterStateInitializer } from '../hooks/features/filter/useGridFilter';
|
|
21
|
+
export { passFilterLogic } from '../hooks/features/filter/gridFilterUtils';
|
|
21
22
|
export type { GridAggregatedFilterItemApplier } from '../hooks/features/filter/gridFilterState';
|
|
22
23
|
export { useGridFocus, focusStateInitializer } from '../hooks/features/focus/useGridFocus';
|
|
23
24
|
export { useGridKeyboardNavigation } from '../hooks/features/keyboardNavigation/useGridKeyboardNavigation';
|
package/internals/index.js
CHANGED
|
@@ -15,6 +15,7 @@ export { useGridDensity, densityStateInitializer } from '../hooks/features/densi
|
|
|
15
15
|
export { useGridCsvExport } from '../hooks/features/export/useGridCsvExport';
|
|
16
16
|
export { useGridPrintExport } from '../hooks/features/export/useGridPrintExport';
|
|
17
17
|
export { useGridFilter, filterStateInitializer } from '../hooks/features/filter/useGridFilter';
|
|
18
|
+
export { passFilterLogic } from '../hooks/features/filter/gridFilterUtils';
|
|
18
19
|
export { useGridFocus, focusStateInitializer } from '../hooks/features/focus/useGridFocus';
|
|
19
20
|
export { useGridKeyboardNavigation } from '../hooks/features/keyboardNavigation/useGridKeyboardNavigation';
|
|
20
21
|
export { useGridPagination, paginationStateInitializer } from '../hooks/features/pagination/useGridPagination';
|
|
@@ -647,7 +647,7 @@ DataGridRaw.propTypes = {
|
|
|
647
647
|
* @param {GridState} state The new state.
|
|
648
648
|
* @param {MuiEvent<{}>} event The event object.
|
|
649
649
|
* @param {GridCallbackDetails} details Additional details for this callback.
|
|
650
|
-
* @
|
|
650
|
+
* @ignore - do not document.
|
|
651
651
|
*/
|
|
652
652
|
onStateChange: PropTypes.func,
|
|
653
653
|
|
|
@@ -23,6 +23,7 @@ export var useGridCellEditing = function useGridCellEditing(apiRef, props) {
|
|
|
23
23
|
cellModesModel = _React$useState2[0],
|
|
24
24
|
setCellModesModel = _React$useState2[1];
|
|
25
25
|
|
|
26
|
+
var cellModesModelRef = React.useRef(cellModesModel);
|
|
26
27
|
var prevCellModesModel = React.useRef({});
|
|
27
28
|
var processRowUpdate = props.processRowUpdate,
|
|
28
29
|
onProcessRowUpdateError = props.onProcessRowUpdateError,
|
|
@@ -70,6 +71,10 @@ export var useGridCellEditing = function useGridCellEditing(apiRef, props) {
|
|
|
70
71
|
return;
|
|
71
72
|
}
|
|
72
73
|
|
|
74
|
+
if (apiRef.current.getCellMode(params.id, params.field) === GridCellModes.View) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
73
78
|
var newParams = _extends({}, params, {
|
|
74
79
|
reason: GridCellEditStopReasons.cellFocusOut
|
|
75
80
|
});
|
|
@@ -198,17 +203,20 @@ export var useGridCellEditing = function useGridCellEditing(apiRef, props) {
|
|
|
198
203
|
}
|
|
199
204
|
|
|
200
205
|
setCellModesModel(newModel);
|
|
206
|
+
cellModesModelRef.current = newModel;
|
|
201
207
|
apiRef.current.publishEvent('cellModesModelChange', newModel);
|
|
202
208
|
}, [apiRef, onCellModesModelChange, props.cellModesModel, signature]);
|
|
203
209
|
var updateFieldInCellModesModel = React.useCallback(function (id, field, newProps) {
|
|
204
|
-
|
|
210
|
+
// We use the ref because it always contain the up-to-date value, different from the state
|
|
211
|
+
// that needs a rerender to reflect the new value
|
|
212
|
+
var newModel = _extends({}, cellModesModelRef.current);
|
|
205
213
|
|
|
206
214
|
if (newProps !== null) {
|
|
207
215
|
newModel[id] = _extends({}, newModel[id], _defineProperty({}, field, _extends({}, newProps)));
|
|
208
216
|
} else {
|
|
209
|
-
var
|
|
210
|
-
fieldToRemove =
|
|
211
|
-
otherFields = _objectWithoutProperties(
|
|
217
|
+
var _newModel$id = newModel[id],
|
|
218
|
+
fieldToRemove = _newModel$id[field],
|
|
219
|
+
otherFields = _objectWithoutProperties(_newModel$id, [field].map(_toPropertyKey)); // Ensure that we have a new object, not a reference
|
|
212
220
|
|
|
213
221
|
|
|
214
222
|
newModel[id] = otherFields;
|
|
@@ -219,7 +227,7 @@ export var useGridCellEditing = function useGridCellEditing(apiRef, props) {
|
|
|
219
227
|
}
|
|
220
228
|
|
|
221
229
|
updateCellModesModel(newModel);
|
|
222
|
-
}, [
|
|
230
|
+
}, [updateCellModesModel]);
|
|
223
231
|
var updateOrDeleteFieldState = React.useCallback(function (id, field, newProps) {
|
|
224
232
|
apiRef.current.setState(function (state) {
|
|
225
233
|
var newEditingState = _extends({}, state.editRows);
|
|
@@ -286,12 +294,12 @@ export var useGridCellEditing = function useGridCellEditing(apiRef, props) {
|
|
|
286
294
|
apiRef.current.unstable_runPendingEditCellValueMutation(id, field);
|
|
287
295
|
|
|
288
296
|
finishCellEditMode = function finishCellEditMode() {
|
|
297
|
+
updateOrDeleteFieldState(id, field, null);
|
|
298
|
+
updateFieldInCellModesModel(id, field, null);
|
|
299
|
+
|
|
289
300
|
if (cellToFocusAfter !== 'none') {
|
|
290
301
|
apiRef.current.unstable_moveFocusToRelativeCell(id, field, cellToFocusAfter);
|
|
291
302
|
}
|
|
292
|
-
|
|
293
|
-
updateOrDeleteFieldState(id, field, null);
|
|
294
|
-
updateFieldInCellModesModel(id, field, null);
|
|
295
303
|
};
|
|
296
304
|
|
|
297
305
|
if (!ignoreModifications) {
|