@redsift/table 12.5.5 → 12.5.6-muiv7
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/_internal/BaseComponents.js +1 -1
- package/_internal/BasePopper.js +2453 -0
- package/_internal/BasePopper.js.map +1 -0
- package/_internal/DataGrid2.js +102 -180
- package/_internal/DataGrid2.js.map +1 -1
- package/_internal/GridToolbarFilterSemanticField2.js +2 -1339
- package/_internal/GridToolbarFilterSemanticField2.js.map +1 -1
- package/_internal/Pagination.js +1 -1
- package/_internal/Portal.js +6563 -0
- package/_internal/Portal.js.map +1 -0
- package/_internal/ServerSideControlledPagination.js +11710 -70
- package/_internal/ServerSideControlledPagination.js.map +1 -1
- package/_internal/StatefulDataGrid.js +1 -1
- package/_internal/StatefulDataGrid2.js +1833 -989
- package/_internal/StatefulDataGrid2.js.map +1 -1
- package/_internal/Toolbar2.js +1 -1
- package/_internal/Toolbar2.js.map +1 -1
- package/_internal/ToolbarWrapper2.js.map +1 -1
- package/_internal/jsx-runtime.js +1342 -0
- package/_internal/jsx-runtime.js.map +1 -0
- package/_internal/useControlledDatagridState.js +1218 -6
- package/_internal/useControlledDatagridState.js.map +1 -1
- package/index.d.ts +229 -503
- package/index.js +143 -177
- package/index.js.map +1 -1
- package/package.json +10 -9
- package/_internal/BaseIconButton.js +0 -126
- package/_internal/BaseIconButton.js.map +0 -1
|
@@ -1,21 +1,1500 @@
|
|
|
1
1
|
import { _ as _objectSpread2, a as _objectWithoutProperties, b as _extends } from './_rollupPluginBabelHelpers.js';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import React__default, { useCallback, useEffect, useRef, useMemo, forwardRef, useState } from 'react';
|
|
4
|
-
import { createTheme, ThemeProvider as ThemeProvider$1 } from '@mui/material/styles';
|
|
5
4
|
import classNames from 'classnames';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { u as useControlledDatagridState, S as StyledDataGrid } from './useControlledDatagridState.js';
|
|
10
|
-
import Box from '@mui/material/Box';
|
|
11
|
-
import TextField from '@mui/material/TextField';
|
|
5
|
+
import { Icon, useTheme as useTheme$1, RedsiftColorBlueN, RedsiftColorNeutralXDarkGrey, RedsiftColorNeutralWhite, ThemeProvider } from '@redsift/design-system';
|
|
6
|
+
import { getGridNumericOperators as getGridNumericOperators$1, GridFilterInputValue, GridFilterInputSingleSelect, GridFilterInputMultipleValue, GridFilterInputMultipleSingleSelect, getGridStringOperators as getGridStringOperators$1, getGridBooleanOperators, getGridDateOperators, getGridSingleSelectOperators, GridLogicOperator, useGridApiRef, gridFilteredSortedRowEntriesSelector, gridFilteredSortedRowIdsSelector, DataGridPro } from '@mui/x-data-grid-pro';
|
|
7
|
+
import { L as LicenseInfo, u as useControlledDatagridState, T as ThemeProvider$1, S as StyledDataGrid, B as BelowToolbar, a as BottomPagination, b as baseGridSlots } from './useControlledDatagridState.js';
|
|
12
8
|
import { mdiSync } from '@redsift/icons';
|
|
9
|
+
import { d as defaultSxConfig, i as isPlainObject, s as styled, a as styleFunctionSx, c as clsx, g as generateUtilityClasses, b as createTheme, T as THEME_ID, C as ClassNameGenerator, P as PropTypes, e as generateUtilityClass, f as styled$1, u as useDefaultProps, h as composeClasses, r as rootShouldForwardProp, j as refType } from './Portal.js';
|
|
10
|
+
import { j as jsxRuntimeExports } from './jsx-runtime.js';
|
|
11
|
+
import { u as useTheme, m as memoTheme, c as createSimplePaletteValueFilter, a as useFormControl, b as formControlState, d as capitalize, i as isAdornedStart, e as isFilled, F as FormControlContext, h as useId, j as useSlot, k as Select, I as Input, l as FilledInput, O as OutlinedInput, o as onServerSideSelectionStatusChange } from './ServerSideControlledPagination.js';
|
|
13
12
|
import { decompressFromEncodedURIComponent, compressToEncodedURIComponent } from 'lz-string';
|
|
14
|
-
import { n as normalizeRowSelectionModel, o as onServerSideSelectionStatusChange, g as getSelectionCount, i as isRowSelected, S as ServerSideControlledPagination, C as ControlledPagination } from './ServerSideControlledPagination.js';
|
|
15
|
-
import { B as BaseButton, a as BaseCheckbox, c as BaseIconButton, b as BaseIcon } from './BaseIconButton.js';
|
|
16
|
-
import { T as ToolbarWrapper } from './ToolbarWrapper2.js';
|
|
17
13
|
import { T as Toolbar } from './Toolbar2.js';
|
|
18
14
|
|
|
15
|
+
const splitProps = props => {
|
|
16
|
+
const result = {
|
|
17
|
+
systemProps: {},
|
|
18
|
+
otherProps: {}
|
|
19
|
+
};
|
|
20
|
+
const config = props?.theme?.unstable_sxConfig ?? defaultSxConfig;
|
|
21
|
+
Object.keys(props).forEach(prop => {
|
|
22
|
+
if (config[prop]) {
|
|
23
|
+
result.systemProps[prop] = props[prop];
|
|
24
|
+
} else {
|
|
25
|
+
result.otherProps[prop] = props[prop];
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
return result;
|
|
29
|
+
};
|
|
30
|
+
function extendSxProp(props) {
|
|
31
|
+
const {
|
|
32
|
+
sx: inSx,
|
|
33
|
+
...other
|
|
34
|
+
} = props;
|
|
35
|
+
const {
|
|
36
|
+
systemProps,
|
|
37
|
+
otherProps
|
|
38
|
+
} = splitProps(other);
|
|
39
|
+
let finalSx;
|
|
40
|
+
if (Array.isArray(inSx)) {
|
|
41
|
+
finalSx = [systemProps, ...inSx];
|
|
42
|
+
} else if (typeof inSx === 'function') {
|
|
43
|
+
finalSx = (...args) => {
|
|
44
|
+
const result = inSx(...args);
|
|
45
|
+
if (!isPlainObject(result)) {
|
|
46
|
+
return systemProps;
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
...systemProps,
|
|
50
|
+
...result
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
} else {
|
|
54
|
+
finalSx = {
|
|
55
|
+
...systemProps,
|
|
56
|
+
...inSx
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
...otherProps,
|
|
61
|
+
sx: finalSx
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function createBox(options = {}) {
|
|
66
|
+
const {
|
|
67
|
+
themeId,
|
|
68
|
+
defaultTheme,
|
|
69
|
+
defaultClassName = 'MuiBox-root',
|
|
70
|
+
generateClassName
|
|
71
|
+
} = options;
|
|
72
|
+
const BoxRoot = styled('div', {
|
|
73
|
+
shouldForwardProp: prop => prop !== 'theme' && prop !== 'sx' && prop !== 'as'
|
|
74
|
+
})(styleFunctionSx);
|
|
75
|
+
const Box = /*#__PURE__*/React.forwardRef(function Box(inProps, ref) {
|
|
76
|
+
const theme = useTheme(defaultTheme);
|
|
77
|
+
const {
|
|
78
|
+
className,
|
|
79
|
+
component = 'div',
|
|
80
|
+
...other
|
|
81
|
+
} = extendSxProp(inProps);
|
|
82
|
+
return /*#__PURE__*/jsxRuntimeExports.jsx(BoxRoot, {
|
|
83
|
+
as: component,
|
|
84
|
+
ref: ref,
|
|
85
|
+
className: clsx(className, generateClassName ? generateClassName(defaultClassName) : defaultClassName),
|
|
86
|
+
theme: themeId ? theme[themeId] || theme : theme,
|
|
87
|
+
...other
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
return Box;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function isMuiElement(element, muiNames) {
|
|
94
|
+
return /*#__PURE__*/React.isValidElement(element) && muiNames.indexOf(
|
|
95
|
+
// For server components `muiName` is avaialble in element.type._payload.value.muiName
|
|
96
|
+
// relevant info - https://github.com/facebook/react/blob/2807d781a08db8e9873687fccc25c0f12b4fb3d4/packages/react/src/ReactLazy.js#L45
|
|
97
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
98
|
+
element.type.muiName ?? element.type?._payload?.value?.muiName) !== -1;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const boxClasses = generateUtilityClasses('MuiBox', ['root']);
|
|
102
|
+
var boxClasses$1 = boxClasses;
|
|
103
|
+
|
|
104
|
+
const defaultTheme = createTheme();
|
|
105
|
+
const Box = createBox({
|
|
106
|
+
themeId: THEME_ID,
|
|
107
|
+
defaultTheme,
|
|
108
|
+
defaultClassName: boxClasses$1.root,
|
|
109
|
+
generateClassName: ClassNameGenerator.generate
|
|
110
|
+
});
|
|
111
|
+
process.env.NODE_ENV !== "production" ? Box.propTypes /* remove-proptypes */ = {
|
|
112
|
+
// ┌────────────────────────────── Warning ──────────────────────────────┐
|
|
113
|
+
// │ These PropTypes are generated from the TypeScript type definitions. │
|
|
114
|
+
// │ To update them, edit the d.ts file and run `pnpm proptypes`. │
|
|
115
|
+
// └─────────────────────────────────────────────────────────────────────┘
|
|
116
|
+
/**
|
|
117
|
+
* @ignore
|
|
118
|
+
*/
|
|
119
|
+
children: PropTypes.node,
|
|
120
|
+
/**
|
|
121
|
+
* The component used for the root node.
|
|
122
|
+
* Either a string to use a HTML element or a component.
|
|
123
|
+
*/
|
|
124
|
+
component: PropTypes.elementType,
|
|
125
|
+
/**
|
|
126
|
+
* The system prop that allows defining system overrides as well as additional CSS styles.
|
|
127
|
+
*/
|
|
128
|
+
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
|
|
129
|
+
} : void 0;
|
|
130
|
+
var Box$1 = Box;
|
|
131
|
+
|
|
132
|
+
function getFormLabelUtilityClasses(slot) {
|
|
133
|
+
return generateUtilityClass('MuiFormLabel', slot);
|
|
134
|
+
}
|
|
135
|
+
const formLabelClasses = generateUtilityClasses('MuiFormLabel', ['root', 'colorSecondary', 'focused', 'disabled', 'error', 'filled', 'required', 'asterisk']);
|
|
136
|
+
var formLabelClasses$1 = formLabelClasses;
|
|
137
|
+
|
|
138
|
+
const useUtilityClasses$4 = ownerState => {
|
|
139
|
+
const {
|
|
140
|
+
classes,
|
|
141
|
+
color,
|
|
142
|
+
focused,
|
|
143
|
+
disabled,
|
|
144
|
+
error,
|
|
145
|
+
filled,
|
|
146
|
+
required
|
|
147
|
+
} = ownerState;
|
|
148
|
+
const slots = {
|
|
149
|
+
root: ['root', `color${capitalize(color)}`, disabled && 'disabled', error && 'error', filled && 'filled', focused && 'focused', required && 'required'],
|
|
150
|
+
asterisk: ['asterisk', error && 'error']
|
|
151
|
+
};
|
|
152
|
+
return composeClasses(slots, getFormLabelUtilityClasses, classes);
|
|
153
|
+
};
|
|
154
|
+
const FormLabelRoot = styled$1('label', {
|
|
155
|
+
name: 'MuiFormLabel',
|
|
156
|
+
slot: 'Root',
|
|
157
|
+
overridesResolver: (props, styles) => {
|
|
158
|
+
const {
|
|
159
|
+
ownerState
|
|
160
|
+
} = props;
|
|
161
|
+
return [styles.root, ownerState.color === 'secondary' && styles.colorSecondary, ownerState.filled && styles.filled];
|
|
162
|
+
}
|
|
163
|
+
})(memoTheme(({
|
|
164
|
+
theme
|
|
165
|
+
}) => ({
|
|
166
|
+
color: (theme.vars || theme).palette.text.secondary,
|
|
167
|
+
...theme.typography.body1,
|
|
168
|
+
lineHeight: '1.4375em',
|
|
169
|
+
padding: 0,
|
|
170
|
+
position: 'relative',
|
|
171
|
+
variants: [...Object.entries(theme.palette).filter(createSimplePaletteValueFilter()).map(([color]) => ({
|
|
172
|
+
props: {
|
|
173
|
+
color
|
|
174
|
+
},
|
|
175
|
+
style: {
|
|
176
|
+
[`&.${formLabelClasses$1.focused}`]: {
|
|
177
|
+
color: (theme.vars || theme).palette[color].main
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
})), {
|
|
181
|
+
props: {},
|
|
182
|
+
style: {
|
|
183
|
+
[`&.${formLabelClasses$1.disabled}`]: {
|
|
184
|
+
color: (theme.vars || theme).palette.text.disabled
|
|
185
|
+
},
|
|
186
|
+
[`&.${formLabelClasses$1.error}`]: {
|
|
187
|
+
color: (theme.vars || theme).palette.error.main
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}]
|
|
191
|
+
})));
|
|
192
|
+
const AsteriskComponent = styled$1('span', {
|
|
193
|
+
name: 'MuiFormLabel',
|
|
194
|
+
slot: 'Asterisk',
|
|
195
|
+
overridesResolver: (props, styles) => styles.asterisk
|
|
196
|
+
})(memoTheme(({
|
|
197
|
+
theme
|
|
198
|
+
}) => ({
|
|
199
|
+
[`&.${formLabelClasses$1.error}`]: {
|
|
200
|
+
color: (theme.vars || theme).palette.error.main
|
|
201
|
+
}
|
|
202
|
+
})));
|
|
203
|
+
const FormLabel = /*#__PURE__*/React.forwardRef(function FormLabel(inProps, ref) {
|
|
204
|
+
const props = useDefaultProps({
|
|
205
|
+
props: inProps,
|
|
206
|
+
name: 'MuiFormLabel'
|
|
207
|
+
});
|
|
208
|
+
const {
|
|
209
|
+
children,
|
|
210
|
+
className,
|
|
211
|
+
color,
|
|
212
|
+
component = 'label',
|
|
213
|
+
disabled,
|
|
214
|
+
error,
|
|
215
|
+
filled,
|
|
216
|
+
focused,
|
|
217
|
+
required,
|
|
218
|
+
...other
|
|
219
|
+
} = props;
|
|
220
|
+
const muiFormControl = useFormControl();
|
|
221
|
+
const fcs = formControlState({
|
|
222
|
+
props,
|
|
223
|
+
muiFormControl,
|
|
224
|
+
states: ['color', 'required', 'focused', 'disabled', 'error', 'filled']
|
|
225
|
+
});
|
|
226
|
+
const ownerState = {
|
|
227
|
+
...props,
|
|
228
|
+
color: fcs.color || 'primary',
|
|
229
|
+
component,
|
|
230
|
+
disabled: fcs.disabled,
|
|
231
|
+
error: fcs.error,
|
|
232
|
+
filled: fcs.filled,
|
|
233
|
+
focused: fcs.focused,
|
|
234
|
+
required: fcs.required
|
|
235
|
+
};
|
|
236
|
+
const classes = useUtilityClasses$4(ownerState);
|
|
237
|
+
return /*#__PURE__*/jsxRuntimeExports.jsxs(FormLabelRoot, {
|
|
238
|
+
as: component,
|
|
239
|
+
ownerState: ownerState,
|
|
240
|
+
className: clsx(classes.root, className),
|
|
241
|
+
ref: ref,
|
|
242
|
+
...other,
|
|
243
|
+
children: [children, fcs.required && /*#__PURE__*/jsxRuntimeExports.jsxs(AsteriskComponent, {
|
|
244
|
+
ownerState: ownerState,
|
|
245
|
+
"aria-hidden": true,
|
|
246
|
+
className: classes.asterisk,
|
|
247
|
+
children: ["\u2009", '*']
|
|
248
|
+
})]
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
process.env.NODE_ENV !== "production" ? FormLabel.propTypes /* remove-proptypes */ = {
|
|
252
|
+
// ┌────────────────────────────── Warning ──────────────────────────────┐
|
|
253
|
+
// │ These PropTypes are generated from the TypeScript type definitions. │
|
|
254
|
+
// │ To update them, edit the d.ts file and run `pnpm proptypes`. │
|
|
255
|
+
// └─────────────────────────────────────────────────────────────────────┘
|
|
256
|
+
/**
|
|
257
|
+
* The content of the component.
|
|
258
|
+
*/
|
|
259
|
+
children: PropTypes.node,
|
|
260
|
+
/**
|
|
261
|
+
* Override or extend the styles applied to the component.
|
|
262
|
+
*/
|
|
263
|
+
classes: PropTypes.object,
|
|
264
|
+
/**
|
|
265
|
+
* @ignore
|
|
266
|
+
*/
|
|
267
|
+
className: PropTypes.string,
|
|
268
|
+
/**
|
|
269
|
+
* The color of the component.
|
|
270
|
+
* It supports both default and custom theme colors, which can be added as shown in the
|
|
271
|
+
* [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
|
|
272
|
+
*/
|
|
273
|
+
color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['error', 'info', 'primary', 'secondary', 'success', 'warning']), PropTypes.string]),
|
|
274
|
+
/**
|
|
275
|
+
* The component used for the root node.
|
|
276
|
+
* Either a string to use a HTML element or a component.
|
|
277
|
+
*/
|
|
278
|
+
component: PropTypes.elementType,
|
|
279
|
+
/**
|
|
280
|
+
* If `true`, the label should be displayed in a disabled state.
|
|
281
|
+
*/
|
|
282
|
+
disabled: PropTypes.bool,
|
|
283
|
+
/**
|
|
284
|
+
* If `true`, the label is displayed in an error state.
|
|
285
|
+
*/
|
|
286
|
+
error: PropTypes.bool,
|
|
287
|
+
/**
|
|
288
|
+
* If `true`, the label should use filled classes key.
|
|
289
|
+
*/
|
|
290
|
+
filled: PropTypes.bool,
|
|
291
|
+
/**
|
|
292
|
+
* If `true`, the input of this label is focused (used by `FormGroup` components).
|
|
293
|
+
*/
|
|
294
|
+
focused: PropTypes.bool,
|
|
295
|
+
/**
|
|
296
|
+
* If `true`, the label will indicate that the `input` is required.
|
|
297
|
+
*/
|
|
298
|
+
required: PropTypes.bool,
|
|
299
|
+
/**
|
|
300
|
+
* The system prop that allows defining system overrides as well as additional CSS styles.
|
|
301
|
+
*/
|
|
302
|
+
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
|
|
303
|
+
} : void 0;
|
|
304
|
+
var FormLabel$1 = FormLabel;
|
|
305
|
+
|
|
306
|
+
function getInputLabelUtilityClasses(slot) {
|
|
307
|
+
return generateUtilityClass('MuiInputLabel', slot);
|
|
308
|
+
}
|
|
309
|
+
generateUtilityClasses('MuiInputLabel', ['root', 'focused', 'disabled', 'error', 'required', 'asterisk', 'formControl', 'sizeSmall', 'shrink', 'animated', 'standard', 'filled', 'outlined']);
|
|
310
|
+
|
|
311
|
+
const useUtilityClasses$3 = ownerState => {
|
|
312
|
+
const {
|
|
313
|
+
classes,
|
|
314
|
+
formControl,
|
|
315
|
+
size,
|
|
316
|
+
shrink,
|
|
317
|
+
disableAnimation,
|
|
318
|
+
variant,
|
|
319
|
+
required
|
|
320
|
+
} = ownerState;
|
|
321
|
+
const slots = {
|
|
322
|
+
root: ['root', formControl && 'formControl', !disableAnimation && 'animated', shrink && 'shrink', size && size !== 'normal' && `size${capitalize(size)}`, variant],
|
|
323
|
+
asterisk: [required && 'asterisk']
|
|
324
|
+
};
|
|
325
|
+
const composedClasses = composeClasses(slots, getInputLabelUtilityClasses, classes);
|
|
326
|
+
return {
|
|
327
|
+
...classes,
|
|
328
|
+
// forward the focused, disabled, etc. classes to the FormLabel
|
|
329
|
+
...composedClasses
|
|
330
|
+
};
|
|
331
|
+
};
|
|
332
|
+
const InputLabelRoot = styled$1(FormLabel$1, {
|
|
333
|
+
shouldForwardProp: prop => rootShouldForwardProp(prop) || prop === 'classes',
|
|
334
|
+
name: 'MuiInputLabel',
|
|
335
|
+
slot: 'Root',
|
|
336
|
+
overridesResolver: (props, styles) => {
|
|
337
|
+
const {
|
|
338
|
+
ownerState
|
|
339
|
+
} = props;
|
|
340
|
+
return [{
|
|
341
|
+
[`& .${formLabelClasses$1.asterisk}`]: styles.asterisk
|
|
342
|
+
}, styles.root, ownerState.formControl && styles.formControl, ownerState.size === 'small' && styles.sizeSmall, ownerState.shrink && styles.shrink, !ownerState.disableAnimation && styles.animated, ownerState.focused && styles.focused, styles[ownerState.variant]];
|
|
343
|
+
}
|
|
344
|
+
})(memoTheme(({
|
|
345
|
+
theme
|
|
346
|
+
}) => ({
|
|
347
|
+
display: 'block',
|
|
348
|
+
transformOrigin: 'top left',
|
|
349
|
+
whiteSpace: 'nowrap',
|
|
350
|
+
overflow: 'hidden',
|
|
351
|
+
textOverflow: 'ellipsis',
|
|
352
|
+
maxWidth: '100%',
|
|
353
|
+
variants: [{
|
|
354
|
+
props: ({
|
|
355
|
+
ownerState
|
|
356
|
+
}) => ownerState.formControl,
|
|
357
|
+
style: {
|
|
358
|
+
position: 'absolute',
|
|
359
|
+
left: 0,
|
|
360
|
+
top: 0,
|
|
361
|
+
// slight alteration to spec spacing to match visual spec result
|
|
362
|
+
transform: 'translate(0, 20px) scale(1)'
|
|
363
|
+
}
|
|
364
|
+
}, {
|
|
365
|
+
props: {
|
|
366
|
+
size: 'small'
|
|
367
|
+
},
|
|
368
|
+
style: {
|
|
369
|
+
// Compensation for the `Input.inputSizeSmall` style.
|
|
370
|
+
transform: 'translate(0, 17px) scale(1)'
|
|
371
|
+
}
|
|
372
|
+
}, {
|
|
373
|
+
props: ({
|
|
374
|
+
ownerState
|
|
375
|
+
}) => ownerState.shrink,
|
|
376
|
+
style: {
|
|
377
|
+
transform: 'translate(0, -1.5px) scale(0.75)',
|
|
378
|
+
transformOrigin: 'top left',
|
|
379
|
+
maxWidth: '133%'
|
|
380
|
+
}
|
|
381
|
+
}, {
|
|
382
|
+
props: ({
|
|
383
|
+
ownerState
|
|
384
|
+
}) => !ownerState.disableAnimation,
|
|
385
|
+
style: {
|
|
386
|
+
transition: theme.transitions.create(['color', 'transform', 'max-width'], {
|
|
387
|
+
duration: theme.transitions.duration.shorter,
|
|
388
|
+
easing: theme.transitions.easing.easeOut
|
|
389
|
+
})
|
|
390
|
+
}
|
|
391
|
+
}, {
|
|
392
|
+
props: {
|
|
393
|
+
variant: 'filled'
|
|
394
|
+
},
|
|
395
|
+
style: {
|
|
396
|
+
// Chrome's autofill feature gives the input field a yellow background.
|
|
397
|
+
// Since the input field is behind the label in the HTML tree,
|
|
398
|
+
// the input field is drawn last and hides the label with an opaque background color.
|
|
399
|
+
// zIndex: 1 will raise the label above opaque background-colors of input.
|
|
400
|
+
zIndex: 1,
|
|
401
|
+
pointerEvents: 'none',
|
|
402
|
+
transform: 'translate(12px, 16px) scale(1)',
|
|
403
|
+
maxWidth: 'calc(100% - 24px)'
|
|
404
|
+
}
|
|
405
|
+
}, {
|
|
406
|
+
props: {
|
|
407
|
+
variant: 'filled',
|
|
408
|
+
size: 'small'
|
|
409
|
+
},
|
|
410
|
+
style: {
|
|
411
|
+
transform: 'translate(12px, 13px) scale(1)'
|
|
412
|
+
}
|
|
413
|
+
}, {
|
|
414
|
+
props: ({
|
|
415
|
+
variant,
|
|
416
|
+
ownerState
|
|
417
|
+
}) => variant === 'filled' && ownerState.shrink,
|
|
418
|
+
style: {
|
|
419
|
+
userSelect: 'none',
|
|
420
|
+
pointerEvents: 'auto',
|
|
421
|
+
transform: 'translate(12px, 7px) scale(0.75)',
|
|
422
|
+
maxWidth: 'calc(133% - 24px)'
|
|
423
|
+
}
|
|
424
|
+
}, {
|
|
425
|
+
props: ({
|
|
426
|
+
variant,
|
|
427
|
+
ownerState,
|
|
428
|
+
size
|
|
429
|
+
}) => variant === 'filled' && ownerState.shrink && size === 'small',
|
|
430
|
+
style: {
|
|
431
|
+
transform: 'translate(12px, 4px) scale(0.75)'
|
|
432
|
+
}
|
|
433
|
+
}, {
|
|
434
|
+
props: {
|
|
435
|
+
variant: 'outlined'
|
|
436
|
+
},
|
|
437
|
+
style: {
|
|
438
|
+
// see comment above on filled.zIndex
|
|
439
|
+
zIndex: 1,
|
|
440
|
+
pointerEvents: 'none',
|
|
441
|
+
transform: 'translate(14px, 16px) scale(1)',
|
|
442
|
+
maxWidth: 'calc(100% - 24px)'
|
|
443
|
+
}
|
|
444
|
+
}, {
|
|
445
|
+
props: {
|
|
446
|
+
variant: 'outlined',
|
|
447
|
+
size: 'small'
|
|
448
|
+
},
|
|
449
|
+
style: {
|
|
450
|
+
transform: 'translate(14px, 9px) scale(1)'
|
|
451
|
+
}
|
|
452
|
+
}, {
|
|
453
|
+
props: ({
|
|
454
|
+
variant,
|
|
455
|
+
ownerState
|
|
456
|
+
}) => variant === 'outlined' && ownerState.shrink,
|
|
457
|
+
style: {
|
|
458
|
+
userSelect: 'none',
|
|
459
|
+
pointerEvents: 'auto',
|
|
460
|
+
// Theoretically, we should have (8+5)*2/0.75 = 34px
|
|
461
|
+
// but it feels a better when it bleeds a bit on the left, so 32px.
|
|
462
|
+
maxWidth: 'calc(133% - 32px)',
|
|
463
|
+
transform: 'translate(14px, -9px) scale(0.75)'
|
|
464
|
+
}
|
|
465
|
+
}]
|
|
466
|
+
})));
|
|
467
|
+
const InputLabel = /*#__PURE__*/React.forwardRef(function InputLabel(inProps, ref) {
|
|
468
|
+
const props = useDefaultProps({
|
|
469
|
+
name: 'MuiInputLabel',
|
|
470
|
+
props: inProps
|
|
471
|
+
});
|
|
472
|
+
const {
|
|
473
|
+
disableAnimation = false,
|
|
474
|
+
margin,
|
|
475
|
+
shrink: shrinkProp,
|
|
476
|
+
variant,
|
|
477
|
+
className,
|
|
478
|
+
...other
|
|
479
|
+
} = props;
|
|
480
|
+
const muiFormControl = useFormControl();
|
|
481
|
+
let shrink = shrinkProp;
|
|
482
|
+
if (typeof shrink === 'undefined' && muiFormControl) {
|
|
483
|
+
shrink = muiFormControl.filled || muiFormControl.focused || muiFormControl.adornedStart;
|
|
484
|
+
}
|
|
485
|
+
const fcs = formControlState({
|
|
486
|
+
props,
|
|
487
|
+
muiFormControl,
|
|
488
|
+
states: ['size', 'variant', 'required', 'focused']
|
|
489
|
+
});
|
|
490
|
+
const ownerState = {
|
|
491
|
+
...props,
|
|
492
|
+
disableAnimation,
|
|
493
|
+
formControl: muiFormControl,
|
|
494
|
+
shrink,
|
|
495
|
+
size: fcs.size,
|
|
496
|
+
variant: fcs.variant,
|
|
497
|
+
required: fcs.required,
|
|
498
|
+
focused: fcs.focused
|
|
499
|
+
};
|
|
500
|
+
const classes = useUtilityClasses$3(ownerState);
|
|
501
|
+
return /*#__PURE__*/jsxRuntimeExports.jsx(InputLabelRoot, {
|
|
502
|
+
"data-shrink": shrink,
|
|
503
|
+
ref: ref,
|
|
504
|
+
className: clsx(classes.root, className),
|
|
505
|
+
...other,
|
|
506
|
+
ownerState: ownerState,
|
|
507
|
+
classes: classes
|
|
508
|
+
});
|
|
509
|
+
});
|
|
510
|
+
process.env.NODE_ENV !== "production" ? InputLabel.propTypes /* remove-proptypes */ = {
|
|
511
|
+
// ┌────────────────────────────── Warning ──────────────────────────────┐
|
|
512
|
+
// │ These PropTypes are generated from the TypeScript type definitions. │
|
|
513
|
+
// │ To update them, edit the d.ts file and run `pnpm proptypes`. │
|
|
514
|
+
// └─────────────────────────────────────────────────────────────────────┘
|
|
515
|
+
/**
|
|
516
|
+
* The content of the component.
|
|
517
|
+
*/
|
|
518
|
+
children: PropTypes.node,
|
|
519
|
+
/**
|
|
520
|
+
* Override or extend the styles applied to the component.
|
|
521
|
+
*/
|
|
522
|
+
classes: PropTypes.object,
|
|
523
|
+
/**
|
|
524
|
+
* @ignore
|
|
525
|
+
*/
|
|
526
|
+
className: PropTypes.string,
|
|
527
|
+
/**
|
|
528
|
+
* The color of the component.
|
|
529
|
+
* It supports both default and custom theme colors, which can be added as shown in the
|
|
530
|
+
* [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
|
|
531
|
+
*/
|
|
532
|
+
color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['error', 'info', 'primary', 'secondary', 'success', 'warning']), PropTypes.string]),
|
|
533
|
+
/**
|
|
534
|
+
* If `true`, the transition animation is disabled.
|
|
535
|
+
* @default false
|
|
536
|
+
*/
|
|
537
|
+
disableAnimation: PropTypes.bool,
|
|
538
|
+
/**
|
|
539
|
+
* If `true`, the component is disabled.
|
|
540
|
+
*/
|
|
541
|
+
disabled: PropTypes.bool,
|
|
542
|
+
/**
|
|
543
|
+
* If `true`, the label is displayed in an error state.
|
|
544
|
+
*/
|
|
545
|
+
error: PropTypes.bool,
|
|
546
|
+
/**
|
|
547
|
+
* If `true`, the `input` of this label is focused.
|
|
548
|
+
*/
|
|
549
|
+
focused: PropTypes.bool,
|
|
550
|
+
/**
|
|
551
|
+
* If `dense`, will adjust vertical spacing. This is normally obtained via context from
|
|
552
|
+
* FormControl.
|
|
553
|
+
*/
|
|
554
|
+
margin: PropTypes.oneOf(['dense']),
|
|
555
|
+
/**
|
|
556
|
+
* if `true`, the label will indicate that the `input` is required.
|
|
557
|
+
*/
|
|
558
|
+
required: PropTypes.bool,
|
|
559
|
+
/**
|
|
560
|
+
* If `true`, the label is shrunk.
|
|
561
|
+
*/
|
|
562
|
+
shrink: PropTypes.bool,
|
|
563
|
+
/**
|
|
564
|
+
* The size of the component.
|
|
565
|
+
* @default 'normal'
|
|
566
|
+
*/
|
|
567
|
+
size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['normal', 'small']), PropTypes.string]),
|
|
568
|
+
/**
|
|
569
|
+
* The system prop that allows defining system overrides as well as additional CSS styles.
|
|
570
|
+
*/
|
|
571
|
+
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
|
|
572
|
+
/**
|
|
573
|
+
* The variant to use.
|
|
574
|
+
*/
|
|
575
|
+
variant: PropTypes.oneOf(['filled', 'outlined', 'standard'])
|
|
576
|
+
} : void 0;
|
|
577
|
+
var InputLabel$1 = InputLabel;
|
|
578
|
+
|
|
579
|
+
function getFormControlUtilityClasses(slot) {
|
|
580
|
+
return generateUtilityClass('MuiFormControl', slot);
|
|
581
|
+
}
|
|
582
|
+
generateUtilityClasses('MuiFormControl', ['root', 'marginNone', 'marginNormal', 'marginDense', 'fullWidth', 'disabled']);
|
|
583
|
+
|
|
584
|
+
const useUtilityClasses$2 = ownerState => {
|
|
585
|
+
const {
|
|
586
|
+
classes,
|
|
587
|
+
margin,
|
|
588
|
+
fullWidth
|
|
589
|
+
} = ownerState;
|
|
590
|
+
const slots = {
|
|
591
|
+
root: ['root', margin !== 'none' && `margin${capitalize(margin)}`, fullWidth && 'fullWidth']
|
|
592
|
+
};
|
|
593
|
+
return composeClasses(slots, getFormControlUtilityClasses, classes);
|
|
594
|
+
};
|
|
595
|
+
const FormControlRoot = styled$1('div', {
|
|
596
|
+
name: 'MuiFormControl',
|
|
597
|
+
slot: 'Root',
|
|
598
|
+
overridesResolver: (props, styles) => {
|
|
599
|
+
const {
|
|
600
|
+
ownerState
|
|
601
|
+
} = props;
|
|
602
|
+
return [styles.root, styles[`margin${capitalize(ownerState.margin)}`], ownerState.fullWidth && styles.fullWidth];
|
|
603
|
+
}
|
|
604
|
+
})({
|
|
605
|
+
display: 'inline-flex',
|
|
606
|
+
flexDirection: 'column',
|
|
607
|
+
position: 'relative',
|
|
608
|
+
// Reset fieldset default style.
|
|
609
|
+
minWidth: 0,
|
|
610
|
+
padding: 0,
|
|
611
|
+
margin: 0,
|
|
612
|
+
border: 0,
|
|
613
|
+
verticalAlign: 'top',
|
|
614
|
+
// Fix alignment issue on Safari.
|
|
615
|
+
variants: [{
|
|
616
|
+
props: {
|
|
617
|
+
margin: 'normal'
|
|
618
|
+
},
|
|
619
|
+
style: {
|
|
620
|
+
marginTop: 16,
|
|
621
|
+
marginBottom: 8
|
|
622
|
+
}
|
|
623
|
+
}, {
|
|
624
|
+
props: {
|
|
625
|
+
margin: 'dense'
|
|
626
|
+
},
|
|
627
|
+
style: {
|
|
628
|
+
marginTop: 8,
|
|
629
|
+
marginBottom: 4
|
|
630
|
+
}
|
|
631
|
+
}, {
|
|
632
|
+
props: {
|
|
633
|
+
fullWidth: true
|
|
634
|
+
},
|
|
635
|
+
style: {
|
|
636
|
+
width: '100%'
|
|
637
|
+
}
|
|
638
|
+
}]
|
|
639
|
+
});
|
|
640
|
+
|
|
641
|
+
/**
|
|
642
|
+
* Provides context such as filled/focused/error/required for form inputs.
|
|
643
|
+
* Relying on the context provides high flexibility and ensures that the state always stays
|
|
644
|
+
* consistent across the children of the `FormControl`.
|
|
645
|
+
* This context is used by the following components:
|
|
646
|
+
*
|
|
647
|
+
* - FormLabel
|
|
648
|
+
* - FormHelperText
|
|
649
|
+
* - Input
|
|
650
|
+
* - InputLabel
|
|
651
|
+
*
|
|
652
|
+
* You can find one composition example below and more going to [the demos](/material-ui/react-text-field/#components).
|
|
653
|
+
*
|
|
654
|
+
* ```jsx
|
|
655
|
+
* <FormControl>
|
|
656
|
+
* <InputLabel htmlFor="my-input">Email address</InputLabel>
|
|
657
|
+
* <Input id="my-input" aria-describedby="my-helper-text" />
|
|
658
|
+
* <FormHelperText id="my-helper-text">We'll never share your email.</FormHelperText>
|
|
659
|
+
* </FormControl>
|
|
660
|
+
* ```
|
|
661
|
+
*
|
|
662
|
+
* ⚠️ Only one `InputBase` can be used within a FormControl because it creates visual inconsistencies.
|
|
663
|
+
* For instance, only one input can be focused at the same time, the state shouldn't be shared.
|
|
664
|
+
*/
|
|
665
|
+
const FormControl = /*#__PURE__*/React.forwardRef(function FormControl(inProps, ref) {
|
|
666
|
+
const props = useDefaultProps({
|
|
667
|
+
props: inProps,
|
|
668
|
+
name: 'MuiFormControl'
|
|
669
|
+
});
|
|
670
|
+
const {
|
|
671
|
+
children,
|
|
672
|
+
className,
|
|
673
|
+
color = 'primary',
|
|
674
|
+
component = 'div',
|
|
675
|
+
disabled = false,
|
|
676
|
+
error = false,
|
|
677
|
+
focused: visuallyFocused,
|
|
678
|
+
fullWidth = false,
|
|
679
|
+
hiddenLabel = false,
|
|
680
|
+
margin = 'none',
|
|
681
|
+
required = false,
|
|
682
|
+
size = 'medium',
|
|
683
|
+
variant = 'outlined',
|
|
684
|
+
...other
|
|
685
|
+
} = props;
|
|
686
|
+
const ownerState = {
|
|
687
|
+
...props,
|
|
688
|
+
color,
|
|
689
|
+
component,
|
|
690
|
+
disabled,
|
|
691
|
+
error,
|
|
692
|
+
fullWidth,
|
|
693
|
+
hiddenLabel,
|
|
694
|
+
margin,
|
|
695
|
+
required,
|
|
696
|
+
size,
|
|
697
|
+
variant
|
|
698
|
+
};
|
|
699
|
+
const classes = useUtilityClasses$2(ownerState);
|
|
700
|
+
const [adornedStart, setAdornedStart] = React.useState(() => {
|
|
701
|
+
// We need to iterate through the children and find the Input in order
|
|
702
|
+
// to fully support server-side rendering.
|
|
703
|
+
let initialAdornedStart = false;
|
|
704
|
+
if (children) {
|
|
705
|
+
React.Children.forEach(children, child => {
|
|
706
|
+
if (!isMuiElement(child, ['Input', 'Select'])) {
|
|
707
|
+
return;
|
|
708
|
+
}
|
|
709
|
+
const input = isMuiElement(child, ['Select']) ? child.props.input : child;
|
|
710
|
+
if (input && isAdornedStart(input.props)) {
|
|
711
|
+
initialAdornedStart = true;
|
|
712
|
+
}
|
|
713
|
+
});
|
|
714
|
+
}
|
|
715
|
+
return initialAdornedStart;
|
|
716
|
+
});
|
|
717
|
+
const [filled, setFilled] = React.useState(() => {
|
|
718
|
+
// We need to iterate through the children and find the Input in order
|
|
719
|
+
// to fully support server-side rendering.
|
|
720
|
+
let initialFilled = false;
|
|
721
|
+
if (children) {
|
|
722
|
+
React.Children.forEach(children, child => {
|
|
723
|
+
if (!isMuiElement(child, ['Input', 'Select'])) {
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
726
|
+
if (isFilled(child.props, true) || isFilled(child.props.inputProps, true)) {
|
|
727
|
+
initialFilled = true;
|
|
728
|
+
}
|
|
729
|
+
});
|
|
730
|
+
}
|
|
731
|
+
return initialFilled;
|
|
732
|
+
});
|
|
733
|
+
const [focusedState, setFocused] = React.useState(false);
|
|
734
|
+
if (disabled && focusedState) {
|
|
735
|
+
setFocused(false);
|
|
736
|
+
}
|
|
737
|
+
const focused = visuallyFocused !== undefined && !disabled ? visuallyFocused : focusedState;
|
|
738
|
+
let registerEffect;
|
|
739
|
+
const registeredInput = React.useRef(false);
|
|
740
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
741
|
+
registerEffect = () => {
|
|
742
|
+
if (registeredInput.current) {
|
|
743
|
+
console.error(['MUI: There are multiple `InputBase` components inside a FormControl.', 'This creates visual inconsistencies, only use one `InputBase`.'].join('\n'));
|
|
744
|
+
}
|
|
745
|
+
registeredInput.current = true;
|
|
746
|
+
return () => {
|
|
747
|
+
registeredInput.current = false;
|
|
748
|
+
};
|
|
749
|
+
};
|
|
750
|
+
}
|
|
751
|
+
const onFilled = React.useCallback(() => {
|
|
752
|
+
setFilled(true);
|
|
753
|
+
}, []);
|
|
754
|
+
const onEmpty = React.useCallback(() => {
|
|
755
|
+
setFilled(false);
|
|
756
|
+
}, []);
|
|
757
|
+
const childContext = React.useMemo(() => {
|
|
758
|
+
return {
|
|
759
|
+
adornedStart,
|
|
760
|
+
setAdornedStart,
|
|
761
|
+
color,
|
|
762
|
+
disabled,
|
|
763
|
+
error,
|
|
764
|
+
filled,
|
|
765
|
+
focused,
|
|
766
|
+
fullWidth,
|
|
767
|
+
hiddenLabel,
|
|
768
|
+
size,
|
|
769
|
+
onBlur: () => {
|
|
770
|
+
setFocused(false);
|
|
771
|
+
},
|
|
772
|
+
onFocus: () => {
|
|
773
|
+
setFocused(true);
|
|
774
|
+
},
|
|
775
|
+
onEmpty,
|
|
776
|
+
onFilled,
|
|
777
|
+
registerEffect,
|
|
778
|
+
required,
|
|
779
|
+
variant
|
|
780
|
+
};
|
|
781
|
+
}, [adornedStart, color, disabled, error, filled, focused, fullWidth, hiddenLabel, registerEffect, onEmpty, onFilled, required, size, variant]);
|
|
782
|
+
return /*#__PURE__*/jsxRuntimeExports.jsx(FormControlContext.Provider, {
|
|
783
|
+
value: childContext,
|
|
784
|
+
children: /*#__PURE__*/jsxRuntimeExports.jsx(FormControlRoot, {
|
|
785
|
+
as: component,
|
|
786
|
+
ownerState: ownerState,
|
|
787
|
+
className: clsx(classes.root, className),
|
|
788
|
+
ref: ref,
|
|
789
|
+
...other,
|
|
790
|
+
children: children
|
|
791
|
+
})
|
|
792
|
+
});
|
|
793
|
+
});
|
|
794
|
+
process.env.NODE_ENV !== "production" ? FormControl.propTypes /* remove-proptypes */ = {
|
|
795
|
+
// ┌────────────────────────────── Warning ──────────────────────────────┐
|
|
796
|
+
// │ These PropTypes are generated from the TypeScript type definitions. │
|
|
797
|
+
// │ To update them, edit the d.ts file and run `pnpm proptypes`. │
|
|
798
|
+
// └─────────────────────────────────────────────────────────────────────┘
|
|
799
|
+
/**
|
|
800
|
+
* The content of the component.
|
|
801
|
+
*/
|
|
802
|
+
children: PropTypes.node,
|
|
803
|
+
/**
|
|
804
|
+
* Override or extend the styles applied to the component.
|
|
805
|
+
*/
|
|
806
|
+
classes: PropTypes.object,
|
|
807
|
+
/**
|
|
808
|
+
* @ignore
|
|
809
|
+
*/
|
|
810
|
+
className: PropTypes.string,
|
|
811
|
+
/**
|
|
812
|
+
* The color of the component.
|
|
813
|
+
* It supports both default and custom theme colors, which can be added as shown in the
|
|
814
|
+
* [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
|
|
815
|
+
* @default 'primary'
|
|
816
|
+
*/
|
|
817
|
+
color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['primary', 'secondary', 'error', 'info', 'success', 'warning']), PropTypes.string]),
|
|
818
|
+
/**
|
|
819
|
+
* The component used for the root node.
|
|
820
|
+
* Either a string to use a HTML element or a component.
|
|
821
|
+
*/
|
|
822
|
+
component: PropTypes.elementType,
|
|
823
|
+
/**
|
|
824
|
+
* If `true`, the label, input and helper text should be displayed in a disabled state.
|
|
825
|
+
* @default false
|
|
826
|
+
*/
|
|
827
|
+
disabled: PropTypes.bool,
|
|
828
|
+
/**
|
|
829
|
+
* If `true`, the label is displayed in an error state.
|
|
830
|
+
* @default false
|
|
831
|
+
*/
|
|
832
|
+
error: PropTypes.bool,
|
|
833
|
+
/**
|
|
834
|
+
* If `true`, the component is displayed in focused state.
|
|
835
|
+
*/
|
|
836
|
+
focused: PropTypes.bool,
|
|
837
|
+
/**
|
|
838
|
+
* If `true`, the component will take up the full width of its container.
|
|
839
|
+
* @default false
|
|
840
|
+
*/
|
|
841
|
+
fullWidth: PropTypes.bool,
|
|
842
|
+
/**
|
|
843
|
+
* If `true`, the label is hidden.
|
|
844
|
+
* This is used to increase density for a `FilledInput`.
|
|
845
|
+
* Be sure to add `aria-label` to the `input` element.
|
|
846
|
+
* @default false
|
|
847
|
+
*/
|
|
848
|
+
hiddenLabel: PropTypes.bool,
|
|
849
|
+
/**
|
|
850
|
+
* If `dense` or `normal`, will adjust vertical spacing of this and contained components.
|
|
851
|
+
* @default 'none'
|
|
852
|
+
*/
|
|
853
|
+
margin: PropTypes.oneOf(['dense', 'none', 'normal']),
|
|
854
|
+
/**
|
|
855
|
+
* If `true`, the label will indicate that the `input` is required.
|
|
856
|
+
* @default false
|
|
857
|
+
*/
|
|
858
|
+
required: PropTypes.bool,
|
|
859
|
+
/**
|
|
860
|
+
* The size of the component.
|
|
861
|
+
* @default 'medium'
|
|
862
|
+
*/
|
|
863
|
+
size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['medium', 'small']), PropTypes.string]),
|
|
864
|
+
/**
|
|
865
|
+
* The system prop that allows defining system overrides as well as additional CSS styles.
|
|
866
|
+
*/
|
|
867
|
+
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
|
|
868
|
+
/**
|
|
869
|
+
* The variant to use.
|
|
870
|
+
* @default 'outlined'
|
|
871
|
+
*/
|
|
872
|
+
variant: PropTypes.oneOf(['filled', 'outlined', 'standard'])
|
|
873
|
+
} : void 0;
|
|
874
|
+
var FormControl$1 = FormControl;
|
|
875
|
+
|
|
876
|
+
function getFormHelperTextUtilityClasses(slot) {
|
|
877
|
+
return generateUtilityClass('MuiFormHelperText', slot);
|
|
878
|
+
}
|
|
879
|
+
const formHelperTextClasses = generateUtilityClasses('MuiFormHelperText', ['root', 'error', 'disabled', 'sizeSmall', 'sizeMedium', 'contained', 'focused', 'filled', 'required']);
|
|
880
|
+
var formHelperTextClasses$1 = formHelperTextClasses;
|
|
881
|
+
|
|
882
|
+
var _span;
|
|
883
|
+
const useUtilityClasses$1 = ownerState => {
|
|
884
|
+
const {
|
|
885
|
+
classes,
|
|
886
|
+
contained,
|
|
887
|
+
size,
|
|
888
|
+
disabled,
|
|
889
|
+
error,
|
|
890
|
+
filled,
|
|
891
|
+
focused,
|
|
892
|
+
required
|
|
893
|
+
} = ownerState;
|
|
894
|
+
const slots = {
|
|
895
|
+
root: ['root', disabled && 'disabled', error && 'error', size && `size${capitalize(size)}`, contained && 'contained', focused && 'focused', filled && 'filled', required && 'required']
|
|
896
|
+
};
|
|
897
|
+
return composeClasses(slots, getFormHelperTextUtilityClasses, classes);
|
|
898
|
+
};
|
|
899
|
+
const FormHelperTextRoot = styled$1('p', {
|
|
900
|
+
name: 'MuiFormHelperText',
|
|
901
|
+
slot: 'Root',
|
|
902
|
+
overridesResolver: (props, styles) => {
|
|
903
|
+
const {
|
|
904
|
+
ownerState
|
|
905
|
+
} = props;
|
|
906
|
+
return [styles.root, ownerState.size && styles[`size${capitalize(ownerState.size)}`], ownerState.contained && styles.contained, ownerState.filled && styles.filled];
|
|
907
|
+
}
|
|
908
|
+
})(memoTheme(({
|
|
909
|
+
theme
|
|
910
|
+
}) => ({
|
|
911
|
+
color: (theme.vars || theme).palette.text.secondary,
|
|
912
|
+
...theme.typography.caption,
|
|
913
|
+
textAlign: 'left',
|
|
914
|
+
marginTop: 3,
|
|
915
|
+
marginRight: 0,
|
|
916
|
+
marginBottom: 0,
|
|
917
|
+
marginLeft: 0,
|
|
918
|
+
[`&.${formHelperTextClasses$1.disabled}`]: {
|
|
919
|
+
color: (theme.vars || theme).palette.text.disabled
|
|
920
|
+
},
|
|
921
|
+
[`&.${formHelperTextClasses$1.error}`]: {
|
|
922
|
+
color: (theme.vars || theme).palette.error.main
|
|
923
|
+
},
|
|
924
|
+
variants: [{
|
|
925
|
+
props: {
|
|
926
|
+
size: 'small'
|
|
927
|
+
},
|
|
928
|
+
style: {
|
|
929
|
+
marginTop: 4
|
|
930
|
+
}
|
|
931
|
+
}, {
|
|
932
|
+
props: ({
|
|
933
|
+
ownerState
|
|
934
|
+
}) => ownerState.contained,
|
|
935
|
+
style: {
|
|
936
|
+
marginLeft: 14,
|
|
937
|
+
marginRight: 14
|
|
938
|
+
}
|
|
939
|
+
}]
|
|
940
|
+
})));
|
|
941
|
+
const FormHelperText = /*#__PURE__*/React.forwardRef(function FormHelperText(inProps, ref) {
|
|
942
|
+
const props = useDefaultProps({
|
|
943
|
+
props: inProps,
|
|
944
|
+
name: 'MuiFormHelperText'
|
|
945
|
+
});
|
|
946
|
+
const {
|
|
947
|
+
children,
|
|
948
|
+
className,
|
|
949
|
+
component = 'p',
|
|
950
|
+
disabled,
|
|
951
|
+
error,
|
|
952
|
+
filled,
|
|
953
|
+
focused,
|
|
954
|
+
margin,
|
|
955
|
+
required,
|
|
956
|
+
variant,
|
|
957
|
+
...other
|
|
958
|
+
} = props;
|
|
959
|
+
const muiFormControl = useFormControl();
|
|
960
|
+
const fcs = formControlState({
|
|
961
|
+
props,
|
|
962
|
+
muiFormControl,
|
|
963
|
+
states: ['variant', 'size', 'disabled', 'error', 'filled', 'focused', 'required']
|
|
964
|
+
});
|
|
965
|
+
const ownerState = {
|
|
966
|
+
...props,
|
|
967
|
+
component,
|
|
968
|
+
contained: fcs.variant === 'filled' || fcs.variant === 'outlined',
|
|
969
|
+
variant: fcs.variant,
|
|
970
|
+
size: fcs.size,
|
|
971
|
+
disabled: fcs.disabled,
|
|
972
|
+
error: fcs.error,
|
|
973
|
+
filled: fcs.filled,
|
|
974
|
+
focused: fcs.focused,
|
|
975
|
+
required: fcs.required
|
|
976
|
+
};
|
|
977
|
+
|
|
978
|
+
// This issue explains why this is required: https://github.com/mui/material-ui/issues/42184
|
|
979
|
+
delete ownerState.ownerState;
|
|
980
|
+
const classes = useUtilityClasses$1(ownerState);
|
|
981
|
+
return /*#__PURE__*/jsxRuntimeExports.jsx(FormHelperTextRoot, {
|
|
982
|
+
as: component,
|
|
983
|
+
className: clsx(classes.root, className),
|
|
984
|
+
ref: ref,
|
|
985
|
+
...other,
|
|
986
|
+
ownerState: ownerState,
|
|
987
|
+
children: children === ' ' ? // notranslate needed while Google Translate will not fix zero-width space issue
|
|
988
|
+
_span || (_span = /*#__PURE__*/jsxRuntimeExports.jsx("span", {
|
|
989
|
+
className: "notranslate",
|
|
990
|
+
"aria-hidden": true,
|
|
991
|
+
children: "\u200B"
|
|
992
|
+
})) : children
|
|
993
|
+
});
|
|
994
|
+
});
|
|
995
|
+
process.env.NODE_ENV !== "production" ? FormHelperText.propTypes /* remove-proptypes */ = {
|
|
996
|
+
// ┌────────────────────────────── Warning ──────────────────────────────┐
|
|
997
|
+
// │ These PropTypes are generated from the TypeScript type definitions. │
|
|
998
|
+
// │ To update them, edit the d.ts file and run `pnpm proptypes`. │
|
|
999
|
+
// └─────────────────────────────────────────────────────────────────────┘
|
|
1000
|
+
/**
|
|
1001
|
+
* The content of the component.
|
|
1002
|
+
*
|
|
1003
|
+
* If `' '` is provided, the component reserves one line height for displaying a future message.
|
|
1004
|
+
*/
|
|
1005
|
+
children: PropTypes.node,
|
|
1006
|
+
/**
|
|
1007
|
+
* Override or extend the styles applied to the component.
|
|
1008
|
+
*/
|
|
1009
|
+
classes: PropTypes.object,
|
|
1010
|
+
/**
|
|
1011
|
+
* @ignore
|
|
1012
|
+
*/
|
|
1013
|
+
className: PropTypes.string,
|
|
1014
|
+
/**
|
|
1015
|
+
* The component used for the root node.
|
|
1016
|
+
* Either a string to use a HTML element or a component.
|
|
1017
|
+
*/
|
|
1018
|
+
component: PropTypes.elementType,
|
|
1019
|
+
/**
|
|
1020
|
+
* If `true`, the helper text should be displayed in a disabled state.
|
|
1021
|
+
*/
|
|
1022
|
+
disabled: PropTypes.bool,
|
|
1023
|
+
/**
|
|
1024
|
+
* If `true`, helper text should be displayed in an error state.
|
|
1025
|
+
*/
|
|
1026
|
+
error: PropTypes.bool,
|
|
1027
|
+
/**
|
|
1028
|
+
* If `true`, the helper text should use filled classes key.
|
|
1029
|
+
*/
|
|
1030
|
+
filled: PropTypes.bool,
|
|
1031
|
+
/**
|
|
1032
|
+
* If `true`, the helper text should use focused classes key.
|
|
1033
|
+
*/
|
|
1034
|
+
focused: PropTypes.bool,
|
|
1035
|
+
/**
|
|
1036
|
+
* If `dense`, will adjust vertical spacing. This is normally obtained via context from
|
|
1037
|
+
* FormControl.
|
|
1038
|
+
*/
|
|
1039
|
+
margin: PropTypes.oneOf(['dense']),
|
|
1040
|
+
/**
|
|
1041
|
+
* If `true`, the helper text should use required classes key.
|
|
1042
|
+
*/
|
|
1043
|
+
required: PropTypes.bool,
|
|
1044
|
+
/**
|
|
1045
|
+
* The system prop that allows defining system overrides as well as additional CSS styles.
|
|
1046
|
+
*/
|
|
1047
|
+
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
|
|
1048
|
+
/**
|
|
1049
|
+
* The variant to use.
|
|
1050
|
+
*/
|
|
1051
|
+
variant: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['filled', 'outlined', 'standard']), PropTypes.string])
|
|
1052
|
+
} : void 0;
|
|
1053
|
+
var FormHelperText$1 = FormHelperText;
|
|
1054
|
+
|
|
1055
|
+
function getTextFieldUtilityClass(slot) {
|
|
1056
|
+
return generateUtilityClass('MuiTextField', slot);
|
|
1057
|
+
}
|
|
1058
|
+
generateUtilityClasses('MuiTextField', ['root']);
|
|
1059
|
+
|
|
1060
|
+
const variantComponent = {
|
|
1061
|
+
standard: Input,
|
|
1062
|
+
filled: FilledInput,
|
|
1063
|
+
outlined: OutlinedInput
|
|
1064
|
+
};
|
|
1065
|
+
const useUtilityClasses = ownerState => {
|
|
1066
|
+
const {
|
|
1067
|
+
classes
|
|
1068
|
+
} = ownerState;
|
|
1069
|
+
const slots = {
|
|
1070
|
+
root: ['root']
|
|
1071
|
+
};
|
|
1072
|
+
return composeClasses(slots, getTextFieldUtilityClass, classes);
|
|
1073
|
+
};
|
|
1074
|
+
const TextFieldRoot = styled$1(FormControl$1, {
|
|
1075
|
+
name: 'MuiTextField',
|
|
1076
|
+
slot: 'Root',
|
|
1077
|
+
overridesResolver: (props, styles) => styles.root
|
|
1078
|
+
})({});
|
|
1079
|
+
|
|
1080
|
+
/**
|
|
1081
|
+
* The `TextField` is a convenience wrapper for the most common cases (80%).
|
|
1082
|
+
* It cannot be all things to all people, otherwise the API would grow out of control.
|
|
1083
|
+
*
|
|
1084
|
+
* ## Advanced Configuration
|
|
1085
|
+
*
|
|
1086
|
+
* It's important to understand that the text field is a simple abstraction
|
|
1087
|
+
* on top of the following components:
|
|
1088
|
+
*
|
|
1089
|
+
* - [FormControl](/material-ui/api/form-control/)
|
|
1090
|
+
* - [InputLabel](/material-ui/api/input-label/)
|
|
1091
|
+
* - [FilledInput](/material-ui/api/filled-input/)
|
|
1092
|
+
* - [OutlinedInput](/material-ui/api/outlined-input/)
|
|
1093
|
+
* - [Input](/material-ui/api/input/)
|
|
1094
|
+
* - [FormHelperText](/material-ui/api/form-helper-text/)
|
|
1095
|
+
*
|
|
1096
|
+
* If you wish to alter the props applied to the `input` element, you can do so as follows:
|
|
1097
|
+
*
|
|
1098
|
+
* ```jsx
|
|
1099
|
+
* const inputProps = {
|
|
1100
|
+
* step: 300,
|
|
1101
|
+
* };
|
|
1102
|
+
*
|
|
1103
|
+
* return <TextField id="time" type="time" inputProps={inputProps} />;
|
|
1104
|
+
* ```
|
|
1105
|
+
*
|
|
1106
|
+
* For advanced cases, please look at the source of TextField by clicking on the
|
|
1107
|
+
* "Edit this page" button above. Consider either:
|
|
1108
|
+
*
|
|
1109
|
+
* - using the upper case props for passing values directly to the components
|
|
1110
|
+
* - using the underlying components directly as shown in the demos
|
|
1111
|
+
*/
|
|
1112
|
+
const TextField = /*#__PURE__*/React.forwardRef(function TextField(inProps, ref) {
|
|
1113
|
+
const props = useDefaultProps({
|
|
1114
|
+
props: inProps,
|
|
1115
|
+
name: 'MuiTextField'
|
|
1116
|
+
});
|
|
1117
|
+
const {
|
|
1118
|
+
autoComplete,
|
|
1119
|
+
autoFocus = false,
|
|
1120
|
+
children,
|
|
1121
|
+
className,
|
|
1122
|
+
color = 'primary',
|
|
1123
|
+
defaultValue,
|
|
1124
|
+
disabled = false,
|
|
1125
|
+
error = false,
|
|
1126
|
+
FormHelperTextProps: FormHelperTextPropsProp,
|
|
1127
|
+
fullWidth = false,
|
|
1128
|
+
helperText,
|
|
1129
|
+
id: idOverride,
|
|
1130
|
+
InputLabelProps: InputLabelPropsProp,
|
|
1131
|
+
inputProps: inputPropsProp,
|
|
1132
|
+
InputProps: InputPropsProp,
|
|
1133
|
+
inputRef,
|
|
1134
|
+
label,
|
|
1135
|
+
maxRows,
|
|
1136
|
+
minRows,
|
|
1137
|
+
multiline = false,
|
|
1138
|
+
name,
|
|
1139
|
+
onBlur,
|
|
1140
|
+
onChange,
|
|
1141
|
+
onFocus,
|
|
1142
|
+
placeholder,
|
|
1143
|
+
required = false,
|
|
1144
|
+
rows,
|
|
1145
|
+
select = false,
|
|
1146
|
+
SelectProps: SelectPropsProp,
|
|
1147
|
+
slots = {},
|
|
1148
|
+
slotProps = {},
|
|
1149
|
+
type,
|
|
1150
|
+
value,
|
|
1151
|
+
variant = 'outlined',
|
|
1152
|
+
...other
|
|
1153
|
+
} = props;
|
|
1154
|
+
const ownerState = {
|
|
1155
|
+
...props,
|
|
1156
|
+
autoFocus,
|
|
1157
|
+
color,
|
|
1158
|
+
disabled,
|
|
1159
|
+
error,
|
|
1160
|
+
fullWidth,
|
|
1161
|
+
multiline,
|
|
1162
|
+
required,
|
|
1163
|
+
select,
|
|
1164
|
+
variant
|
|
1165
|
+
};
|
|
1166
|
+
const classes = useUtilityClasses(ownerState);
|
|
1167
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
1168
|
+
if (select && !children) {
|
|
1169
|
+
console.error('MUI: `children` must be passed when using the `TextField` component with `select`.');
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
const id = useId(idOverride);
|
|
1173
|
+
const helperTextId = helperText && id ? `${id}-helper-text` : undefined;
|
|
1174
|
+
const inputLabelId = label && id ? `${id}-label` : undefined;
|
|
1175
|
+
const InputComponent = variantComponent[variant];
|
|
1176
|
+
const externalForwardedProps = {
|
|
1177
|
+
slots,
|
|
1178
|
+
slotProps: {
|
|
1179
|
+
input: InputPropsProp,
|
|
1180
|
+
inputLabel: InputLabelPropsProp,
|
|
1181
|
+
htmlInput: inputPropsProp,
|
|
1182
|
+
formHelperText: FormHelperTextPropsProp,
|
|
1183
|
+
select: SelectPropsProp,
|
|
1184
|
+
...slotProps
|
|
1185
|
+
}
|
|
1186
|
+
};
|
|
1187
|
+
const inputAdditionalProps = {};
|
|
1188
|
+
const inputLabelSlotProps = externalForwardedProps.slotProps.inputLabel;
|
|
1189
|
+
if (variant === 'outlined') {
|
|
1190
|
+
if (inputLabelSlotProps && typeof inputLabelSlotProps.shrink !== 'undefined') {
|
|
1191
|
+
inputAdditionalProps.notched = inputLabelSlotProps.shrink;
|
|
1192
|
+
}
|
|
1193
|
+
inputAdditionalProps.label = label;
|
|
1194
|
+
}
|
|
1195
|
+
if (select) {
|
|
1196
|
+
// unset defaults from textbox inputs
|
|
1197
|
+
if (!SelectPropsProp || !SelectPropsProp.native) {
|
|
1198
|
+
inputAdditionalProps.id = undefined;
|
|
1199
|
+
}
|
|
1200
|
+
inputAdditionalProps['aria-describedby'] = undefined;
|
|
1201
|
+
}
|
|
1202
|
+
const [RootSlot, rootProps] = useSlot('root', {
|
|
1203
|
+
elementType: TextFieldRoot,
|
|
1204
|
+
shouldForwardComponentProp: true,
|
|
1205
|
+
externalForwardedProps: {
|
|
1206
|
+
...externalForwardedProps,
|
|
1207
|
+
...other
|
|
1208
|
+
},
|
|
1209
|
+
ownerState,
|
|
1210
|
+
className: clsx(classes.root, className),
|
|
1211
|
+
ref,
|
|
1212
|
+
additionalProps: {
|
|
1213
|
+
disabled,
|
|
1214
|
+
error,
|
|
1215
|
+
fullWidth,
|
|
1216
|
+
required,
|
|
1217
|
+
color,
|
|
1218
|
+
variant
|
|
1219
|
+
}
|
|
1220
|
+
});
|
|
1221
|
+
const [InputSlot, inputProps] = useSlot('input', {
|
|
1222
|
+
elementType: InputComponent,
|
|
1223
|
+
externalForwardedProps,
|
|
1224
|
+
additionalProps: inputAdditionalProps,
|
|
1225
|
+
ownerState
|
|
1226
|
+
});
|
|
1227
|
+
const [InputLabelSlot, inputLabelProps] = useSlot('inputLabel', {
|
|
1228
|
+
elementType: InputLabel$1,
|
|
1229
|
+
externalForwardedProps,
|
|
1230
|
+
ownerState
|
|
1231
|
+
});
|
|
1232
|
+
const [HtmlInputSlot, htmlInputProps] = useSlot('htmlInput', {
|
|
1233
|
+
elementType: 'input',
|
|
1234
|
+
externalForwardedProps,
|
|
1235
|
+
ownerState
|
|
1236
|
+
});
|
|
1237
|
+
const [FormHelperTextSlot, formHelperTextProps] = useSlot('formHelperText', {
|
|
1238
|
+
elementType: FormHelperText$1,
|
|
1239
|
+
externalForwardedProps,
|
|
1240
|
+
ownerState
|
|
1241
|
+
});
|
|
1242
|
+
const [SelectSlot, selectProps] = useSlot('select', {
|
|
1243
|
+
elementType: Select,
|
|
1244
|
+
externalForwardedProps,
|
|
1245
|
+
ownerState
|
|
1246
|
+
});
|
|
1247
|
+
const InputElement = /*#__PURE__*/jsxRuntimeExports.jsx(InputSlot, {
|
|
1248
|
+
"aria-describedby": helperTextId,
|
|
1249
|
+
autoComplete: autoComplete,
|
|
1250
|
+
autoFocus: autoFocus,
|
|
1251
|
+
defaultValue: defaultValue,
|
|
1252
|
+
fullWidth: fullWidth,
|
|
1253
|
+
multiline: multiline,
|
|
1254
|
+
name: name,
|
|
1255
|
+
rows: rows,
|
|
1256
|
+
maxRows: maxRows,
|
|
1257
|
+
minRows: minRows,
|
|
1258
|
+
type: type,
|
|
1259
|
+
value: value,
|
|
1260
|
+
id: id,
|
|
1261
|
+
inputRef: inputRef,
|
|
1262
|
+
onBlur: onBlur,
|
|
1263
|
+
onChange: onChange,
|
|
1264
|
+
onFocus: onFocus,
|
|
1265
|
+
placeholder: placeholder,
|
|
1266
|
+
inputProps: htmlInputProps,
|
|
1267
|
+
slots: {
|
|
1268
|
+
input: slots.htmlInput ? HtmlInputSlot : undefined
|
|
1269
|
+
},
|
|
1270
|
+
...inputProps
|
|
1271
|
+
});
|
|
1272
|
+
return /*#__PURE__*/jsxRuntimeExports.jsxs(RootSlot, {
|
|
1273
|
+
...rootProps,
|
|
1274
|
+
children: [label != null && label !== '' && /*#__PURE__*/jsxRuntimeExports.jsx(InputLabelSlot, {
|
|
1275
|
+
htmlFor: id,
|
|
1276
|
+
id: inputLabelId,
|
|
1277
|
+
...inputLabelProps,
|
|
1278
|
+
children: label
|
|
1279
|
+
}), select ? /*#__PURE__*/jsxRuntimeExports.jsx(SelectSlot, {
|
|
1280
|
+
"aria-describedby": helperTextId,
|
|
1281
|
+
id: id,
|
|
1282
|
+
labelId: inputLabelId,
|
|
1283
|
+
value: value,
|
|
1284
|
+
input: InputElement,
|
|
1285
|
+
...selectProps,
|
|
1286
|
+
children: children
|
|
1287
|
+
}) : InputElement, helperText && /*#__PURE__*/jsxRuntimeExports.jsx(FormHelperTextSlot, {
|
|
1288
|
+
id: helperTextId,
|
|
1289
|
+
...formHelperTextProps,
|
|
1290
|
+
children: helperText
|
|
1291
|
+
})]
|
|
1292
|
+
});
|
|
1293
|
+
});
|
|
1294
|
+
process.env.NODE_ENV !== "production" ? TextField.propTypes /* remove-proptypes */ = {
|
|
1295
|
+
// ┌────────────────────────────── Warning ──────────────────────────────┐
|
|
1296
|
+
// │ These PropTypes are generated from the TypeScript type definitions. │
|
|
1297
|
+
// │ To update them, edit the d.ts file and run `pnpm proptypes`. │
|
|
1298
|
+
// └─────────────────────────────────────────────────────────────────────┘
|
|
1299
|
+
/**
|
|
1300
|
+
* This prop helps users to fill forms faster, especially on mobile devices.
|
|
1301
|
+
* The name can be confusing, as it's more like an autofill.
|
|
1302
|
+
* You can learn more about it [following the specification](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill).
|
|
1303
|
+
*/
|
|
1304
|
+
autoComplete: PropTypes.string,
|
|
1305
|
+
/**
|
|
1306
|
+
* If `true`, the `input` element is focused during the first mount.
|
|
1307
|
+
* @default false
|
|
1308
|
+
*/
|
|
1309
|
+
autoFocus: PropTypes.bool,
|
|
1310
|
+
/**
|
|
1311
|
+
* @ignore
|
|
1312
|
+
*/
|
|
1313
|
+
children: PropTypes.node,
|
|
1314
|
+
/**
|
|
1315
|
+
* Override or extend the styles applied to the component.
|
|
1316
|
+
*/
|
|
1317
|
+
classes: PropTypes.object,
|
|
1318
|
+
/**
|
|
1319
|
+
* @ignore
|
|
1320
|
+
*/
|
|
1321
|
+
className: PropTypes.string,
|
|
1322
|
+
/**
|
|
1323
|
+
* The color of the component.
|
|
1324
|
+
* It supports both default and custom theme colors, which can be added as shown in the
|
|
1325
|
+
* [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
|
|
1326
|
+
* @default 'primary'
|
|
1327
|
+
*/
|
|
1328
|
+
color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['primary', 'secondary', 'error', 'info', 'success', 'warning']), PropTypes.string]),
|
|
1329
|
+
/**
|
|
1330
|
+
* The default value. Use when the component is not controlled.
|
|
1331
|
+
*/
|
|
1332
|
+
defaultValue: PropTypes.any,
|
|
1333
|
+
/**
|
|
1334
|
+
* If `true`, the component is disabled.
|
|
1335
|
+
* @default false
|
|
1336
|
+
*/
|
|
1337
|
+
disabled: PropTypes.bool,
|
|
1338
|
+
/**
|
|
1339
|
+
* If `true`, the label is displayed in an error state.
|
|
1340
|
+
* @default false
|
|
1341
|
+
*/
|
|
1342
|
+
error: PropTypes.bool,
|
|
1343
|
+
/**
|
|
1344
|
+
* Props applied to the [`FormHelperText`](https://mui.com/material-ui/api/form-helper-text/) element.
|
|
1345
|
+
* @deprecated Use `slotProps.formHelperText` instead. This prop will be removed in v7. See [Migrating from deprecated APIs](https://mui.com/material-ui/migration/migrating-from-deprecated-apis/) for more details.
|
|
1346
|
+
*/
|
|
1347
|
+
FormHelperTextProps: PropTypes.object,
|
|
1348
|
+
/**
|
|
1349
|
+
* If `true`, the input will take up the full width of its container.
|
|
1350
|
+
* @default false
|
|
1351
|
+
*/
|
|
1352
|
+
fullWidth: PropTypes.bool,
|
|
1353
|
+
/**
|
|
1354
|
+
* The helper text content.
|
|
1355
|
+
*/
|
|
1356
|
+
helperText: PropTypes.node,
|
|
1357
|
+
/**
|
|
1358
|
+
* The id of the `input` element.
|
|
1359
|
+
* Use this prop to make `label` and `helperText` accessible for screen readers.
|
|
1360
|
+
*/
|
|
1361
|
+
id: PropTypes.string,
|
|
1362
|
+
/**
|
|
1363
|
+
* Props applied to the [`InputLabel`](https://mui.com/material-ui/api/input-label/) element.
|
|
1364
|
+
* Pointer events like `onClick` are enabled if and only if `shrink` is `true`.
|
|
1365
|
+
* @deprecated Use `slotProps.inputLabel` instead. This prop will be removed in v7. See [Migrating from deprecated APIs](https://mui.com/material-ui/migration/migrating-from-deprecated-apis/) for more details.
|
|
1366
|
+
*/
|
|
1367
|
+
InputLabelProps: PropTypes.object,
|
|
1368
|
+
/**
|
|
1369
|
+
* [Attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Attributes) applied to the `input` element.
|
|
1370
|
+
* @deprecated Use `slotProps.htmlInput` instead. This prop will be removed in v7. See [Migrating from deprecated APIs](https://mui.com/material-ui/migration/migrating-from-deprecated-apis/) for more details.
|
|
1371
|
+
*/
|
|
1372
|
+
inputProps: PropTypes.object,
|
|
1373
|
+
/**
|
|
1374
|
+
* Props applied to the Input element.
|
|
1375
|
+
* It will be a [`FilledInput`](https://mui.com/material-ui/api/filled-input/),
|
|
1376
|
+
* [`OutlinedInput`](https://mui.com/material-ui/api/outlined-input/) or [`Input`](https://mui.com/material-ui/api/input/)
|
|
1377
|
+
* component depending on the `variant` prop value.
|
|
1378
|
+
* @deprecated Use `slotProps.input` instead. This prop will be removed in v7. See [Migrating from deprecated APIs](https://mui.com/material-ui/migration/migrating-from-deprecated-apis/) for more details.
|
|
1379
|
+
*/
|
|
1380
|
+
InputProps: PropTypes.object,
|
|
1381
|
+
/**
|
|
1382
|
+
* Pass a ref to the `input` element.
|
|
1383
|
+
*/
|
|
1384
|
+
inputRef: refType,
|
|
1385
|
+
/**
|
|
1386
|
+
* The label content.
|
|
1387
|
+
*/
|
|
1388
|
+
label: PropTypes.node,
|
|
1389
|
+
/**
|
|
1390
|
+
* If `dense` or `normal`, will adjust vertical spacing of this and contained components.
|
|
1391
|
+
* @default 'none'
|
|
1392
|
+
*/
|
|
1393
|
+
margin: PropTypes.oneOf(['dense', 'none', 'normal']),
|
|
1394
|
+
/**
|
|
1395
|
+
* Maximum number of rows to display when multiline option is set to true.
|
|
1396
|
+
*/
|
|
1397
|
+
maxRows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
|
1398
|
+
/**
|
|
1399
|
+
* Minimum number of rows to display when multiline option is set to true.
|
|
1400
|
+
*/
|
|
1401
|
+
minRows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
|
1402
|
+
/**
|
|
1403
|
+
* If `true`, a `textarea` element is rendered instead of an input.
|
|
1404
|
+
* @default false
|
|
1405
|
+
*/
|
|
1406
|
+
multiline: PropTypes.bool,
|
|
1407
|
+
/**
|
|
1408
|
+
* Name attribute of the `input` element.
|
|
1409
|
+
*/
|
|
1410
|
+
name: PropTypes.string,
|
|
1411
|
+
/**
|
|
1412
|
+
* @ignore
|
|
1413
|
+
*/
|
|
1414
|
+
onBlur: PropTypes.func,
|
|
1415
|
+
/**
|
|
1416
|
+
* Callback fired when the value is changed.
|
|
1417
|
+
*
|
|
1418
|
+
* @param {object} event The event source of the callback.
|
|
1419
|
+
* You can pull out the new value by accessing `event.target.value` (string).
|
|
1420
|
+
*/
|
|
1421
|
+
onChange: PropTypes.func,
|
|
1422
|
+
/**
|
|
1423
|
+
* @ignore
|
|
1424
|
+
*/
|
|
1425
|
+
onFocus: PropTypes.func,
|
|
1426
|
+
/**
|
|
1427
|
+
* The short hint displayed in the `input` before the user enters a value.
|
|
1428
|
+
*/
|
|
1429
|
+
placeholder: PropTypes.string,
|
|
1430
|
+
/**
|
|
1431
|
+
* If `true`, the label is displayed as required and the `input` element is required.
|
|
1432
|
+
* @default false
|
|
1433
|
+
*/
|
|
1434
|
+
required: PropTypes.bool,
|
|
1435
|
+
/**
|
|
1436
|
+
* Number of rows to display when multiline option is set to true.
|
|
1437
|
+
*/
|
|
1438
|
+
rows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
|
1439
|
+
/**
|
|
1440
|
+
* Render a [`Select`](https://mui.com/material-ui/api/select/) element while passing the Input element to `Select` as `input` parameter.
|
|
1441
|
+
* If this option is set you must pass the options of the select as children.
|
|
1442
|
+
* @default false
|
|
1443
|
+
*/
|
|
1444
|
+
select: PropTypes.bool,
|
|
1445
|
+
/**
|
|
1446
|
+
* Props applied to the [`Select`](https://mui.com/material-ui/api/select/) element.
|
|
1447
|
+
* @deprecated Use `slotProps.select` instead. This prop will be removed in v7. See [Migrating from deprecated APIs](https://mui.com/material-ui/migration/migrating-from-deprecated-apis/) for more details.
|
|
1448
|
+
*/
|
|
1449
|
+
SelectProps: PropTypes.object,
|
|
1450
|
+
/**
|
|
1451
|
+
* The size of the component.
|
|
1452
|
+
* @default 'medium'
|
|
1453
|
+
*/
|
|
1454
|
+
size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['medium', 'small']), PropTypes.string]),
|
|
1455
|
+
/**
|
|
1456
|
+
* The props used for each slot inside.
|
|
1457
|
+
* @default {}
|
|
1458
|
+
*/
|
|
1459
|
+
slotProps: PropTypes /* @typescript-to-proptypes-ignore */.shape({
|
|
1460
|
+
formHelperText: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
|
|
1461
|
+
htmlInput: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
|
|
1462
|
+
input: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
|
|
1463
|
+
inputLabel: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
|
|
1464
|
+
select: PropTypes.oneOfType([PropTypes.func, PropTypes.object])
|
|
1465
|
+
}),
|
|
1466
|
+
/**
|
|
1467
|
+
* The components used for each slot inside.
|
|
1468
|
+
* @default {}
|
|
1469
|
+
*/
|
|
1470
|
+
slots: PropTypes.shape({
|
|
1471
|
+
formHelperText: PropTypes.elementType,
|
|
1472
|
+
htmlInput: PropTypes.elementType,
|
|
1473
|
+
input: PropTypes.elementType,
|
|
1474
|
+
inputLabel: PropTypes.elementType,
|
|
1475
|
+
root: PropTypes.elementType,
|
|
1476
|
+
select: PropTypes.elementType
|
|
1477
|
+
}),
|
|
1478
|
+
/**
|
|
1479
|
+
* The system prop that allows defining system overrides as well as additional CSS styles.
|
|
1480
|
+
*/
|
|
1481
|
+
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
|
|
1482
|
+
/**
|
|
1483
|
+
* Type of the `input` element. It should be [a valid HTML5 input type](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Form_%3Cinput%3E_types).
|
|
1484
|
+
*/
|
|
1485
|
+
type: PropTypes /* @typescript-to-proptypes-ignore */.string,
|
|
1486
|
+
/**
|
|
1487
|
+
* The value of the `input` element, required for a controlled component.
|
|
1488
|
+
*/
|
|
1489
|
+
value: PropTypes.any,
|
|
1490
|
+
/**
|
|
1491
|
+
* The variant to use.
|
|
1492
|
+
* @default 'outlined'
|
|
1493
|
+
*/
|
|
1494
|
+
variant: PropTypes.oneOf(['filled', 'outlined', 'standard'])
|
|
1495
|
+
} : void 0;
|
|
1496
|
+
var TextField$1 = TextField;
|
|
1497
|
+
|
|
19
1498
|
const SUBMIT_FILTER_STROKE_TIME = 500;
|
|
20
1499
|
const InputNumberInterval = props => {
|
|
21
1500
|
var _item$value;
|
|
@@ -56,7 +1535,7 @@ const InputNumberInterval = props => {
|
|
|
56
1535
|
const newLowerBound = event.target.value;
|
|
57
1536
|
updateFilterValue(newLowerBound, filterValueState[1]);
|
|
58
1537
|
};
|
|
59
|
-
return /*#__PURE__*/React.createElement(Box, {
|
|
1538
|
+
return /*#__PURE__*/React.createElement(Box$1, {
|
|
60
1539
|
sx: {
|
|
61
1540
|
display: 'inline-flex',
|
|
62
1541
|
flexDirection: 'row',
|
|
@@ -64,7 +1543,7 @@ const InputNumberInterval = props => {
|
|
|
64
1543
|
height: 48,
|
|
65
1544
|
pl: '20px'
|
|
66
1545
|
}
|
|
67
|
-
}, /*#__PURE__*/React.createElement(TextField, {
|
|
1546
|
+
}, /*#__PURE__*/React.createElement(TextField$1, {
|
|
68
1547
|
name: "lower-bound-input",
|
|
69
1548
|
placeholder: "From",
|
|
70
1549
|
label: "From",
|
|
@@ -76,7 +1555,7 @@ const InputNumberInterval = props => {
|
|
|
76
1555
|
sx: {
|
|
77
1556
|
mr: 2
|
|
78
1557
|
}
|
|
79
|
-
}), /*#__PURE__*/React.createElement(TextField, {
|
|
1558
|
+
}), /*#__PURE__*/React.createElement(TextField$1, {
|
|
80
1559
|
name: "upper-bound-input",
|
|
81
1560
|
placeholder: "To",
|
|
82
1561
|
label: "To",
|
|
@@ -705,20 +2184,14 @@ const DIMENSION_MODEL_KEY = 'dimension';
|
|
|
705
2184
|
const FILTER_SEARCH_KEY = 'searchModel';
|
|
706
2185
|
const DENSITY_MODEL_KEY = 'densityModel';
|
|
707
2186
|
const COLUMN_ORDER_MODEL_KEY = 'columnOrderModel';
|
|
708
|
-
const
|
|
709
|
-
const AGGREGATION_MODEL_KEY = 'aggregationModel';
|
|
710
|
-
/** Storage category key for the pivot column/row/value configuration. Consumer interop — use with `buildStorageKey`. */
|
|
711
|
-
const PIVOT_MODEL_KEY = 'pivotModel';
|
|
712
|
-
/** Storage category key for whether pivoting is active. Consumer interop — use with `buildStorageKey`. */
|
|
713
|
-
const PIVOT_ACTIVE_KEY = 'pivotActive';
|
|
714
|
-
const CATEGORIES = [PAGINATION_MODEL_KEY, FILTER_MODEL_KEY, SORT_MODEL_KEY, VISIBILITY_MODEL_KEY, DIMENSION_MODEL_KEY, FILTER_SEARCH_KEY, PINNED_COLUMNS, DENSITY_MODEL_KEY, COLUMN_ORDER_MODEL_KEY, ROW_GROUPING_MODEL_KEY, AGGREGATION_MODEL_KEY, PIVOT_MODEL_KEY, PIVOT_ACTIVE_KEY];
|
|
2187
|
+
const CATEGORIES = [PAGINATION_MODEL_KEY, FILTER_MODEL_KEY, SORT_MODEL_KEY, VISIBILITY_MODEL_KEY, DIMENSION_MODEL_KEY, FILTER_SEARCH_KEY, PINNED_COLUMNS, DENSITY_MODEL_KEY, COLUMN_ORDER_MODEL_KEY];
|
|
715
2188
|
/**
|
|
716
2189
|
* Build the localStorage key for a specific grid state category.
|
|
717
2190
|
* Consumers can use this to read or clear individual state entries directly.
|
|
718
2191
|
*
|
|
719
2192
|
* @example
|
|
720
2193
|
* ```ts
|
|
721
|
-
* const key = buildStorageKey({ id: pathname, version: 2, category:
|
|
2194
|
+
* const key = buildStorageKey({ id: pathname, version: 2, category: SORT_MODEL_KEY });
|
|
722
2195
|
* localStorage.removeItem(key);
|
|
723
2196
|
* ```
|
|
724
2197
|
*/
|
|
@@ -768,22 +2241,6 @@ const clearPreviousVersionStorage = (id, previousLocalStorageVersions) => {
|
|
|
768
2241
|
id,
|
|
769
2242
|
version,
|
|
770
2243
|
category: COLUMN_ORDER_MODEL_KEY
|
|
771
|
-
}), buildStorageKey({
|
|
772
|
-
id,
|
|
773
|
-
version,
|
|
774
|
-
category: ROW_GROUPING_MODEL_KEY
|
|
775
|
-
}), buildStorageKey({
|
|
776
|
-
id,
|
|
777
|
-
version,
|
|
778
|
-
category: AGGREGATION_MODEL_KEY
|
|
779
|
-
}), buildStorageKey({
|
|
780
|
-
id,
|
|
781
|
-
version,
|
|
782
|
-
category: PIVOT_MODEL_KEY
|
|
783
|
-
}), buildStorageKey({
|
|
784
|
-
id,
|
|
785
|
-
version,
|
|
786
|
-
category: PIVOT_ACTIVE_KEY
|
|
787
2244
|
})];
|
|
788
2245
|
for (const keyToDelete of keysToDelete) {
|
|
789
2246
|
try {
|
|
@@ -858,14 +2315,13 @@ const resetStatefulDataGridState = _ref2 => {
|
|
|
858
2315
|
* default (all columns visible). Clears the persisted `visibilityModel`
|
|
859
2316
|
* localStorage entry for the given versions and strips the `_columnVisibility`
|
|
860
2317
|
* param from the live URL, leaving every other piece of grid state (filters,
|
|
861
|
-
* sort,
|
|
2318
|
+
* sort, pagination, pinned columns, …) untouched.
|
|
862
2319
|
*
|
|
863
2320
|
* This is the visibility-scoped counterpart to `resetStatefulDataGridState`.
|
|
864
|
-
* Reach for it at transition points
|
|
865
|
-
*
|
|
866
|
-
*
|
|
867
|
-
*
|
|
868
|
-
* same transition.
|
|
2321
|
+
* Reach for it at transition points where a stale visibility snapshot would
|
|
2322
|
+
* otherwise re-seed and keep base columns hidden. Because it leaves the other
|
|
2323
|
+
* params alone it will not clobber a filter the caller is writing in the same
|
|
2324
|
+
* transition.
|
|
869
2325
|
*
|
|
870
2326
|
* Like `resetStatefulDataGridState`, the URL strip reads `window.location.search`
|
|
871
2327
|
* directly so it operates on the live URL (the caller's captured snapshot may
|
|
@@ -915,7 +2371,7 @@ const COMPRESSED_PREFIX = '~';
|
|
|
915
2371
|
* Params listed first are compressed first (least valuable to read in the URL).
|
|
916
2372
|
* The filter aggregate step uses the special key `_filters_aggregate`.
|
|
917
2373
|
*/
|
|
918
|
-
const COMPRESSION_PRIORITY = ['_columnOrder', '_columnVisibility', '_pinnedColumnsLeft', '_pinnedColumnsRight', '_filters_aggregate', '
|
|
2374
|
+
const COMPRESSION_PRIORITY = ['_columnOrder', '_columnVisibility', '_pinnedColumnsLeft', '_pinnedColumnsRight', '_filters_aggregate', '_quickFilterValues'];
|
|
919
2375
|
|
|
920
2376
|
/** Params that are always short and should never be compressed. */
|
|
921
2377
|
const NEVER_COMPRESS = new Set(['_sortColumn', '_pagination', '_density', '_logicOperator', 'v', 'tab']);
|
|
@@ -993,7 +2449,7 @@ const tryAggregateFilters = (params, filterKeys) => {
|
|
|
993
2449
|
* Filter params are those that start with `_` but are not well-known system params.
|
|
994
2450
|
*/
|
|
995
2451
|
const getFilterParamKeys = params => {
|
|
996
|
-
const systemPrefixes = ['_sortColumn', '_pagination', '_density', '_logicOperator', '_quickFilterValues', '_columnVisibility', '_columnOrder', '_pinnedColumnsLeft', '_pinnedColumnsRight', '
|
|
2452
|
+
const systemPrefixes = ['_sortColumn', '_pagination', '_density', '_logicOperator', '_quickFilterValues', '_columnVisibility', '_columnOrder', '_pinnedColumnsLeft', '_pinnedColumnsRight', '_filters'];
|
|
997
2453
|
const filterKeys = [];
|
|
998
2454
|
for (const key of params.keys()) {
|
|
999
2455
|
if (!key.startsWith('_')) continue;
|
|
@@ -1224,21 +2680,6 @@ const convertToDisplayFormat = search => {
|
|
|
1224
2680
|
return param;
|
|
1225
2681
|
}
|
|
1226
2682
|
|
|
1227
|
-
// Handle _rowGrouping=[a,b,c]
|
|
1228
|
-
if (param.startsWith('_rowGrouping=')) {
|
|
1229
|
-
const value = param.slice('_rowGrouping='.length);
|
|
1230
|
-
if (value.startsWith('[') && value.endsWith(']')) {
|
|
1231
|
-
const inner = value.slice(1, -1);
|
|
1232
|
-
return `_rowGrouping=${inner}`;
|
|
1233
|
-
}
|
|
1234
|
-
return param;
|
|
1235
|
-
}
|
|
1236
|
-
|
|
1237
|
-
// _aggregation and _pivot do not use bracket notation — pass through
|
|
1238
|
-
if (param.startsWith('_aggregation=') || param.startsWith('_pivot=')) {
|
|
1239
|
-
return param;
|
|
1240
|
-
}
|
|
1241
|
-
|
|
1242
2683
|
// Handle _field[operator,type]=value or _field[operator,type]=list[a,b,c]
|
|
1243
2684
|
const bracketMatch = param.match(/^_([^[]+)\[([^\]]+)\]=(.*)$/);
|
|
1244
2685
|
if (bracketMatch) {
|
|
@@ -1352,17 +2793,8 @@ const convertFromDisplayFormat = (search, columns) => {
|
|
|
1352
2793
|
return `_columnOrder=[${value}]`;
|
|
1353
2794
|
}
|
|
1354
2795
|
|
|
1355
|
-
//
|
|
1356
|
-
if (param.startsWith('
|
|
1357
|
-
const value = param.slice('_rowGrouping='.length);
|
|
1358
|
-
if (value.startsWith('[')) {
|
|
1359
|
-
return param;
|
|
1360
|
-
}
|
|
1361
|
-
return `_rowGrouping=[${value}]`;
|
|
1362
|
-
}
|
|
1363
|
-
|
|
1364
|
-
// _aggregation, _pivot, _filters — pass through (no bracket conversion needed)
|
|
1365
|
-
if (param.startsWith('_aggregation=') || param.startsWith('_pivot=') || param.startsWith('_filters=')) {
|
|
2796
|
+
// _filters — pass through (no bracket conversion needed)
|
|
2797
|
+
if (param.startsWith('_filters=')) {
|
|
1366
2798
|
return param;
|
|
1367
2799
|
}
|
|
1368
2800
|
|
|
@@ -1409,9 +2841,8 @@ const getDecodedSearchFromUrl = (search, columns) => {
|
|
|
1409
2841
|
const hasPinnedWithoutBrackets = /(_pinnedColumnsLeft|_pinnedColumnsRight)=[^&[]*(&|$)/.test(searchWithoutLeadingQuestion);
|
|
1410
2842
|
const hasVisibilityWithoutBrackets = /_columnVisibility=[^&[]*(&|$)/.test(searchWithoutLeadingQuestion);
|
|
1411
2843
|
const hasColumnOrderWithoutBrackets = /_columnOrder=[^&[]*(&|$)/.test(searchWithoutLeadingQuestion);
|
|
1412
|
-
const hasRowGroupingWithoutBrackets = /_rowGrouping=[^&[]*(&|$)/.test(searchWithoutLeadingQuestion);
|
|
1413
2844
|
const hasBracketNotation = /\[.*\]=/.test(searchWithoutLeadingQuestion);
|
|
1414
|
-
const isDisplayFormat = (hasDotNotationFilter || hasEmptySortColumn || hasSortDotNotation || hasPaginationDotNotation || hasPinnedWithoutBrackets || hasVisibilityWithoutBrackets || hasColumnOrderWithoutBrackets
|
|
2845
|
+
const isDisplayFormat = (hasDotNotationFilter || hasEmptySortColumn || hasSortDotNotation || hasPaginationDotNotation || hasPinnedWithoutBrackets || hasVisibilityWithoutBrackets || hasColumnOrderWithoutBrackets) && !hasBracketNotation;
|
|
1415
2846
|
if (isDisplayFormat) {
|
|
1416
2847
|
return '?' + convertFromDisplayFormat(searchWithoutLeadingQuestion, columns);
|
|
1417
2848
|
}
|
|
@@ -1536,26 +2967,24 @@ const isValueValid = (value, field, columns, operator) => {
|
|
|
1536
2967
|
}
|
|
1537
2968
|
const type = (_column$type = column['type']) !== null && _column$type !== void 0 ? _column$type : 'string';
|
|
1538
2969
|
|
|
1539
|
-
// Only date and
|
|
1540
|
-
|
|
2970
|
+
// Only date and dateTime need value validation; other types either accept
|
|
2971
|
+
// any string or reset themselves to undefined.
|
|
2972
|
+
if (type !== 'date' && type !== 'dateTime') {
|
|
1541
2973
|
return true;
|
|
1542
2974
|
}
|
|
1543
2975
|
|
|
1544
|
-
//
|
|
1545
|
-
|
|
1546
|
-
|
|
2976
|
+
// format: YYYY-MM-DD — strict, so corrupt/locale/ISO strings (e.g. a
|
|
2977
|
+
// stringified Date, or an ISO value with a `T` suffix) are rejected rather
|
|
2978
|
+
// than reaching a server consumer. Canonical values come from
|
|
2979
|
+
// `normalizeDateValue`.
|
|
2980
|
+
if (type === 'date') {
|
|
2981
|
+
return /^\d{4}-\d{2}-\d{2}$/.test(value);
|
|
1547
2982
|
}
|
|
1548
2983
|
|
|
1549
|
-
// format: YYYY-MM-
|
|
1550
|
-
//
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
const dateSplitted = value.split('-');
|
|
1554
|
-
if (dateSplitted.length !== 3) {
|
|
1555
|
-
return false;
|
|
1556
|
-
}
|
|
1557
|
-
const [YYYY, MM, DD] = dateSplitted;
|
|
1558
|
-
return !isNaN(parseInt(YYYY)) && !isNaN(parseInt(MM)) && !isNaN(parseInt(DD));
|
|
2984
|
+
// format: YYYY-MM-DDTHH:mm:ss — local wall-clock, matching the datetime-local
|
|
2985
|
+
// input (see `normalizeDateValue`).
|
|
2986
|
+
if (type === 'dateTime') {
|
|
2987
|
+
return /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/.test(value);
|
|
1559
2988
|
}
|
|
1560
2989
|
return false;
|
|
1561
2990
|
};
|
|
@@ -1570,15 +2999,22 @@ const getFilterModelFromString = (searchString, columns) => {
|
|
|
1570
2999
|
}
|
|
1571
3000
|
let logicOperator = GridLogicOperator.And;
|
|
1572
3001
|
let quickFilterValues = [];
|
|
3002
|
+
// Whether the URL carries explicit filter metadata (`_logicOperator` /
|
|
3003
|
+
// `_quickFilterValues`). Distinguishes an explicit empty filter (which the
|
|
3004
|
+
// grid serialises with `_logicOperator`) from a URL that has no filter params
|
|
3005
|
+
// at all, so the latter can fall through to localStorage. (ODM-3149)
|
|
3006
|
+
let hasFilterMeta = false;
|
|
1573
3007
|
const searchParams = new URLSearchParams();
|
|
1574
3008
|
for (const [key, value] of new URLSearchParams(searchString)) {
|
|
1575
|
-
if (key.startsWith('_') && !['_logicOperator', '_sortColumn', '_pinnedColumnsLeft', '_pinnedColumnsRight', '_columnVisibility', '_pagination', '_quickFilterValues', '_columnOrder', '
|
|
3009
|
+
if (key.startsWith('_') && !['_logicOperator', '_sortColumn', '_pinnedColumnsLeft', '_pinnedColumnsRight', '_columnVisibility', '_pagination', '_quickFilterValues', '_columnOrder', '_density', '_filters'].includes(key)) {
|
|
1576
3010
|
searchParams.set(key, value);
|
|
1577
3011
|
}
|
|
1578
3012
|
if (key === '_logicOperator') {
|
|
3013
|
+
hasFilterMeta = true;
|
|
1579
3014
|
logicOperator = value === GridLogicOperator.And || value === GridLogicOperator.Or ? value : GridLogicOperator.And;
|
|
1580
3015
|
}
|
|
1581
3016
|
if (key === '_quickFilterValues') {
|
|
3017
|
+
hasFilterMeta = true;
|
|
1582
3018
|
try {
|
|
1583
3019
|
quickFilterValues = JSON.parse(decodeURIComponent(value));
|
|
1584
3020
|
} catch {
|
|
@@ -1633,28 +3069,81 @@ const getFilterModelFromString = (searchString, columns) => {
|
|
|
1633
3069
|
if (isInvalid) {
|
|
1634
3070
|
return 'invalid';
|
|
1635
3071
|
}
|
|
3072
|
+
|
|
3073
|
+
// The URL carries no filter signal at all — no logic operator, no quick filter,
|
|
3074
|
+
// and no valid filter items (e.g. a bare `?period=30` written by another URL
|
|
3075
|
+
// owner before the grid mounts). This is NOT an explicit empty filter, so
|
|
3076
|
+
// return 'invalid' to let the caller fall through to localStorage instead of
|
|
3077
|
+
// returning an empty model that would overwrite the user's persisted filters
|
|
3078
|
+
// (and clobber localStorage on the way out). (ODM-3149)
|
|
3079
|
+
if (items.length === 0 && !hasFilterMeta) {
|
|
3080
|
+
return 'invalid';
|
|
3081
|
+
}
|
|
1636
3082
|
return {
|
|
1637
3083
|
items,
|
|
1638
3084
|
logicOperator,
|
|
1639
3085
|
quickFilterValues
|
|
1640
3086
|
};
|
|
1641
3087
|
};
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
3088
|
+
|
|
3089
|
+
/**
|
|
3090
|
+
* Normalises a `date` / `dateTime` filter value to a canonical, URL-safe string
|
|
3091
|
+
* before it is serialised into the URL.
|
|
3092
|
+
*
|
|
3093
|
+
* MUI's `GridFilterInputDate` commits filter values as JS `Date` objects. The
|
|
3094
|
+
* generic `encodeValue` would stringify those via `String(value)`, producing a
|
|
3095
|
+
* locale string (e.g. `"Thu Jun 25 2026 02:00:00 GMT+0200 (…)"`) that cannot
|
|
3096
|
+
* survive the URL round-trip and is rejected by `isValueValid`, silently erasing
|
|
3097
|
+
* the filter value (DS-90). We instead mirror MUI's own
|
|
3098
|
+
* `convertFilterItemValueToInputValue` so the canonical string matches what the
|
|
3099
|
+
* date input renders and round-trips losslessly:
|
|
3100
|
+
* - `date` → `YYYY-MM-DD` (UTC, timezone-stable)
|
|
3101
|
+
* - `dateTime` → `YYYY-MM-DDTHH:mm:ss` (local wall-clock, matching the
|
|
3102
|
+
* datetime-local input)
|
|
3103
|
+
* Non-date types, empty values, arrays of dates (e.g. `isBetween`) and
|
|
3104
|
+
* unparseable values are handled so the existing string / number / list
|
|
3105
|
+
* paths are untouched and invalid values still fall through to `isValueValid`.
|
|
3106
|
+
*/
|
|
3107
|
+
const normalizeDateValue = (value, type) => {
|
|
3108
|
+
if (type !== 'date' && type !== 'dateTime') {
|
|
3109
|
+
return value;
|
|
3110
|
+
}
|
|
3111
|
+
if (value === undefined || value === null || value === '') {
|
|
3112
|
+
return value;
|
|
3113
|
+
}
|
|
3114
|
+
if (Array.isArray(value)) {
|
|
3115
|
+
return value.map(entry => normalizeDateValue(entry, type));
|
|
3116
|
+
}
|
|
3117
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
3118
|
+
if (isNaN(date.getTime())) {
|
|
3119
|
+
return value;
|
|
3120
|
+
}
|
|
3121
|
+
if (type === 'date') {
|
|
3122
|
+
return date.toISOString().substring(0, 10);
|
|
3123
|
+
}
|
|
3124
|
+
// dateTime: mirror MUI's datetime-local conversion (subtract the timezone
|
|
3125
|
+
// offset so the serialised wall-clock time matches the rendered input value).
|
|
3126
|
+
const local = new Date(date.getTime());
|
|
3127
|
+
local.setMinutes(local.getMinutes() - local.getTimezoneOffset());
|
|
3128
|
+
return local.toISOString().substring(0, 19);
|
|
3129
|
+
};
|
|
3130
|
+
const getSearchParamsFromFilterModel = filterModel => {
|
|
3131
|
+
var _filterModel$quickFil;
|
|
3132
|
+
const searchParams = new URLSearchParams();
|
|
3133
|
+
searchParams.set('_logicOperator', filterModel['logicOperator'] || '');
|
|
3134
|
+
filterModel['items'].forEach(item => {
|
|
3135
|
+
const {
|
|
3136
|
+
field,
|
|
3137
|
+
operator,
|
|
3138
|
+
value,
|
|
3139
|
+
type
|
|
3140
|
+
} = item;
|
|
3141
|
+
const normalizedValue = normalizeDateValue(value, type);
|
|
3142
|
+
if (Object.keys(numberOperatorEncoder).includes(operator)) {
|
|
3143
|
+
searchParams.set(`_${field}[${numberOperatorEncoder[operator]},${encodeValue(type)}]`, encodeValue(normalizedValue));
|
|
3144
|
+
} else {
|
|
3145
|
+
searchParams.set(`_${field}[${encodeValue(operator)},${encodeValue(type)}]`, encodeValue(normalizedValue));
|
|
3146
|
+
}
|
|
1658
3147
|
});
|
|
1659
3148
|
if ((_filterModel$quickFil = filterModel.quickFilterValues) !== null && _filterModel$quickFil !== void 0 && _filterModel$quickFil.length) {
|
|
1660
3149
|
searchParams.set('_quickFilterValues', encodeURIComponent(JSON.stringify(filterModel.quickFilterValues)));
|
|
@@ -1709,7 +3198,19 @@ const getSortingFromString = (searchString, columns) => {
|
|
|
1709
3198
|
}
|
|
1710
3199
|
const searchParams = new URLSearchParams(searchString);
|
|
1711
3200
|
const value = searchParams.get('_sortColumn');
|
|
1712
|
-
|
|
3201
|
+
|
|
3202
|
+
// `_sortColumn` absent entirely → the URL is not expressing sort state (e.g. it
|
|
3203
|
+
// only carries a foreign param such as `?period=30` written by another URL
|
|
3204
|
+
// owner before the grid mounts). Return 'invalid' so the caller falls through
|
|
3205
|
+
// to localStorage instead of returning an empty model that would clobber the
|
|
3206
|
+
// user's persisted sort. (ODM-3149)
|
|
3207
|
+
if (value === null) {
|
|
3208
|
+
return 'invalid';
|
|
3209
|
+
}
|
|
3210
|
+
|
|
3211
|
+
// Explicit empty sort (`_sortColumn=` / `_sortColumn=[]`, written when the user
|
|
3212
|
+
// clears sorting) → respect it.
|
|
3213
|
+
if (value === '' || value === '[]') {
|
|
1713
3214
|
return [];
|
|
1714
3215
|
}
|
|
1715
3216
|
const fields = columns.map(column => column.field);
|
|
@@ -1855,8 +3356,8 @@ const getColumnVisibilityFromString = (searchString, columns) => {
|
|
|
1855
3356
|
// by 12.5.5-muiv8-alpha.5/alpha.6 (replaced by the URL-safe `!` form below — see
|
|
1856
3357
|
// getSearchParamsFromColumnVisibility). Still parsed so any localStorage entry
|
|
1857
3358
|
// persisted by those alphas keeps working; never written anymore. The two sets are
|
|
1858
|
-
// split on the fixed `];h:[` separator, so a `[` or `]` inside a
|
|
1859
|
-
//
|
|
3359
|
+
// split on the fixed `];h:[` separator, so a `[` or `]` inside a field name does
|
|
3360
|
+
// not break parsing.
|
|
1860
3361
|
if (value.startsWith('v:[') && value.endsWith(']') && value.includes('];h:[')) {
|
|
1861
3362
|
const inner = value.slice('v:['.length, -1);
|
|
1862
3363
|
const separatorIndex = inner.indexOf('];h:[');
|
|
@@ -1946,14 +3447,14 @@ const getSearchParamsFromColumnVisibility = (columnVisibility, columns) => {
|
|
|
1946
3447
|
}, columnVisibility);
|
|
1947
3448
|
|
|
1948
3449
|
// Serialise a single comma list over the static columns plus any extra keys present
|
|
1949
|
-
// in the model (dynamically-generated
|
|
1950
|
-
//
|
|
1951
|
-
//
|
|
1952
|
-
//
|
|
1953
|
-
//
|
|
1954
|
-
//
|
|
1955
|
-
//
|
|
1956
|
-
//
|
|
3450
|
+
// in the model (dynamically-generated fields, preserved in model order). Hidden
|
|
3451
|
+
// fields are prefixed `!`; visible fields are bare. This URL-safe form round-trips
|
|
3452
|
+
// idempotently through `URLSearchParams.toString()` percent-encoding — the earlier
|
|
3453
|
+
// `v:[..];h:[..]` form did NOT (its `:`/`;` were percent-encoded and mis-parsed on
|
|
3454
|
+
// read-back, driving an unbounded `history.replace` loop, ODM-3033). `!` (not `~`,
|
|
3455
|
+
// the compression sentinel — compression.ts COMPRESSED_PREFIX) is used so a leading
|
|
3456
|
+
// hidden field can't be mistaken for a compressed value. The hidden set is still
|
|
3457
|
+
// explicit, so deselected dynamic columns survive reloads.
|
|
1957
3458
|
const allFields = [...fields];
|
|
1958
3459
|
for (const field of Object.keys(finalColumnVisibility)) {
|
|
1959
3460
|
if (!allFields.includes(field)) {
|
|
@@ -2169,274 +3670,6 @@ const getSearchParamsFromColumnOrder = columnOrder => {
|
|
|
2169
3670
|
}
|
|
2170
3671
|
return searchParams;
|
|
2171
3672
|
};
|
|
2172
|
-
const getColumnOrder = (search, columns, localStorageColumnOrder, setLocalStorageColumnOrder, initialState, isNewVersion) => {
|
|
2173
|
-
var _initialState$columns4, _initialState$columns5;
|
|
2174
|
-
const defaultValue = (_initialState$columns4 = initialState === null || initialState === void 0 ? void 0 : (_initialState$columns5 = initialState.columns) === null || _initialState$columns5 === void 0 ? void 0 : _initialState$columns5.orderedFields) !== null && _initialState$columns4 !== void 0 ? _initialState$columns4 : columns.map(c => c.field);
|
|
2175
|
-
const persistDefault = () => {
|
|
2176
|
-
const searchFromDefault = getSearchParamsFromColumnOrder(defaultValue);
|
|
2177
|
-
const searchString = urlSearchParamsToString(searchFromDefault);
|
|
2178
|
-
if (searchString !== localStorageColumnOrder) {
|
|
2179
|
-
setLocalStorageColumnOrder(searchString);
|
|
2180
|
-
}
|
|
2181
|
-
};
|
|
2182
|
-
if (isNewVersion) {
|
|
2183
|
-
persistDefault();
|
|
2184
|
-
return defaultValue;
|
|
2185
|
-
}
|
|
2186
|
-
const fromUrl = getColumnOrderFromString(search);
|
|
2187
|
-
if (fromUrl !== 'invalid') {
|
|
2188
|
-
const searchFromModel = getSearchParamsFromColumnOrder(fromUrl);
|
|
2189
|
-
const searchString = urlSearchParamsToString(searchFromModel);
|
|
2190
|
-
if (searchString !== localStorageColumnOrder) {
|
|
2191
|
-
setLocalStorageColumnOrder(searchString);
|
|
2192
|
-
}
|
|
2193
|
-
return fromUrl;
|
|
2194
|
-
}
|
|
2195
|
-
const fromLocalStorage = getColumnOrderFromString(localStorageColumnOrder);
|
|
2196
|
-
if (fromLocalStorage !== 'invalid') {
|
|
2197
|
-
return fromLocalStorage;
|
|
2198
|
-
}
|
|
2199
|
-
persistDefault();
|
|
2200
|
-
return defaultValue;
|
|
2201
|
-
};
|
|
2202
|
-
|
|
2203
|
-
/** ROW GROUPING */
|
|
2204
|
-
|
|
2205
|
-
const getRowGroupingFromString = searchString => {
|
|
2206
|
-
if (!searchString) return 'invalid';
|
|
2207
|
-
const searchParams = new URLSearchParams(searchString);
|
|
2208
|
-
const value = searchParams.get('_rowGrouping');
|
|
2209
|
-
if (value === '' || value === null || value === '[]') return 'invalid';
|
|
2210
|
-
const inner = value.startsWith('[') && value.endsWith(']') ? value.slice(1, -1) : value;
|
|
2211
|
-
if (!inner) return 'invalid';
|
|
2212
|
-
return inner.split(',').filter(Boolean);
|
|
2213
|
-
};
|
|
2214
|
-
const getSearchParamsFromRowGrouping = rowGrouping => {
|
|
2215
|
-
const searchParams = new URLSearchParams();
|
|
2216
|
-
if (rowGrouping.length > 0) {
|
|
2217
|
-
searchParams.set('_rowGrouping', `[${rowGrouping.join(',')}]`);
|
|
2218
|
-
}
|
|
2219
|
-
return searchParams;
|
|
2220
|
-
};
|
|
2221
|
-
const getRowGroupingModel = (search, localStorageRowGrouping, setLocalStorageRowGrouping, initialState, isNewVersion) => {
|
|
2222
|
-
var _initialState$rowGrou, _initialState$rowGrou2;
|
|
2223
|
-
const defaultValue = (_initialState$rowGrou = initialState === null || initialState === void 0 ? void 0 : (_initialState$rowGrou2 = initialState.rowGrouping) === null || _initialState$rowGrou2 === void 0 ? void 0 : _initialState$rowGrou2.model) !== null && _initialState$rowGrou !== void 0 ? _initialState$rowGrou : [];
|
|
2224
|
-
const persistDefault = () => {
|
|
2225
|
-
const searchFromDefault = getSearchParamsFromRowGrouping(defaultValue);
|
|
2226
|
-
const searchString = urlSearchParamsToString(searchFromDefault);
|
|
2227
|
-
if (searchString !== localStorageRowGrouping) {
|
|
2228
|
-
setLocalStorageRowGrouping(searchString);
|
|
2229
|
-
}
|
|
2230
|
-
};
|
|
2231
|
-
if (isNewVersion) {
|
|
2232
|
-
persistDefault();
|
|
2233
|
-
return defaultValue;
|
|
2234
|
-
}
|
|
2235
|
-
const fromUrl = getRowGroupingFromString(search);
|
|
2236
|
-
if (fromUrl !== 'invalid') {
|
|
2237
|
-
const searchFromModel = getSearchParamsFromRowGrouping(fromUrl);
|
|
2238
|
-
const searchString = urlSearchParamsToString(searchFromModel);
|
|
2239
|
-
if (searchString !== localStorageRowGrouping) {
|
|
2240
|
-
setLocalStorageRowGrouping(searchString);
|
|
2241
|
-
}
|
|
2242
|
-
return fromUrl;
|
|
2243
|
-
}
|
|
2244
|
-
const fromLocalStorage = getRowGroupingFromString(localStorageRowGrouping);
|
|
2245
|
-
if (fromLocalStorage !== 'invalid') {
|
|
2246
|
-
return fromLocalStorage;
|
|
2247
|
-
}
|
|
2248
|
-
persistDefault();
|
|
2249
|
-
return defaultValue;
|
|
2250
|
-
};
|
|
2251
|
-
|
|
2252
|
-
/** AGGREGATION */
|
|
2253
|
-
|
|
2254
|
-
const getAggregationFromString = searchString => {
|
|
2255
|
-
if (!searchString) return 'invalid';
|
|
2256
|
-
const searchParams = new URLSearchParams(searchString);
|
|
2257
|
-
const value = searchParams.get('_aggregation');
|
|
2258
|
-
if (value === '' || value === null) return 'invalid';
|
|
2259
|
-
|
|
2260
|
-
// Format: field1.sum,field2.avg or [field1.sum,field2.avg]
|
|
2261
|
-
const inner = value.startsWith('[') && value.endsWith(']') ? value.slice(1, -1) : value;
|
|
2262
|
-
if (!inner) return 'invalid';
|
|
2263
|
-
const model = {};
|
|
2264
|
-
for (const entry of inner.split(',')) {
|
|
2265
|
-
const dotIndex = entry.lastIndexOf('.');
|
|
2266
|
-
if (dotIndex <= 0) return 'invalid';
|
|
2267
|
-
const field = entry.slice(0, dotIndex);
|
|
2268
|
-
const aggFunc = entry.slice(dotIndex + 1);
|
|
2269
|
-
if (!field || !aggFunc) return 'invalid';
|
|
2270
|
-
model[field] = aggFunc;
|
|
2271
|
-
}
|
|
2272
|
-
return Object.keys(model).length > 0 ? model : 'invalid';
|
|
2273
|
-
};
|
|
2274
|
-
const getSearchParamsFromAggregation = aggregation => {
|
|
2275
|
-
const searchParams = new URLSearchParams();
|
|
2276
|
-
const entries = Object.entries(aggregation);
|
|
2277
|
-
if (entries.length > 0) {
|
|
2278
|
-
const value = entries.map(_ref => {
|
|
2279
|
-
let [field, aggFunc] = _ref;
|
|
2280
|
-
return `${field}.${aggFunc}`;
|
|
2281
|
-
}).join(',');
|
|
2282
|
-
searchParams.set('_aggregation', value);
|
|
2283
|
-
}
|
|
2284
|
-
return searchParams;
|
|
2285
|
-
};
|
|
2286
|
-
const getAggregationModel = (search, localStorageAggregation, setLocalStorageAggregation, initialState, isNewVersion) => {
|
|
2287
|
-
var _initialState$aggrega, _initialState$aggrega2;
|
|
2288
|
-
const defaultValue = (_initialState$aggrega = initialState === null || initialState === void 0 ? void 0 : (_initialState$aggrega2 = initialState.aggregation) === null || _initialState$aggrega2 === void 0 ? void 0 : _initialState$aggrega2.model) !== null && _initialState$aggrega !== void 0 ? _initialState$aggrega : {};
|
|
2289
|
-
const persistDefault = () => {
|
|
2290
|
-
const searchFromDefault = getSearchParamsFromAggregation(defaultValue);
|
|
2291
|
-
const searchString = urlSearchParamsToString(searchFromDefault);
|
|
2292
|
-
if (searchString !== localStorageAggregation) {
|
|
2293
|
-
setLocalStorageAggregation(searchString);
|
|
2294
|
-
}
|
|
2295
|
-
};
|
|
2296
|
-
if (isNewVersion) {
|
|
2297
|
-
persistDefault();
|
|
2298
|
-
return defaultValue;
|
|
2299
|
-
}
|
|
2300
|
-
const fromUrl = getAggregationFromString(search);
|
|
2301
|
-
if (fromUrl !== 'invalid') {
|
|
2302
|
-
const searchFromModel = getSearchParamsFromAggregation(fromUrl);
|
|
2303
|
-
const searchString = urlSearchParamsToString(searchFromModel);
|
|
2304
|
-
if (searchString !== localStorageAggregation) {
|
|
2305
|
-
setLocalStorageAggregation(searchString);
|
|
2306
|
-
}
|
|
2307
|
-
return fromUrl;
|
|
2308
|
-
}
|
|
2309
|
-
const fromLocalStorage = getAggregationFromString(localStorageAggregation);
|
|
2310
|
-
if (fromLocalStorage !== 'invalid') {
|
|
2311
|
-
return fromLocalStorage;
|
|
2312
|
-
}
|
|
2313
|
-
persistDefault();
|
|
2314
|
-
return defaultValue;
|
|
2315
|
-
};
|
|
2316
|
-
|
|
2317
|
-
/** PIVOT */
|
|
2318
|
-
|
|
2319
|
-
/** Convert MUI's GridPivotModel → our simplified PivotModel */
|
|
2320
|
-
const fromGridPivotModel = model => ({
|
|
2321
|
-
columns: model.columns.map(c => c.field),
|
|
2322
|
-
rows: model.rows.map(r => r.field),
|
|
2323
|
-
values: model.values.map(_ref2 => {
|
|
2324
|
-
let {
|
|
2325
|
-
field,
|
|
2326
|
-
aggFunc
|
|
2327
|
-
} = _ref2;
|
|
2328
|
-
return {
|
|
2329
|
-
field,
|
|
2330
|
-
aggFunc
|
|
2331
|
-
};
|
|
2332
|
-
})
|
|
2333
|
-
});
|
|
2334
|
-
|
|
2335
|
-
/**
|
|
2336
|
-
* Pivot format: `cols:f1,f2;rows:f3;vals:f4.sum,f5.avg`
|
|
2337
|
-
*/
|
|
2338
|
-
const getPivotFromString = searchString => {
|
|
2339
|
-
if (!searchString) return 'invalid';
|
|
2340
|
-
const searchParams = new URLSearchParams(searchString);
|
|
2341
|
-
const value = searchParams.get('_pivot');
|
|
2342
|
-
if (value === '' || value === null) return 'invalid';
|
|
2343
|
-
const model = {
|
|
2344
|
-
columns: [],
|
|
2345
|
-
rows: [],
|
|
2346
|
-
values: []
|
|
2347
|
-
};
|
|
2348
|
-
for (const segment of value.split(';')) {
|
|
2349
|
-
const colonIndex = segment.indexOf(':');
|
|
2350
|
-
if (colonIndex <= 0) return 'invalid';
|
|
2351
|
-
const key = segment.slice(0, colonIndex);
|
|
2352
|
-
const content = segment.slice(colonIndex + 1);
|
|
2353
|
-
if (key === 'cols') {
|
|
2354
|
-
model.columns = content ? content.split(',').filter(Boolean) : [];
|
|
2355
|
-
} else if (key === 'rows') {
|
|
2356
|
-
model.rows = content ? content.split(',').filter(Boolean) : [];
|
|
2357
|
-
} else if (key === 'vals') {
|
|
2358
|
-
if (!content) continue;
|
|
2359
|
-
for (const entry of content.split(',')) {
|
|
2360
|
-
const dotIndex = entry.lastIndexOf('.');
|
|
2361
|
-
if (dotIndex <= 0) return 'invalid';
|
|
2362
|
-
model.values.push({
|
|
2363
|
-
field: entry.slice(0, dotIndex),
|
|
2364
|
-
aggFunc: entry.slice(dotIndex + 1)
|
|
2365
|
-
});
|
|
2366
|
-
}
|
|
2367
|
-
}
|
|
2368
|
-
}
|
|
2369
|
-
|
|
2370
|
-
// At least one section must have content
|
|
2371
|
-
if (model.columns.length === 0 && model.rows.length === 0 && model.values.length === 0) {
|
|
2372
|
-
return 'invalid';
|
|
2373
|
-
}
|
|
2374
|
-
return model;
|
|
2375
|
-
};
|
|
2376
|
-
const getSearchParamsFromPivot = pivot => {
|
|
2377
|
-
const searchParams = new URLSearchParams();
|
|
2378
|
-
const hasContent = pivot.columns.length > 0 || pivot.rows.length > 0 || pivot.values.length > 0;
|
|
2379
|
-
if (hasContent) {
|
|
2380
|
-
const parts = [];
|
|
2381
|
-
parts.push(`cols:${pivot.columns.join(',')}`);
|
|
2382
|
-
parts.push(`rows:${pivot.rows.join(',')}`);
|
|
2383
|
-
if (pivot.values.length > 0) {
|
|
2384
|
-
parts.push(`vals:${pivot.values.map(v => `${v.field}.${v.aggFunc}`).join(',')}`);
|
|
2385
|
-
}
|
|
2386
|
-
searchParams.set('_pivot', parts.join(';'));
|
|
2387
|
-
}
|
|
2388
|
-
return searchParams;
|
|
2389
|
-
};
|
|
2390
|
-
const getPivotModel = (search, localStoragePivot, setLocalStoragePivot, initialState, isNewVersion) => {
|
|
2391
|
-
var _initialState$pivotin;
|
|
2392
|
-
const defaultValue = initialState !== null && initialState !== void 0 && (_initialState$pivotin = initialState.pivoting) !== null && _initialState$pivotin !== void 0 && _initialState$pivotin.model ? fromGridPivotModel(initialState.pivoting.model) : {
|
|
2393
|
-
columns: [],
|
|
2394
|
-
rows: [],
|
|
2395
|
-
values: []
|
|
2396
|
-
};
|
|
2397
|
-
const persistDefault = () => {
|
|
2398
|
-
const searchFromDefault = getSearchParamsFromPivot(defaultValue);
|
|
2399
|
-
const searchString = urlSearchParamsToString(searchFromDefault);
|
|
2400
|
-
if (searchString !== localStoragePivot) {
|
|
2401
|
-
setLocalStoragePivot(searchString);
|
|
2402
|
-
}
|
|
2403
|
-
};
|
|
2404
|
-
if (isNewVersion) {
|
|
2405
|
-
persistDefault();
|
|
2406
|
-
return defaultValue;
|
|
2407
|
-
}
|
|
2408
|
-
const fromUrl = getPivotFromString(search);
|
|
2409
|
-
if (fromUrl !== 'invalid') {
|
|
2410
|
-
const searchFromModel = getSearchParamsFromPivot(fromUrl);
|
|
2411
|
-
const searchString = urlSearchParamsToString(searchFromModel);
|
|
2412
|
-
if (searchString !== localStoragePivot) {
|
|
2413
|
-
setLocalStoragePivot(searchString);
|
|
2414
|
-
}
|
|
2415
|
-
return fromUrl;
|
|
2416
|
-
}
|
|
2417
|
-
const fromLocalStorage = getPivotFromString(localStoragePivot);
|
|
2418
|
-
if (fromLocalStorage !== 'invalid') {
|
|
2419
|
-
return fromLocalStorage;
|
|
2420
|
-
}
|
|
2421
|
-
persistDefault();
|
|
2422
|
-
return defaultValue;
|
|
2423
|
-
};
|
|
2424
|
-
|
|
2425
|
-
/** PIVOT ACTIVE */
|
|
2426
|
-
|
|
2427
|
-
const getPivotActiveFromString = searchString => {
|
|
2428
|
-
if (!searchString) return 'invalid';
|
|
2429
|
-
const searchParams = new URLSearchParams(searchString);
|
|
2430
|
-
const value = searchParams.get('_pivotActive');
|
|
2431
|
-
if (value === 'true') return true;
|
|
2432
|
-
if (value === 'false') return false;
|
|
2433
|
-
return 'invalid';
|
|
2434
|
-
};
|
|
2435
|
-
const getSearchParamsFromPivotActive = active => {
|
|
2436
|
-
const searchParams = new URLSearchParams();
|
|
2437
|
-
searchParams.set('_pivotActive', String(active));
|
|
2438
|
-
return searchParams;
|
|
2439
|
-
};
|
|
2440
3673
|
|
|
2441
3674
|
/**
|
|
2442
3675
|
* Builds the `v=<version>` search param the grid uses to detect stale URLs.
|
|
@@ -2460,37 +3693,37 @@ const getSearchParamsFromVersion = version => {
|
|
|
2460
3693
|
searchParams.set('v', String(version));
|
|
2461
3694
|
return searchParams;
|
|
2462
3695
|
};
|
|
2463
|
-
const
|
|
2464
|
-
var _initialState$
|
|
2465
|
-
const defaultValue = (_initialState$
|
|
3696
|
+
const getColumnOrder = (search, columns, localStorageColumnOrder, setLocalStorageColumnOrder, initialState, isNewVersion) => {
|
|
3697
|
+
var _initialState$columns4, _initialState$columns5;
|
|
3698
|
+
const defaultValue = (_initialState$columns4 = initialState === null || initialState === void 0 ? void 0 : (_initialState$columns5 = initialState.columns) === null || _initialState$columns5 === void 0 ? void 0 : _initialState$columns5.orderedFields) !== null && _initialState$columns4 !== void 0 ? _initialState$columns4 : columns.map(c => c.field);
|
|
2466
3699
|
const persistDefault = () => {
|
|
2467
|
-
const searchFromDefault =
|
|
3700
|
+
const searchFromDefault = getSearchParamsFromColumnOrder(defaultValue);
|
|
2468
3701
|
const searchString = urlSearchParamsToString(searchFromDefault);
|
|
2469
|
-
if (searchString !==
|
|
2470
|
-
|
|
3702
|
+
if (searchString !== localStorageColumnOrder) {
|
|
3703
|
+
setLocalStorageColumnOrder(searchString);
|
|
2471
3704
|
}
|
|
2472
3705
|
};
|
|
2473
3706
|
if (isNewVersion) {
|
|
2474
3707
|
persistDefault();
|
|
2475
3708
|
return defaultValue;
|
|
2476
3709
|
}
|
|
2477
|
-
const fromUrl =
|
|
3710
|
+
const fromUrl = getColumnOrderFromString(search);
|
|
2478
3711
|
if (fromUrl !== 'invalid') {
|
|
2479
|
-
const searchFromModel =
|
|
3712
|
+
const searchFromModel = getSearchParamsFromColumnOrder(fromUrl);
|
|
2480
3713
|
const searchString = urlSearchParamsToString(searchFromModel);
|
|
2481
|
-
if (searchString !==
|
|
2482
|
-
|
|
3714
|
+
if (searchString !== localStorageColumnOrder) {
|
|
3715
|
+
setLocalStorageColumnOrder(searchString);
|
|
2483
3716
|
}
|
|
2484
3717
|
return fromUrl;
|
|
2485
3718
|
}
|
|
2486
|
-
const fromLocalStorage =
|
|
3719
|
+
const fromLocalStorage = getColumnOrderFromString(localStorageColumnOrder);
|
|
2487
3720
|
if (fromLocalStorage !== 'invalid') {
|
|
2488
3721
|
return fromLocalStorage;
|
|
2489
3722
|
}
|
|
2490
3723
|
persistDefault();
|
|
2491
3724
|
return defaultValue;
|
|
2492
3725
|
};
|
|
2493
|
-
const getFinalSearch =
|
|
3726
|
+
const getFinalSearch = _ref => {
|
|
2494
3727
|
let {
|
|
2495
3728
|
search,
|
|
2496
3729
|
localStorageVersion,
|
|
@@ -2502,12 +3735,8 @@ const getFinalSearch = _ref3 => {
|
|
|
2502
3735
|
density,
|
|
2503
3736
|
columnOrderModel,
|
|
2504
3737
|
defaultColumnOrder,
|
|
2505
|
-
rowGroupingModel,
|
|
2506
|
-
aggregationModel,
|
|
2507
|
-
pivotModel,
|
|
2508
|
-
pivotActive,
|
|
2509
3738
|
columns
|
|
2510
|
-
} =
|
|
3739
|
+
} = _ref;
|
|
2511
3740
|
const filterModelSearch = getSearchParamsFromFilterModel(filterModel);
|
|
2512
3741
|
const sortModelSearch = getSearchParamsFromSorting(sortModel);
|
|
2513
3742
|
const paginationModelSearch = getSearchParamsFromPagination(paginationModel);
|
|
@@ -2516,10 +3745,6 @@ const getFinalSearch = _ref3 => {
|
|
|
2516
3745
|
const densitySearch = getSearchParamsFromDensity(density);
|
|
2517
3746
|
// Only include _columnOrder in URL when it differs from the default
|
|
2518
3747
|
const columnOrderSearch = columnOrderModel.length !== defaultColumnOrder.length || columnOrderModel.some((field, i) => field !== defaultColumnOrder[i]) ? getSearchParamsFromColumnOrder(columnOrderModel) : new URLSearchParams();
|
|
2519
|
-
const rowGroupingSearch = getSearchParamsFromRowGrouping(rowGroupingModel);
|
|
2520
|
-
const aggregationSearch = getSearchParamsFromAggregation(aggregationModel);
|
|
2521
|
-
const pivotSearch = getSearchParamsFromPivot(pivotModel);
|
|
2522
|
-
const pivotActiveSearch = getSearchParamsFromPivotActive(pivotActive);
|
|
2523
3748
|
const tabSearch = getSearchParamsFromTab(search);
|
|
2524
3749
|
const searchParams = new URLSearchParams();
|
|
2525
3750
|
for (const [key, value] of new URLSearchParams(search)) {
|
|
@@ -2534,7 +3759,7 @@ const getFinalSearch = _ref3 => {
|
|
|
2534
3759
|
// Encode array as JSON string to preserve all values in one param
|
|
2535
3760
|
searchParams.set('_quickFilterValues', encodeURIComponent(JSON.stringify(filterModel.quickFilterValues)));
|
|
2536
3761
|
}
|
|
2537
|
-
return new URLSearchParams([...searchParams, ...filterModelSearch, ...sortModelSearch, ...paginationModelSearch, ...tabSearch, ...pinnedColumnsModelSearch, ...columnVisibilityModelSearch, ...densitySearch, ...columnOrderSearch
|
|
3762
|
+
return new URLSearchParams([...searchParams, ...filterModelSearch, ...sortModelSearch, ...paginationModelSearch, ...tabSearch, ...pinnedColumnsModelSearch, ...columnVisibilityModelSearch, ...densitySearch, ...columnOrderSearch]);
|
|
2538
3763
|
};
|
|
2539
3764
|
/** Return the state of the table given the URL and the local storage state */
|
|
2540
3765
|
const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, columns, initialState, localStorage) => {
|
|
@@ -2574,15 +3799,7 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
|
|
|
2574
3799
|
localStorageDensity,
|
|
2575
3800
|
setLocalStorageDensity,
|
|
2576
3801
|
localStorageColumnOrder,
|
|
2577
|
-
setLocalStorageColumnOrder
|
|
2578
|
-
localStorageRowGrouping,
|
|
2579
|
-
setLocalStorageRowGrouping,
|
|
2580
|
-
localStorageAggregation,
|
|
2581
|
-
setLocalStorageAggregation,
|
|
2582
|
-
localStoragePivot,
|
|
2583
|
-
setLocalStoragePivot,
|
|
2584
|
-
localStoragePivotActive,
|
|
2585
|
-
setLocalStoragePivotActive
|
|
3802
|
+
setLocalStorageColumnOrder
|
|
2586
3803
|
} = localStorage;
|
|
2587
3804
|
const filterModel = getFilterModel(decodedSearch, columns, localStorageFilters, setLocalStorageFilters, initialState, isNewVersion);
|
|
2588
3805
|
const sortModel = getSortModel(decodedSearch, columns, localStorageSorting, setLocalStorageSorting, initialState, isNewVersion);
|
|
@@ -2591,10 +3808,6 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
|
|
|
2591
3808
|
const pinnedColumnsModel = getPinnedColumns(decodedSearch, columns, localStoragePinnedColumns, setLocalStoragePinnedColumns, initialState, isNewVersion);
|
|
2592
3809
|
const density = getDensityModel(decodedSearch, localStorageDensity, setLocalStorageDensity, initialState, isNewVersion);
|
|
2593
3810
|
const columnOrderModel = getColumnOrder(decodedSearch, columns, localStorageColumnOrder, setLocalStorageColumnOrder, initialState, isNewVersion);
|
|
2594
|
-
const rowGroupingModel = getRowGroupingModel(decodedSearch, localStorageRowGrouping, setLocalStorageRowGrouping, initialState, isNewVersion);
|
|
2595
|
-
const aggregationModel = getAggregationModel(decodedSearch, localStorageAggregation, setLocalStorageAggregation, initialState, isNewVersion);
|
|
2596
|
-
const pivotModel = getPivotModel(decodedSearch, localStoragePivot, setLocalStoragePivot, initialState, isNewVersion);
|
|
2597
|
-
const pivotActive = getPivotActive(decodedSearch, localStoragePivotActive, setLocalStoragePivotActive, initialState, isNewVersion);
|
|
2598
3811
|
const defaultColumnOrder = (_initialState$columns6 = initialState === null || initialState === void 0 ? void 0 : (_initialState$columns7 = initialState.columns) === null || _initialState$columns7 === void 0 ? void 0 : _initialState$columns7.orderedFields) !== null && _initialState$columns6 !== void 0 ? _initialState$columns6 : columns.map(c => c.field);
|
|
2599
3812
|
const finalSearch = getFinalSearch({
|
|
2600
3813
|
localStorageVersion,
|
|
@@ -2607,10 +3820,6 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
|
|
|
2607
3820
|
density,
|
|
2608
3821
|
columnOrderModel,
|
|
2609
3822
|
defaultColumnOrder,
|
|
2610
|
-
rowGroupingModel,
|
|
2611
|
-
aggregationModel,
|
|
2612
|
-
pivotModel,
|
|
2613
|
-
pivotActive,
|
|
2614
3823
|
columns
|
|
2615
3824
|
});
|
|
2616
3825
|
const internalSearchString = urlSearchParamsToString(finalSearch);
|
|
@@ -2631,14 +3840,10 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
|
|
|
2631
3840
|
pinnedColumnsModel,
|
|
2632
3841
|
density,
|
|
2633
3842
|
columnOrderModel,
|
|
2634
|
-
rowGroupingModel,
|
|
2635
|
-
aggregationModel,
|
|
2636
|
-
pivotModel,
|
|
2637
|
-
pivotActive,
|
|
2638
3843
|
pendingSearch
|
|
2639
3844
|
};
|
|
2640
3845
|
};
|
|
2641
|
-
const updateUrl = (
|
|
3846
|
+
const updateUrl = (_ref2, search, localStorageVersion, historyReplace, columns) => {
|
|
2642
3847
|
let {
|
|
2643
3848
|
filterModel,
|
|
2644
3849
|
sortModel,
|
|
@@ -2647,12 +3852,8 @@ const updateUrl = (_ref4, search, localStorageVersion, historyReplace, columns)
|
|
|
2647
3852
|
pinnedColumnsModel,
|
|
2648
3853
|
density,
|
|
2649
3854
|
columnOrderModel,
|
|
2650
|
-
defaultColumnOrder
|
|
2651
|
-
|
|
2652
|
-
aggregationModel,
|
|
2653
|
-
pivotModel,
|
|
2654
|
-
pivotActive
|
|
2655
|
-
} = _ref4;
|
|
3855
|
+
defaultColumnOrder
|
|
3856
|
+
} = _ref2;
|
|
2656
3857
|
// Convert from display format to internal format if needed
|
|
2657
3858
|
const decodedSearch = getDecodedSearchFromUrl(search, columns);
|
|
2658
3859
|
const newSearch = getFinalSearch({
|
|
@@ -2666,10 +3867,6 @@ const updateUrl = (_ref4, search, localStorageVersion, historyReplace, columns)
|
|
|
2666
3867
|
density,
|
|
2667
3868
|
columnOrderModel,
|
|
2668
3869
|
defaultColumnOrder,
|
|
2669
|
-
rowGroupingModel,
|
|
2670
|
-
aggregationModel,
|
|
2671
|
-
pivotModel,
|
|
2672
|
-
pivotActive,
|
|
2673
3870
|
columns
|
|
2674
3871
|
});
|
|
2675
3872
|
const internalSearchString = urlSearchParamsToString(newSearch);
|
|
@@ -2748,7 +3945,12 @@ const areFilterModelsEquivalent = (filterModel, filterModelToMatch) => {
|
|
|
2748
3945
|
* Also handles the `_filters` aggregate param: expands it back into individual filter params.
|
|
2749
3946
|
*/
|
|
2750
3947
|
const decompressSearchParams = search => {
|
|
2751
|
-
|
|
3948
|
+
// The `~` compression sentinel is form-encoded to `%7E` by URLSearchParams
|
|
3949
|
+
// (which the React Router adapter uses when it writes the URL), so a literal-`~`
|
|
3950
|
+
// check alone would skip decompression of every adapter-written compressed
|
|
3951
|
+
// value — leaving the payload compressed and unreadable. Detect both forms; the
|
|
3952
|
+
// URLSearchParams parse below decodes `%7E` back to `~` for `decompressValue`. (ODM-2833)
|
|
3953
|
+
if (!search || !search.includes('~') && !/%7[eE]/.test(search)) return search;
|
|
2752
3954
|
const cleanSearch = search.startsWith('?') ? search.slice(1) : search;
|
|
2753
3955
|
const params = new URLSearchParams(cleanSearch);
|
|
2754
3956
|
const result = new URLSearchParams();
|
|
@@ -2857,26 +4059,6 @@ const useTableStates = (id, version) => {
|
|
|
2857
4059
|
version,
|
|
2858
4060
|
category: COLUMN_ORDER_MODEL_KEY
|
|
2859
4061
|
}));
|
|
2860
|
-
const [rowGroupingModel, setRowGroupingModel] = useFetchState('', buildStorageKey({
|
|
2861
|
-
id,
|
|
2862
|
-
version,
|
|
2863
|
-
category: ROW_GROUPING_MODEL_KEY
|
|
2864
|
-
}));
|
|
2865
|
-
const [aggregationModel, setAggregationModel] = useFetchState('', buildStorageKey({
|
|
2866
|
-
id,
|
|
2867
|
-
version,
|
|
2868
|
-
category: AGGREGATION_MODEL_KEY
|
|
2869
|
-
}));
|
|
2870
|
-
const [pivotModel, setPivotModel] = useFetchState('', buildStorageKey({
|
|
2871
|
-
id,
|
|
2872
|
-
version,
|
|
2873
|
-
category: PIVOT_MODEL_KEY
|
|
2874
|
-
}));
|
|
2875
|
-
const [pivotActive, setPivotActive] = useFetchState('', buildStorageKey({
|
|
2876
|
-
id,
|
|
2877
|
-
version,
|
|
2878
|
-
category: PIVOT_ACTIVE_KEY
|
|
2879
|
-
}));
|
|
2880
4062
|
return {
|
|
2881
4063
|
paginationModel,
|
|
2882
4064
|
setPaginationModel,
|
|
@@ -2893,41 +4075,13 @@ const useTableStates = (id, version) => {
|
|
|
2893
4075
|
densityModel,
|
|
2894
4076
|
setDensityModel,
|
|
2895
4077
|
columnOrderModel,
|
|
2896
|
-
setColumnOrderModel
|
|
2897
|
-
rowGroupingModel,
|
|
2898
|
-
setRowGroupingModel,
|
|
2899
|
-
aggregationModel,
|
|
2900
|
-
setAggregationModel,
|
|
2901
|
-
pivotModel,
|
|
2902
|
-
setPivotModel,
|
|
2903
|
-
pivotActive,
|
|
2904
|
-
setPivotActive
|
|
4078
|
+
setColumnOrderModel
|
|
2905
4079
|
};
|
|
2906
4080
|
};
|
|
2907
4081
|
|
|
2908
|
-
/** Convert our simplified PivotModel → MUI's GridPivotModel */
|
|
2909
|
-
const toGridPivotModel = model => ({
|
|
2910
|
-
columns: model.columns.map(field => ({
|
|
2911
|
-
field
|
|
2912
|
-
})),
|
|
2913
|
-
rows: model.rows.map(field => ({
|
|
2914
|
-
field
|
|
2915
|
-
})),
|
|
2916
|
-
values: model.values.map(_ref => {
|
|
2917
|
-
let {
|
|
2918
|
-
field,
|
|
2919
|
-
aggFunc
|
|
2920
|
-
} = _ref;
|
|
2921
|
-
return {
|
|
2922
|
-
field,
|
|
2923
|
-
aggFunc
|
|
2924
|
-
};
|
|
2925
|
-
})
|
|
2926
|
-
});
|
|
2927
|
-
|
|
2928
4082
|
/**
|
|
2929
4083
|
* Deep-equal comparison for plain objects / arrays.
|
|
2930
|
-
* Used to stabilise parsed model references so that MUI
|
|
4084
|
+
* Used to stabilise parsed model references so that MUI does not
|
|
2931
4085
|
* reset pagination on every render.
|
|
2932
4086
|
*/
|
|
2933
4087
|
function isDeepEqual(a, b) {
|
|
@@ -2954,9 +4108,6 @@ const useStatefulTable = props => {
|
|
|
2954
4108
|
onPaginationModelChange: propsOnPaginationModelChange,
|
|
2955
4109
|
onPinnedColumnsChange: propsOnPinnedColumnsChange,
|
|
2956
4110
|
onSortModelChange: propsOnSortModelChange,
|
|
2957
|
-
onRowGroupingModelChange: propsOnRowGroupingModelChange,
|
|
2958
|
-
onAggregationModelChange: propsOnAggregationModelChange,
|
|
2959
|
-
onPivotModelChange: propsOnPivotModelChange,
|
|
2960
4111
|
useRouter,
|
|
2961
4112
|
localStorageVersion = 1,
|
|
2962
4113
|
previousLocalStorageVersions = []
|
|
@@ -2985,24 +4136,16 @@ const useStatefulTable = props => {
|
|
|
2985
4136
|
densityModel,
|
|
2986
4137
|
setDensityModel,
|
|
2987
4138
|
columnOrderModel: localStorageColumnOrder,
|
|
2988
|
-
setColumnOrderModel: setLocalStorageColumnOrder
|
|
2989
|
-
rowGroupingModel: localStorageRowGrouping,
|
|
2990
|
-
setRowGroupingModel: setLocalStorageRowGrouping,
|
|
2991
|
-
aggregationModel: localStorageAggregation,
|
|
2992
|
-
setAggregationModel: setLocalStorageAggregation,
|
|
2993
|
-
pivotModel: localStoragePivot,
|
|
2994
|
-
setPivotModel: setLocalStoragePivot,
|
|
2995
|
-
pivotActive: localStoragePivotActive,
|
|
2996
|
-
setPivotActive: setLocalStoragePivotActive
|
|
4139
|
+
setColumnOrderModel: setLocalStorageColumnOrder
|
|
2997
4140
|
} = useTableStates(id, localStorageVersion);
|
|
2998
4141
|
|
|
2999
4142
|
// clearing up old version keys, triggering only on first render
|
|
3000
4143
|
useEffect(() => clearPreviousVersionStorage(id, previousLocalStorageVersions), [id, previousLocalStorageVersions]);
|
|
3001
|
-
const onColumnDimensionChange = useCallback(
|
|
4144
|
+
const onColumnDimensionChange = useCallback(_ref => {
|
|
3002
4145
|
let {
|
|
3003
4146
|
newWidth,
|
|
3004
4147
|
field
|
|
3005
|
-
} =
|
|
4148
|
+
} = _ref;
|
|
3006
4149
|
setDimensionModel(_objectSpread2(_objectSpread2({}, dimensionModel), {}, {
|
|
3007
4150
|
[field]: newWidth
|
|
3008
4151
|
}));
|
|
@@ -3015,10 +4158,6 @@ const useStatefulTable = props => {
|
|
|
3015
4158
|
pinnedColumnsModel,
|
|
3016
4159
|
density: densityParsed,
|
|
3017
4160
|
columnOrderModel: columnOrderParsed,
|
|
3018
|
-
rowGroupingModel: rowGroupingParsed,
|
|
3019
|
-
aggregationModel: aggregationParsed,
|
|
3020
|
-
pivotModel: pivotParsed,
|
|
3021
|
-
pivotActive: pivotActiveParsed,
|
|
3022
4161
|
pendingSearch
|
|
3023
4162
|
} = getModelsParsedOrUpdateLocalStorage(search || '', localStorageVersion, propsColumns, initialState, {
|
|
3024
4163
|
localStorageFilters,
|
|
@@ -3034,15 +4173,7 @@ const useStatefulTable = props => {
|
|
|
3034
4173
|
localStorageDensity: densityModel,
|
|
3035
4174
|
setLocalStorageDensity: setDensityModel,
|
|
3036
4175
|
localStorageColumnOrder,
|
|
3037
|
-
setLocalStorageColumnOrder
|
|
3038
|
-
localStorageRowGrouping,
|
|
3039
|
-
setLocalStorageRowGrouping,
|
|
3040
|
-
localStorageAggregation,
|
|
3041
|
-
setLocalStorageAggregation,
|
|
3042
|
-
localStoragePivot,
|
|
3043
|
-
setLocalStoragePivot,
|
|
3044
|
-
localStoragePivotActive: localStoragePivotActive,
|
|
3045
|
-
setLocalStoragePivotActive: setLocalStoragePivotActive
|
|
4176
|
+
setLocalStorageColumnOrder
|
|
3046
4177
|
});
|
|
3047
4178
|
|
|
3048
4179
|
// Sync URL in an effect rather than during render to comply with React rules
|
|
@@ -3052,7 +4183,7 @@ const useStatefulTable = props => {
|
|
|
3052
4183
|
}
|
|
3053
4184
|
}, [pendingSearch, historyReplace]);
|
|
3054
4185
|
|
|
3055
|
-
// Stabilise parsed model references to prevent MUI
|
|
4186
|
+
// Stabilise parsed model references to prevent MUI from resetting
|
|
3056
4187
|
// pagination on every render due to new object identity.
|
|
3057
4188
|
const filterParsedRef = useRef(filterParsed);
|
|
3058
4189
|
if (!isDeepEqual(filterParsedRef.current, filterParsed)) {
|
|
@@ -3078,18 +4209,6 @@ const useStatefulTable = props => {
|
|
|
3078
4209
|
if (!isDeepEqual(columnOrderParsedRef.current, columnOrderParsed)) {
|
|
3079
4210
|
columnOrderParsedRef.current = columnOrderParsed;
|
|
3080
4211
|
}
|
|
3081
|
-
const rowGroupingParsedRef = useRef(rowGroupingParsed);
|
|
3082
|
-
if (!isDeepEqual(rowGroupingParsedRef.current, rowGroupingParsed)) {
|
|
3083
|
-
rowGroupingParsedRef.current = rowGroupingParsed;
|
|
3084
|
-
}
|
|
3085
|
-
const aggregationParsedRef = useRef(aggregationParsed);
|
|
3086
|
-
if (!isDeepEqual(aggregationParsedRef.current, aggregationParsed)) {
|
|
3087
|
-
aggregationParsedRef.current = aggregationParsed;
|
|
3088
|
-
}
|
|
3089
|
-
const pivotParsedRef = useRef(pivotParsed);
|
|
3090
|
-
if (!isDeepEqual(pivotParsedRef.current, pivotParsed)) {
|
|
3091
|
-
pivotParsedRef.current = pivotParsed;
|
|
3092
|
-
}
|
|
3093
4212
|
const columns = useMemo(() => propsColumns.map(column => {
|
|
3094
4213
|
return _objectSpread2(_objectSpread2({}, column), {}, {
|
|
3095
4214
|
width: dimensionModel[column.field] || column.width || 100
|
|
@@ -3098,13 +4217,29 @@ const useStatefulTable = props => {
|
|
|
3098
4217
|
if (apiRef.current) {
|
|
3099
4218
|
/** Add resetPage method to apiRef. */
|
|
3100
4219
|
apiRef.current.resetPage = () => {
|
|
3101
|
-
|
|
3102
|
-
(_apiRef$current = apiRef.current) === null || _apiRef$current === void 0 ? void 0 : _apiRef$current.setPage(0);
|
|
4220
|
+
apiRef.current.setPage(0);
|
|
3103
4221
|
};
|
|
3104
4222
|
}
|
|
3105
4223
|
const defaultColumnOrder = (_initialState$columns = initialState === null || initialState === void 0 ? void 0 : (_initialState$columns2 = initialState.columns) === null || _initialState$columns2 === void 0 ? void 0 : _initialState$columns2.orderedFields) !== null && _initialState$columns !== void 0 ? _initialState$columns : propsColumns.map(c => c.field);
|
|
3106
4224
|
|
|
3107
|
-
//
|
|
4225
|
+
// Helper to build the current DataGridModel for updateUrl calls
|
|
4226
|
+
const buildModel = function () {
|
|
4227
|
+
var _apiRef$current$state, _apiRef$current;
|
|
4228
|
+
let overrides = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
4229
|
+
return _objectSpread2({
|
|
4230
|
+
filterModel: filterParsed,
|
|
4231
|
+
sortModel: sortModelParsed,
|
|
4232
|
+
paginationModel: paginationModelParsed,
|
|
4233
|
+
columnsModel: (_apiRef$current$state = (_apiRef$current = apiRef.current) === null || _apiRef$current === void 0 ? void 0 : _apiRef$current.state.columns.columnVisibilityModel) !== null && _apiRef$current$state !== void 0 ? _apiRef$current$state : {},
|
|
4234
|
+
pinnedColumnsModel: pinnedColumnsModel,
|
|
4235
|
+
density: densityParsed,
|
|
4236
|
+
columnOrderModel: columnOrderParsed,
|
|
4237
|
+
defaultColumnOrder
|
|
4238
|
+
}, overrides);
|
|
4239
|
+
};
|
|
4240
|
+
|
|
4241
|
+
// Subscribe to density changes via stateChange event
|
|
4242
|
+
// (MUI v7 supports onDensityChange, but stateChange works and avoids a larger refactor)
|
|
3108
4243
|
useEffect(() => {
|
|
3109
4244
|
const api = apiRef.current;
|
|
3110
4245
|
if (!(api !== null && api !== void 0 && api.subscribeEvent)) return;
|
|
@@ -3113,24 +4248,14 @@ const useStatefulTable = props => {
|
|
|
3113
4248
|
const currentDensity = api.state.density;
|
|
3114
4249
|
if (currentDensity !== prevDensity) {
|
|
3115
4250
|
prevDensity = currentDensity;
|
|
3116
|
-
updateUrl({
|
|
3117
|
-
filterModel: filterParsed,
|
|
3118
|
-
sortModel: sortModelParsed,
|
|
3119
|
-
paginationModel: paginationModelParsed,
|
|
4251
|
+
updateUrl(buildModel({
|
|
3120
4252
|
columnsModel: api.state.columns.columnVisibilityModel,
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
columnOrderModel: columnOrderParsed,
|
|
3124
|
-
defaultColumnOrder,
|
|
3125
|
-
rowGroupingModel: rowGroupingParsed,
|
|
3126
|
-
aggregationModel: aggregationParsed,
|
|
3127
|
-
pivotModel: pivotParsed,
|
|
3128
|
-
pivotActive: pivotActiveParsed
|
|
3129
|
-
}, search, localStorageVersion, historyReplace, columns);
|
|
4253
|
+
density: currentDensity
|
|
4254
|
+
}), search, localStorageVersion, historyReplace, columns);
|
|
3130
4255
|
}
|
|
3131
4256
|
});
|
|
3132
4257
|
return unsub;
|
|
3133
|
-
}, [apiRef, densityParsed, filterParsed, sortModelParsed, paginationModelParsed, pinnedColumnsModel, columnOrderParsed, defaultColumnOrder,
|
|
4258
|
+
}, [apiRef, densityParsed, filterParsed, sortModelParsed, paginationModelParsed, pinnedColumnsModel, columnOrderParsed, defaultColumnOrder, search, localStorageVersion, historyReplace, columns]);
|
|
3134
4259
|
|
|
3135
4260
|
// Subscribe to column order changes via columnOrderChange (drag-drop) and columnIndexChange (programmatic setColumnIndex)
|
|
3136
4261
|
useEffect(() => {
|
|
@@ -3139,20 +4264,9 @@ const useStatefulTable = props => {
|
|
|
3139
4264
|
const handleColumnOrderChange = () => {
|
|
3140
4265
|
const orderedFields = api.state.columns.orderedFields;
|
|
3141
4266
|
if (orderedFields && !isDeepEqual(orderedFields, columnOrderParsed)) {
|
|
3142
|
-
updateUrl({
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
paginationModel: paginationModelParsed,
|
|
3146
|
-
columnsModel: api.state.columns.columnVisibilityModel,
|
|
3147
|
-
pinnedColumnsModel,
|
|
3148
|
-
density: densityParsed,
|
|
3149
|
-
columnOrderModel: orderedFields,
|
|
3150
|
-
defaultColumnOrder,
|
|
3151
|
-
rowGroupingModel: rowGroupingParsed,
|
|
3152
|
-
aggregationModel: aggregationParsed,
|
|
3153
|
-
pivotModel: pivotParsed,
|
|
3154
|
-
pivotActive: pivotActiveParsed
|
|
3155
|
-
}, search, localStorageVersion, historyReplace, columns);
|
|
4267
|
+
updateUrl(buildModel({
|
|
4268
|
+
columnOrderModel: orderedFields
|
|
4269
|
+
}), search, localStorageVersion, historyReplace, columns);
|
|
3156
4270
|
}
|
|
3157
4271
|
};
|
|
3158
4272
|
const unsub1 = api.subscribeEvent('columnOrderChange', handleColumnOrderChange);
|
|
@@ -3161,53 +4275,28 @@ const useStatefulTable = props => {
|
|
|
3161
4275
|
unsub1();
|
|
3162
4276
|
unsub2();
|
|
3163
4277
|
};
|
|
3164
|
-
}, [apiRef, columnOrderParsed, defaultColumnOrder, filterParsed, sortModelParsed, paginationModelParsed, pinnedColumnsModel, densityParsed,
|
|
3165
|
-
|
|
3166
|
-
// Helper to build the current DataGridModel for updateUrl calls
|
|
3167
|
-
const buildModel = function () {
|
|
3168
|
-
var _apiRef$current$state, _apiRef$current2;
|
|
3169
|
-
let overrides = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
3170
|
-
return _objectSpread2({
|
|
3171
|
-
filterModel: filterParsed,
|
|
3172
|
-
sortModel: sortModelParsed,
|
|
3173
|
-
paginationModel: paginationModelParsed,
|
|
3174
|
-
columnsModel: (_apiRef$current$state = (_apiRef$current2 = apiRef.current) === null || _apiRef$current2 === void 0 ? void 0 : _apiRef$current2.state.columns.columnVisibilityModel) !== null && _apiRef$current$state !== void 0 ? _apiRef$current$state : {},
|
|
3175
|
-
pinnedColumnsModel: pinnedColumnsModel,
|
|
3176
|
-
density: densityParsed,
|
|
3177
|
-
columnOrderModel: columnOrderParsed,
|
|
3178
|
-
defaultColumnOrder,
|
|
3179
|
-
rowGroupingModel: rowGroupingParsed,
|
|
3180
|
-
aggregationModel: aggregationParsed,
|
|
3181
|
-
pivotModel: pivotParsed,
|
|
3182
|
-
pivotActive: pivotActiveParsed
|
|
3183
|
-
}, overrides);
|
|
3184
|
-
};
|
|
3185
|
-
|
|
3186
|
-
// Stable GridPivotModel identity — only recompute when the simplified value changes.
|
|
3187
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3188
|
-
const pivotModelMui = useMemo(() => toGridPivotModel(pivotParsed), [JSON.stringify(pivotParsed)]);
|
|
4278
|
+
}, [apiRef, columnOrderParsed, defaultColumnOrder, filterParsed, sortModelParsed, paginationModelParsed, pinnedColumnsModel, densityParsed, search, localStorageVersion, historyReplace, columns]);
|
|
3189
4279
|
|
|
3190
4280
|
// Track last emitted values for deep-equal guards to avoid feedback loops.
|
|
3191
4281
|
// Initialised from the current parsed values; updated only when we actually fire.
|
|
3192
4282
|
const lastEmittedFilterRef = useRef(filterParsed);
|
|
3193
4283
|
const lastEmittedSortRef = useRef(sortModelParsed);
|
|
3194
4284
|
const lastEmittedPaginationRef = useRef(paginationModelParsed);
|
|
3195
|
-
const lastEmittedPivotRef = useRef(pivotParsed);
|
|
3196
4285
|
return {
|
|
3197
4286
|
apiRef,
|
|
3198
4287
|
columns,
|
|
3199
4288
|
density: densityParsed,
|
|
4289
|
+
onDensityChange: newDensity => {
|
|
4290
|
+
updateUrl(buildModel({
|
|
4291
|
+
density: newDensity
|
|
4292
|
+
}), search, localStorageVersion, historyReplace, columns);
|
|
4293
|
+
},
|
|
3200
4294
|
columnOrderModel: columnOrderParsedRef.current,
|
|
3201
|
-
rowGroupingModel: rowGroupingParsedRef.current,
|
|
3202
|
-
aggregationModel: aggregationParsedRef.current,
|
|
3203
|
-
pivotModel: pivotModelMui,
|
|
3204
|
-
pivotActive: pivotActiveParsed,
|
|
3205
4295
|
onFilterModelChange: (model, details) => {
|
|
3206
4296
|
const filterModel = _objectSpread2(_objectSpread2({}, model), {}, {
|
|
3207
4297
|
items: model.items.map(item => {
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
item.type = (column === null || column === void 0 ? void 0 : column.type) || 'string';
|
|
4298
|
+
const column = apiRef.current.getColumn(item.field);
|
|
4299
|
+
item.type = column.type || 'string';
|
|
3211
4300
|
return item;
|
|
3212
4301
|
}),
|
|
3213
4302
|
quickFilterValues: model.quickFilterValues || []
|
|
@@ -3230,20 +4319,10 @@ const useStatefulTable = props => {
|
|
|
3230
4319
|
},
|
|
3231
4320
|
sortModel: sortModelParsedRef.current,
|
|
3232
4321
|
onPinnedColumnsChange: (pinnedColumns, details) => {
|
|
3233
|
-
var _apiRef$current$state2, _apiRef$current4, _apiRef$current4$stat, _apiRef$current4$stat2;
|
|
3234
|
-
// While pivot mode is active, MUI Premium emits synthetic pinned-column
|
|
3235
|
-
// models (e.g. `__row_group_by_columns_group__` for the grouping column)
|
|
3236
|
-
// that must not be persisted to the URL / localStorage. Read the live
|
|
3237
|
-
// grid state from apiRef rather than the parsed URL value because the
|
|
3238
|
-
// URL lags by a tick during pivot enable/disable transitions. Consumer
|
|
3239
|
-
// callbacks are always forwarded so observers can still react.
|
|
3240
|
-
const pivotActiveLive = (_apiRef$current$state2 = (_apiRef$current4 = apiRef.current) === null || _apiRef$current4 === void 0 ? void 0 : (_apiRef$current4$stat = _apiRef$current4.state) === null || _apiRef$current4$stat === void 0 ? void 0 : (_apiRef$current4$stat2 = _apiRef$current4$stat.pivoting) === null || _apiRef$current4$stat2 === void 0 ? void 0 : _apiRef$current4$stat2.active) !== null && _apiRef$current$state2 !== void 0 ? _apiRef$current$state2 : pivotActiveParsed;
|
|
3241
|
-
if (!pivotActiveLive) {
|
|
3242
|
-
updateUrl(buildModel({
|
|
3243
|
-
pinnedColumnsModel: pinnedColumns
|
|
3244
|
-
}), search, localStorageVersion, historyReplace, columns);
|
|
3245
|
-
}
|
|
3246
4322
|
propsOnPinnedColumnsChange === null || propsOnPinnedColumnsChange === void 0 ? void 0 : propsOnPinnedColumnsChange(pinnedColumns, details);
|
|
4323
|
+
updateUrl(buildModel({
|
|
4324
|
+
pinnedColumnsModel: pinnedColumns
|
|
4325
|
+
}), search, localStorageVersion, historyReplace, columns);
|
|
3247
4326
|
},
|
|
3248
4327
|
pinnedColumns: pinnedColumnsModelRef.current,
|
|
3249
4328
|
paginationModel: paginationModelParsedRef.current,
|
|
@@ -3260,21 +4339,10 @@ const useStatefulTable = props => {
|
|
|
3260
4339
|
},
|
|
3261
4340
|
columnVisibilityModel: visibilityModelRef.current,
|
|
3262
4341
|
onColumnVisibilityModelChange: (columnsVisibilityModel, details) => {
|
|
3263
|
-
var _apiRef$current$state3, _apiRef$current5, _apiRef$current5$stat, _apiRef$current5$stat2;
|
|
3264
|
-
// While pivot mode is active, MUI Premium emits synthetic visibility
|
|
3265
|
-
// models that whitelist only the pivot value fields (hiding every base
|
|
3266
|
-
// column). Persisting that to the URL would re-hide all base columns
|
|
3267
|
-
// on the next load (see getColumnVisibilityFromString whitelist logic).
|
|
3268
|
-
// Read the live grid state rather than the parsed URL value because the
|
|
3269
|
-
// URL lags by a tick during pivot enable/disable transitions. Consumer
|
|
3270
|
-
// callbacks are always forwarded.
|
|
3271
|
-
const pivotActiveLive = (_apiRef$current$state3 = (_apiRef$current5 = apiRef.current) === null || _apiRef$current5 === void 0 ? void 0 : (_apiRef$current5$stat = _apiRef$current5.state) === null || _apiRef$current5$stat === void 0 ? void 0 : (_apiRef$current5$stat2 = _apiRef$current5$stat.pivoting) === null || _apiRef$current5$stat2 === void 0 ? void 0 : _apiRef$current5$stat2.active) !== null && _apiRef$current$state3 !== void 0 ? _apiRef$current$state3 : pivotActiveParsed;
|
|
3272
|
-
if (!pivotActiveLive) {
|
|
3273
|
-
updateUrl(buildModel({
|
|
3274
|
-
columnsModel: columnsVisibilityModel
|
|
3275
|
-
}), search, localStorageVersion, historyReplace, columns);
|
|
3276
|
-
}
|
|
3277
4342
|
propsOnColumnVisibilityModelChange === null || propsOnColumnVisibilityModelChange === void 0 ? void 0 : propsOnColumnVisibilityModelChange(columnsVisibilityModel, details);
|
|
4343
|
+
updateUrl(buildModel({
|
|
4344
|
+
columnsModel: columnsVisibilityModel
|
|
4345
|
+
}), search, localStorageVersion, historyReplace, columns);
|
|
3278
4346
|
},
|
|
3279
4347
|
onColumnWidthChange: (params, event, details) => {
|
|
3280
4348
|
propsOnColumnWidthChange === null || propsOnColumnWidthChange === void 0 ? void 0 : propsOnColumnWidthChange(params, event, details);
|
|
@@ -3282,38 +4350,11 @@ const useStatefulTable = props => {
|
|
|
3282
4350
|
newWidth: params.width,
|
|
3283
4351
|
field: params.colDef.field
|
|
3284
4352
|
});
|
|
3285
|
-
},
|
|
3286
|
-
onRowGroupingModelChange: (model, details) => {
|
|
3287
|
-
updateUrl(buildModel({
|
|
3288
|
-
rowGroupingModel: model
|
|
3289
|
-
}), search, localStorageVersion, historyReplace, columns);
|
|
3290
|
-
propsOnRowGroupingModelChange === null || propsOnRowGroupingModelChange === void 0 ? void 0 : propsOnRowGroupingModelChange(model, details);
|
|
3291
|
-
},
|
|
3292
|
-
onAggregationModelChange: (model, details) => {
|
|
3293
|
-
updateUrl(buildModel({
|
|
3294
|
-
aggregationModel: model
|
|
3295
|
-
}), search, localStorageVersion, historyReplace, columns);
|
|
3296
|
-
propsOnAggregationModelChange === null || propsOnAggregationModelChange === void 0 ? void 0 : propsOnAggregationModelChange(model, details);
|
|
3297
|
-
},
|
|
3298
|
-
onPivotModelChange: model => {
|
|
3299
|
-
const simplified = fromGridPivotModel(model);
|
|
3300
|
-
if (isDeepEqual(simplified, lastEmittedPivotRef.current)) return;
|
|
3301
|
-
lastEmittedPivotRef.current = simplified;
|
|
3302
|
-
updateUrl(buildModel({
|
|
3303
|
-
pivotModel: simplified
|
|
3304
|
-
}), search, localStorageVersion, historyReplace, columns);
|
|
3305
|
-
propsOnPivotModelChange === null || propsOnPivotModelChange === void 0 ? void 0 : propsOnPivotModelChange(model);
|
|
3306
|
-
},
|
|
3307
|
-
onPivotActiveChange: active => {
|
|
3308
|
-
if (active === pivotActiveParsed) return;
|
|
3309
|
-
updateUrl(buildModel({
|
|
3310
|
-
pivotActive: active
|
|
3311
|
-
}), search, localStorageVersion, historyReplace, columns);
|
|
3312
4353
|
}
|
|
3313
4354
|
};
|
|
3314
4355
|
};
|
|
3315
4356
|
|
|
3316
|
-
const _excluded = ["apiRef", "autoHeight", "className", "columns", "slots", "slotProps", "filterModel", "columnVisibilityModel", "pinnedColumns", "sortModel", "paginationModel", "height", "hideToolbar", "initialState", "isRowSelectable", "license", "localStorageVersion", "previousLocalStorageVersions", "onFilterModelChange", "rowSelectionModel", "onColumnWidthChange", "onPaginationModelChange", "onRowSelectionModelChange", "onColumnVisibilityModelChange", "onPinnedColumnsChange", "onSortModelChange", "
|
|
4357
|
+
const _excluded = ["apiRef", "autoHeight", "className", "columns", "slots", "slotProps", "filterModel", "columnVisibilityModel", "pinnedColumns", "sortModel", "paginationModel", "height", "hideToolbar", "initialState", "isRowSelectable", "license", "localStorageVersion", "previousLocalStorageVersions", "onFilterModelChange", "rowSelectionModel", "onColumnWidthChange", "onPaginationModelChange", "onRowSelectionModelChange", "onColumnVisibilityModelChange", "onPinnedColumnsChange", "onSortModelChange", "pagination", "paginationPlacement", "selectionBannerPlacement", "paginationProps", "rows", "pageSizeOptions", "sx", "theme", "useRouter", "paginationMode", "rowCount"];
|
|
3317
4358
|
const COMPONENT_NAME = 'DataGrid';
|
|
3318
4359
|
const CLASSNAME = 'redsift-datagrid';
|
|
3319
4360
|
|
|
@@ -3397,9 +4438,6 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
3397
4438
|
onColumnVisibilityModelChange: propsOnColumnVisibilityModelChange,
|
|
3398
4439
|
onPinnedColumnsChange: propsOnPinnedColumnsChange,
|
|
3399
4440
|
onSortModelChange: propsOnSortModelChange,
|
|
3400
|
-
onRowGroupingModelChange: propsOnRowGroupingModelChange,
|
|
3401
|
-
onAggregationModelChange: propsOnAggregationModelChange,
|
|
3402
|
-
onPivotModelChange: propsOnPivotModelChange,
|
|
3403
4441
|
pagination,
|
|
3404
4442
|
paginationPlacement = 'both',
|
|
3405
4443
|
selectionBannerPlacement = 'top',
|
|
@@ -3410,26 +4448,15 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
3410
4448
|
theme: propsTheme,
|
|
3411
4449
|
useRouter,
|
|
3412
4450
|
paginationMode = 'client',
|
|
3413
|
-
rowCount
|
|
3414
|
-
density: _density,
|
|
3415
|
-
dataSource,
|
|
3416
|
-
filterMode: propsFilterMode,
|
|
3417
|
-
sortingMode: propsSortingMode
|
|
4451
|
+
rowCount
|
|
3418
4452
|
} = props,
|
|
3419
4453
|
forwardedProps = _objectWithoutProperties(props, _excluded);
|
|
3420
|
-
const theme = useTheme(propsTheme);
|
|
4454
|
+
const theme = useTheme$1(propsTheme);
|
|
3421
4455
|
const _apiRef = useGridApiRef();
|
|
3422
4456
|
const apiRef = propsApiRef !== null && propsApiRef !== void 0 ? propsApiRef : _apiRef;
|
|
4457
|
+
const RenderedToolbar = slots !== null && slots !== void 0 && slots.toolbar ? slots.toolbar : Toolbar;
|
|
3423
4458
|
LicenseInfo.setLicenseKey(license);
|
|
3424
4459
|
const height = propsHeight !== null && propsHeight !== void 0 ? propsHeight : autoHeight ? undefined : '500px';
|
|
3425
|
-
|
|
3426
|
-
// When dataSource is present, MUI manages filter/sort/pagination internally.
|
|
3427
|
-
// We must not pass controlled models — only initialState (one-time) and
|
|
3428
|
-
// write-only onChange handlers for URL/localStorage persistence.
|
|
3429
|
-
const isDataSourceMode = Boolean(dataSource);
|
|
3430
|
-
const effectivePaginationMode = isDataSourceMode ? 'server' : paginationMode;
|
|
3431
|
-
const effectiveFilterMode = isDataSourceMode ? 'server' : propsFilterMode;
|
|
3432
|
-
const effectiveSortingMode = isDataSourceMode ? 'server' : propsSortingMode;
|
|
3433
4460
|
const {
|
|
3434
4461
|
onColumnVisibilityModelChange: controlledOnColumnVisibilityModelChange,
|
|
3435
4462
|
onFilterModelChange: controlledOnFilterModelChange,
|
|
@@ -3455,6 +4482,7 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
3455
4482
|
density: controlledDensity,
|
|
3456
4483
|
filterModel,
|
|
3457
4484
|
onColumnVisibilityModelChange,
|
|
4485
|
+
onDensityChange,
|
|
3458
4486
|
onFilterModelChange,
|
|
3459
4487
|
onPaginationModelChange,
|
|
3460
4488
|
onPinnedColumnsChange,
|
|
@@ -3463,15 +4491,7 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
3463
4491
|
pinnedColumns,
|
|
3464
4492
|
sortModel,
|
|
3465
4493
|
onColumnWidthChange,
|
|
3466
|
-
columnOrderModel
|
|
3467
|
-
rowGroupingModel,
|
|
3468
|
-
aggregationModel,
|
|
3469
|
-
pivotModel,
|
|
3470
|
-
pivotActive,
|
|
3471
|
-
onRowGroupingModelChange,
|
|
3472
|
-
onAggregationModelChange,
|
|
3473
|
-
onPivotModelChange,
|
|
3474
|
-
onPivotActiveChange
|
|
4494
|
+
columnOrderModel
|
|
3475
4495
|
} = useStatefulTable({
|
|
3476
4496
|
apiRef: apiRef,
|
|
3477
4497
|
initialState,
|
|
@@ -3482,68 +4502,44 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
3482
4502
|
onPaginationModelChange: controlledOnPaginationModelChange,
|
|
3483
4503
|
onPinnedColumnsChange: controlledOnPinnedColumnsChange,
|
|
3484
4504
|
onSortModelChange: controlledOnSortModelChange,
|
|
3485
|
-
onRowGroupingModelChange: propsOnRowGroupingModelChange,
|
|
3486
|
-
onAggregationModelChange: propsOnAggregationModelChange,
|
|
3487
|
-
onPivotModelChange: propsOnPivotModelChange,
|
|
3488
4505
|
useRouter: useRouter,
|
|
3489
4506
|
localStorageVersion,
|
|
3490
4507
|
previousLocalStorageVersions
|
|
3491
4508
|
});
|
|
3492
4509
|
|
|
3493
|
-
//
|
|
3494
|
-
//
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
//
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
//
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
(
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
// it changed (slot click, apiRef.setPaginationModel from consumer code,
|
|
3522
|
-
// MUI internal updates, etc.). Relying on MUI's `onPaginationModelChange`
|
|
3523
|
-
// prop callback alone is not sufficient: in pivot/GroupedData strategy mode
|
|
3524
|
-
// and with `paginationModel` seeded via `initialState` (rather than as a
|
|
3525
|
-
// controlled prop), the prop callback can be missed under certain
|
|
3526
|
-
// re-render orderings. The event fires reliably whenever the internal
|
|
3527
|
-
// state changes via `setState('setPaginationModel')`, see
|
|
3528
|
-
// `useGridStateInitialization.setState` → `publishEvent(changeEvent, …)`.
|
|
3529
|
-
// The deep-equal guard inside `useStatefulTable.onPaginationModelChange`
|
|
3530
|
-
// dedupes any duplicate emits, so overlap with the prop callback is safe.
|
|
3531
|
-
useEffect(() => {
|
|
3532
|
-
if (!isDataSourceMode) return;
|
|
3533
|
-
const api = apiRef.current;
|
|
3534
|
-
if (!(api !== null && api !== void 0 && api.subscribeEvent)) return;
|
|
3535
|
-
return api.subscribeEvent('paginationModelChange', model => {
|
|
3536
|
-
wrappedOnPaginationModelChange({
|
|
3537
|
-
page: model.page,
|
|
3538
|
-
pageSize: model.pageSize
|
|
3539
|
-
}, {
|
|
3540
|
-
reason: 'paginationModelChange'
|
|
3541
|
-
});
|
|
4510
|
+
// Pre-sort the columns handed to the grid to match the persisted column order.
|
|
4511
|
+
// MUI rebuilds `orderedFields` from the columns-prop array order whenever that
|
|
4512
|
+
// prop's reference changes (createColumnsState with keepOnlyColumnsToUpsert),
|
|
4513
|
+
// discarding any drag-drop reorder that was only seeded once via
|
|
4514
|
+
// initialState.columns.orderedFields. Consumers routinely pass a fresh
|
|
4515
|
+
// `columns` reference (e.g. a columns memo recomputing on a cell-renderer
|
|
4516
|
+
// dependency), so without this the user's reordering silently reverts to
|
|
4517
|
+
// definition order mid-session — and the reverted order then gets persisted
|
|
4518
|
+
// over the real one. Sorting here makes that reconciliation a no-op.
|
|
4519
|
+
const orderedColumns = useMemo(() => {
|
|
4520
|
+
if (!columnOrderModel || columnOrderModel.length === 0) return columns;
|
|
4521
|
+
const rank = new Map(columnOrderModel.map((field, index) => [field, index]));
|
|
4522
|
+
// Fields absent from the persisted order (newly added columns) keep their
|
|
4523
|
+
// original relative position, appended after the ranked ones — matching
|
|
4524
|
+
// MUI's own "append unknown fields to the end" behaviour.
|
|
4525
|
+
return columns.map((column, index) => ({
|
|
4526
|
+
column,
|
|
4527
|
+
index
|
|
4528
|
+
})).sort((a, b) => {
|
|
4529
|
+
var _rank$get, _rank$get2;
|
|
4530
|
+
const rankA = (_rank$get = rank.get(a.column.field)) !== null && _rank$get !== void 0 ? _rank$get : Number.MAX_SAFE_INTEGER;
|
|
4531
|
+
const rankB = (_rank$get2 = rank.get(b.column.field)) !== null && _rank$get2 !== void 0 ? _rank$get2 : Number.MAX_SAFE_INTEGER;
|
|
4532
|
+
return rankA === rankB ? a.index - b.index : rankA - rankB;
|
|
4533
|
+
}).map(_ref => {
|
|
4534
|
+
let {
|
|
4535
|
+
column
|
|
4536
|
+
} = _ref;
|
|
4537
|
+
return column;
|
|
3542
4538
|
});
|
|
3543
|
-
}, [
|
|
3544
|
-
const [rowSelectionModel, setRowSelectionModel] = useState(
|
|
4539
|
+
}, [columns, columnOrderModel]);
|
|
4540
|
+
const [rowSelectionModel, setRowSelectionModel] = useState(propsRowSelectionModel !== null && propsRowSelectionModel !== void 0 ? propsRowSelectionModel : []);
|
|
3545
4541
|
useEffect(() => {
|
|
3546
|
-
setRowSelectionModel(
|
|
4542
|
+
setRowSelectionModel(propsRowSelectionModel !== null && propsRowSelectionModel !== void 0 ? propsRowSelectionModel : []);
|
|
3547
4543
|
}, [propsRowSelectionModel]);
|
|
3548
4544
|
const onRowSelectionModelChange = (selectionModel, details) => {
|
|
3549
4545
|
setRowSelectionModel(selectionModel);
|
|
@@ -3562,44 +4558,23 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
3562
4558
|
|
|
3563
4559
|
// The checkboxSelectionVisibleOnly should only be applied to client-side pagination,
|
|
3564
4560
|
// for server-side pagination it produces inconsistent behavior when selecting all rows in pages 2 and beyond
|
|
3565
|
-
const checkboxSelectionVisibleOnly = Boolean(pagination) && Boolean(
|
|
4561
|
+
const checkboxSelectionVisibleOnly = Boolean(pagination) && Boolean(paginationMode != 'server');
|
|
3566
4562
|
|
|
3567
4563
|
// Banner and pager placements are independent. `belowToolbar` (for either) renders
|
|
3568
|
-
// in
|
|
4564
|
+
// in the toolbar-slot row, and only applies when pagination is on.
|
|
3569
4565
|
const bannerAtTop = selectionBannerPlacement === 'top';
|
|
3570
4566
|
const bannerAtBottom = selectionBannerPlacement === 'bottom';
|
|
3571
4567
|
const bannerBelowToolbar = selectionBannerPlacement === 'belowToolbar' && Boolean(pagination);
|
|
3572
4568
|
const pagerBelowToolbar = paginationPlacement === 'belowToolbar' && Boolean(pagination);
|
|
3573
|
-
const belowToolbarActive = bannerBelowToolbar || pagerBelowToolbar;
|
|
3574
|
-
|
|
3575
|
-
// Track when the grid API is ready to ensure top pagination renders correctly
|
|
3576
|
-
const [gridReady, setGridReady] = useState(false);
|
|
3577
|
-
|
|
3578
|
-
// Force re-render when the grid API becomes ready (for top pagination)
|
|
3579
|
-
useEffect(() => {
|
|
3580
|
-
if (apiRef.current && !gridReady) {
|
|
3581
|
-
setGridReady(true);
|
|
3582
|
-
}
|
|
3583
|
-
});
|
|
3584
|
-
|
|
3585
|
-
// Sync persisted density via apiRef — initialState only applies on mount,
|
|
3586
|
-
// so this handles SPA back/forward navigation where controlledDensity changes after mount
|
|
3587
|
-
useEffect(() => {
|
|
3588
|
-
if (apiRef.current) {
|
|
3589
|
-
apiRef.current.setDensity(controlledDensity);
|
|
3590
|
-
}
|
|
3591
|
-
}, [controlledDensity, apiRef]);
|
|
3592
4569
|
|
|
3593
4570
|
// in server-side pagination we want to update the selection status
|
|
3594
4571
|
// every time we navigate between pages, resize our page or select something
|
|
3595
4572
|
useEffect(() => {
|
|
3596
|
-
if (
|
|
3597
|
-
onServerSideSelectionStatusChange(rowSelectionModel, apiRef, selectionStatusRef, forceSelectionUpdate, isRowSelectable,
|
|
4573
|
+
if (paginationMode == 'server') {
|
|
4574
|
+
onServerSideSelectionStatusChange(Array.isArray(rowSelectionModel) ? rowSelectionModel : [rowSelectionModel], apiRef, selectionStatusRef, forceSelectionUpdate, isRowSelectable, paginationModel.page, paginationModel.pageSize);
|
|
3598
4575
|
}
|
|
3599
|
-
}, [rowSelectionModel,
|
|
3600
|
-
|
|
3601
|
-
// In dataSource mode MUI provides rows internally; skip the guard.
|
|
3602
|
-
if (!isDataSourceMode && !Array.isArray(rows)) {
|
|
4576
|
+
}, [rowSelectionModel, paginationModel.page, paginationModel.pageSize, rows]);
|
|
4577
|
+
if (!Array.isArray(rows)) {
|
|
3603
4578
|
return null;
|
|
3604
4579
|
}
|
|
3605
4580
|
|
|
@@ -3608,34 +4583,29 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
3608
4583
|
// receive the fresh value in the same render cycle — no extra re-render needed.
|
|
3609
4584
|
// The ref is kept in sync for the onRowSelectionModelChange callback's deselect logic.
|
|
3610
4585
|
let selectionStatus = selectionStatusRef.current;
|
|
3611
|
-
if (pagination &&
|
|
4586
|
+
if (pagination && paginationMode !== 'server' && Array.isArray(rowSelectionModel) && rowSelectionModel.length > 0) {
|
|
3612
4587
|
try {
|
|
3613
|
-
// Use manual page slicing instead of
|
|
3614
|
-
//
|
|
3615
|
-
//
|
|
3616
|
-
|
|
3617
|
-
const pageStart =
|
|
3618
|
-
const
|
|
3619
|
-
const selectableRowsInPage = isRowSelectable ?
|
|
4588
|
+
// Use manual page slicing with our React state's paginationModel instead of
|
|
4589
|
+
// gridPaginatedVisibleSortedGridRow*Selector(apiRef). In MUI v7, the apiRef's
|
|
4590
|
+
// internal pagination state can lag behind the React state after a page change,
|
|
4591
|
+
// causing the selection status to be one page behind.
|
|
4592
|
+
const pageStart = paginationModel.page * paginationModel.pageSize;
|
|
4593
|
+
const pageEnd = pageStart + paginationModel.pageSize;
|
|
4594
|
+
const selectableRowsInPage = isRowSelectable ? gridFilteredSortedRowEntriesSelector(apiRef).slice(pageStart, pageEnd).filter(_ref2 => {
|
|
3620
4595
|
let {
|
|
3621
4596
|
model
|
|
3622
|
-
} =
|
|
4597
|
+
} = _ref2;
|
|
3623
4598
|
return isRowSelectable({
|
|
3624
4599
|
row: model
|
|
3625
4600
|
});
|
|
3626
|
-
}).map(
|
|
3627
|
-
let {
|
|
3628
|
-
id
|
|
3629
|
-
} = _ref2;
|
|
3630
|
-
return id;
|
|
3631
|
-
}) : pageEntries.map(_ref3 => {
|
|
4601
|
+
}).map(_ref3 => {
|
|
3632
4602
|
let {
|
|
3633
4603
|
id
|
|
3634
4604
|
} = _ref3;
|
|
3635
4605
|
return id;
|
|
3636
|
-
});
|
|
4606
|
+
}) : gridFilteredSortedRowIdsSelector(apiRef).slice(pageStart, pageEnd);
|
|
3637
4607
|
const numberOfSelectableRowsInPage = selectableRowsInPage.length;
|
|
3638
|
-
const selectableRowsInTable = isRowSelectable ?
|
|
4608
|
+
const selectableRowsInTable = isRowSelectable ? gridFilteredSortedRowEntriesSelector(apiRef).filter(_ref4 => {
|
|
3639
4609
|
let {
|
|
3640
4610
|
model
|
|
3641
4611
|
} = _ref4;
|
|
@@ -3649,8 +4619,8 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
3649
4619
|
return id;
|
|
3650
4620
|
}) : gridFilteredSortedRowIdsSelector(apiRef);
|
|
3651
4621
|
const numberOfSelectableRowsInTable = selectableRowsInTable.length;
|
|
3652
|
-
const numberOfSelectedRows =
|
|
3653
|
-
const selectedOnCurrentPage = selectableRowsInPage.filter(id =>
|
|
4622
|
+
const numberOfSelectedRows = rowSelectionModel.length;
|
|
4623
|
+
const selectedOnCurrentPage = selectableRowsInPage.filter(id => rowSelectionModel.includes(id));
|
|
3654
4624
|
if (numberOfSelectedRows === numberOfSelectableRowsInTable && numberOfSelectableRowsInPage < numberOfSelectableRowsInTable) {
|
|
3655
4625
|
selectionStatus = {
|
|
3656
4626
|
type: 'table',
|
|
@@ -3675,7 +4645,7 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
3675
4645
|
} catch {
|
|
3676
4646
|
// apiRef may not be initialized on first render
|
|
3677
4647
|
}
|
|
3678
|
-
} else if (pagination &&
|
|
4648
|
+
} else if (pagination && paginationMode !== 'server') {
|
|
3679
4649
|
selectionStatus = {
|
|
3680
4650
|
type: 'none',
|
|
3681
4651
|
numberOfSelectedRows: 0
|
|
@@ -3694,6 +4664,46 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
3694
4664
|
}
|
|
3695
4665
|
}
|
|
3696
4666
|
}), [theme]);
|
|
4667
|
+
|
|
4668
|
+
// Per-render data for the stable `BelowToolbar`/`BottomPagination` slots, injected via
|
|
4669
|
+
// `slotProps` so the slot identities stay constant and their subtrees are re-rendered, not
|
|
4670
|
+
// remounted (remounting the toolbar dropped quick-search focus on every keystroke). Typed as
|
|
4671
|
+
// ToolbarWrapper props so mistakes are caught here; cast to MUI's slot types at the injection
|
|
4672
|
+
// sites below. See ../DataGrid/defaultSlots.
|
|
4673
|
+
const toolbarSlotProps = {
|
|
4674
|
+
hideToolbar,
|
|
4675
|
+
RenderedToolbar,
|
|
4676
|
+
filterModel,
|
|
4677
|
+
onFilterModelChange,
|
|
4678
|
+
pagination,
|
|
4679
|
+
displaySelection: bannerAtTop || bannerBelowToolbar,
|
|
4680
|
+
displayPagination: ['top', 'both'].includes(paginationPlacement) || pagerBelowToolbar,
|
|
4681
|
+
displayRowsPerPage: pagerBelowToolbar,
|
|
4682
|
+
selectionStatus,
|
|
4683
|
+
apiRef,
|
|
4684
|
+
isRowSelectable,
|
|
4685
|
+
paginationModel,
|
|
4686
|
+
onPaginationModelChange,
|
|
4687
|
+
pageSizeOptions,
|
|
4688
|
+
paginationProps,
|
|
4689
|
+
paginationMode,
|
|
4690
|
+
rowCount
|
|
4691
|
+
};
|
|
4692
|
+
const bottomPaginationSlotProps = {
|
|
4693
|
+
pagination,
|
|
4694
|
+
paginationMode,
|
|
4695
|
+
displaySelection: bannerAtBottom,
|
|
4696
|
+
displayRowsPerPage: ['bottom', 'both'].includes(paginationPlacement),
|
|
4697
|
+
displayPagination: ['bottom', 'both'].includes(paginationPlacement),
|
|
4698
|
+
selectionStatus,
|
|
4699
|
+
paginationModel,
|
|
4700
|
+
onPaginationModelChange,
|
|
4701
|
+
apiRef,
|
|
4702
|
+
isRowSelectable,
|
|
4703
|
+
pageSizeOptions,
|
|
4704
|
+
paginationProps,
|
|
4705
|
+
rowCount
|
|
4706
|
+
};
|
|
3697
4707
|
return /*#__PURE__*/React__default.createElement(ThemeProvider, {
|
|
3698
4708
|
value: {
|
|
3699
4709
|
theme
|
|
@@ -3704,256 +4714,90 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
3704
4714
|
ref: datagridRef,
|
|
3705
4715
|
className: classNames(StatefulDataGrid.className, className),
|
|
3706
4716
|
$height: height
|
|
3707
|
-
},
|
|
3708
|
-
displaySelection: bannerAtTop,
|
|
3709
|
-
displayRowsPerPage: ['top', 'both'].includes(paginationPlacement),
|
|
3710
|
-
displayPagination: ['top', 'both'].includes(paginationPlacement),
|
|
3711
|
-
selectionStatus: selectionStatus,
|
|
3712
|
-
paginationModel: activePaginationModel,
|
|
3713
|
-
onPaginationModelChange: isDataSourceMode ? dataSourcePaginationChange : onPaginationModelChange,
|
|
3714
|
-
pageSizeOptions: pageSizeOptions,
|
|
3715
|
-
paginationProps: paginationProps,
|
|
3716
|
-
rowCount: rowCount
|
|
3717
|
-
}) : /*#__PURE__*/React__default.createElement(ControlledPagination, {
|
|
3718
|
-
displaySelection: bannerAtTop,
|
|
3719
|
-
displayRowsPerPage: ['top', 'both'].includes(paginationPlacement),
|
|
3720
|
-
displayPagination: ['top', 'both'].includes(paginationPlacement),
|
|
3721
|
-
selectionStatus: selectionStatus,
|
|
3722
|
-
apiRef: apiRef,
|
|
3723
|
-
isRowSelectable: isRowSelectable,
|
|
3724
|
-
paginationModel: activePaginationModel,
|
|
3725
|
-
onPaginationModelChange: onPaginationModelChange,
|
|
3726
|
-
pageSizeOptions: pageSizeOptions,
|
|
3727
|
-
paginationProps: paginationProps
|
|
3728
|
-
}) : null, /*#__PURE__*/React__default.createElement(DataGridPremium, _extends({}, forwardedProps, {
|
|
4717
|
+
}, /*#__PURE__*/React__default.createElement(DataGridPro, _extends({}, forwardedProps, {
|
|
3729
4718
|
apiRef: apiRef,
|
|
3730
|
-
|
|
3731
|
-
|
|
4719
|
+
columns: orderedColumns,
|
|
4720
|
+
columnVisibilityModel: columnVisibilityModel,
|
|
4721
|
+
density: controlledDensity,
|
|
4722
|
+
filterModel: filterModel,
|
|
3732
4723
|
onColumnVisibilityModelChange: onColumnVisibilityModelChange,
|
|
4724
|
+
onDensityChange: onDensityChange,
|
|
4725
|
+
onFilterModelChange: onFilterModelChange,
|
|
4726
|
+
onPaginationModelChange: onPaginationModelChange,
|
|
3733
4727
|
onPinnedColumnsChange: onPinnedColumnsChange,
|
|
4728
|
+
onSortModelChange: onSortModelChange,
|
|
4729
|
+
paginationModel: paginationModel,
|
|
4730
|
+
pinnedColumns: pinnedColumns,
|
|
4731
|
+
sortModel: sortModel,
|
|
3734
4732
|
pageSizeOptions: pageSizeOptions,
|
|
3735
4733
|
onColumnWidthChange: onColumnWidthChange,
|
|
3736
|
-
onRowGroupingModelChange: onRowGroupingModelChange,
|
|
3737
|
-
onAggregationModelChange: onAggregationModelChange,
|
|
3738
|
-
onPivotModelChange: onPivotModelChange,
|
|
3739
|
-
pivotActive: pivotActive,
|
|
3740
|
-
onPivotActiveChange: onPivotActiveChange
|
|
3741
|
-
// In dataSource mode: models are uncontrolled (MUI owns them),
|
|
3742
|
-
// onChange handlers are write-only for URL/localStorage persistence,
|
|
3743
|
-
// and initialState seeds MUI on mount from the persisted URL state.
|
|
3744
|
-
// columnVisibilityModel / pinnedColumns / rowGroupingModel /
|
|
3745
|
-
// aggregationModel / pivotModel are also uncontrolled here to
|
|
3746
|
-
// avoid a controlled re-render race with consumer-side
|
|
3747
|
-
// microtask-deferred history updates (otherwise user toggles
|
|
3748
|
-
// flip back when MUI re-emits with the stale controlled value).
|
|
3749
|
-
// pivotModel specifically also carries `hidden`/`sort` field
|
|
3750
|
-
// metadata that our simplified URL representation strips — so
|
|
3751
|
-
// controlling it would prevent users from unchecking fields in
|
|
3752
|
-
// the pivot panel (the controlled prop would immediately re-add
|
|
3753
|
-
// them). Consumers needing programmatic changes should use the
|
|
3754
|
-
// apiRef imperative API.
|
|
3755
|
-
}, isDataSourceMode ? {
|
|
3756
|
-
onFilterModelChange: onFilterModelChange,
|
|
3757
|
-
onSortModelChange: onSortModelChange,
|
|
3758
|
-
onPaginationModelChange: wrappedOnPaginationModelChange,
|
|
3759
|
-
initialState: _objectSpread2(_objectSpread2({}, initialState), {}, {
|
|
3760
|
-
density: controlledDensity,
|
|
3761
|
-
columns: _objectSpread2(_objectSpread2({}, initialState === null || initialState === void 0 ? void 0 : initialState.columns), {}, {
|
|
3762
|
-
orderedFields: columnOrderModel,
|
|
3763
|
-
columnVisibilityModel
|
|
3764
|
-
}),
|
|
3765
|
-
pinnedColumns,
|
|
3766
|
-
rowGrouping: _objectSpread2(_objectSpread2({}, initialState === null || initialState === void 0 ? void 0 : initialState.rowGrouping), {}, {
|
|
3767
|
-
model: rowGroupingModel
|
|
3768
|
-
}),
|
|
3769
|
-
aggregation: _objectSpread2(_objectSpread2({}, initialState === null || initialState === void 0 ? void 0 : initialState.aggregation), {}, {
|
|
3770
|
-
model: aggregationModel
|
|
3771
|
-
}),
|
|
3772
|
-
filter: {
|
|
3773
|
-
filterModel
|
|
3774
|
-
},
|
|
3775
|
-
sorting: {
|
|
3776
|
-
sortModel
|
|
3777
|
-
},
|
|
3778
|
-
pagination: {
|
|
3779
|
-
paginationModel
|
|
3780
|
-
},
|
|
3781
|
-
pivoting: _objectSpread2(_objectSpread2({}, initialState === null || initialState === void 0 ? void 0 : initialState.pivoting), {}, {
|
|
3782
|
-
model: pivotModel,
|
|
3783
|
-
enabled: pivotActive
|
|
3784
|
-
})
|
|
3785
|
-
})
|
|
3786
|
-
} : {
|
|
3787
|
-
columnVisibilityModel,
|
|
3788
|
-
pinnedColumns,
|
|
3789
|
-
rowGroupingModel,
|
|
3790
|
-
aggregationModel,
|
|
3791
|
-
filterModel,
|
|
3792
|
-
sortModel,
|
|
3793
|
-
paginationModel,
|
|
3794
|
-
pivotModel,
|
|
3795
|
-
onFilterModelChange: onFilterModelChange,
|
|
3796
|
-
onSortModelChange: onSortModelChange,
|
|
3797
|
-
onPaginationModelChange: wrappedOnPaginationModelChange,
|
|
3798
4734
|
initialState: _objectSpread2(_objectSpread2({}, initialState), {}, {
|
|
3799
|
-
density: controlledDensity,
|
|
3800
4735
|
columns: _objectSpread2(_objectSpread2({}, initialState === null || initialState === void 0 ? void 0 : initialState.columns), {}, {
|
|
3801
4736
|
orderedFields: columnOrderModel
|
|
3802
4737
|
})
|
|
3803
|
-
})
|
|
3804
|
-
}, {
|
|
4738
|
+
}),
|
|
3805
4739
|
isRowSelectable: isRowSelectable,
|
|
3806
4740
|
pagination: pagination,
|
|
3807
|
-
paginationMode:
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
keepNonExistentRowsSelected: effectivePaginationMode == 'server',
|
|
3811
|
-
rows: isDataSourceMode ? [] : rows,
|
|
4741
|
+
paginationMode: paginationMode,
|
|
4742
|
+
keepNonExistentRowsSelected: paginationMode == 'server',
|
|
4743
|
+
rows: rows,
|
|
3812
4744
|
rowCount: rowCount,
|
|
3813
4745
|
autoHeight: autoHeight,
|
|
3814
4746
|
checkboxSelectionVisibleOnly: checkboxSelectionVisibleOnly,
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
})),
|
|
3830
|
-
|
|
3831
|
-
displayName: "columnSortedDescendingIcon"
|
|
3832
|
-
})),
|
|
3833
|
-
densityCompactIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
|
|
3834
|
-
displayName: "densityCompactIcon"
|
|
3835
|
-
})),
|
|
3836
|
-
densityStandardIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
|
|
3837
|
-
displayName: "densityStandardIcon"
|
|
3838
|
-
})),
|
|
3839
|
-
densityComfortableIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
|
|
3840
|
-
displayName: "densityComfortableIcon"
|
|
3841
|
-
})),
|
|
3842
|
-
detailPanelCollapseIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
|
|
3843
|
-
displayName: "detailPanelCollapseIcon"
|
|
3844
|
-
})),
|
|
3845
|
-
detailPanelExpandIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
|
|
3846
|
-
displayName: "detailPanelExpandIcon"
|
|
3847
|
-
})),
|
|
3848
|
-
exportIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
|
|
3849
|
-
displayName: "exportIcon"
|
|
3850
|
-
})),
|
|
3851
|
-
openFilterButtonIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
|
|
3852
|
-
displayName: "openFilterButtonIcon"
|
|
3853
|
-
}))
|
|
3854
|
-
}, slots), belowToolbarActive ? {
|
|
3855
|
-
toolbar: toolbarProps => {
|
|
3856
|
-
var _ref6;
|
|
3857
|
-
return /*#__PURE__*/React__default.createElement(ToolbarWrapper, _extends({}, toolbarProps, {
|
|
3858
|
-
RenderedToolbar: (_ref6 = slots === null || slots === void 0 ? void 0 : slots.toolbar) !== null && _ref6 !== void 0 ? _ref6 : Toolbar,
|
|
3859
|
-
hideToolbar: hideToolbar,
|
|
3860
|
-
filterModel: filterModel,
|
|
3861
|
-
onFilterModelChange: onFilterModelChange,
|
|
3862
|
-
pagination: pagination,
|
|
3863
|
-
paginationMode: effectivePaginationMode,
|
|
3864
|
-
displaySelection: bannerBelowToolbar,
|
|
3865
|
-
displayPagination: pagerBelowToolbar,
|
|
3866
|
-
displayRowsPerPage: pagerBelowToolbar,
|
|
3867
|
-
selectionStatus: selectionStatus,
|
|
3868
|
-
apiRef: apiRef,
|
|
3869
|
-
isRowSelectable: isRowSelectable,
|
|
3870
|
-
paginationModel: activePaginationModel,
|
|
3871
|
-
onPaginationModelChange: isDataSourceMode ? dataSourcePaginationChange : onPaginationModelChange,
|
|
3872
|
-
pageSizeOptions: pageSizeOptions,
|
|
3873
|
-
paginationProps: paginationProps,
|
|
3874
|
-
rowCount: rowCount
|
|
3875
|
-
}));
|
|
3876
|
-
}
|
|
3877
|
-
} : {}), {}, {
|
|
3878
|
-
pagination: props => {
|
|
3879
|
-
return pagination ? effectivePaginationMode == 'server' ? /*#__PURE__*/React__default.createElement(ServerSideControlledPagination, _extends({}, props, {
|
|
3880
|
-
displaySelection: bannerAtBottom,
|
|
3881
|
-
displayRowsPerPage: ['bottom', 'both'].includes(paginationPlacement),
|
|
3882
|
-
displayPagination: ['bottom', 'both'].includes(paginationPlacement),
|
|
3883
|
-
selectionStatus: selectionStatus,
|
|
3884
|
-
paginationModel: activePaginationModel
|
|
3885
|
-
// In dataSource mode route through apiRef so MUI's internal pagination
|
|
3886
|
-
// state stays in sync with the displayed model and dataSource.getRows()
|
|
3887
|
-
// re-fetches with the new params. MUI then fires onPaginationModelChange
|
|
3888
|
-
// via the prop, which updates URL/localStorage via useStatefulTable.
|
|
3889
|
-
// Without this the bottom slot only updated local React state + URL,
|
|
3890
|
-
// leaving MUI on its previous internal page (no refetch, stale display).
|
|
3891
|
-
,
|
|
3892
|
-
onPaginationModelChange: isDataSourceMode ? dataSourcePaginationChange : wrappedOnPaginationModelChange,
|
|
3893
|
-
pageSizeOptions: pageSizeOptions,
|
|
3894
|
-
paginationProps: paginationProps,
|
|
3895
|
-
rowCount: rowCount
|
|
3896
|
-
})) : /*#__PURE__*/React__default.createElement(ControlledPagination, _extends({}, props, {
|
|
3897
|
-
displaySelection: bannerAtBottom,
|
|
3898
|
-
displayRowsPerPage: ['bottom', 'both'].includes(paginationPlacement),
|
|
3899
|
-
displayPagination: ['bottom', 'both'].includes(paginationPlacement),
|
|
3900
|
-
selectionStatus: selectionStatus,
|
|
3901
|
-
apiRef: apiRef,
|
|
3902
|
-
isRowSelectable: isRowSelectable,
|
|
3903
|
-
paginationModel: activePaginationModel,
|
|
3904
|
-
onPaginationModelChange: wrappedOnPaginationModelChange,
|
|
3905
|
-
pageSizeOptions: pageSizeOptions,
|
|
3906
|
-
paginationProps: paginationProps
|
|
3907
|
-
})) : null;
|
|
3908
|
-
}
|
|
4747
|
+
slots: _objectSpread2(_objectSpread2(_objectSpread2({}, baseGridSlots), slots), {}, {
|
|
4748
|
+
// `BelowToolbar` and `BottomPagination` are stable module-level components; their
|
|
4749
|
+
// per-render data is injected via `slotProps` below. A fresh inline function here
|
|
4750
|
+
// would remount the slot's subtree every render — for the toolbar that dropped
|
|
4751
|
+
// quick-search focus on every keystroke. The consumer's `slots.toolbar` (or the
|
|
4752
|
+
// default DS Toolbar) is preserved via `RenderedToolbar` inside ToolbarWrapper.
|
|
4753
|
+
toolbar: BelowToolbar,
|
|
4754
|
+
pagination: BottomPagination
|
|
4755
|
+
}),
|
|
4756
|
+
slotProps: _objectSpread2(_objectSpread2({}, slotProps), {}, {
|
|
4757
|
+
// Inject the per-render slot data (built above) here rather than closing over it
|
|
4758
|
+
// in inline slots, so the slot identities stay stable. Consumer slot props are
|
|
4759
|
+
// spread first; the DS layout data wins. Cast at the MUI boundary because these
|
|
4760
|
+
// are ToolbarWrapper props, not the MUI slot prop types.
|
|
4761
|
+
toolbar: _objectSpread2(_objectSpread2({}, slotProps === null || slotProps === void 0 ? void 0 : slotProps.toolbar), toolbarSlotProps),
|
|
4762
|
+
pagination: _objectSpread2(_objectSpread2({}, slotProps === null || slotProps === void 0 ? void 0 : slotProps.pagination), bottomPaginationSlotProps)
|
|
3909
4763
|
}),
|
|
3910
|
-
slotProps: _objectSpread2({}, slotProps),
|
|
3911
4764
|
rowSelectionModel: rowSelectionModel,
|
|
3912
4765
|
onRowSelectionModelChange: (newSelectionModel, details) => {
|
|
3913
|
-
if (pagination &&
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
const
|
|
3917
|
-
const pageStart = activePaginationModel.page * activePaginationModel.pageSize;
|
|
3918
|
-
const pageEntries = allFilteredEntries.slice(pageStart, pageStart + activePaginationModel.pageSize);
|
|
3919
|
-
const selectableRowsInPage = isRowSelectable ? pageEntries.filter(_ref7 => {
|
|
4766
|
+
if (pagination && paginationMode != 'server') {
|
|
4767
|
+
const cbPageStart = paginationModel.page * paginationModel.pageSize;
|
|
4768
|
+
const cbPageEnd = cbPageStart + paginationModel.pageSize;
|
|
4769
|
+
const selectableRowsInPage = isRowSelectable ? gridFilteredSortedRowEntriesSelector(apiRef).slice(cbPageStart, cbPageEnd).filter(_ref6 => {
|
|
3920
4770
|
let {
|
|
3921
4771
|
model
|
|
3922
|
-
} =
|
|
4772
|
+
} = _ref6;
|
|
3923
4773
|
return isRowSelectable({
|
|
3924
4774
|
row: model
|
|
3925
4775
|
});
|
|
3926
|
-
}).map(
|
|
3927
|
-
let {
|
|
3928
|
-
id
|
|
3929
|
-
} = _ref8;
|
|
3930
|
-
return id;
|
|
3931
|
-
}) : pageEntries.map(_ref9 => {
|
|
4776
|
+
}).map(_ref7 => {
|
|
3932
4777
|
let {
|
|
3933
4778
|
id
|
|
3934
|
-
} =
|
|
4779
|
+
} = _ref7;
|
|
3935
4780
|
return id;
|
|
3936
|
-
});
|
|
4781
|
+
}) : gridFilteredSortedRowIdsSelector(apiRef).slice(cbPageStart, cbPageEnd);
|
|
3937
4782
|
const numberOfSelectableRowsInPage = selectableRowsInPage.length;
|
|
3938
|
-
const selectableRowsInTable = isRowSelectable ?
|
|
4783
|
+
const selectableRowsInTable = isRowSelectable ? gridFilteredSortedRowEntriesSelector(apiRef).filter(_ref8 => {
|
|
3939
4784
|
let {
|
|
3940
4785
|
model
|
|
3941
|
-
} =
|
|
4786
|
+
} = _ref8;
|
|
3942
4787
|
return isRowSelectable({
|
|
3943
4788
|
row: model
|
|
3944
4789
|
});
|
|
3945
|
-
}).map(
|
|
4790
|
+
}).map(_ref9 => {
|
|
3946
4791
|
let {
|
|
3947
4792
|
id
|
|
3948
|
-
} =
|
|
4793
|
+
} = _ref9;
|
|
3949
4794
|
return id;
|
|
3950
4795
|
}) : gridFilteredSortedRowIdsSelector(apiRef);
|
|
3951
4796
|
const numberOfSelectableRowsInTable = selectableRowsInTable.length;
|
|
3952
|
-
const numberOfSelectedRows =
|
|
4797
|
+
const numberOfSelectedRows = newSelectionModel.length;
|
|
3953
4798
|
if (selectionStatusRef.current.type === 'table' && numberOfSelectedRows === numberOfSelectableRowsInTable - numberOfSelectableRowsInPage || selectionStatusRef.current.type === 'table' && numberOfSelectedRows === numberOfSelectableRowsInTable || selectionStatusRef.current.type === 'page' && numberOfSelectedRows === numberOfSelectableRowsInPage) {
|
|
3954
4799
|
setTimeout(() => {
|
|
3955
|
-
|
|
3956
|
-
(_apiRef$current2 = apiRef.current) === null || _apiRef$current2 === void 0 ? void 0 : _apiRef$current2.selectRows([], true, true);
|
|
4800
|
+
apiRef.current.selectRows([], true, true);
|
|
3957
4801
|
}, 0);
|
|
3958
4802
|
}
|
|
3959
4803
|
if (numberOfSelectedRows === numberOfSelectableRowsInPage && numberOfSelectableRowsInPage < numberOfSelectableRowsInTable) {
|
|
@@ -3995,5 +4839,5 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
3995
4839
|
StatefulDataGrid.className = CLASSNAME;
|
|
3996
4840
|
StatefulDataGrid.displayName = COMPONENT_NAME;
|
|
3997
4841
|
|
|
3998
|
-
export {
|
|
4842
|
+
export { clearAllVersionStorage as $, ARRAY_IS_EMPTY as A, Box$1 as B, CONTAINS_ANY_OF as C, DOES_NOT_CONTAIN as D, ENDS_WITH_ANY_OF as E, IS as F, IS_NOT as G, HAS_WITH_SELECT as H, IS_ANY_OF as I, getGridStringOperators as J, getGridStringArrayOperators as K, getGridStringArrayOperatorsWithSelect as L, getGridStringArrayOperatorsWithSelectOnStringArrayColumns as M, FILTER_MODEL_KEY as N, SORT_MODEL_KEY as O, PAGINATION_MODEL_KEY as P, PINNED_COLUMNS as Q, DIMENSION_MODEL_KEY as R, STARTS_WITH_ANY_OF as S, TextField$1 as T, FILTER_SEARCH_KEY as U, VISIBILITY_MODEL_KEY as V, DENSITY_MODEL_KEY as W, COLUMN_ORDER_MODEL_KEY as X, CATEGORIES as Y, buildStorageKey as Z, clearPreviousVersionStorage as _, DOES_NOT_EQUAL as a, resetStatefulDataGridState as a0, resetColumnVisibility as a1, convertToDisplayFormat as a2, convertFromDisplayFormat as a3, getDecodedSearchFromUrl as a4, buildQueryParamsString as a5, areSearchStringsEqual as a6, decodeValue as a7, encodeValue as a8, urlSearchParamsToString as a9, StatefulDataGrid as aA, numberOperatorEncoder as aa, numberOperatorDecoder as ab, isOperatorValueValid as ac, isValueValid as ad, getFilterModelFromString as ae, normalizeDateValue as af, getSearchParamsFromFilterModel as ag, getSortingFromString as ah, getSearchParamsFromSorting as ai, getPaginationFromString as aj, getSearchParamsFromPagination as ak, getColumnVisibilityFromString as al, getSearchParamsFromColumnVisibility as am, getPinnedColumnsFromString as an, getSearchParamsFromPinnedColumns as ao, getSearchParamsFromTab as ap, getDensityFromString as aq, getSearchParamsFromDensity as ar, getDensityModel as as, getColumnOrderFromString as at, getSearchParamsFromColumnOrder as au, getSearchParamsFromVersion as av, getFinalSearch as aw, getModelsParsedOrUpdateLocalStorage as ax, updateUrl as ay, areFilterModelsEquivalent as az, DOES_NOT_START_WITH as b, DOES_NOT_END_WITH as c, IS_NOT_ANY_OF as d, DOES_NOT_CONTAIN_ANY_OF as e, DOES_NOT_START_WITH_ANY_OF as f, DOES_NOT_END_WITH_ANY_OF as g, IS_BETWEEN as h, IS_WITH_SELECT as i, IS_NOT_WITH_SELECT as j, IS_ANY_OF_WITH_SELECT as k, IS_NOT_ANY_OF_WITH_SELECT as l, ARRAY_IS_NOT_EMPTY as m, DOES_NOT_HAVE_WITH_SELECT as n, operatorList as o, HAS_ANY_OF_WITH_SELECT as p, HAS_ALL_OF_WITH_SELECT as q, DOES_NOT_HAVE_ANY_OF_WITH_SELECT as r, HAS_ONLY_WITH_SELECT as s, HAS as t, DOES_NOT_HAVE as u, HAS_ANY_OF as v, HAS_ALL_OF as w, DOES_NOT_HAVE_ANY_OF as x, HAS_ONLY as y, getGridNumericOperators as z };
|
|
3999
4843
|
//# sourceMappingURL=StatefulDataGrid2.js.map
|