@mui/x-data-grid 7.0.0-alpha.5 → 7.0.0-alpha.6
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 +226 -6
- package/DataGrid/DataGrid.js +25 -19
- package/DataGrid/useDataGridProps.js +0 -1
- package/colDef/gridDateOperators.js +13 -6
- package/colDef/gridSingleSelectColDef.js +6 -15
- package/components/cell/GridEditSingleSelectCell.d.ts +1 -2
- package/components/cell/GridEditSingleSelectCell.js +9 -29
- package/components/columnSelection/GridHeaderCheckbox.js +3 -1
- package/components/panel/filterPanel/GridFilterForm.js +44 -9
- package/components/panel/filterPanel/GridFilterInputBoolean.js +1 -1
- package/components/panel/filterPanel/GridFilterInputDate.js +25 -8
- package/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.d.ts +2 -2
- package/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.js +7 -48
- package/components/panel/filterPanel/GridFilterInputSingleSelect.d.ts +1 -2
- package/components/panel/filterPanel/GridFilterInputSingleSelect.js +15 -57
- package/components/panel/filterPanel/filterPanelUtils.d.ts +3 -2
- package/components/panel/filterPanel/filterPanelUtils.js +10 -5
- package/hooks/features/rowSelection/useGridRowSelection.js +9 -9
- package/hooks/features/rowSelection/utils.d.ts +2 -0
- package/hooks/features/rowSelection/utils.js +8 -0
- package/hooks/utils/useGridAriaAttributes.js +2 -1
- package/index.js +1 -1
- package/legacy/DataGrid/DataGrid.js +25 -19
- package/legacy/DataGrid/useDataGridProps.js +0 -1
- package/legacy/colDef/gridDateOperators.js +13 -13
- package/legacy/colDef/gridSingleSelectColDef.js +6 -15
- package/legacy/components/cell/GridEditSingleSelectCell.js +8 -28
- package/legacy/components/columnSelection/GridHeaderCheckbox.js +3 -1
- package/legacy/components/panel/filterPanel/GridFilterForm.js +51 -19
- package/legacy/components/panel/filterPanel/GridFilterInputBoolean.js +1 -1
- package/legacy/components/panel/filterPanel/GridFilterInputDate.js +27 -8
- package/legacy/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.js +6 -53
- package/legacy/components/panel/filterPanel/GridFilterInputSingleSelect.js +14 -59
- package/legacy/components/panel/filterPanel/filterPanelUtils.js +10 -6
- package/legacy/hooks/features/rowSelection/useGridRowSelection.js +9 -9
- package/legacy/hooks/features/rowSelection/utils.js +8 -0
- package/legacy/hooks/utils/useGridAriaAttributes.js +2 -1
- package/legacy/index.js +1 -1
- package/models/props/DataGridProps.d.ts +26 -25
- package/modern/DataGrid/DataGrid.js +25 -19
- package/modern/DataGrid/useDataGridProps.js +0 -1
- package/modern/colDef/gridDateOperators.js +13 -6
- package/modern/colDef/gridSingleSelectColDef.js +6 -15
- package/modern/components/cell/GridEditSingleSelectCell.js +9 -29
- package/modern/components/columnSelection/GridHeaderCheckbox.js +3 -1
- package/modern/components/panel/filterPanel/GridFilterForm.js +44 -9
- package/modern/components/panel/filterPanel/GridFilterInputBoolean.js +1 -1
- package/modern/components/panel/filterPanel/GridFilterInputDate.js +24 -6
- package/modern/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.js +7 -47
- package/modern/components/panel/filterPanel/GridFilterInputSingleSelect.js +15 -56
- package/modern/components/panel/filterPanel/filterPanelUtils.js +10 -5
- package/modern/hooks/features/rowSelection/useGridRowSelection.js +9 -9
- package/modern/hooks/features/rowSelection/utils.js +8 -0
- package/modern/hooks/utils/useGridAriaAttributes.js +2 -1
- package/modern/index.js +1 -1
- package/node/DataGrid/DataGrid.js +25 -19
- package/node/DataGrid/useDataGridProps.js +0 -1
- package/node/colDef/gridDateOperators.js +13 -6
- package/node/colDef/gridSingleSelectColDef.js +5 -14
- package/node/components/cell/GridEditSingleSelectCell.js +8 -28
- package/node/components/columnSelection/GridHeaderCheckbox.js +3 -1
- package/node/components/panel/filterPanel/GridFilterForm.js +44 -9
- package/node/components/panel/filterPanel/GridFilterInputBoolean.js +1 -1
- package/node/components/panel/filterPanel/GridFilterInputDate.js +24 -6
- package/node/components/panel/filterPanel/GridFilterInputMultipleSingleSelect.js +6 -46
- package/node/components/panel/filterPanel/GridFilterInputSingleSelect.js +14 -55
- package/node/components/panel/filterPanel/filterPanelUtils.js +12 -7
- package/node/hooks/features/rowSelection/useGridRowSelection.js +9 -9
- package/node/hooks/features/rowSelection/utils.js +14 -0
- package/node/hooks/utils/useGridAriaAttributes.js +2 -1
- package/node/index.js +1 -1
- package/package.json +3 -3
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { GridFilterInputDate } from '../components/panel/filterPanel/GridFilterInputDate';
|
|
2
|
-
const dateRegex = /(\d+)-(\d+)-(\d+)/;
|
|
3
|
-
const dateTimeRegex = /(\d+)-(\d+)-(\d+)T(\d+):(\d+)/;
|
|
4
2
|
function buildApplyFilterFn(filterItem, compareFn, showTime, keepHours) {
|
|
5
3
|
if (!filterItem.value) {
|
|
6
4
|
return null;
|
|
7
5
|
}
|
|
8
|
-
const
|
|
9
|
-
|
|
6
|
+
const date = new Date(filterItem.value);
|
|
7
|
+
if (showTime) {
|
|
8
|
+
date.setSeconds(0, 0);
|
|
9
|
+
} else {
|
|
10
|
+
date.setHours(0, 0, 0, 0);
|
|
11
|
+
}
|
|
12
|
+
const time = date.getTime();
|
|
10
13
|
return value => {
|
|
11
14
|
if (!value) {
|
|
12
15
|
return false;
|
|
@@ -17,8 +20,12 @@ function buildApplyFilterFn(filterItem, compareFn, showTime, keepHours) {
|
|
|
17
20
|
|
|
18
21
|
// Make a copy of the date to not reset the hours in the original object
|
|
19
22
|
const dateCopy = new Date(value);
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
if (showTime) {
|
|
24
|
+
dateCopy.setSeconds(0, 0);
|
|
25
|
+
} else {
|
|
26
|
+
dateCopy.setHours(0, 0, 0, 0);
|
|
27
|
+
}
|
|
28
|
+
return compareFn(dateCopy.getTime(), time);
|
|
22
29
|
};
|
|
23
30
|
}
|
|
24
31
|
export const getGridDateOperators = showTime => [{
|
|
@@ -2,7 +2,7 @@ import _extends from "@babel/runtime/helpers/esm/extends";
|
|
|
2
2
|
import { GRID_STRING_COL_DEF } from './gridStringColDef';
|
|
3
3
|
import { renderEditSingleSelectCell } from '../components/cell/GridEditSingleSelectCell';
|
|
4
4
|
import { getGridSingleSelectOperators } from './gridSingleSelectOperators';
|
|
5
|
-
import { isSingleSelectColDef } from '../components/panel/filterPanel/filterPanelUtils';
|
|
5
|
+
import { getValueOptions, isSingleSelectColDef } from '../components/panel/filterPanel/filterPanelUtils';
|
|
6
6
|
import { isObject } from '../utils/utils';
|
|
7
7
|
const isArrayOfObjects = options => {
|
|
8
8
|
return typeof options[0] === 'object';
|
|
@@ -28,16 +28,10 @@ export const GRID_SINGLE_SELECT_COL_DEF = _extends({}, GRID_STRING_COL_DEF, {
|
|
|
28
28
|
if (!isSingleSelectColDef(colDef)) {
|
|
29
29
|
return '';
|
|
30
30
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
row: id ? api.getRow(id) : null,
|
|
36
|
-
field
|
|
37
|
-
});
|
|
38
|
-
} else {
|
|
39
|
-
valueOptions = colDef.valueOptions;
|
|
40
|
-
}
|
|
31
|
+
const valueOptions = getValueOptions(colDef, {
|
|
32
|
+
id,
|
|
33
|
+
row: id ? api.getRow(id) : null
|
|
34
|
+
});
|
|
41
35
|
if (value == null) {
|
|
42
36
|
return '';
|
|
43
37
|
}
|
|
@@ -55,10 +49,7 @@ export const GRID_SINGLE_SELECT_COL_DEF = _extends({}, GRID_STRING_COL_DEF, {
|
|
|
55
49
|
// @ts-ignore
|
|
56
50
|
pastedValueParser: (value, params) => {
|
|
57
51
|
const colDef = params.colDef;
|
|
58
|
-
const
|
|
59
|
-
const valueOptions = typeof colDefValueOptions === 'function' ? colDefValueOptions({
|
|
60
|
-
field: colDef.field
|
|
61
|
-
}) : colDefValueOptions || [];
|
|
52
|
+
const valueOptions = getValueOptions(colDef) || [];
|
|
62
53
|
const getOptionValue = colDef.getOptionValue;
|
|
63
54
|
const valueOption = valueOptions.find(option => {
|
|
64
55
|
if (getOptionValue(option) === value) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
2
|
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
|
3
|
-
const _excluded = ["id", "value", "formattedValue", "api", "field", "row", "rowNode", "colDef", "cellMode", "isEditable", "tabIndex", "className", "hasFocus", "isValidating", "isProcessingProps", "error", "onValueChange", "initialOpen"
|
|
3
|
+
const _excluded = ["id", "value", "formattedValue", "api", "field", "row", "rowNode", "colDef", "cellMode", "isEditable", "tabIndex", "className", "hasFocus", "isValidating", "isProcessingProps", "error", "onValueChange", "initialOpen"],
|
|
4
4
|
_excluded2 = ["MenuProps"];
|
|
5
5
|
import * as React from 'react';
|
|
6
6
|
import PropTypes from 'prop-types';
|
|
@@ -9,7 +9,7 @@ import { GridCellEditStopReasons } from '../../models/params/gridEditCellParams'
|
|
|
9
9
|
import { isEscapeKey } from '../../utils/keyboardUtils';
|
|
10
10
|
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
|
|
11
11
|
import { GridEditModes } from '../../models/gridEditRowModel';
|
|
12
|
-
import { getValueFromValueOptions, isSingleSelectColDef } from '../panel/filterPanel/filterPanelUtils';
|
|
12
|
+
import { getValueFromValueOptions, getValueOptions, isSingleSelectColDef } from '../panel/filterPanel/filterPanelUtils';
|
|
13
13
|
import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
|
|
14
14
|
import { createElement as _createElement } from "react";
|
|
15
15
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
@@ -27,9 +27,7 @@ function GridEditSingleSelectCell(props) {
|
|
|
27
27
|
hasFocus,
|
|
28
28
|
error,
|
|
29
29
|
onValueChange,
|
|
30
|
-
initialOpen = rootProps.editMode === GridEditModes.Cell
|
|
31
|
-
getOptionLabel: getOptionLabelProp,
|
|
32
|
-
getOptionValue: getOptionValueProp
|
|
30
|
+
initialOpen = rootProps.editMode === GridEditModes.Cell
|
|
33
31
|
} = props,
|
|
34
32
|
other = _objectWithoutPropertiesLoose(props, _excluded);
|
|
35
33
|
const apiRef = useGridApiContext();
|
|
@@ -51,21 +49,15 @@ function GridEditSingleSelectCell(props) {
|
|
|
51
49
|
if (!isSingleSelectColDef(colDef)) {
|
|
52
50
|
return null;
|
|
53
51
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
row,
|
|
59
|
-
field
|
|
60
|
-
});
|
|
61
|
-
} else {
|
|
62
|
-
valueOptions = colDef?.valueOptions;
|
|
63
|
-
}
|
|
52
|
+
const valueOptions = getValueOptions(colDef, {
|
|
53
|
+
id,
|
|
54
|
+
row
|
|
55
|
+
});
|
|
64
56
|
if (!valueOptions) {
|
|
65
57
|
return null;
|
|
66
58
|
}
|
|
67
|
-
const getOptionValue =
|
|
68
|
-
const getOptionLabel =
|
|
59
|
+
const getOptionValue = colDef.getOptionValue;
|
|
60
|
+
const getOptionLabel = colDef.getOptionLabel;
|
|
69
61
|
const handleChange = async event => {
|
|
70
62
|
if (!isSingleSelectColDef(colDef) || !valueOptions) {
|
|
71
63
|
return;
|
|
@@ -154,18 +146,6 @@ process.env.NODE_ENV !== "production" ? GridEditSingleSelectCell.propTypes = {
|
|
|
154
146
|
* The cell value formatted with the column valueFormatter.
|
|
155
147
|
*/
|
|
156
148
|
formattedValue: PropTypes.any,
|
|
157
|
-
/**
|
|
158
|
-
* Used to determine the label displayed for a given value option.
|
|
159
|
-
* @param {ValueOptions} value The current value option.
|
|
160
|
-
* @returns {string} The text to be displayed.
|
|
161
|
-
*/
|
|
162
|
-
getOptionLabel: PropTypes.func,
|
|
163
|
-
/**
|
|
164
|
-
* Used to determine the value used for a value option.
|
|
165
|
-
* @param {ValueOptions} value The current value option.
|
|
166
|
-
* @returns {string} The value to be used.
|
|
167
|
-
*/
|
|
168
|
-
getOptionValue: PropTypes.func,
|
|
169
149
|
/**
|
|
170
150
|
* If true, the cell is the active element.
|
|
171
151
|
*/
|
|
@@ -4,6 +4,7 @@ const _excluded = ["field", "colDef"];
|
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import PropTypes from 'prop-types';
|
|
6
6
|
import { unstable_composeClasses as composeClasses } from '@mui/utils';
|
|
7
|
+
import { isMultipleRowSelectionEnabled } from '../../hooks/features/rowSelection/utils';
|
|
7
8
|
import { useGridSelector } from '../../hooks/utils/useGridSelector';
|
|
8
9
|
import { gridTabIndexColumnHeaderSelector } from '../../hooks/features/focus/gridFocusStateSelector';
|
|
9
10
|
import { gridRowSelectionStateSelector } from '../../hooks/features/rowSelection/gridRowSelectionSelector';
|
|
@@ -102,7 +103,8 @@ const GridHeaderCheckbox = /*#__PURE__*/React.forwardRef(function GridHeaderChec
|
|
|
102
103
|
'aria-label': label
|
|
103
104
|
},
|
|
104
105
|
tabIndex: tabIndex,
|
|
105
|
-
onKeyDown: handleKeyDown
|
|
106
|
+
onKeyDown: handleKeyDown,
|
|
107
|
+
disabled: !isMultipleRowSelectionEnabled(rootProps)
|
|
106
108
|
}, rootProps.slotProps?.baseCheckbox, other));
|
|
107
109
|
});
|
|
108
110
|
process.env.NODE_ENV !== "production" ? GridHeaderCheckbox.propTypes = {
|
|
@@ -14,6 +14,7 @@ import { GridLogicOperator } from '../../../models/gridFilterItem';
|
|
|
14
14
|
import { useGridApiContext } from '../../../hooks/utils/useGridApiContext';
|
|
15
15
|
import { useGridRootProps } from '../../../hooks/utils/useGridRootProps';
|
|
16
16
|
import { getDataGridUtilityClass } from '../../../constants/gridClasses';
|
|
17
|
+
import { getValueFromValueOptions, getValueOptions } from './filterPanelUtils';
|
|
17
18
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
18
19
|
import { createElement as _createElement } from "react";
|
|
19
20
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
@@ -130,23 +131,39 @@ const GridFilterForm = /*#__PURE__*/React.forwardRef(function GridFilterForm(pro
|
|
|
130
131
|
const hasLogicOperatorColumn = hasMultipleFilters && logicOperators.length > 0;
|
|
131
132
|
const baseFormControlProps = rootProps.slotProps?.baseFormControl || {};
|
|
132
133
|
const baseSelectProps = rootProps.slotProps?.baseSelect || {};
|
|
133
|
-
const isBaseSelectNative = baseSelectProps.native ??
|
|
134
|
+
const isBaseSelectNative = baseSelectProps.native ?? false;
|
|
134
135
|
const baseInputLabelProps = rootProps.slotProps?.baseInputLabel || {};
|
|
135
136
|
const baseSelectOptionProps = rootProps.slotProps?.baseSelectOption || {};
|
|
136
137
|
const {
|
|
137
138
|
InputComponentProps
|
|
138
139
|
} = valueInputProps,
|
|
139
140
|
valueInputPropsOther = _objectWithoutPropertiesLoose(valueInputProps, _excluded2);
|
|
140
|
-
const
|
|
141
|
+
const {
|
|
142
|
+
filteredColumns,
|
|
143
|
+
selectedField
|
|
144
|
+
} = React.useMemo(() => {
|
|
145
|
+
let itemField = item.field;
|
|
141
146
|
if (filterColumns === undefined || typeof filterColumns !== 'function') {
|
|
142
|
-
return
|
|
147
|
+
return {
|
|
148
|
+
filteredColumns: filterableColumns,
|
|
149
|
+
selectedField: itemField
|
|
150
|
+
};
|
|
143
151
|
}
|
|
144
152
|
const filteredFields = filterColumns({
|
|
145
153
|
field: item.field,
|
|
146
154
|
columns: filterableColumns,
|
|
147
155
|
currentFilters: filterModel?.items || []
|
|
148
156
|
});
|
|
149
|
-
return
|
|
157
|
+
return {
|
|
158
|
+
filteredColumns: filterableColumns.filter(column => {
|
|
159
|
+
const isFieldIncluded = filteredFields.includes(column.field);
|
|
160
|
+
if (column.field === item.field && !isFieldIncluded) {
|
|
161
|
+
itemField = undefined;
|
|
162
|
+
}
|
|
163
|
+
return isFieldIncluded;
|
|
164
|
+
}),
|
|
165
|
+
selectedField: itemField
|
|
166
|
+
};
|
|
150
167
|
}, [filterColumns, filterModel?.items, filterableColumns, item.field]);
|
|
151
168
|
const sortedFilteredColumns = React.useMemo(() => {
|
|
152
169
|
switch (columnsSort) {
|
|
@@ -177,11 +194,29 @@ const GridFilterForm = /*#__PURE__*/React.forwardRef(function GridFilterForm(pro
|
|
|
177
194
|
const newOperator = column.filterOperators.find(operator => operator.value === item.operator) || column.filterOperators[0];
|
|
178
195
|
|
|
179
196
|
// Erase filter value if the input component or filtered column type is modified
|
|
180
|
-
const
|
|
197
|
+
const eraseFilterValue = !newOperator.InputComponent || newOperator.InputComponent !== currentOperator?.InputComponent || column.type !== currentColumn.type;
|
|
198
|
+
let filterValue = eraseFilterValue ? undefined : item.value;
|
|
199
|
+
|
|
200
|
+
// Check filter value against the new valueOptions
|
|
201
|
+
if (column.type === 'singleSelect' && filterValue !== undefined) {
|
|
202
|
+
const colDef = column;
|
|
203
|
+
const valueOptions = getValueOptions(colDef);
|
|
204
|
+
if (Array.isArray(filterValue)) {
|
|
205
|
+
filterValue = filterValue.filter(val => {
|
|
206
|
+
return (
|
|
207
|
+
// Only keep values that are in the new value options
|
|
208
|
+
getValueFromValueOptions(val, valueOptions, colDef?.getOptionValue) !== undefined
|
|
209
|
+
);
|
|
210
|
+
});
|
|
211
|
+
} else if (getValueFromValueOptions(item.value, valueOptions, colDef?.getOptionValue) === undefined) {
|
|
212
|
+
// Reset the filter value if it is not in the new value options
|
|
213
|
+
filterValue = undefined;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
181
216
|
applyFilterChanges(_extends({}, item, {
|
|
182
217
|
field,
|
|
183
218
|
operator: newOperator.value,
|
|
184
|
-
value:
|
|
219
|
+
value: filterValue
|
|
185
220
|
}));
|
|
186
221
|
}, [apiRef, applyFilterChanges, item, currentColumn, currentOperator]);
|
|
187
222
|
const changeOperator = React.useCallback(event => {
|
|
@@ -256,7 +291,7 @@ const GridFilterForm = /*#__PURE__*/React.forwardRef(function GridFilterForm(pro
|
|
|
256
291
|
inputProps: {
|
|
257
292
|
'aria-label': apiRef.current.getLocaleText('filterPanelLogicOperator')
|
|
258
293
|
},
|
|
259
|
-
value: multiFilterOperator,
|
|
294
|
+
value: multiFilterOperator ?? '',
|
|
260
295
|
onChange: changeLogicOperator,
|
|
261
296
|
disabled: !!disableMultiFilterOperator || logicOperators.length === 1,
|
|
262
297
|
native: isBaseSelectNative
|
|
@@ -281,7 +316,7 @@ const GridFilterForm = /*#__PURE__*/React.forwardRef(function GridFilterForm(pro
|
|
|
281
316
|
labelId: columnSelectLabelId,
|
|
282
317
|
id: columnSelectId,
|
|
283
318
|
label: apiRef.current.getLocaleText('filterPanelColumns'),
|
|
284
|
-
value:
|
|
319
|
+
value: selectedField ?? '',
|
|
285
320
|
onChange: changeColumn,
|
|
286
321
|
native: isBaseSelectNative
|
|
287
322
|
}, rootProps.slotProps?.baseSelect, {
|
|
@@ -327,7 +362,7 @@ const GridFilterForm = /*#__PURE__*/React.forwardRef(function GridFilterForm(pro
|
|
|
327
362
|
item: item,
|
|
328
363
|
applyValue: applyFilterChanges,
|
|
329
364
|
focusElementRef: valueRef
|
|
330
|
-
}, currentOperator.InputComponentProps, InputComponentProps)) : null
|
|
365
|
+
}, currentOperator.InputComponentProps, InputComponentProps), item.field) : null
|
|
331
366
|
}))]
|
|
332
367
|
}));
|
|
333
368
|
});
|
|
@@ -32,7 +32,7 @@ function GridFilterInputBoolean(props) {
|
|
|
32
32
|
const labelId = useId();
|
|
33
33
|
const selectId = useId();
|
|
34
34
|
const baseSelectProps = rootProps.slotProps?.baseSelect || {};
|
|
35
|
-
const isSelectNative = baseSelectProps.native ??
|
|
35
|
+
const isSelectNative = baseSelectProps.native ?? false;
|
|
36
36
|
const baseSelectOptionProps = rootProps.slotProps?.baseSelectOption || {};
|
|
37
37
|
const onFilterChange = React.useCallback(event => {
|
|
38
38
|
const value = event.target.value;
|
|
@@ -7,6 +7,23 @@ import { unstable_useId as useId } from '@mui/utils';
|
|
|
7
7
|
import { useTimeout } from '../../../hooks/utils/useTimeout';
|
|
8
8
|
import { useGridRootProps } from '../../../hooks/utils/useGridRootProps';
|
|
9
9
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
10
|
+
function convertFilterItemValueToInputValue(itemValue, inputType) {
|
|
11
|
+
if (itemValue == null) {
|
|
12
|
+
return '';
|
|
13
|
+
}
|
|
14
|
+
const dateCopy = new Date(itemValue);
|
|
15
|
+
// The date picker expects the date to be in the local timezone.
|
|
16
|
+
// But .toISOString() converts it to UTC with zero offset.
|
|
17
|
+
// So we need to subtract the timezone offset.
|
|
18
|
+
dateCopy.setMinutes(dateCopy.getMinutes() - dateCopy.getTimezoneOffset());
|
|
19
|
+
if (inputType === 'date') {
|
|
20
|
+
return dateCopy.toISOString().substring(0, 10);
|
|
21
|
+
}
|
|
22
|
+
if (inputType === 'datetime-local') {
|
|
23
|
+
return dateCopy.toISOString().substring(0, 19);
|
|
24
|
+
}
|
|
25
|
+
return dateCopy.toISOString().substring(0, 10);
|
|
26
|
+
}
|
|
10
27
|
function GridFilterInputDate(props) {
|
|
11
28
|
const {
|
|
12
29
|
item,
|
|
@@ -21,25 +38,26 @@ function GridFilterInputDate(props) {
|
|
|
21
38
|
} = props,
|
|
22
39
|
other = _objectWithoutPropertiesLoose(props, _excluded);
|
|
23
40
|
const filterTimeout = useTimeout();
|
|
24
|
-
const [filterValueState, setFilterValueState] = React.useState(item.value
|
|
41
|
+
const [filterValueState, setFilterValueState] = React.useState(() => convertFilterItemValueToInputValue(item.value, type));
|
|
25
42
|
const [applying, setIsApplying] = React.useState(false);
|
|
26
43
|
const id = useId();
|
|
27
44
|
const rootProps = useGridRootProps();
|
|
28
45
|
const onFilterChange = React.useCallback(event => {
|
|
46
|
+
filterTimeout.clear();
|
|
29
47
|
const value = event.target.value;
|
|
30
|
-
setFilterValueState(
|
|
48
|
+
setFilterValueState(value);
|
|
31
49
|
setIsApplying(true);
|
|
32
50
|
filterTimeout.start(rootProps.filterDebounceMs, () => {
|
|
33
51
|
applyValue(_extends({}, item, {
|
|
34
|
-
value
|
|
52
|
+
value: new Date(value)
|
|
35
53
|
}));
|
|
36
54
|
setIsApplying(false);
|
|
37
55
|
});
|
|
38
56
|
}, [applyValue, item, rootProps.filterDebounceMs, filterTimeout]);
|
|
39
57
|
React.useEffect(() => {
|
|
40
|
-
const
|
|
41
|
-
setFilterValueState(
|
|
42
|
-
}, [item.value]);
|
|
58
|
+
const value = convertFilterItemValueToInputValue(item.value, type);
|
|
59
|
+
setFilterValueState(value);
|
|
60
|
+
}, [item.value, type]);
|
|
43
61
|
return /*#__PURE__*/_jsx(rootProps.slots.baseTextField, _extends({
|
|
44
62
|
fullWidth: true,
|
|
45
63
|
id: id,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
2
|
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
|
3
|
-
const _excluded = ["item", "applyValue", "type", "apiRef", "focusElementRef", "color", "error", "helperText", "size", "variant"
|
|
3
|
+
const _excluded = ["item", "applyValue", "type", "apiRef", "focusElementRef", "color", "error", "helperText", "size", "variant"];
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import PropTypes from 'prop-types';
|
|
6
6
|
import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete';
|
|
7
7
|
import { unstable_useId as useId } from '@mui/utils';
|
|
8
|
-
import { isSingleSelectColDef } from './filterPanelUtils';
|
|
8
|
+
import { getValueOptions, isSingleSelectColDef } from './filterPanelUtils';
|
|
9
9
|
import { useGridRootProps } from '../../../hooks/utils/useGridRootProps';
|
|
10
10
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
11
11
|
const filter = createFilterOptions();
|
|
@@ -19,9 +19,7 @@ function GridFilterInputMultipleSingleSelect(props) {
|
|
|
19
19
|
error,
|
|
20
20
|
helperText,
|
|
21
21
|
size,
|
|
22
|
-
variant = 'standard'
|
|
23
|
-
getOptionLabel: getOptionLabelProp,
|
|
24
|
-
getOptionValue: getOptionValueProp
|
|
22
|
+
variant = 'standard'
|
|
25
23
|
} = props,
|
|
26
24
|
other = _objectWithoutPropertiesLoose(props, _excluded);
|
|
27
25
|
const TextFieldProps = {
|
|
@@ -40,23 +38,12 @@ function GridFilterInputMultipleSingleSelect(props) {
|
|
|
40
38
|
resolvedColumn = column;
|
|
41
39
|
}
|
|
42
40
|
}
|
|
43
|
-
const getOptionValue =
|
|
44
|
-
const getOptionLabel =
|
|
41
|
+
const getOptionValue = resolvedColumn?.getOptionValue;
|
|
42
|
+
const getOptionLabel = resolvedColumn?.getOptionLabel;
|
|
45
43
|
const isOptionEqualToValue = React.useCallback((option, value) => getOptionValue(option) === getOptionValue(value), [getOptionValue]);
|
|
46
44
|
const resolvedValueOptions = React.useMemo(() => {
|
|
47
|
-
|
|
48
|
-
return [];
|
|
49
|
-
}
|
|
50
|
-
if (typeof resolvedColumn.valueOptions === 'function') {
|
|
51
|
-
return resolvedColumn.valueOptions({
|
|
52
|
-
field: resolvedColumn.field
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
return resolvedColumn.valueOptions;
|
|
45
|
+
return getValueOptions(resolvedColumn) || [];
|
|
56
46
|
}, [resolvedColumn]);
|
|
57
|
-
const resolvedFormattedValueOptions = React.useMemo(() => {
|
|
58
|
-
return resolvedValueOptions?.map(getOptionValue);
|
|
59
|
-
}, [resolvedValueOptions, getOptionValue]);
|
|
60
47
|
|
|
61
48
|
// The value is computed from the item.value and used directly
|
|
62
49
|
// If it was done by a useEffect/useState, the Autocomplete could receive incoherent value and options
|
|
@@ -64,23 +51,8 @@ function GridFilterInputMultipleSingleSelect(props) {
|
|
|
64
51
|
if (!Array.isArray(item.value)) {
|
|
65
52
|
return [];
|
|
66
53
|
}
|
|
67
|
-
if (resolvedValueOptions !== undefined) {
|
|
68
|
-
const itemValueIndexes = item.value.map(element => {
|
|
69
|
-
// Gets the index matching between values and valueOptions
|
|
70
|
-
return resolvedFormattedValueOptions?.findIndex(formattedOption => formattedOption === element);
|
|
71
|
-
});
|
|
72
|
-
return itemValueIndexes.filter(index => index >= 0).map(index => resolvedValueOptions[index]);
|
|
73
|
-
}
|
|
74
54
|
return item.value;
|
|
75
|
-
}, [item.value
|
|
76
|
-
React.useEffect(() => {
|
|
77
|
-
if (!Array.isArray(item.value) || filteredValues.length !== item.value.length) {
|
|
78
|
-
// Updates the state if the filter value has been cleaned by the component
|
|
79
|
-
applyValue(_extends({}, item, {
|
|
80
|
-
value: filteredValues.map(getOptionValue)
|
|
81
|
-
}));
|
|
82
|
-
}
|
|
83
|
-
}, [item, filteredValues, applyValue, getOptionValue]);
|
|
55
|
+
}, [item.value]);
|
|
84
56
|
const handleChange = React.useCallback((event, value) => {
|
|
85
57
|
applyValue(_extends({}, item, {
|
|
86
58
|
value: value.map(getOptionValue)
|
|
@@ -123,18 +95,6 @@ process.env.NODE_ENV !== "production" ? GridFilterInputMultipleSingleSelect.prop
|
|
|
123
95
|
}).isRequired,
|
|
124
96
|
applyValue: PropTypes.func.isRequired,
|
|
125
97
|
focusElementRef: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.func, PropTypes.object]),
|
|
126
|
-
/**
|
|
127
|
-
* Used to determine the label displayed for a given value option.
|
|
128
|
-
* @param {ValueOptions} value The current value option.
|
|
129
|
-
* @returns {string} The text to be displayed.
|
|
130
|
-
*/
|
|
131
|
-
getOptionLabel: PropTypes.func,
|
|
132
|
-
/**
|
|
133
|
-
* Used to determine the value used for a value option.
|
|
134
|
-
* @param {ValueOptions} value The current value option.
|
|
135
|
-
* @returns {string} The value to be used.
|
|
136
|
-
*/
|
|
137
|
-
getOptionValue: PropTypes.func,
|
|
138
98
|
item: PropTypes.shape({
|
|
139
99
|
field: PropTypes.string.isRequired,
|
|
140
100
|
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
|
@@ -1,32 +1,30 @@
|
|
|
1
1
|
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
|
2
2
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
3
|
-
const _excluded = ["item", "applyValue", "type", "apiRef", "focusElementRef", "
|
|
3
|
+
const _excluded = ["item", "applyValue", "type", "apiRef", "focusElementRef", "placeholder", "tabIndex", "label", "isFilterActive", "clearButton", "InputLabelProps"];
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import PropTypes from 'prop-types';
|
|
6
6
|
import { unstable_useId as useId } from '@mui/utils';
|
|
7
7
|
import { styled } from '@mui/material/styles';
|
|
8
8
|
import { useGridRootProps } from '../../../hooks/utils/useGridRootProps';
|
|
9
|
-
import { getValueFromValueOptions, isSingleSelectColDef } from './filterPanelUtils';
|
|
9
|
+
import { getValueFromValueOptions, getValueOptions, isSingleSelectColDef } from './filterPanelUtils';
|
|
10
10
|
import { createElement as _createElement } from "react";
|
|
11
11
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
12
12
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
13
|
const renderSingleSelectOptions = ({
|
|
14
|
-
column
|
|
15
|
-
valueOptions,
|
|
16
|
-
field
|
|
17
|
-
},
|
|
14
|
+
column,
|
|
18
15
|
OptionComponent,
|
|
19
16
|
getOptionLabel,
|
|
20
17
|
getOptionValue,
|
|
21
18
|
isSelectNative,
|
|
22
19
|
baseSelectOptionProps
|
|
23
20
|
}) => {
|
|
24
|
-
const iterableColumnValues =
|
|
25
|
-
field
|
|
26
|
-
})] : ['', ...(valueOptions || [])];
|
|
21
|
+
const iterableColumnValues = ['', ...(getValueOptions(column) || [])];
|
|
27
22
|
return iterableColumnValues.map(option => {
|
|
28
23
|
const value = getOptionValue(option);
|
|
29
|
-
|
|
24
|
+
let label = getOptionLabel(option);
|
|
25
|
+
if (label === '') {
|
|
26
|
+
label = ' '; // To force the height of the empty option
|
|
27
|
+
}
|
|
30
28
|
return /*#__PURE__*/_createElement(OptionComponent, _extends({}, baseSelectOptionProps, {
|
|
31
29
|
native: isSelectNative,
|
|
32
30
|
key: value,
|
|
@@ -49,19 +47,17 @@ function GridFilterInputSingleSelect(props) {
|
|
|
49
47
|
type,
|
|
50
48
|
apiRef,
|
|
51
49
|
focusElementRef,
|
|
52
|
-
getOptionLabel: getOptionLabelProp,
|
|
53
|
-
getOptionValue: getOptionValueProp,
|
|
54
50
|
placeholder,
|
|
55
51
|
tabIndex,
|
|
56
52
|
label: labelProp,
|
|
57
53
|
clearButton
|
|
58
54
|
} = props,
|
|
59
55
|
others = _objectWithoutPropertiesLoose(props, _excluded);
|
|
60
|
-
const
|
|
56
|
+
const filterValue = item.value ?? '';
|
|
61
57
|
const id = useId();
|
|
62
58
|
const labelId = useId();
|
|
63
59
|
const rootProps = useGridRootProps();
|
|
64
|
-
const isSelectNative = rootProps.slotProps?.baseSelect?.native ??
|
|
60
|
+
const isSelectNative = rootProps.slotProps?.baseSelect?.native ?? false;
|
|
65
61
|
let resolvedColumn = null;
|
|
66
62
|
if (item.field) {
|
|
67
63
|
const column = apiRef.current.getColumn(item.field);
|
|
@@ -69,52 +65,27 @@ function GridFilterInputSingleSelect(props) {
|
|
|
69
65
|
resolvedColumn = column;
|
|
70
66
|
}
|
|
71
67
|
}
|
|
72
|
-
const getOptionValue =
|
|
73
|
-
const getOptionLabel =
|
|
68
|
+
const getOptionValue = resolvedColumn?.getOptionValue;
|
|
69
|
+
const getOptionLabel = resolvedColumn?.getOptionLabel;
|
|
74
70
|
const currentValueOptions = React.useMemo(() => {
|
|
75
|
-
|
|
76
|
-
return undefined;
|
|
77
|
-
}
|
|
78
|
-
return typeof resolvedColumn.valueOptions === 'function' ? resolvedColumn.valueOptions({
|
|
79
|
-
field: resolvedColumn.field
|
|
80
|
-
}) : resolvedColumn.valueOptions;
|
|
71
|
+
return getValueOptions(resolvedColumn);
|
|
81
72
|
}, [resolvedColumn]);
|
|
82
73
|
const onFilterChange = React.useCallback(event => {
|
|
83
74
|
let value = event.target.value;
|
|
84
75
|
|
|
85
76
|
// NativeSelect casts the value to a string.
|
|
86
77
|
value = getValueFromValueOptions(value, currentValueOptions, getOptionValue);
|
|
87
|
-
setFilterValueState(String(value));
|
|
88
78
|
applyValue(_extends({}, item, {
|
|
89
79
|
value
|
|
90
80
|
}));
|
|
91
81
|
}, [currentValueOptions, getOptionValue, applyValue, item]);
|
|
92
|
-
React.useEffect(() => {
|
|
93
|
-
let itemValue;
|
|
94
|
-
if (currentValueOptions !== undefined) {
|
|
95
|
-
// sanitize if valueOptions are provided
|
|
96
|
-
itemValue = getValueFromValueOptions(item.value, currentValueOptions, getOptionValue);
|
|
97
|
-
if (itemValue !== item.value) {
|
|
98
|
-
applyValue(_extends({}, item, {
|
|
99
|
-
value: itemValue
|
|
100
|
-
}));
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
} else {
|
|
104
|
-
itemValue = item.value;
|
|
105
|
-
}
|
|
106
|
-
itemValue = itemValue ?? '';
|
|
107
|
-
setFilterValueState(String(itemValue));
|
|
108
|
-
}, [item, currentValueOptions, applyValue, getOptionValue]);
|
|
109
|
-
if (!isSingleSelectColDef(resolvedColumn)) {
|
|
110
|
-
return null;
|
|
111
|
-
}
|
|
112
82
|
if (!isSingleSelectColDef(resolvedColumn)) {
|
|
113
83
|
return null;
|
|
114
84
|
}
|
|
115
85
|
const label = labelProp ?? apiRef.current.getLocaleText('filterPanelInputLabel');
|
|
116
86
|
return /*#__PURE__*/_jsxs(SingleSelectOperatorContainer, {
|
|
117
87
|
children: [/*#__PURE__*/_jsxs(rootProps.slots.baseFormControl, {
|
|
88
|
+
fullWidth: true,
|
|
118
89
|
children: [/*#__PURE__*/_jsx(rootProps.slots.baseInputLabel, _extends({}, rootProps.slotProps?.baseInputLabel, {
|
|
119
90
|
id: labelId,
|
|
120
91
|
htmlFor: id,
|
|
@@ -125,7 +96,7 @@ function GridFilterInputSingleSelect(props) {
|
|
|
125
96
|
id: id,
|
|
126
97
|
label: label,
|
|
127
98
|
labelId: labelId,
|
|
128
|
-
value:
|
|
99
|
+
value: filterValue,
|
|
129
100
|
onChange: onFilterChange,
|
|
130
101
|
variant: "standard",
|
|
131
102
|
type: type || 'text',
|
|
@@ -159,18 +130,6 @@ process.env.NODE_ENV !== "production" ? GridFilterInputSingleSelect.propTypes =
|
|
|
159
130
|
applyValue: PropTypes.func.isRequired,
|
|
160
131
|
clearButton: PropTypes.node,
|
|
161
132
|
focusElementRef: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.func, PropTypes.object]),
|
|
162
|
-
/**
|
|
163
|
-
* Used to determine the label displayed for a given value option.
|
|
164
|
-
* @param {ValueOptions} value The current value option.
|
|
165
|
-
* @returns {string} The text to be displayed.
|
|
166
|
-
*/
|
|
167
|
-
getOptionLabel: PropTypes.func,
|
|
168
|
-
/**
|
|
169
|
-
* Used to determine the value used for a value option.
|
|
170
|
-
* @param {ValueOptions} value The current value option.
|
|
171
|
-
* @returns {string} The value to be used.
|
|
172
|
-
*/
|
|
173
|
-
getOptionValue: PropTypes.func,
|
|
174
133
|
/**
|
|
175
134
|
* It is `true` if the filter either has a value or an operator with no value
|
|
176
135
|
* required is selected (e.g. `isEmpty`)
|
|
@@ -1,6 +1,15 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
1
2
|
export function isSingleSelectColDef(colDef) {
|
|
2
3
|
return colDef?.type === 'singleSelect';
|
|
3
4
|
}
|
|
5
|
+
export function getValueOptions(column, additionalParams) {
|
|
6
|
+
if (!column) {
|
|
7
|
+
return undefined;
|
|
8
|
+
}
|
|
9
|
+
return typeof column.valueOptions === 'function' ? column.valueOptions(_extends({
|
|
10
|
+
field: column.field
|
|
11
|
+
}, additionalParams)) : column.valueOptions;
|
|
12
|
+
}
|
|
4
13
|
export function getValueFromValueOptions(value, valueOptions, getOptionValue) {
|
|
5
14
|
if (valueOptions === undefined) {
|
|
6
15
|
return undefined;
|
|
@@ -10,8 +19,4 @@ export function getValueFromValueOptions(value, valueOptions, getOptionValue) {
|
|
|
10
19
|
return String(optionValue) === String(value);
|
|
11
20
|
});
|
|
12
21
|
return getOptionValue(result);
|
|
13
|
-
}
|
|
14
|
-
export const getLabelFromValueOption = valueOption => {
|
|
15
|
-
const label = typeof valueOption === 'object' ? valueOption.label : valueOption;
|
|
16
|
-
return label != null ? String(label) : '';
|
|
17
|
-
};
|
|
22
|
+
}
|