@redsift/table 12.5.13-muiv6 → 12.5.14
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/BaseIconButton.js +126 -0
- package/_internal/BaseIconButton.js.map +1 -0
- package/_internal/DataGrid2.js +149 -81
- package/_internal/DataGrid2.js.map +1 -1
- package/_internal/GridToolbarFilterSemanticField2.js +1340 -3
- package/_internal/GridToolbarFilterSemanticField2.js.map +1 -1
- package/_internal/Pagination.js +1 -1
- package/_internal/ServerSideControlledPagination.js +337 -0
- package/_internal/ServerSideControlledPagination.js.map +1 -0
- package/_internal/StatefulDataGrid.js +1 -1
- package/_internal/StatefulDataGrid2.js +1151 -1561
- package/_internal/StatefulDataGrid2.js.map +1 -1
- package/_internal/Toolbar2.js +23 -6
- package/_internal/Toolbar2.js.map +1 -1
- package/_internal/ToolbarWrapper2.js +1 -1
- package/_internal/useControlledDatagridState.js +43 -308
- package/_internal/useControlledDatagridState.js.map +1 -1
- package/index.d.ts +520 -355
- package/index.js +46 -15
- package/index.js.map +1 -1
- package/package.json +9 -10
- package/_internal/BasePopper.js +0 -2469
- package/_internal/BasePopper.js.map +0 -1
- package/_internal/ControlledPagination.js +0 -11004
- package/_internal/ControlledPagination.js.map +0 -1
- package/_internal/Portal.js +0 -6538
- package/_internal/Portal.js.map +0 -1
- package/_internal/jsx-runtime.js +0 -1342
- package/_internal/jsx-runtime.js.map +0 -1
|
@@ -1,1248 +1,18 @@
|
|
|
1
|
-
import { _ as _objectSpread2, a as _objectWithoutProperties, b as _extends
|
|
1
|
+
import { _ as _objectSpread2, a as _objectWithoutProperties, b as _extends } from './_rollupPluginBabelHelpers.js';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import React__default, { useCallback, useEffect,
|
|
3
|
+
import React__default, { useCallback, useEffect, useRef, useMemo, forwardRef, useState } from 'react';
|
|
4
|
+
import { createTheme, ThemeProvider as ThemeProvider$1 } from '@mui/material/styles';
|
|
4
5
|
import classNames from 'classnames';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { LicenseInfo } from '@mui/x-license';
|
|
7
|
+
import { Icon, useTheme, RedsiftColorBlueN, RedsiftColorNeutralXDarkGrey, RedsiftColorNeutralWhite, ThemeProvider } from '@redsift/design-system';
|
|
8
|
+
import { getGridNumericOperators as getGridNumericOperators$1, GridFilterInputValue, GridFilterInputSingleSelect, GridFilterInputMultipleValue, GridFilterInputMultipleSingleSelect, getGridStringOperators as getGridStringOperators$1, getGridBooleanOperators, getGridDateOperators, getGridSingleSelectOperators, GridLogicOperator, useGridApiRef, gridFilteredSortedRowEntriesSelector, gridFilteredSortedRowIdsSelector, DataGridPremium } from '@mui/x-data-grid-premium';
|
|
9
|
+
import { u as useControlledDatagridState, S as StyledDataGrid, B as BottomPagination, b as baseGridSlots, a as BelowToolbar } from './useControlledDatagridState.js';
|
|
10
|
+
import Box from '@mui/material/Box';
|
|
11
|
+
import TextField from '@mui/material/TextField';
|
|
8
12
|
import { mdiSync } from '@redsift/icons';
|
|
9
|
-
import { s as styled, a as styleFunctionSx, e as extendSxProp, _ as _objectWithoutPropertiesLoose, b as _extends, g as generateUtilityClasses, c as createTheme, T as THEME_ID, C as ClassNameGenerator, P as PropTypes, d as generateUtilityClass, f as styled$1, h as _extends$1, u as useDefaultProps, i as _objectWithoutPropertiesLoose$1, j as capitalize, k as composeClasses, r as rootShouldForwardProp, l as refType } from './Portal.js';
|
|
10
|
-
import { u as useTheme, a as useFormControl, b as formControlState, c as clsx$1, i as isAdornedStart, d as isFilled, F as FormControlContext, e as useId, h as Select, I as Input, j as FilledInput, O as OutlinedInput, o as onServerSideSelectionStatusChange } from './ControlledPagination.js';
|
|
11
|
-
import { j as jsxRuntimeExports } from './jsx-runtime.js';
|
|
12
13
|
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';
|
|
13
15
|
import { T as Toolbar } from './Toolbar2.js';
|
|
14
|
-
import { T as ToolbarWrapper } from './ToolbarWrapper2.js';
|
|
15
|
-
|
|
16
|
-
function r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;else if("object"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=" "),n+=f);}else for(f in e)e[f]&&(n&&(n+=" "),n+=f);return n}function clsx(){for(var e,t,f=0,n="",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=" "),n+=t);return n}
|
|
17
|
-
|
|
18
|
-
const _excluded$6 = ["className", "component"];
|
|
19
|
-
function createBox(options = {}) {
|
|
20
|
-
const {
|
|
21
|
-
themeId,
|
|
22
|
-
defaultTheme,
|
|
23
|
-
defaultClassName = 'MuiBox-root',
|
|
24
|
-
generateClassName
|
|
25
|
-
} = options;
|
|
26
|
-
const BoxRoot = styled('div', {
|
|
27
|
-
shouldForwardProp: prop => prop !== 'theme' && prop !== 'sx' && prop !== 'as'
|
|
28
|
-
})(styleFunctionSx);
|
|
29
|
-
const Box = /*#__PURE__*/React.forwardRef(function Box(inProps, ref) {
|
|
30
|
-
const theme = useTheme(defaultTheme);
|
|
31
|
-
const _extendSxProp = extendSxProp(inProps),
|
|
32
|
-
{
|
|
33
|
-
className,
|
|
34
|
-
component = 'div'
|
|
35
|
-
} = _extendSxProp,
|
|
36
|
-
other = _objectWithoutPropertiesLoose(_extendSxProp, _excluded$6);
|
|
37
|
-
return /*#__PURE__*/jsxRuntimeExports.jsx(BoxRoot, _extends({
|
|
38
|
-
as: component,
|
|
39
|
-
ref: ref,
|
|
40
|
-
className: clsx(className, generateClassName ? generateClassName(defaultClassName) : defaultClassName),
|
|
41
|
-
theme: themeId ? theme[themeId] || theme : theme
|
|
42
|
-
}, other));
|
|
43
|
-
});
|
|
44
|
-
return Box;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function isMuiElement(element, muiNames) {
|
|
48
|
-
var _muiName, _element$type;
|
|
49
|
-
return /*#__PURE__*/React.isValidElement(element) && muiNames.indexOf( // For server components `muiName` is avaialble in element.type._payload.value.muiName
|
|
50
|
-
// relevant info - https://github.com/facebook/react/blob/2807d781a08db8e9873687fccc25c0f12b4fb3d4/packages/react/src/ReactLazy.js#L45
|
|
51
|
-
// eslint-disable-next-line no-underscore-dangle
|
|
52
|
-
(_muiName = element.type.muiName) != null ? _muiName : (_element$type = element.type) == null || (_element$type = _element$type._payload) == null || (_element$type = _element$type.value) == null ? void 0 : _element$type.muiName) !== -1;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const boxClasses = generateUtilityClasses('MuiBox', ['root']);
|
|
56
|
-
var boxClasses$1 = boxClasses;
|
|
57
|
-
|
|
58
|
-
const defaultTheme = createTheme();
|
|
59
|
-
const Box = createBox({
|
|
60
|
-
themeId: THEME_ID,
|
|
61
|
-
defaultTheme,
|
|
62
|
-
defaultClassName: boxClasses$1.root,
|
|
63
|
-
generateClassName: ClassNameGenerator.generate
|
|
64
|
-
});
|
|
65
|
-
process.env.NODE_ENV !== "production" ? Box.propTypes /* remove-proptypes */ = {
|
|
66
|
-
// ┌────────────────────────────── Warning ──────────────────────────────┐
|
|
67
|
-
// │ These PropTypes are generated from the TypeScript type definitions. │
|
|
68
|
-
// │ To update them, edit the d.ts file and run `pnpm proptypes`. │
|
|
69
|
-
// └─────────────────────────────────────────────────────────────────────┘
|
|
70
|
-
/**
|
|
71
|
-
* @ignore
|
|
72
|
-
*/
|
|
73
|
-
children: PropTypes.node,
|
|
74
|
-
/**
|
|
75
|
-
* The component used for the root node.
|
|
76
|
-
* Either a string to use a HTML element or a component.
|
|
77
|
-
*/
|
|
78
|
-
component: PropTypes.elementType,
|
|
79
|
-
/**
|
|
80
|
-
* The system prop that allows defining system overrides as well as additional CSS styles.
|
|
81
|
-
*/
|
|
82
|
-
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
|
|
83
|
-
} : void 0;
|
|
84
|
-
var Box$1 = Box;
|
|
85
|
-
|
|
86
|
-
function getFormLabelUtilityClasses(slot) {
|
|
87
|
-
return generateUtilityClass('MuiFormLabel', slot);
|
|
88
|
-
}
|
|
89
|
-
const formLabelClasses = generateUtilityClasses('MuiFormLabel', ['root', 'colorSecondary', 'focused', 'disabled', 'error', 'filled', 'required', 'asterisk']);
|
|
90
|
-
var formLabelClasses$1 = formLabelClasses;
|
|
91
|
-
|
|
92
|
-
const _excluded$5 = ["children", "className", "color", "component", "disabled", "error", "filled", "focused", "required"];
|
|
93
|
-
const useUtilityClasses$4 = ownerState => {
|
|
94
|
-
const {
|
|
95
|
-
classes,
|
|
96
|
-
color,
|
|
97
|
-
focused,
|
|
98
|
-
disabled,
|
|
99
|
-
error,
|
|
100
|
-
filled,
|
|
101
|
-
required
|
|
102
|
-
} = ownerState;
|
|
103
|
-
const slots = {
|
|
104
|
-
root: ['root', `color${capitalize(color)}`, disabled && 'disabled', error && 'error', filled && 'filled', focused && 'focused', required && 'required'],
|
|
105
|
-
asterisk: ['asterisk', error && 'error']
|
|
106
|
-
};
|
|
107
|
-
return composeClasses(slots, getFormLabelUtilityClasses, classes);
|
|
108
|
-
};
|
|
109
|
-
const FormLabelRoot = styled$1('label', {
|
|
110
|
-
name: 'MuiFormLabel',
|
|
111
|
-
slot: 'Root',
|
|
112
|
-
overridesResolver: ({
|
|
113
|
-
ownerState
|
|
114
|
-
}, styles) => {
|
|
115
|
-
return _extends$1({}, styles.root, ownerState.color === 'secondary' && styles.colorSecondary, ownerState.filled && styles.filled);
|
|
116
|
-
}
|
|
117
|
-
})(({
|
|
118
|
-
theme,
|
|
119
|
-
ownerState
|
|
120
|
-
}) => _extends$1({
|
|
121
|
-
color: (theme.vars || theme).palette.text.secondary
|
|
122
|
-
}, theme.typography.body1, {
|
|
123
|
-
lineHeight: '1.4375em',
|
|
124
|
-
padding: 0,
|
|
125
|
-
position: 'relative',
|
|
126
|
-
[`&.${formLabelClasses$1.focused}`]: {
|
|
127
|
-
color: (theme.vars || theme).palette[ownerState.color].main
|
|
128
|
-
},
|
|
129
|
-
[`&.${formLabelClasses$1.disabled}`]: {
|
|
130
|
-
color: (theme.vars || theme).palette.text.disabled
|
|
131
|
-
},
|
|
132
|
-
[`&.${formLabelClasses$1.error}`]: {
|
|
133
|
-
color: (theme.vars || theme).palette.error.main
|
|
134
|
-
}
|
|
135
|
-
}));
|
|
136
|
-
const AsteriskComponent = styled$1('span', {
|
|
137
|
-
name: 'MuiFormLabel',
|
|
138
|
-
slot: 'Asterisk',
|
|
139
|
-
overridesResolver: (props, styles) => styles.asterisk
|
|
140
|
-
})(({
|
|
141
|
-
theme
|
|
142
|
-
}) => ({
|
|
143
|
-
[`&.${formLabelClasses$1.error}`]: {
|
|
144
|
-
color: (theme.vars || theme).palette.error.main
|
|
145
|
-
}
|
|
146
|
-
}));
|
|
147
|
-
const FormLabel = /*#__PURE__*/React.forwardRef(function FormLabel(inProps, ref) {
|
|
148
|
-
const props = useDefaultProps({
|
|
149
|
-
props: inProps,
|
|
150
|
-
name: 'MuiFormLabel'
|
|
151
|
-
});
|
|
152
|
-
const {
|
|
153
|
-
children,
|
|
154
|
-
className,
|
|
155
|
-
component = 'label'
|
|
156
|
-
} = props,
|
|
157
|
-
other = _objectWithoutPropertiesLoose$1(props, _excluded$5);
|
|
158
|
-
const muiFormControl = useFormControl();
|
|
159
|
-
const fcs = formControlState({
|
|
160
|
-
props,
|
|
161
|
-
muiFormControl,
|
|
162
|
-
states: ['color', 'required', 'focused', 'disabled', 'error', 'filled']
|
|
163
|
-
});
|
|
164
|
-
const ownerState = _extends$1({}, props, {
|
|
165
|
-
color: fcs.color || 'primary',
|
|
166
|
-
component,
|
|
167
|
-
disabled: fcs.disabled,
|
|
168
|
-
error: fcs.error,
|
|
169
|
-
filled: fcs.filled,
|
|
170
|
-
focused: fcs.focused,
|
|
171
|
-
required: fcs.required
|
|
172
|
-
});
|
|
173
|
-
const classes = useUtilityClasses$4(ownerState);
|
|
174
|
-
return /*#__PURE__*/jsxRuntimeExports.jsxs(FormLabelRoot, _extends$1({
|
|
175
|
-
as: component,
|
|
176
|
-
ownerState: ownerState,
|
|
177
|
-
className: clsx$1(classes.root, className),
|
|
178
|
-
ref: ref
|
|
179
|
-
}, other, {
|
|
180
|
-
children: [children, fcs.required && /*#__PURE__*/jsxRuntimeExports.jsxs(AsteriskComponent, {
|
|
181
|
-
ownerState: ownerState,
|
|
182
|
-
"aria-hidden": true,
|
|
183
|
-
className: classes.asterisk,
|
|
184
|
-
children: ["\u2009", '*']
|
|
185
|
-
})]
|
|
186
|
-
}));
|
|
187
|
-
});
|
|
188
|
-
process.env.NODE_ENV !== "production" ? FormLabel.propTypes /* remove-proptypes */ = {
|
|
189
|
-
// ┌────────────────────────────── Warning ──────────────────────────────┐
|
|
190
|
-
// │ These PropTypes are generated from the TypeScript type definitions. │
|
|
191
|
-
// │ To update them, edit the d.ts file and run `pnpm proptypes`. │
|
|
192
|
-
// └─────────────────────────────────────────────────────────────────────┘
|
|
193
|
-
/**
|
|
194
|
-
* The content of the component.
|
|
195
|
-
*/
|
|
196
|
-
children: PropTypes.node,
|
|
197
|
-
/**
|
|
198
|
-
* Override or extend the styles applied to the component.
|
|
199
|
-
*/
|
|
200
|
-
classes: PropTypes.object,
|
|
201
|
-
/**
|
|
202
|
-
* @ignore
|
|
203
|
-
*/
|
|
204
|
-
className: PropTypes.string,
|
|
205
|
-
/**
|
|
206
|
-
* The color of the component.
|
|
207
|
-
* It supports both default and custom theme colors, which can be added as shown in the
|
|
208
|
-
* [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
|
|
209
|
-
*/
|
|
210
|
-
color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['error', 'info', 'primary', 'secondary', 'success', 'warning']), PropTypes.string]),
|
|
211
|
-
/**
|
|
212
|
-
* The component used for the root node.
|
|
213
|
-
* Either a string to use a HTML element or a component.
|
|
214
|
-
*/
|
|
215
|
-
component: PropTypes.elementType,
|
|
216
|
-
/**
|
|
217
|
-
* If `true`, the label should be displayed in a disabled state.
|
|
218
|
-
*/
|
|
219
|
-
disabled: PropTypes.bool,
|
|
220
|
-
/**
|
|
221
|
-
* If `true`, the label is displayed in an error state.
|
|
222
|
-
*/
|
|
223
|
-
error: PropTypes.bool,
|
|
224
|
-
/**
|
|
225
|
-
* If `true`, the label should use filled classes key.
|
|
226
|
-
*/
|
|
227
|
-
filled: PropTypes.bool,
|
|
228
|
-
/**
|
|
229
|
-
* If `true`, the input of this label is focused (used by `FormGroup` components).
|
|
230
|
-
*/
|
|
231
|
-
focused: PropTypes.bool,
|
|
232
|
-
/**
|
|
233
|
-
* If `true`, the label will indicate that the `input` is required.
|
|
234
|
-
*/
|
|
235
|
-
required: PropTypes.bool,
|
|
236
|
-
/**
|
|
237
|
-
* The system prop that allows defining system overrides as well as additional CSS styles.
|
|
238
|
-
*/
|
|
239
|
-
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
|
|
240
|
-
} : void 0;
|
|
241
|
-
var FormLabel$1 = FormLabel;
|
|
242
|
-
|
|
243
|
-
function getInputLabelUtilityClasses(slot) {
|
|
244
|
-
return generateUtilityClass('MuiInputLabel', slot);
|
|
245
|
-
}
|
|
246
|
-
generateUtilityClasses('MuiInputLabel', ['root', 'focused', 'disabled', 'error', 'required', 'asterisk', 'formControl', 'sizeSmall', 'shrink', 'animated', 'standard', 'filled', 'outlined']);
|
|
247
|
-
|
|
248
|
-
const _excluded$4 = ["disableAnimation", "margin", "shrink", "variant", "className"];
|
|
249
|
-
const useUtilityClasses$3 = ownerState => {
|
|
250
|
-
const {
|
|
251
|
-
classes,
|
|
252
|
-
formControl,
|
|
253
|
-
size,
|
|
254
|
-
shrink,
|
|
255
|
-
disableAnimation,
|
|
256
|
-
variant,
|
|
257
|
-
required
|
|
258
|
-
} = ownerState;
|
|
259
|
-
const slots = {
|
|
260
|
-
root: ['root', formControl && 'formControl', !disableAnimation && 'animated', shrink && 'shrink', size && size !== 'normal' && `size${capitalize(size)}`, variant],
|
|
261
|
-
asterisk: [required && 'asterisk']
|
|
262
|
-
};
|
|
263
|
-
const composedClasses = composeClasses(slots, getInputLabelUtilityClasses, classes);
|
|
264
|
-
return _extends$1({}, classes, composedClasses);
|
|
265
|
-
};
|
|
266
|
-
const InputLabelRoot = styled$1(FormLabel$1, {
|
|
267
|
-
shouldForwardProp: prop => rootShouldForwardProp(prop) || prop === 'classes',
|
|
268
|
-
name: 'MuiInputLabel',
|
|
269
|
-
slot: 'Root',
|
|
270
|
-
overridesResolver: (props, styles) => {
|
|
271
|
-
const {
|
|
272
|
-
ownerState
|
|
273
|
-
} = props;
|
|
274
|
-
return [{
|
|
275
|
-
[`& .${formLabelClasses$1.asterisk}`]: styles.asterisk
|
|
276
|
-
}, 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]];
|
|
277
|
-
}
|
|
278
|
-
})(({
|
|
279
|
-
theme,
|
|
280
|
-
ownerState
|
|
281
|
-
}) => _extends$1({
|
|
282
|
-
display: 'block',
|
|
283
|
-
transformOrigin: 'top left',
|
|
284
|
-
whiteSpace: 'nowrap',
|
|
285
|
-
overflow: 'hidden',
|
|
286
|
-
textOverflow: 'ellipsis',
|
|
287
|
-
maxWidth: '100%'
|
|
288
|
-
}, ownerState.formControl && {
|
|
289
|
-
position: 'absolute',
|
|
290
|
-
left: 0,
|
|
291
|
-
top: 0,
|
|
292
|
-
// slight alteration to spec spacing to match visual spec result
|
|
293
|
-
transform: 'translate(0, 20px) scale(1)'
|
|
294
|
-
}, ownerState.size === 'small' && {
|
|
295
|
-
// Compensation for the `Input.inputSizeSmall` style.
|
|
296
|
-
transform: 'translate(0, 17px) scale(1)'
|
|
297
|
-
}, ownerState.shrink && {
|
|
298
|
-
transform: 'translate(0, -1.5px) scale(0.75)',
|
|
299
|
-
transformOrigin: 'top left',
|
|
300
|
-
maxWidth: '133%'
|
|
301
|
-
}, !ownerState.disableAnimation && {
|
|
302
|
-
transition: theme.transitions.create(['color', 'transform', 'max-width'], {
|
|
303
|
-
duration: theme.transitions.duration.shorter,
|
|
304
|
-
easing: theme.transitions.easing.easeOut
|
|
305
|
-
})
|
|
306
|
-
}, ownerState.variant === 'filled' && _extends$1({
|
|
307
|
-
// Chrome's autofill feature gives the input field a yellow background.
|
|
308
|
-
// Since the input field is behind the label in the HTML tree,
|
|
309
|
-
// the input field is drawn last and hides the label with an opaque background color.
|
|
310
|
-
// zIndex: 1 will raise the label above opaque background-colors of input.
|
|
311
|
-
zIndex: 1,
|
|
312
|
-
pointerEvents: 'none',
|
|
313
|
-
transform: 'translate(12px, 16px) scale(1)',
|
|
314
|
-
maxWidth: 'calc(100% - 24px)'
|
|
315
|
-
}, ownerState.size === 'small' && {
|
|
316
|
-
transform: 'translate(12px, 13px) scale(1)'
|
|
317
|
-
}, ownerState.shrink && _extends$1({
|
|
318
|
-
userSelect: 'none',
|
|
319
|
-
pointerEvents: 'auto',
|
|
320
|
-
transform: 'translate(12px, 7px) scale(0.75)',
|
|
321
|
-
maxWidth: 'calc(133% - 24px)'
|
|
322
|
-
}, ownerState.size === 'small' && {
|
|
323
|
-
transform: 'translate(12px, 4px) scale(0.75)'
|
|
324
|
-
})), ownerState.variant === 'outlined' && _extends$1({
|
|
325
|
-
// see comment above on filled.zIndex
|
|
326
|
-
zIndex: 1,
|
|
327
|
-
pointerEvents: 'none',
|
|
328
|
-
transform: 'translate(14px, 16px) scale(1)',
|
|
329
|
-
maxWidth: 'calc(100% - 24px)'
|
|
330
|
-
}, ownerState.size === 'small' && {
|
|
331
|
-
transform: 'translate(14px, 9px) scale(1)'
|
|
332
|
-
}, ownerState.shrink && {
|
|
333
|
-
userSelect: 'none',
|
|
334
|
-
pointerEvents: 'auto',
|
|
335
|
-
// Theoretically, we should have (8+5)*2/0.75 = 34px
|
|
336
|
-
// but it feels a better when it bleeds a bit on the left, so 32px.
|
|
337
|
-
maxWidth: 'calc(133% - 32px)',
|
|
338
|
-
transform: 'translate(14px, -9px) scale(0.75)'
|
|
339
|
-
})));
|
|
340
|
-
const InputLabel = /*#__PURE__*/React.forwardRef(function InputLabel(inProps, ref) {
|
|
341
|
-
const props = useDefaultProps({
|
|
342
|
-
name: 'MuiInputLabel',
|
|
343
|
-
props: inProps
|
|
344
|
-
});
|
|
345
|
-
const {
|
|
346
|
-
disableAnimation = false,
|
|
347
|
-
shrink: shrinkProp,
|
|
348
|
-
className
|
|
349
|
-
} = props,
|
|
350
|
-
other = _objectWithoutPropertiesLoose$1(props, _excluded$4);
|
|
351
|
-
const muiFormControl = useFormControl();
|
|
352
|
-
let shrink = shrinkProp;
|
|
353
|
-
if (typeof shrink === 'undefined' && muiFormControl) {
|
|
354
|
-
shrink = muiFormControl.filled || muiFormControl.focused || muiFormControl.adornedStart;
|
|
355
|
-
}
|
|
356
|
-
const fcs = formControlState({
|
|
357
|
-
props,
|
|
358
|
-
muiFormControl,
|
|
359
|
-
states: ['size', 'variant', 'required', 'focused']
|
|
360
|
-
});
|
|
361
|
-
const ownerState = _extends$1({}, props, {
|
|
362
|
-
disableAnimation,
|
|
363
|
-
formControl: muiFormControl,
|
|
364
|
-
shrink,
|
|
365
|
-
size: fcs.size,
|
|
366
|
-
variant: fcs.variant,
|
|
367
|
-
required: fcs.required,
|
|
368
|
-
focused: fcs.focused
|
|
369
|
-
});
|
|
370
|
-
const classes = useUtilityClasses$3(ownerState);
|
|
371
|
-
return /*#__PURE__*/jsxRuntimeExports.jsx(InputLabelRoot, _extends$1({
|
|
372
|
-
"data-shrink": shrink,
|
|
373
|
-
ownerState: ownerState,
|
|
374
|
-
ref: ref,
|
|
375
|
-
className: clsx$1(classes.root, className)
|
|
376
|
-
}, other, {
|
|
377
|
-
classes: classes
|
|
378
|
-
}));
|
|
379
|
-
});
|
|
380
|
-
process.env.NODE_ENV !== "production" ? InputLabel.propTypes /* remove-proptypes */ = {
|
|
381
|
-
// ┌────────────────────────────── Warning ──────────────────────────────┐
|
|
382
|
-
// │ These PropTypes are generated from the TypeScript type definitions. │
|
|
383
|
-
// │ To update them, edit the d.ts file and run `pnpm proptypes`. │
|
|
384
|
-
// └─────────────────────────────────────────────────────────────────────┘
|
|
385
|
-
/**
|
|
386
|
-
* The content of the component.
|
|
387
|
-
*/
|
|
388
|
-
children: PropTypes.node,
|
|
389
|
-
/**
|
|
390
|
-
* Override or extend the styles applied to the component.
|
|
391
|
-
*/
|
|
392
|
-
classes: PropTypes.object,
|
|
393
|
-
/**
|
|
394
|
-
* @ignore
|
|
395
|
-
*/
|
|
396
|
-
className: PropTypes.string,
|
|
397
|
-
/**
|
|
398
|
-
* The color of the component.
|
|
399
|
-
* It supports both default and custom theme colors, which can be added as shown in the
|
|
400
|
-
* [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
|
|
401
|
-
*/
|
|
402
|
-
color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['error', 'info', 'primary', 'secondary', 'success', 'warning']), PropTypes.string]),
|
|
403
|
-
/**
|
|
404
|
-
* If `true`, the transition animation is disabled.
|
|
405
|
-
* @default false
|
|
406
|
-
*/
|
|
407
|
-
disableAnimation: PropTypes.bool,
|
|
408
|
-
/**
|
|
409
|
-
* If `true`, the component is disabled.
|
|
410
|
-
*/
|
|
411
|
-
disabled: PropTypes.bool,
|
|
412
|
-
/**
|
|
413
|
-
* If `true`, the label is displayed in an error state.
|
|
414
|
-
*/
|
|
415
|
-
error: PropTypes.bool,
|
|
416
|
-
/**
|
|
417
|
-
* If `true`, the `input` of this label is focused.
|
|
418
|
-
*/
|
|
419
|
-
focused: PropTypes.bool,
|
|
420
|
-
/**
|
|
421
|
-
* If `dense`, will adjust vertical spacing. This is normally obtained via context from
|
|
422
|
-
* FormControl.
|
|
423
|
-
*/
|
|
424
|
-
margin: PropTypes.oneOf(['dense']),
|
|
425
|
-
/**
|
|
426
|
-
* if `true`, the label will indicate that the `input` is required.
|
|
427
|
-
*/
|
|
428
|
-
required: PropTypes.bool,
|
|
429
|
-
/**
|
|
430
|
-
* If `true`, the label is shrunk.
|
|
431
|
-
*/
|
|
432
|
-
shrink: PropTypes.bool,
|
|
433
|
-
/**
|
|
434
|
-
* The size of the component.
|
|
435
|
-
* @default 'normal'
|
|
436
|
-
*/
|
|
437
|
-
size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['normal', 'small']), PropTypes.string]),
|
|
438
|
-
/**
|
|
439
|
-
* The system prop that allows defining system overrides as well as additional CSS styles.
|
|
440
|
-
*/
|
|
441
|
-
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
|
|
442
|
-
/**
|
|
443
|
-
* The variant to use.
|
|
444
|
-
*/
|
|
445
|
-
variant: PropTypes.oneOf(['filled', 'outlined', 'standard'])
|
|
446
|
-
} : void 0;
|
|
447
|
-
var InputLabel$1 = InputLabel;
|
|
448
|
-
|
|
449
|
-
function getFormControlUtilityClasses(slot) {
|
|
450
|
-
return generateUtilityClass('MuiFormControl', slot);
|
|
451
|
-
}
|
|
452
|
-
generateUtilityClasses('MuiFormControl', ['root', 'marginNone', 'marginNormal', 'marginDense', 'fullWidth', 'disabled']);
|
|
453
|
-
|
|
454
|
-
const _excluded$3 = ["children", "className", "color", "component", "disabled", "error", "focused", "fullWidth", "hiddenLabel", "margin", "required", "size", "variant"];
|
|
455
|
-
const useUtilityClasses$2 = ownerState => {
|
|
456
|
-
const {
|
|
457
|
-
classes,
|
|
458
|
-
margin,
|
|
459
|
-
fullWidth
|
|
460
|
-
} = ownerState;
|
|
461
|
-
const slots = {
|
|
462
|
-
root: ['root', margin !== 'none' && `margin${capitalize(margin)}`, fullWidth && 'fullWidth']
|
|
463
|
-
};
|
|
464
|
-
return composeClasses(slots, getFormControlUtilityClasses, classes);
|
|
465
|
-
};
|
|
466
|
-
const FormControlRoot = styled$1('div', {
|
|
467
|
-
name: 'MuiFormControl',
|
|
468
|
-
slot: 'Root',
|
|
469
|
-
overridesResolver: ({
|
|
470
|
-
ownerState
|
|
471
|
-
}, styles) => {
|
|
472
|
-
return _extends$1({}, styles.root, styles[`margin${capitalize(ownerState.margin)}`], ownerState.fullWidth && styles.fullWidth);
|
|
473
|
-
}
|
|
474
|
-
})(({
|
|
475
|
-
ownerState
|
|
476
|
-
}) => _extends$1({
|
|
477
|
-
display: 'inline-flex',
|
|
478
|
-
flexDirection: 'column',
|
|
479
|
-
position: 'relative',
|
|
480
|
-
// Reset fieldset default style.
|
|
481
|
-
minWidth: 0,
|
|
482
|
-
padding: 0,
|
|
483
|
-
margin: 0,
|
|
484
|
-
border: 0,
|
|
485
|
-
verticalAlign: 'top'
|
|
486
|
-
}, ownerState.margin === 'normal' && {
|
|
487
|
-
marginTop: 16,
|
|
488
|
-
marginBottom: 8
|
|
489
|
-
}, ownerState.margin === 'dense' && {
|
|
490
|
-
marginTop: 8,
|
|
491
|
-
marginBottom: 4
|
|
492
|
-
}, ownerState.fullWidth && {
|
|
493
|
-
width: '100%'
|
|
494
|
-
}));
|
|
495
|
-
|
|
496
|
-
/**
|
|
497
|
-
* Provides context such as filled/focused/error/required for form inputs.
|
|
498
|
-
* Relying on the context provides high flexibility and ensures that the state always stays
|
|
499
|
-
* consistent across the children of the `FormControl`.
|
|
500
|
-
* This context is used by the following components:
|
|
501
|
-
*
|
|
502
|
-
* - FormLabel
|
|
503
|
-
* - FormHelperText
|
|
504
|
-
* - Input
|
|
505
|
-
* - InputLabel
|
|
506
|
-
*
|
|
507
|
-
* You can find one composition example below and more going to [the demos](/material-ui/react-text-field/#components).
|
|
508
|
-
*
|
|
509
|
-
* ```jsx
|
|
510
|
-
* <FormControl>
|
|
511
|
-
* <InputLabel htmlFor="my-input">Email address</InputLabel>
|
|
512
|
-
* <Input id="my-input" aria-describedby="my-helper-text" />
|
|
513
|
-
* <FormHelperText id="my-helper-text">We'll never share your email.</FormHelperText>
|
|
514
|
-
* </FormControl>
|
|
515
|
-
* ```
|
|
516
|
-
*
|
|
517
|
-
* ⚠️ Only one `InputBase` can be used within a FormControl because it creates visual inconsistencies.
|
|
518
|
-
* For instance, only one input can be focused at the same time, the state shouldn't be shared.
|
|
519
|
-
*/
|
|
520
|
-
const FormControl = /*#__PURE__*/React.forwardRef(function FormControl(inProps, ref) {
|
|
521
|
-
const props = useDefaultProps({
|
|
522
|
-
props: inProps,
|
|
523
|
-
name: 'MuiFormControl'
|
|
524
|
-
});
|
|
525
|
-
const {
|
|
526
|
-
children,
|
|
527
|
-
className,
|
|
528
|
-
color = 'primary',
|
|
529
|
-
component = 'div',
|
|
530
|
-
disabled = false,
|
|
531
|
-
error = false,
|
|
532
|
-
focused: visuallyFocused,
|
|
533
|
-
fullWidth = false,
|
|
534
|
-
hiddenLabel = false,
|
|
535
|
-
margin = 'none',
|
|
536
|
-
required = false,
|
|
537
|
-
size = 'medium',
|
|
538
|
-
variant = 'outlined'
|
|
539
|
-
} = props,
|
|
540
|
-
other = _objectWithoutPropertiesLoose$1(props, _excluded$3);
|
|
541
|
-
const ownerState = _extends$1({}, props, {
|
|
542
|
-
color,
|
|
543
|
-
component,
|
|
544
|
-
disabled,
|
|
545
|
-
error,
|
|
546
|
-
fullWidth,
|
|
547
|
-
hiddenLabel,
|
|
548
|
-
margin,
|
|
549
|
-
required,
|
|
550
|
-
size,
|
|
551
|
-
variant
|
|
552
|
-
});
|
|
553
|
-
const classes = useUtilityClasses$2(ownerState);
|
|
554
|
-
const [adornedStart, setAdornedStart] = React.useState(() => {
|
|
555
|
-
// We need to iterate through the children and find the Input in order
|
|
556
|
-
// to fully support server-side rendering.
|
|
557
|
-
let initialAdornedStart = false;
|
|
558
|
-
if (children) {
|
|
559
|
-
React.Children.forEach(children, child => {
|
|
560
|
-
if (!isMuiElement(child, ['Input', 'Select'])) {
|
|
561
|
-
return;
|
|
562
|
-
}
|
|
563
|
-
const input = isMuiElement(child, ['Select']) ? child.props.input : child;
|
|
564
|
-
if (input && isAdornedStart(input.props)) {
|
|
565
|
-
initialAdornedStart = true;
|
|
566
|
-
}
|
|
567
|
-
});
|
|
568
|
-
}
|
|
569
|
-
return initialAdornedStart;
|
|
570
|
-
});
|
|
571
|
-
const [filled, setFilled] = React.useState(() => {
|
|
572
|
-
// We need to iterate through the children and find the Input in order
|
|
573
|
-
// to fully support server-side rendering.
|
|
574
|
-
let initialFilled = false;
|
|
575
|
-
if (children) {
|
|
576
|
-
React.Children.forEach(children, child => {
|
|
577
|
-
if (!isMuiElement(child, ['Input', 'Select'])) {
|
|
578
|
-
return;
|
|
579
|
-
}
|
|
580
|
-
if (isFilled(child.props, true) || isFilled(child.props.inputProps, true)) {
|
|
581
|
-
initialFilled = true;
|
|
582
|
-
}
|
|
583
|
-
});
|
|
584
|
-
}
|
|
585
|
-
return initialFilled;
|
|
586
|
-
});
|
|
587
|
-
const [focusedState, setFocused] = React.useState(false);
|
|
588
|
-
if (disabled && focusedState) {
|
|
589
|
-
setFocused(false);
|
|
590
|
-
}
|
|
591
|
-
const focused = visuallyFocused !== undefined && !disabled ? visuallyFocused : focusedState;
|
|
592
|
-
let registerEffect;
|
|
593
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
594
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
595
|
-
const registeredInput = React.useRef(false);
|
|
596
|
-
registerEffect = () => {
|
|
597
|
-
if (registeredInput.current) {
|
|
598
|
-
console.error(['MUI: There are multiple `InputBase` components inside a FormControl.', 'This creates visual inconsistencies, only use one `InputBase`.'].join('\n'));
|
|
599
|
-
}
|
|
600
|
-
registeredInput.current = true;
|
|
601
|
-
return () => {
|
|
602
|
-
registeredInput.current = false;
|
|
603
|
-
};
|
|
604
|
-
};
|
|
605
|
-
}
|
|
606
|
-
const childContext = React.useMemo(() => {
|
|
607
|
-
return {
|
|
608
|
-
adornedStart,
|
|
609
|
-
setAdornedStart,
|
|
610
|
-
color,
|
|
611
|
-
disabled,
|
|
612
|
-
error,
|
|
613
|
-
filled,
|
|
614
|
-
focused,
|
|
615
|
-
fullWidth,
|
|
616
|
-
hiddenLabel,
|
|
617
|
-
size,
|
|
618
|
-
onBlur: () => {
|
|
619
|
-
setFocused(false);
|
|
620
|
-
},
|
|
621
|
-
onEmpty: () => {
|
|
622
|
-
setFilled(false);
|
|
623
|
-
},
|
|
624
|
-
onFilled: () => {
|
|
625
|
-
setFilled(true);
|
|
626
|
-
},
|
|
627
|
-
onFocus: () => {
|
|
628
|
-
setFocused(true);
|
|
629
|
-
},
|
|
630
|
-
registerEffect,
|
|
631
|
-
required,
|
|
632
|
-
variant
|
|
633
|
-
};
|
|
634
|
-
}, [adornedStart, color, disabled, error, filled, focused, fullWidth, hiddenLabel, registerEffect, required, size, variant]);
|
|
635
|
-
return /*#__PURE__*/jsxRuntimeExports.jsx(FormControlContext.Provider, {
|
|
636
|
-
value: childContext,
|
|
637
|
-
children: /*#__PURE__*/jsxRuntimeExports.jsx(FormControlRoot, _extends$1({
|
|
638
|
-
as: component,
|
|
639
|
-
ownerState: ownerState,
|
|
640
|
-
className: clsx$1(classes.root, className),
|
|
641
|
-
ref: ref
|
|
642
|
-
}, other, {
|
|
643
|
-
children: children
|
|
644
|
-
}))
|
|
645
|
-
});
|
|
646
|
-
});
|
|
647
|
-
process.env.NODE_ENV !== "production" ? FormControl.propTypes /* remove-proptypes */ = {
|
|
648
|
-
// ┌────────────────────────────── Warning ──────────────────────────────┐
|
|
649
|
-
// │ These PropTypes are generated from the TypeScript type definitions. │
|
|
650
|
-
// │ To update them, edit the d.ts file and run `pnpm proptypes`. │
|
|
651
|
-
// └─────────────────────────────────────────────────────────────────────┘
|
|
652
|
-
/**
|
|
653
|
-
* The content of the component.
|
|
654
|
-
*/
|
|
655
|
-
children: PropTypes.node,
|
|
656
|
-
/**
|
|
657
|
-
* Override or extend the styles applied to the component.
|
|
658
|
-
*/
|
|
659
|
-
classes: PropTypes.object,
|
|
660
|
-
/**
|
|
661
|
-
* @ignore
|
|
662
|
-
*/
|
|
663
|
-
className: PropTypes.string,
|
|
664
|
-
/**
|
|
665
|
-
* The color of the component.
|
|
666
|
-
* It supports both default and custom theme colors, which can be added as shown in the
|
|
667
|
-
* [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
|
|
668
|
-
* @default 'primary'
|
|
669
|
-
*/
|
|
670
|
-
color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['primary', 'secondary', 'error', 'info', 'success', 'warning']), PropTypes.string]),
|
|
671
|
-
/**
|
|
672
|
-
* The component used for the root node.
|
|
673
|
-
* Either a string to use a HTML element or a component.
|
|
674
|
-
*/
|
|
675
|
-
component: PropTypes.elementType,
|
|
676
|
-
/**
|
|
677
|
-
* If `true`, the label, input and helper text should be displayed in a disabled state.
|
|
678
|
-
* @default false
|
|
679
|
-
*/
|
|
680
|
-
disabled: PropTypes.bool,
|
|
681
|
-
/**
|
|
682
|
-
* If `true`, the label is displayed in an error state.
|
|
683
|
-
* @default false
|
|
684
|
-
*/
|
|
685
|
-
error: PropTypes.bool,
|
|
686
|
-
/**
|
|
687
|
-
* If `true`, the component is displayed in focused state.
|
|
688
|
-
*/
|
|
689
|
-
focused: PropTypes.bool,
|
|
690
|
-
/**
|
|
691
|
-
* If `true`, the component will take up the full width of its container.
|
|
692
|
-
* @default false
|
|
693
|
-
*/
|
|
694
|
-
fullWidth: PropTypes.bool,
|
|
695
|
-
/**
|
|
696
|
-
* If `true`, the label is hidden.
|
|
697
|
-
* This is used to increase density for a `FilledInput`.
|
|
698
|
-
* Be sure to add `aria-label` to the `input` element.
|
|
699
|
-
* @default false
|
|
700
|
-
*/
|
|
701
|
-
hiddenLabel: PropTypes.bool,
|
|
702
|
-
/**
|
|
703
|
-
* If `dense` or `normal`, will adjust vertical spacing of this and contained components.
|
|
704
|
-
* @default 'none'
|
|
705
|
-
*/
|
|
706
|
-
margin: PropTypes.oneOf(['dense', 'none', 'normal']),
|
|
707
|
-
/**
|
|
708
|
-
* If `true`, the label will indicate that the `input` is required.
|
|
709
|
-
* @default false
|
|
710
|
-
*/
|
|
711
|
-
required: PropTypes.bool,
|
|
712
|
-
/**
|
|
713
|
-
* The size of the component.
|
|
714
|
-
* @default 'medium'
|
|
715
|
-
*/
|
|
716
|
-
size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['medium', 'small']), PropTypes.string]),
|
|
717
|
-
/**
|
|
718
|
-
* The system prop that allows defining system overrides as well as additional CSS styles.
|
|
719
|
-
*/
|
|
720
|
-
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
|
|
721
|
-
/**
|
|
722
|
-
* The variant to use.
|
|
723
|
-
* @default 'outlined'
|
|
724
|
-
*/
|
|
725
|
-
variant: PropTypes.oneOf(['filled', 'outlined', 'standard'])
|
|
726
|
-
} : void 0;
|
|
727
|
-
var FormControl$1 = FormControl;
|
|
728
|
-
|
|
729
|
-
function getFormHelperTextUtilityClasses(slot) {
|
|
730
|
-
return generateUtilityClass('MuiFormHelperText', slot);
|
|
731
|
-
}
|
|
732
|
-
const formHelperTextClasses = generateUtilityClasses('MuiFormHelperText', ['root', 'error', 'disabled', 'sizeSmall', 'sizeMedium', 'contained', 'focused', 'filled', 'required']);
|
|
733
|
-
var formHelperTextClasses$1 = formHelperTextClasses;
|
|
734
|
-
|
|
735
|
-
var _span;
|
|
736
|
-
const _excluded$2 = ["children", "className", "component", "disabled", "error", "filled", "focused", "margin", "required", "variant"];
|
|
737
|
-
const useUtilityClasses$1 = ownerState => {
|
|
738
|
-
const {
|
|
739
|
-
classes,
|
|
740
|
-
contained,
|
|
741
|
-
size,
|
|
742
|
-
disabled,
|
|
743
|
-
error,
|
|
744
|
-
filled,
|
|
745
|
-
focused,
|
|
746
|
-
required
|
|
747
|
-
} = ownerState;
|
|
748
|
-
const slots = {
|
|
749
|
-
root: ['root', disabled && 'disabled', error && 'error', size && `size${capitalize(size)}`, contained && 'contained', focused && 'focused', filled && 'filled', required && 'required']
|
|
750
|
-
};
|
|
751
|
-
return composeClasses(slots, getFormHelperTextUtilityClasses, classes);
|
|
752
|
-
};
|
|
753
|
-
const FormHelperTextRoot = styled$1('p', {
|
|
754
|
-
name: 'MuiFormHelperText',
|
|
755
|
-
slot: 'Root',
|
|
756
|
-
overridesResolver: (props, styles) => {
|
|
757
|
-
const {
|
|
758
|
-
ownerState
|
|
759
|
-
} = props;
|
|
760
|
-
return [styles.root, ownerState.size && styles[`size${capitalize(ownerState.size)}`], ownerState.contained && styles.contained, ownerState.filled && styles.filled];
|
|
761
|
-
}
|
|
762
|
-
})(({
|
|
763
|
-
theme,
|
|
764
|
-
ownerState
|
|
765
|
-
}) => _extends$1({
|
|
766
|
-
color: (theme.vars || theme).palette.text.secondary
|
|
767
|
-
}, theme.typography.caption, {
|
|
768
|
-
textAlign: 'left',
|
|
769
|
-
marginTop: 3,
|
|
770
|
-
marginRight: 0,
|
|
771
|
-
marginBottom: 0,
|
|
772
|
-
marginLeft: 0,
|
|
773
|
-
[`&.${formHelperTextClasses$1.disabled}`]: {
|
|
774
|
-
color: (theme.vars || theme).palette.text.disabled
|
|
775
|
-
},
|
|
776
|
-
[`&.${formHelperTextClasses$1.error}`]: {
|
|
777
|
-
color: (theme.vars || theme).palette.error.main
|
|
778
|
-
}
|
|
779
|
-
}, ownerState.size === 'small' && {
|
|
780
|
-
marginTop: 4
|
|
781
|
-
}, ownerState.contained && {
|
|
782
|
-
marginLeft: 14,
|
|
783
|
-
marginRight: 14
|
|
784
|
-
}));
|
|
785
|
-
const FormHelperText = /*#__PURE__*/React.forwardRef(function FormHelperText(inProps, ref) {
|
|
786
|
-
const props = useDefaultProps({
|
|
787
|
-
props: inProps,
|
|
788
|
-
name: 'MuiFormHelperText'
|
|
789
|
-
});
|
|
790
|
-
const {
|
|
791
|
-
children,
|
|
792
|
-
className,
|
|
793
|
-
component = 'p'
|
|
794
|
-
} = props,
|
|
795
|
-
other = _objectWithoutPropertiesLoose$1(props, _excluded$2);
|
|
796
|
-
const muiFormControl = useFormControl();
|
|
797
|
-
const fcs = formControlState({
|
|
798
|
-
props,
|
|
799
|
-
muiFormControl,
|
|
800
|
-
states: ['variant', 'size', 'disabled', 'error', 'filled', 'focused', 'required']
|
|
801
|
-
});
|
|
802
|
-
const ownerState = _extends$1({}, props, {
|
|
803
|
-
component,
|
|
804
|
-
contained: fcs.variant === 'filled' || fcs.variant === 'outlined',
|
|
805
|
-
variant: fcs.variant,
|
|
806
|
-
size: fcs.size,
|
|
807
|
-
disabled: fcs.disabled,
|
|
808
|
-
error: fcs.error,
|
|
809
|
-
filled: fcs.filled,
|
|
810
|
-
focused: fcs.focused,
|
|
811
|
-
required: fcs.required
|
|
812
|
-
});
|
|
813
|
-
const classes = useUtilityClasses$1(ownerState);
|
|
814
|
-
return /*#__PURE__*/jsxRuntimeExports.jsx(FormHelperTextRoot, _extends$1({
|
|
815
|
-
as: component,
|
|
816
|
-
ownerState: ownerState,
|
|
817
|
-
className: clsx$1(classes.root, className),
|
|
818
|
-
ref: ref
|
|
819
|
-
}, other, {
|
|
820
|
-
children: children === ' ' ? // notranslate needed while Google Translate will not fix zero-width space issue
|
|
821
|
-
_span || (_span = /*#__PURE__*/jsxRuntimeExports.jsx("span", {
|
|
822
|
-
className: "notranslate",
|
|
823
|
-
children: "\u200B"
|
|
824
|
-
})) : children
|
|
825
|
-
}));
|
|
826
|
-
});
|
|
827
|
-
process.env.NODE_ENV !== "production" ? FormHelperText.propTypes /* remove-proptypes */ = {
|
|
828
|
-
// ┌────────────────────────────── Warning ──────────────────────────────┐
|
|
829
|
-
// │ These PropTypes are generated from the TypeScript type definitions. │
|
|
830
|
-
// │ To update them, edit the d.ts file and run `pnpm proptypes`. │
|
|
831
|
-
// └─────────────────────────────────────────────────────────────────────┘
|
|
832
|
-
/**
|
|
833
|
-
* The content of the component.
|
|
834
|
-
*
|
|
835
|
-
* If `' '` is provided, the component reserves one line height for displaying a future message.
|
|
836
|
-
*/
|
|
837
|
-
children: PropTypes.node,
|
|
838
|
-
/**
|
|
839
|
-
* Override or extend the styles applied to the component.
|
|
840
|
-
*/
|
|
841
|
-
classes: PropTypes.object,
|
|
842
|
-
/**
|
|
843
|
-
* @ignore
|
|
844
|
-
*/
|
|
845
|
-
className: PropTypes.string,
|
|
846
|
-
/**
|
|
847
|
-
* The component used for the root node.
|
|
848
|
-
* Either a string to use a HTML element or a component.
|
|
849
|
-
*/
|
|
850
|
-
component: PropTypes.elementType,
|
|
851
|
-
/**
|
|
852
|
-
* If `true`, the helper text should be displayed in a disabled state.
|
|
853
|
-
*/
|
|
854
|
-
disabled: PropTypes.bool,
|
|
855
|
-
/**
|
|
856
|
-
* If `true`, helper text should be displayed in an error state.
|
|
857
|
-
*/
|
|
858
|
-
error: PropTypes.bool,
|
|
859
|
-
/**
|
|
860
|
-
* If `true`, the helper text should use filled classes key.
|
|
861
|
-
*/
|
|
862
|
-
filled: PropTypes.bool,
|
|
863
|
-
/**
|
|
864
|
-
* If `true`, the helper text should use focused classes key.
|
|
865
|
-
*/
|
|
866
|
-
focused: PropTypes.bool,
|
|
867
|
-
/**
|
|
868
|
-
* If `dense`, will adjust vertical spacing. This is normally obtained via context from
|
|
869
|
-
* FormControl.
|
|
870
|
-
*/
|
|
871
|
-
margin: PropTypes.oneOf(['dense']),
|
|
872
|
-
/**
|
|
873
|
-
* If `true`, the helper text should use required classes key.
|
|
874
|
-
*/
|
|
875
|
-
required: PropTypes.bool,
|
|
876
|
-
/**
|
|
877
|
-
* The system prop that allows defining system overrides as well as additional CSS styles.
|
|
878
|
-
*/
|
|
879
|
-
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
|
|
880
|
-
/**
|
|
881
|
-
* The variant to use.
|
|
882
|
-
*/
|
|
883
|
-
variant: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['filled', 'outlined', 'standard']), PropTypes.string])
|
|
884
|
-
} : void 0;
|
|
885
|
-
var FormHelperText$1 = FormHelperText;
|
|
886
|
-
|
|
887
|
-
function getTextFieldUtilityClass(slot) {
|
|
888
|
-
return generateUtilityClass('MuiTextField', slot);
|
|
889
|
-
}
|
|
890
|
-
generateUtilityClasses('MuiTextField', ['root']);
|
|
891
|
-
|
|
892
|
-
const _excluded$1 = ["autoComplete", "autoFocus", "children", "className", "color", "defaultValue", "disabled", "error", "FormHelperTextProps", "fullWidth", "helperText", "id", "InputLabelProps", "inputProps", "InputProps", "inputRef", "label", "maxRows", "minRows", "multiline", "name", "onBlur", "onChange", "onFocus", "placeholder", "required", "rows", "select", "SelectProps", "type", "value", "variant"];
|
|
893
|
-
const variantComponent = {
|
|
894
|
-
standard: Input,
|
|
895
|
-
filled: FilledInput,
|
|
896
|
-
outlined: OutlinedInput
|
|
897
|
-
};
|
|
898
|
-
const useUtilityClasses = ownerState => {
|
|
899
|
-
const {
|
|
900
|
-
classes
|
|
901
|
-
} = ownerState;
|
|
902
|
-
const slots = {
|
|
903
|
-
root: ['root']
|
|
904
|
-
};
|
|
905
|
-
return composeClasses(slots, getTextFieldUtilityClass, classes);
|
|
906
|
-
};
|
|
907
|
-
const TextFieldRoot = styled$1(FormControl$1, {
|
|
908
|
-
name: 'MuiTextField',
|
|
909
|
-
slot: 'Root',
|
|
910
|
-
overridesResolver: (props, styles) => styles.root
|
|
911
|
-
})({});
|
|
912
|
-
|
|
913
|
-
/**
|
|
914
|
-
* The `TextField` is a convenience wrapper for the most common cases (80%).
|
|
915
|
-
* It cannot be all things to all people, otherwise the API would grow out of control.
|
|
916
|
-
*
|
|
917
|
-
* ## Advanced Configuration
|
|
918
|
-
*
|
|
919
|
-
* It's important to understand that the text field is a simple abstraction
|
|
920
|
-
* on top of the following components:
|
|
921
|
-
*
|
|
922
|
-
* - [FormControl](/material-ui/api/form-control/)
|
|
923
|
-
* - [InputLabel](/material-ui/api/input-label/)
|
|
924
|
-
* - [FilledInput](/material-ui/api/filled-input/)
|
|
925
|
-
* - [OutlinedInput](/material-ui/api/outlined-input/)
|
|
926
|
-
* - [Input](/material-ui/api/input/)
|
|
927
|
-
* - [FormHelperText](/material-ui/api/form-helper-text/)
|
|
928
|
-
*
|
|
929
|
-
* If you wish to alter the props applied to the `input` element, you can do so as follows:
|
|
930
|
-
*
|
|
931
|
-
* ```jsx
|
|
932
|
-
* const inputProps = {
|
|
933
|
-
* step: 300,
|
|
934
|
-
* };
|
|
935
|
-
*
|
|
936
|
-
* return <TextField id="time" type="time" inputProps={inputProps} />;
|
|
937
|
-
* ```
|
|
938
|
-
*
|
|
939
|
-
* For advanced cases, please look at the source of TextField by clicking on the
|
|
940
|
-
* "Edit this page" button above. Consider either:
|
|
941
|
-
*
|
|
942
|
-
* - using the upper case props for passing values directly to the components
|
|
943
|
-
* - using the underlying components directly as shown in the demos
|
|
944
|
-
*/
|
|
945
|
-
const TextField = /*#__PURE__*/React.forwardRef(function TextField(inProps, ref) {
|
|
946
|
-
const props = useDefaultProps({
|
|
947
|
-
props: inProps,
|
|
948
|
-
name: 'MuiTextField'
|
|
949
|
-
});
|
|
950
|
-
const {
|
|
951
|
-
autoComplete,
|
|
952
|
-
autoFocus = false,
|
|
953
|
-
children,
|
|
954
|
-
className,
|
|
955
|
-
color = 'primary',
|
|
956
|
-
defaultValue,
|
|
957
|
-
disabled = false,
|
|
958
|
-
error = false,
|
|
959
|
-
FormHelperTextProps,
|
|
960
|
-
fullWidth = false,
|
|
961
|
-
helperText,
|
|
962
|
-
id: idOverride,
|
|
963
|
-
InputLabelProps,
|
|
964
|
-
inputProps,
|
|
965
|
-
InputProps,
|
|
966
|
-
inputRef,
|
|
967
|
-
label,
|
|
968
|
-
maxRows,
|
|
969
|
-
minRows,
|
|
970
|
-
multiline = false,
|
|
971
|
-
name,
|
|
972
|
-
onBlur,
|
|
973
|
-
onChange,
|
|
974
|
-
onFocus,
|
|
975
|
-
placeholder,
|
|
976
|
-
required = false,
|
|
977
|
-
rows,
|
|
978
|
-
select = false,
|
|
979
|
-
SelectProps,
|
|
980
|
-
type,
|
|
981
|
-
value,
|
|
982
|
-
variant = 'outlined'
|
|
983
|
-
} = props,
|
|
984
|
-
other = _objectWithoutPropertiesLoose$1(props, _excluded$1);
|
|
985
|
-
const ownerState = _extends$1({}, props, {
|
|
986
|
-
autoFocus,
|
|
987
|
-
color,
|
|
988
|
-
disabled,
|
|
989
|
-
error,
|
|
990
|
-
fullWidth,
|
|
991
|
-
multiline,
|
|
992
|
-
required,
|
|
993
|
-
select,
|
|
994
|
-
variant
|
|
995
|
-
});
|
|
996
|
-
const classes = useUtilityClasses(ownerState);
|
|
997
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
998
|
-
if (select && !children) {
|
|
999
|
-
console.error('MUI: `children` must be passed when using the `TextField` component with `select`.');
|
|
1000
|
-
}
|
|
1001
|
-
}
|
|
1002
|
-
const InputMore = {};
|
|
1003
|
-
if (variant === 'outlined') {
|
|
1004
|
-
if (InputLabelProps && typeof InputLabelProps.shrink !== 'undefined') {
|
|
1005
|
-
InputMore.notched = InputLabelProps.shrink;
|
|
1006
|
-
}
|
|
1007
|
-
InputMore.label = label;
|
|
1008
|
-
}
|
|
1009
|
-
if (select) {
|
|
1010
|
-
// unset defaults from textbox inputs
|
|
1011
|
-
if (!SelectProps || !SelectProps.native) {
|
|
1012
|
-
InputMore.id = undefined;
|
|
1013
|
-
}
|
|
1014
|
-
InputMore['aria-describedby'] = undefined;
|
|
1015
|
-
}
|
|
1016
|
-
const id = useId(idOverride);
|
|
1017
|
-
const helperTextId = helperText && id ? `${id}-helper-text` : undefined;
|
|
1018
|
-
const inputLabelId = label && id ? `${id}-label` : undefined;
|
|
1019
|
-
const InputComponent = variantComponent[variant];
|
|
1020
|
-
const InputElement = /*#__PURE__*/jsxRuntimeExports.jsx(InputComponent, _extends$1({
|
|
1021
|
-
"aria-describedby": helperTextId,
|
|
1022
|
-
autoComplete: autoComplete,
|
|
1023
|
-
autoFocus: autoFocus,
|
|
1024
|
-
defaultValue: defaultValue,
|
|
1025
|
-
fullWidth: fullWidth,
|
|
1026
|
-
multiline: multiline,
|
|
1027
|
-
name: name,
|
|
1028
|
-
rows: rows,
|
|
1029
|
-
maxRows: maxRows,
|
|
1030
|
-
minRows: minRows,
|
|
1031
|
-
type: type,
|
|
1032
|
-
value: value,
|
|
1033
|
-
id: id,
|
|
1034
|
-
inputRef: inputRef,
|
|
1035
|
-
onBlur: onBlur,
|
|
1036
|
-
onChange: onChange,
|
|
1037
|
-
onFocus: onFocus,
|
|
1038
|
-
placeholder: placeholder,
|
|
1039
|
-
inputProps: inputProps
|
|
1040
|
-
}, InputMore, InputProps));
|
|
1041
|
-
return /*#__PURE__*/jsxRuntimeExports.jsxs(TextFieldRoot, _extends$1({
|
|
1042
|
-
className: clsx$1(classes.root, className),
|
|
1043
|
-
disabled: disabled,
|
|
1044
|
-
error: error,
|
|
1045
|
-
fullWidth: fullWidth,
|
|
1046
|
-
ref: ref,
|
|
1047
|
-
required: required,
|
|
1048
|
-
color: color,
|
|
1049
|
-
variant: variant,
|
|
1050
|
-
ownerState: ownerState
|
|
1051
|
-
}, other, {
|
|
1052
|
-
children: [label != null && label !== '' && /*#__PURE__*/jsxRuntimeExports.jsx(InputLabel$1, _extends$1({
|
|
1053
|
-
htmlFor: id,
|
|
1054
|
-
id: inputLabelId
|
|
1055
|
-
}, InputLabelProps, {
|
|
1056
|
-
children: label
|
|
1057
|
-
})), select ? /*#__PURE__*/jsxRuntimeExports.jsx(Select, _extends$1({
|
|
1058
|
-
"aria-describedby": helperTextId,
|
|
1059
|
-
id: id,
|
|
1060
|
-
labelId: inputLabelId,
|
|
1061
|
-
value: value,
|
|
1062
|
-
input: InputElement
|
|
1063
|
-
}, SelectProps, {
|
|
1064
|
-
children: children
|
|
1065
|
-
})) : InputElement, helperText && /*#__PURE__*/jsxRuntimeExports.jsx(FormHelperText$1, _extends$1({
|
|
1066
|
-
id: helperTextId
|
|
1067
|
-
}, FormHelperTextProps, {
|
|
1068
|
-
children: helperText
|
|
1069
|
-
}))]
|
|
1070
|
-
}));
|
|
1071
|
-
});
|
|
1072
|
-
process.env.NODE_ENV !== "production" ? TextField.propTypes /* remove-proptypes */ = {
|
|
1073
|
-
// ┌────────────────────────────── Warning ──────────────────────────────┐
|
|
1074
|
-
// │ These PropTypes are generated from the TypeScript type definitions. │
|
|
1075
|
-
// │ To update them, edit the d.ts file and run `pnpm proptypes`. │
|
|
1076
|
-
// └─────────────────────────────────────────────────────────────────────┘
|
|
1077
|
-
/**
|
|
1078
|
-
* This prop helps users to fill forms faster, especially on mobile devices.
|
|
1079
|
-
* The name can be confusing, as it's more like an autofill.
|
|
1080
|
-
* You can learn more about it [following the specification](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill).
|
|
1081
|
-
*/
|
|
1082
|
-
autoComplete: PropTypes.string,
|
|
1083
|
-
/**
|
|
1084
|
-
* If `true`, the `input` element is focused during the first mount.
|
|
1085
|
-
* @default false
|
|
1086
|
-
*/
|
|
1087
|
-
autoFocus: PropTypes.bool,
|
|
1088
|
-
/**
|
|
1089
|
-
* @ignore
|
|
1090
|
-
*/
|
|
1091
|
-
children: PropTypes.node,
|
|
1092
|
-
/**
|
|
1093
|
-
* Override or extend the styles applied to the component.
|
|
1094
|
-
*/
|
|
1095
|
-
classes: PropTypes.object,
|
|
1096
|
-
/**
|
|
1097
|
-
* @ignore
|
|
1098
|
-
*/
|
|
1099
|
-
className: PropTypes.string,
|
|
1100
|
-
/**
|
|
1101
|
-
* The color of the component.
|
|
1102
|
-
* It supports both default and custom theme colors, which can be added as shown in the
|
|
1103
|
-
* [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
|
|
1104
|
-
* @default 'primary'
|
|
1105
|
-
*/
|
|
1106
|
-
color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['primary', 'secondary', 'error', 'info', 'success', 'warning']), PropTypes.string]),
|
|
1107
|
-
/**
|
|
1108
|
-
* The default value. Use when the component is not controlled.
|
|
1109
|
-
*/
|
|
1110
|
-
defaultValue: PropTypes.any,
|
|
1111
|
-
/**
|
|
1112
|
-
* If `true`, the component is disabled.
|
|
1113
|
-
* @default false
|
|
1114
|
-
*/
|
|
1115
|
-
disabled: PropTypes.bool,
|
|
1116
|
-
/**
|
|
1117
|
-
* If `true`, the label is displayed in an error state.
|
|
1118
|
-
* @default false
|
|
1119
|
-
*/
|
|
1120
|
-
error: PropTypes.bool,
|
|
1121
|
-
/**
|
|
1122
|
-
* Props applied to the [`FormHelperText`](/material-ui/api/form-helper-text/) element.
|
|
1123
|
-
*/
|
|
1124
|
-
FormHelperTextProps: PropTypes.object,
|
|
1125
|
-
/**
|
|
1126
|
-
* If `true`, the input will take up the full width of its container.
|
|
1127
|
-
* @default false
|
|
1128
|
-
*/
|
|
1129
|
-
fullWidth: PropTypes.bool,
|
|
1130
|
-
/**
|
|
1131
|
-
* The helper text content.
|
|
1132
|
-
*/
|
|
1133
|
-
helperText: PropTypes.node,
|
|
1134
|
-
/**
|
|
1135
|
-
* The id of the `input` element.
|
|
1136
|
-
* Use this prop to make `label` and `helperText` accessible for screen readers.
|
|
1137
|
-
*/
|
|
1138
|
-
id: PropTypes.string,
|
|
1139
|
-
/**
|
|
1140
|
-
* Props applied to the [`InputLabel`](/material-ui/api/input-label/) element.
|
|
1141
|
-
* Pointer events like `onClick` are enabled if and only if `shrink` is `true`.
|
|
1142
|
-
*/
|
|
1143
|
-
InputLabelProps: PropTypes.object,
|
|
1144
|
-
/**
|
|
1145
|
-
* [Attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Attributes) applied to the `input` element.
|
|
1146
|
-
*/
|
|
1147
|
-
inputProps: PropTypes.object,
|
|
1148
|
-
/**
|
|
1149
|
-
* Props applied to the Input element.
|
|
1150
|
-
* It will be a [`FilledInput`](/material-ui/api/filled-input/),
|
|
1151
|
-
* [`OutlinedInput`](/material-ui/api/outlined-input/) or [`Input`](/material-ui/api/input/)
|
|
1152
|
-
* component depending on the `variant` prop value.
|
|
1153
|
-
*/
|
|
1154
|
-
InputProps: PropTypes.object,
|
|
1155
|
-
/**
|
|
1156
|
-
* Pass a ref to the `input` element.
|
|
1157
|
-
*/
|
|
1158
|
-
inputRef: refType,
|
|
1159
|
-
/**
|
|
1160
|
-
* The label content.
|
|
1161
|
-
*/
|
|
1162
|
-
label: PropTypes.node,
|
|
1163
|
-
/**
|
|
1164
|
-
* If `dense` or `normal`, will adjust vertical spacing of this and contained components.
|
|
1165
|
-
* @default 'none'
|
|
1166
|
-
*/
|
|
1167
|
-
margin: PropTypes.oneOf(['dense', 'none', 'normal']),
|
|
1168
|
-
/**
|
|
1169
|
-
* Maximum number of rows to display when multiline option is set to true.
|
|
1170
|
-
*/
|
|
1171
|
-
maxRows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
|
1172
|
-
/**
|
|
1173
|
-
* Minimum number of rows to display when multiline option is set to true.
|
|
1174
|
-
*/
|
|
1175
|
-
minRows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
|
1176
|
-
/**
|
|
1177
|
-
* If `true`, a `textarea` element is rendered instead of an input.
|
|
1178
|
-
* @default false
|
|
1179
|
-
*/
|
|
1180
|
-
multiline: PropTypes.bool,
|
|
1181
|
-
/**
|
|
1182
|
-
* Name attribute of the `input` element.
|
|
1183
|
-
*/
|
|
1184
|
-
name: PropTypes.string,
|
|
1185
|
-
/**
|
|
1186
|
-
* @ignore
|
|
1187
|
-
*/
|
|
1188
|
-
onBlur: PropTypes.func,
|
|
1189
|
-
/**
|
|
1190
|
-
* Callback fired when the value is changed.
|
|
1191
|
-
*
|
|
1192
|
-
* @param {object} event The event source of the callback.
|
|
1193
|
-
* You can pull out the new value by accessing `event.target.value` (string).
|
|
1194
|
-
*/
|
|
1195
|
-
onChange: PropTypes.func,
|
|
1196
|
-
/**
|
|
1197
|
-
* @ignore
|
|
1198
|
-
*/
|
|
1199
|
-
onFocus: PropTypes.func,
|
|
1200
|
-
/**
|
|
1201
|
-
* The short hint displayed in the `input` before the user enters a value.
|
|
1202
|
-
*/
|
|
1203
|
-
placeholder: PropTypes.string,
|
|
1204
|
-
/**
|
|
1205
|
-
* If `true`, the label is displayed as required and the `input` element is required.
|
|
1206
|
-
* @default false
|
|
1207
|
-
*/
|
|
1208
|
-
required: PropTypes.bool,
|
|
1209
|
-
/**
|
|
1210
|
-
* Number of rows to display when multiline option is set to true.
|
|
1211
|
-
*/
|
|
1212
|
-
rows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
|
1213
|
-
/**
|
|
1214
|
-
* Render a [`Select`](/material-ui/api/select/) element while passing the Input element to `Select` as `input` parameter.
|
|
1215
|
-
* If this option is set you must pass the options of the select as children.
|
|
1216
|
-
* @default false
|
|
1217
|
-
*/
|
|
1218
|
-
select: PropTypes.bool,
|
|
1219
|
-
/**
|
|
1220
|
-
* Props applied to the [`Select`](/material-ui/api/select/) element.
|
|
1221
|
-
*/
|
|
1222
|
-
SelectProps: PropTypes.object,
|
|
1223
|
-
/**
|
|
1224
|
-
* The size of the component.
|
|
1225
|
-
*/
|
|
1226
|
-
size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['medium', 'small']), PropTypes.string]),
|
|
1227
|
-
/**
|
|
1228
|
-
* The system prop that allows defining system overrides as well as additional CSS styles.
|
|
1229
|
-
*/
|
|
1230
|
-
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
|
|
1231
|
-
/**
|
|
1232
|
-
* 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).
|
|
1233
|
-
*/
|
|
1234
|
-
type: PropTypes /* @typescript-to-proptypes-ignore */.string,
|
|
1235
|
-
/**
|
|
1236
|
-
* The value of the `input` element, required for a controlled component.
|
|
1237
|
-
*/
|
|
1238
|
-
value: PropTypes.any,
|
|
1239
|
-
/**
|
|
1240
|
-
* The variant to use.
|
|
1241
|
-
* @default 'outlined'
|
|
1242
|
-
*/
|
|
1243
|
-
variant: PropTypes.oneOf(['filled', 'outlined', 'standard'])
|
|
1244
|
-
} : void 0;
|
|
1245
|
-
var TextField$1 = TextField;
|
|
1246
16
|
|
|
1247
17
|
const SUBMIT_FILTER_STROKE_TIME = 500;
|
|
1248
18
|
const InputNumberInterval = props => {
|
|
@@ -1284,7 +54,7 @@ const InputNumberInterval = props => {
|
|
|
1284
54
|
const newLowerBound = event.target.value;
|
|
1285
55
|
updateFilterValue(newLowerBound, filterValueState[1]);
|
|
1286
56
|
};
|
|
1287
|
-
return /*#__PURE__*/React.createElement(Box
|
|
57
|
+
return /*#__PURE__*/React.createElement(Box, {
|
|
1288
58
|
sx: {
|
|
1289
59
|
display: 'inline-flex',
|
|
1290
60
|
flexDirection: 'row',
|
|
@@ -1292,7 +62,7 @@ const InputNumberInterval = props => {
|
|
|
1292
62
|
height: 48,
|
|
1293
63
|
pl: '20px'
|
|
1294
64
|
}
|
|
1295
|
-
}, /*#__PURE__*/React.createElement(TextField
|
|
65
|
+
}, /*#__PURE__*/React.createElement(TextField, {
|
|
1296
66
|
name: "lower-bound-input",
|
|
1297
67
|
placeholder: "From",
|
|
1298
68
|
label: "From",
|
|
@@ -1304,7 +74,7 @@ const InputNumberInterval = props => {
|
|
|
1304
74
|
sx: {
|
|
1305
75
|
mr: 2
|
|
1306
76
|
}
|
|
1307
|
-
}), /*#__PURE__*/React.createElement(TextField
|
|
77
|
+
}), /*#__PURE__*/React.createElement(TextField, {
|
|
1308
78
|
name: "upper-bound-input",
|
|
1309
79
|
placeholder: "To",
|
|
1310
80
|
label: "To",
|
|
@@ -1336,8 +106,8 @@ const isBetweenOperator = {
|
|
|
1336
106
|
if (typeof filterItem.value[0] !== 'number' || typeof filterItem.value[1] !== 'number') {
|
|
1337
107
|
return null;
|
|
1338
108
|
}
|
|
1339
|
-
return
|
|
1340
|
-
return
|
|
109
|
+
return value => {
|
|
110
|
+
return value !== null && value !== undefined && filterItem.value[0] <= value && value <= filterItem.value[1];
|
|
1341
111
|
};
|
|
1342
112
|
},
|
|
1343
113
|
InputComponent: InputNumberInterval
|
|
@@ -1353,14 +123,14 @@ const doesNotContain = {
|
|
|
1353
123
|
if (!filterItem.field || !filterItem.value || !filterItem.operator) {
|
|
1354
124
|
return null;
|
|
1355
125
|
}
|
|
1356
|
-
return
|
|
126
|
+
return value => {
|
|
1357
127
|
if (filterItem.value.length === 0) {
|
|
1358
128
|
return true;
|
|
1359
129
|
}
|
|
1360
|
-
if (
|
|
130
|
+
if (value == null) {
|
|
1361
131
|
return true;
|
|
1362
132
|
}
|
|
1363
|
-
if (String(
|
|
133
|
+
if (String(value).indexOf(filterItem.value) !== -1) {
|
|
1364
134
|
return false;
|
|
1365
135
|
}
|
|
1366
136
|
return true;
|
|
@@ -1377,11 +147,11 @@ const doesNotEndWithOperator = {
|
|
|
1377
147
|
if (!filterItem.field || !filterItem.value || !filterItem.operator) {
|
|
1378
148
|
return null;
|
|
1379
149
|
}
|
|
1380
|
-
return
|
|
1381
|
-
if (
|
|
150
|
+
return value => {
|
|
151
|
+
if (value == null) {
|
|
1382
152
|
return true;
|
|
1383
153
|
}
|
|
1384
|
-
return !String(
|
|
154
|
+
return !String(value).endsWith(filterItem.value);
|
|
1385
155
|
};
|
|
1386
156
|
},
|
|
1387
157
|
InputComponent: GridFilterInputValue
|
|
@@ -1395,11 +165,11 @@ const doesNotEqual = {
|
|
|
1395
165
|
if (!filterItem.field || !filterItem.value || !filterItem.operator) {
|
|
1396
166
|
return null;
|
|
1397
167
|
}
|
|
1398
|
-
return
|
|
1399
|
-
if (
|
|
168
|
+
return value => {
|
|
169
|
+
if (value == null) {
|
|
1400
170
|
return true;
|
|
1401
171
|
}
|
|
1402
|
-
if (String(
|
|
172
|
+
if (String(value) === filterItem.value) {
|
|
1403
173
|
return false;
|
|
1404
174
|
}
|
|
1405
175
|
return true;
|
|
@@ -1416,11 +186,11 @@ const doesNotHaveOperator = {
|
|
|
1416
186
|
if (!filterItem.field || !filterItem.value || !filterItem.operator) {
|
|
1417
187
|
return null;
|
|
1418
188
|
}
|
|
1419
|
-
return
|
|
1420
|
-
if (
|
|
189
|
+
return value => {
|
|
190
|
+
if (value == null) {
|
|
1421
191
|
return true;
|
|
1422
192
|
}
|
|
1423
|
-
const cellValues = Array.isArray(
|
|
193
|
+
const cellValues = Array.isArray(value) ? value : [value];
|
|
1424
194
|
return !cellValues.map(value => String(value)).includes(filterItem.value);
|
|
1425
195
|
};
|
|
1426
196
|
},
|
|
@@ -1438,11 +208,11 @@ const doesNotStartWithOperator = {
|
|
|
1438
208
|
if (!filterItem.field || !filterItem.value || !filterItem.operator) {
|
|
1439
209
|
return null;
|
|
1440
210
|
}
|
|
1441
|
-
return
|
|
1442
|
-
if (
|
|
211
|
+
return value => {
|
|
212
|
+
if (value == null) {
|
|
1443
213
|
return true;
|
|
1444
214
|
}
|
|
1445
|
-
return !String(
|
|
215
|
+
return !String(value).startsWith(filterItem.value);
|
|
1446
216
|
};
|
|
1447
217
|
},
|
|
1448
218
|
InputComponent: GridFilterInputValue
|
|
@@ -1456,11 +226,11 @@ const hasOperator = {
|
|
|
1456
226
|
if (!filterItem.field || !filterItem.value || !filterItem.operator) {
|
|
1457
227
|
return null;
|
|
1458
228
|
}
|
|
1459
|
-
return
|
|
1460
|
-
if (
|
|
229
|
+
return value => {
|
|
230
|
+
if (value == null) {
|
|
1461
231
|
return false;
|
|
1462
232
|
}
|
|
1463
|
-
const cellValues = Array.isArray(
|
|
233
|
+
const cellValues = Array.isArray(value) ? value : [value];
|
|
1464
234
|
return cellValues.map(value => String(value)).includes(filterItem.value);
|
|
1465
235
|
};
|
|
1466
236
|
},
|
|
@@ -1478,11 +248,11 @@ const hasOnlyOperator = {
|
|
|
1478
248
|
if (!filterItem.field || !filterItem.value || !filterItem.operator) {
|
|
1479
249
|
return null;
|
|
1480
250
|
}
|
|
1481
|
-
return
|
|
1482
|
-
if (
|
|
251
|
+
return value => {
|
|
252
|
+
if (value == null) {
|
|
1483
253
|
return false;
|
|
1484
254
|
}
|
|
1485
|
-
const cellValues = Array.isArray(
|
|
255
|
+
const cellValues = Array.isArray(value) ? value : [value];
|
|
1486
256
|
return cellValues.length === 1 && String(cellValues[0]) === filterItem.value;
|
|
1487
257
|
};
|
|
1488
258
|
},
|
|
@@ -1500,14 +270,14 @@ const isOperator = {
|
|
|
1500
270
|
if (!filterItem.field || !filterItem.value || !filterItem.operator) {
|
|
1501
271
|
return null;
|
|
1502
272
|
}
|
|
1503
|
-
return
|
|
1504
|
-
if (
|
|
273
|
+
return value => {
|
|
274
|
+
if (value == null) {
|
|
1505
275
|
return false;
|
|
1506
276
|
}
|
|
1507
|
-
if (Array.isArray(
|
|
277
|
+
if (Array.isArray(value)) {
|
|
1508
278
|
return false;
|
|
1509
279
|
}
|
|
1510
|
-
return String(
|
|
280
|
+
return String(value) === filterItem.value;
|
|
1511
281
|
};
|
|
1512
282
|
},
|
|
1513
283
|
InputComponent: GridFilterInputValue
|
|
@@ -1524,14 +294,14 @@ const isNotOperator = {
|
|
|
1524
294
|
if (!filterItem.field || !filterItem.value || !filterItem.operator) {
|
|
1525
295
|
return null;
|
|
1526
296
|
}
|
|
1527
|
-
return
|
|
1528
|
-
if (
|
|
297
|
+
return value => {
|
|
298
|
+
if (value == null) {
|
|
1529
299
|
return true;
|
|
1530
300
|
}
|
|
1531
|
-
if (Array.isArray(
|
|
301
|
+
if (Array.isArray(value)) {
|
|
1532
302
|
return true;
|
|
1533
303
|
}
|
|
1534
|
-
return String(
|
|
304
|
+
return String(value) !== filterItem.value;
|
|
1535
305
|
};
|
|
1536
306
|
},
|
|
1537
307
|
InputComponent: GridFilterInputValue
|
|
@@ -1548,14 +318,14 @@ const containsAnyOfOperator = {
|
|
|
1548
318
|
if (!filterItem.field || !filterItem.value || !filterItem.operator) {
|
|
1549
319
|
return null;
|
|
1550
320
|
}
|
|
1551
|
-
return
|
|
321
|
+
return value => {
|
|
1552
322
|
if (filterItem.value.length === 0) {
|
|
1553
323
|
return true;
|
|
1554
324
|
}
|
|
1555
|
-
if (
|
|
325
|
+
if (value == null) {
|
|
1556
326
|
return false;
|
|
1557
327
|
}
|
|
1558
|
-
const paramValues = Array.isArray(
|
|
328
|
+
const paramValues = Array.isArray(value) ? value : [value];
|
|
1559
329
|
let match = false;
|
|
1560
330
|
filterItem.value.forEach(filteredValue => {
|
|
1561
331
|
paramValues.forEach(paramValue => {
|
|
@@ -1578,14 +348,14 @@ const doesNotContainAnyOfOperator = {
|
|
|
1578
348
|
if (!filterItem.field || !filterItem.value || !filterItem.operator) {
|
|
1579
349
|
return null;
|
|
1580
350
|
}
|
|
1581
|
-
return
|
|
351
|
+
return value => {
|
|
1582
352
|
if (filterItem.value.length === 0) {
|
|
1583
353
|
return true;
|
|
1584
354
|
}
|
|
1585
|
-
if (
|
|
355
|
+
if (value == null) {
|
|
1586
356
|
return true;
|
|
1587
357
|
}
|
|
1588
|
-
const paramValues = Array.isArray(
|
|
358
|
+
const paramValues = Array.isArray(value) ? value : [value];
|
|
1589
359
|
for (const filteredValue of filterItem.value) {
|
|
1590
360
|
for (const paramValue of paramValues) {
|
|
1591
361
|
if (String(paramValue).indexOf(filteredValue) !== -1) {
|
|
@@ -1607,14 +377,14 @@ const doesNotEndWithAnyOfOperator = {
|
|
|
1607
377
|
if (!filterItem.field || !filterItem.value || !filterItem.operator) {
|
|
1608
378
|
return null;
|
|
1609
379
|
}
|
|
1610
|
-
return
|
|
380
|
+
return value => {
|
|
1611
381
|
if (filterItem.value.length === 0) {
|
|
1612
382
|
return true;
|
|
1613
383
|
}
|
|
1614
|
-
if (
|
|
384
|
+
if (value == null) {
|
|
1615
385
|
return true;
|
|
1616
386
|
}
|
|
1617
|
-
const paramValues = Array.isArray(
|
|
387
|
+
const paramValues = Array.isArray(value) ? value : [value];
|
|
1618
388
|
for (const filteredValue of filterItem.value) {
|
|
1619
389
|
for (const paramValue of paramValues) {
|
|
1620
390
|
if (String(paramValue).endsWith(filteredValue)) {
|
|
@@ -1636,11 +406,11 @@ const doesNotHaveAnyOf = {
|
|
|
1636
406
|
if (!filterItem.field || !filterItem.value || !Array.isArray(filterItem.value) || filterItem.value.length === 0) {
|
|
1637
407
|
return null;
|
|
1638
408
|
}
|
|
1639
|
-
return
|
|
1640
|
-
if (
|
|
409
|
+
return value => {
|
|
410
|
+
if (value == null) {
|
|
1641
411
|
return true;
|
|
1642
412
|
}
|
|
1643
|
-
const cellValues = Array.isArray(
|
|
413
|
+
const cellValues = Array.isArray(value) ? value : [value];
|
|
1644
414
|
|
|
1645
415
|
// Return true only if none of the filter values are in the cell values
|
|
1646
416
|
return filterItem.value.every(filterVal => !cellValues.map(value => String(value)).includes(filterVal));
|
|
@@ -1660,14 +430,14 @@ const doesNotStartWithAnyOfOperator = {
|
|
|
1660
430
|
if (!filterItem.field || !filterItem.value || !filterItem.operator) {
|
|
1661
431
|
return null;
|
|
1662
432
|
}
|
|
1663
|
-
return
|
|
433
|
+
return value => {
|
|
1664
434
|
if (filterItem.value.length === 0) {
|
|
1665
435
|
return true;
|
|
1666
436
|
}
|
|
1667
|
-
if (
|
|
437
|
+
if (value == null) {
|
|
1668
438
|
return true;
|
|
1669
439
|
}
|
|
1670
|
-
const paramValues = Array.isArray(
|
|
440
|
+
const paramValues = Array.isArray(value) ? value : [value];
|
|
1671
441
|
for (const filteredValue of filterItem.value) {
|
|
1672
442
|
for (const paramValue of paramValues) {
|
|
1673
443
|
if (String(paramValue).startsWith(filteredValue)) {
|
|
@@ -1689,14 +459,14 @@ const endsWithAnyOfOperator = {
|
|
|
1689
459
|
if (!filterItem.field || !filterItem.value || !filterItem.operator) {
|
|
1690
460
|
return null;
|
|
1691
461
|
}
|
|
1692
|
-
return
|
|
462
|
+
return value => {
|
|
1693
463
|
if (filterItem.value.length === 0) {
|
|
1694
464
|
return true;
|
|
1695
465
|
}
|
|
1696
|
-
if (
|
|
466
|
+
if (value == null) {
|
|
1697
467
|
return false;
|
|
1698
468
|
}
|
|
1699
|
-
const paramValues = Array.isArray(
|
|
469
|
+
const paramValues = Array.isArray(value) ? value : [value];
|
|
1700
470
|
let match = false;
|
|
1701
471
|
filterItem.value.forEach(filteredValue => {
|
|
1702
472
|
paramValues.forEach(paramValue => {
|
|
@@ -1719,14 +489,14 @@ const hasAllOfOperator = {
|
|
|
1719
489
|
if (!filterItem.field || !filterItem.value || !filterItem.operator) {
|
|
1720
490
|
return null;
|
|
1721
491
|
}
|
|
1722
|
-
return
|
|
492
|
+
return value => {
|
|
1723
493
|
if (filterItem.value.length === 0) {
|
|
1724
494
|
return true;
|
|
1725
495
|
}
|
|
1726
|
-
if (
|
|
496
|
+
if (value == null) {
|
|
1727
497
|
return false;
|
|
1728
498
|
}
|
|
1729
|
-
const cellValues = Array.isArray(
|
|
499
|
+
const cellValues = Array.isArray(value) ? value : [value];
|
|
1730
500
|
const cellStrings = cellValues.map(value => String(value));
|
|
1731
501
|
const filterItemValues = Array.isArray(filterItem.value) ? filterItem.value : [filterItem.value];
|
|
1732
502
|
return filterItemValues.every(v => cellStrings.includes(v));
|
|
@@ -1746,14 +516,14 @@ const hasAnyOfOperator = {
|
|
|
1746
516
|
if (!filterItem.field || !filterItem.value || !filterItem.operator) {
|
|
1747
517
|
return null;
|
|
1748
518
|
}
|
|
1749
|
-
return
|
|
519
|
+
return value => {
|
|
1750
520
|
if (filterItem.value.length === 0) {
|
|
1751
521
|
return true;
|
|
1752
522
|
}
|
|
1753
|
-
if (
|
|
523
|
+
if (value == null) {
|
|
1754
524
|
return false;
|
|
1755
525
|
}
|
|
1756
|
-
const cellValues = Array.isArray(
|
|
526
|
+
const cellValues = Array.isArray(value) ? value : [value];
|
|
1757
527
|
const filterItemValues = Array.isArray(filterItem.value) ? filterItem.value : [filterItem.value];
|
|
1758
528
|
return filterItemValues.some(v => cellValues.map(value => String(value)).includes(v));
|
|
1759
529
|
};
|
|
@@ -1772,14 +542,14 @@ const isAnyOfOperator = {
|
|
|
1772
542
|
if (!filterItem.field || !filterItem.value || !filterItem.operator) {
|
|
1773
543
|
return null;
|
|
1774
544
|
}
|
|
1775
|
-
return
|
|
545
|
+
return value => {
|
|
1776
546
|
if (filterItem.value.length === 0) {
|
|
1777
547
|
return true;
|
|
1778
548
|
}
|
|
1779
|
-
if (
|
|
549
|
+
if (value == null) {
|
|
1780
550
|
return false;
|
|
1781
551
|
}
|
|
1782
|
-
const paramValues = Array.isArray(
|
|
552
|
+
const paramValues = Array.isArray(value) ? value : [value];
|
|
1783
553
|
for (const paramValue of paramValues) {
|
|
1784
554
|
if (filterItem.value.includes(String(paramValue))) {
|
|
1785
555
|
return true;
|
|
@@ -1802,14 +572,14 @@ const isNotAnyOfOperator = {
|
|
|
1802
572
|
if (!filterItem.field || !filterItem.value || !filterItem.operator) {
|
|
1803
573
|
return null;
|
|
1804
574
|
}
|
|
1805
|
-
return
|
|
575
|
+
return value => {
|
|
1806
576
|
if (filterItem.value.length === 0) {
|
|
1807
577
|
return true;
|
|
1808
578
|
}
|
|
1809
|
-
if (
|
|
579
|
+
if (value == null) {
|
|
1810
580
|
return true;
|
|
1811
581
|
}
|
|
1812
|
-
const paramValues = Array.isArray(
|
|
582
|
+
const paramValues = Array.isArray(value) ? value : [value];
|
|
1813
583
|
for (const paramValue of paramValues) {
|
|
1814
584
|
if (filterItem.value.includes(String(paramValue))) {
|
|
1815
585
|
return false;
|
|
@@ -1832,14 +602,14 @@ const startsWithAnyOfOperator = {
|
|
|
1832
602
|
if (!filterItem.field || !filterItem.value || !filterItem.operator) {
|
|
1833
603
|
return null;
|
|
1834
604
|
}
|
|
1835
|
-
return
|
|
605
|
+
return value => {
|
|
1836
606
|
if (filterItem.value.length === 0) {
|
|
1837
607
|
return true;
|
|
1838
608
|
}
|
|
1839
|
-
if (
|
|
609
|
+
if (value == null) {
|
|
1840
610
|
return false;
|
|
1841
611
|
}
|
|
1842
|
-
const paramValues = Array.isArray(
|
|
612
|
+
const paramValues = Array.isArray(value) ? value : [value];
|
|
1843
613
|
let match = false;
|
|
1844
614
|
filterItem.value.forEach(filteredValue => {
|
|
1845
615
|
paramValues.forEach(paramValue => {
|
|
@@ -1866,15 +636,15 @@ const isEmptyOperator = {
|
|
|
1866
636
|
value: 'isEmpty',
|
|
1867
637
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1868
638
|
getApplyFilterFn: _filterItem => {
|
|
1869
|
-
return
|
|
1870
|
-
if (
|
|
639
|
+
return value => {
|
|
640
|
+
if (value == null) {
|
|
1871
641
|
return true;
|
|
1872
642
|
}
|
|
1873
|
-
if (Array.isArray(
|
|
1874
|
-
return
|
|
643
|
+
if (Array.isArray(value)) {
|
|
644
|
+
return value.length === 0;
|
|
1875
645
|
}
|
|
1876
|
-
if (typeof
|
|
1877
|
-
return
|
|
646
|
+
if (typeof value === 'string') {
|
|
647
|
+
return value.trim() === '';
|
|
1878
648
|
}
|
|
1879
649
|
return false;
|
|
1880
650
|
};
|
|
@@ -1886,15 +656,15 @@ const isNotEmptyOperator = {
|
|
|
1886
656
|
value: 'isNotEmpty',
|
|
1887
657
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1888
658
|
getApplyFilterFn: _filterItem => {
|
|
1889
|
-
return
|
|
1890
|
-
if (
|
|
659
|
+
return value => {
|
|
660
|
+
if (value == null) {
|
|
1891
661
|
return false;
|
|
1892
662
|
}
|
|
1893
|
-
if (Array.isArray(
|
|
1894
|
-
return
|
|
663
|
+
if (Array.isArray(value)) {
|
|
664
|
+
return value.length > 0;
|
|
1895
665
|
}
|
|
1896
|
-
if (typeof
|
|
1897
|
-
return
|
|
666
|
+
if (typeof value === 'string') {
|
|
667
|
+
return value.trim() !== '';
|
|
1898
668
|
}
|
|
1899
669
|
return true;
|
|
1900
670
|
};
|
|
@@ -1933,14 +703,20 @@ const DIMENSION_MODEL_KEY = 'dimension';
|
|
|
1933
703
|
const FILTER_SEARCH_KEY = 'searchModel';
|
|
1934
704
|
const DENSITY_MODEL_KEY = 'densityModel';
|
|
1935
705
|
const COLUMN_ORDER_MODEL_KEY = 'columnOrderModel';
|
|
1936
|
-
const
|
|
706
|
+
const ROW_GROUPING_MODEL_KEY = 'rowGroupingModel';
|
|
707
|
+
const AGGREGATION_MODEL_KEY = 'aggregationModel';
|
|
708
|
+
/** Storage category key for the pivot column/row/value configuration. Consumer interop — use with `buildStorageKey`. */
|
|
709
|
+
const PIVOT_MODEL_KEY = 'pivotModel';
|
|
710
|
+
/** Storage category key for whether pivoting is active. Consumer interop — use with `buildStorageKey`. */
|
|
711
|
+
const PIVOT_ACTIVE_KEY = 'pivotActive';
|
|
712
|
+
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];
|
|
1937
713
|
/**
|
|
1938
714
|
* Build the localStorage key for a specific grid state category.
|
|
1939
715
|
* Consumers can use this to read or clear individual state entries directly.
|
|
1940
716
|
*
|
|
1941
717
|
* @example
|
|
1942
718
|
* ```ts
|
|
1943
|
-
* const key = buildStorageKey({ id: pathname, version: 2, category:
|
|
719
|
+
* const key = buildStorageKey({ id: pathname, version: 2, category: PIVOT_ACTIVE_KEY });
|
|
1944
720
|
* localStorage.removeItem(key);
|
|
1945
721
|
* ```
|
|
1946
722
|
*/
|
|
@@ -1990,6 +766,22 @@ const clearPreviousVersionStorage = (id, previousLocalStorageVersions) => {
|
|
|
1990
766
|
id,
|
|
1991
767
|
version,
|
|
1992
768
|
category: COLUMN_ORDER_MODEL_KEY
|
|
769
|
+
}), buildStorageKey({
|
|
770
|
+
id,
|
|
771
|
+
version,
|
|
772
|
+
category: ROW_GROUPING_MODEL_KEY
|
|
773
|
+
}), buildStorageKey({
|
|
774
|
+
id,
|
|
775
|
+
version,
|
|
776
|
+
category: AGGREGATION_MODEL_KEY
|
|
777
|
+
}), buildStorageKey({
|
|
778
|
+
id,
|
|
779
|
+
version,
|
|
780
|
+
category: PIVOT_MODEL_KEY
|
|
781
|
+
}), buildStorageKey({
|
|
782
|
+
id,
|
|
783
|
+
version,
|
|
784
|
+
category: PIVOT_ACTIVE_KEY
|
|
1993
785
|
})];
|
|
1994
786
|
for (const keyToDelete of keysToDelete) {
|
|
1995
787
|
try {
|
|
@@ -2064,13 +856,14 @@ const resetStatefulDataGridState = _ref2 => {
|
|
|
2064
856
|
* default (all columns visible). Clears the persisted `visibilityModel`
|
|
2065
857
|
* localStorage entry for the given versions and strips the `_columnVisibility`
|
|
2066
858
|
* param from the live URL, leaving every other piece of grid state (filters,
|
|
2067
|
-
* sort, pagination, pinned columns, …) untouched.
|
|
859
|
+
* sort, pivot, pagination, pinned columns, …) untouched.
|
|
2068
860
|
*
|
|
2069
861
|
* This is the visibility-scoped counterpart to `resetStatefulDataGridState`.
|
|
2070
|
-
* Reach for it at transition points
|
|
2071
|
-
*
|
|
2072
|
-
*
|
|
2073
|
-
*
|
|
862
|
+
* Reach for it at transition points — for example drilling down from pivot
|
|
863
|
+
* mode to a flat record view — where a stale pivot-era visibility snapshot
|
|
864
|
+
* would otherwise re-seed and keep base columns hidden. Because it leaves the
|
|
865
|
+
* other params alone it will not clobber a filter the caller is writing in the
|
|
866
|
+
* same transition.
|
|
2074
867
|
*
|
|
2075
868
|
* Like `resetStatefulDataGridState`, the URL strip reads `window.location.search`
|
|
2076
869
|
* directly so it operates on the live URL (the caller's captured snapshot may
|
|
@@ -2120,7 +913,7 @@ const COMPRESSED_PREFIX = '~';
|
|
|
2120
913
|
* Params listed first are compressed first (least valuable to read in the URL).
|
|
2121
914
|
* The filter aggregate step uses the special key `_filters_aggregate`.
|
|
2122
915
|
*/
|
|
2123
|
-
const COMPRESSION_PRIORITY = ['_columnOrder', '_columnVisibility', '_pinnedColumnsLeft', '_pinnedColumnsRight', '_filters_aggregate', '_quickFilterValues'];
|
|
916
|
+
const COMPRESSION_PRIORITY = ['_columnOrder', '_columnVisibility', '_pinnedColumnsLeft', '_pinnedColumnsRight', '_filters_aggregate', '_aggregation', '_rowGrouping', '_quickFilterValues', '_pivot'];
|
|
2124
917
|
|
|
2125
918
|
/** Params that are always short and should never be compressed. */
|
|
2126
919
|
const NEVER_COMPRESS = new Set(['_sortColumn', '_pagination', '_density', '_logicOperator', 'v', 'tab']);
|
|
@@ -2361,6 +1154,13 @@ const convertToDisplayFormat = search => {
|
|
|
2361
1154
|
const cleanSearch = search.startsWith('?') ? search.slice(1) : search;
|
|
2362
1155
|
const params = cleanSearch.split('&');
|
|
2363
1156
|
const converted = params.map(param => {
|
|
1157
|
+
const eqIndex = param.indexOf('=');
|
|
1158
|
+
if (eqIndex !== -1) {
|
|
1159
|
+
const value = param.slice(eqIndex + 1);
|
|
1160
|
+
// Skip conversion for compressed values — already URL-safe
|
|
1161
|
+
if (isCompressed(value)) return param;
|
|
1162
|
+
}
|
|
1163
|
+
|
|
2364
1164
|
// Handle _sortColumn=[field,direction]
|
|
2365
1165
|
if (param.startsWith('_sortColumn=')) {
|
|
2366
1166
|
const value = param.slice('_sortColumn='.length);
|
|
@@ -2415,7 +1215,6 @@ const convertToDisplayFormat = search => {
|
|
|
2415
1215
|
// Handle _columnOrder=[a,b,c]
|
|
2416
1216
|
if (param.startsWith('_columnOrder=')) {
|
|
2417
1217
|
const value = param.slice('_columnOrder='.length);
|
|
2418
|
-
if (value.startsWith('~')) return param; // compressed — skip
|
|
2419
1218
|
if (value.startsWith('[') && value.endsWith(']')) {
|
|
2420
1219
|
const inner = value.slice(1, -1);
|
|
2421
1220
|
return `_columnOrder=${inner}`;
|
|
@@ -2423,6 +1222,21 @@ const convertToDisplayFormat = search => {
|
|
|
2423
1222
|
return param;
|
|
2424
1223
|
}
|
|
2425
1224
|
|
|
1225
|
+
// Handle _rowGrouping=[a,b,c]
|
|
1226
|
+
if (param.startsWith('_rowGrouping=')) {
|
|
1227
|
+
const value = param.slice('_rowGrouping='.length);
|
|
1228
|
+
if (value.startsWith('[') && value.endsWith(']')) {
|
|
1229
|
+
const inner = value.slice(1, -1);
|
|
1230
|
+
return `_rowGrouping=${inner}`;
|
|
1231
|
+
}
|
|
1232
|
+
return param;
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
// _aggregation and _pivot do not use bracket notation — pass through
|
|
1236
|
+
if (param.startsWith('_aggregation=') || param.startsWith('_pivot=')) {
|
|
1237
|
+
return param;
|
|
1238
|
+
}
|
|
1239
|
+
|
|
2426
1240
|
// Handle _field[operator,type]=value or _field[operator,type]=list[a,b,c]
|
|
2427
1241
|
const bracketMatch = param.match(/^_([^[]+)\[([^\]]+)\]=(.*)$/);
|
|
2428
1242
|
if (bracketMatch) {
|
|
@@ -2462,6 +1276,13 @@ const convertFromDisplayFormat = (search, columns) => {
|
|
|
2462
1276
|
const cleanSearch = search.startsWith('?') ? search.slice(1) : search;
|
|
2463
1277
|
const params = cleanSearch.split('&');
|
|
2464
1278
|
const converted = params.map(param => {
|
|
1279
|
+
const eqIndex = param.indexOf('=');
|
|
1280
|
+
if (eqIndex !== -1) {
|
|
1281
|
+
const value = param.slice(eqIndex + 1);
|
|
1282
|
+
// Skip conversion for compressed values — already URL-safe
|
|
1283
|
+
if (isCompressed(value)) return param;
|
|
1284
|
+
}
|
|
1285
|
+
|
|
2465
1286
|
// Handle _sortColumn=field.direction or _sortColumn=
|
|
2466
1287
|
if (param.startsWith('_sortColumn=')) {
|
|
2467
1288
|
const value = param.slice('_sortColumn='.length);
|
|
@@ -2513,8 +1334,8 @@ const convertFromDisplayFormat = (search, columns) => {
|
|
|
2513
1334
|
// Handle _columnVisibility display `a,b,!c` → internal `[a,b,!c]`.
|
|
2514
1335
|
if (param.startsWith('_columnVisibility=')) {
|
|
2515
1336
|
const value = param.slice('_columnVisibility='.length);
|
|
2516
|
-
//
|
|
2517
|
-
if (value.startsWith('[')
|
|
1337
|
+
// Already internal (bracketed) — leave it alone.
|
|
1338
|
+
if (value.startsWith('[')) {
|
|
2518
1339
|
return param;
|
|
2519
1340
|
}
|
|
2520
1341
|
return `_columnVisibility=[${value}]`;
|
|
@@ -2523,13 +1344,26 @@ const convertFromDisplayFormat = (search, columns) => {
|
|
|
2523
1344
|
// Handle _columnOrder=a,b,c
|
|
2524
1345
|
if (param.startsWith('_columnOrder=')) {
|
|
2525
1346
|
const value = param.slice('_columnOrder='.length);
|
|
2526
|
-
|
|
2527
|
-
if (value.startsWith('[') || value.startsWith('~')) {
|
|
1347
|
+
if (value.startsWith('[')) {
|
|
2528
1348
|
return param;
|
|
2529
1349
|
}
|
|
2530
1350
|
return `_columnOrder=[${value}]`;
|
|
2531
1351
|
}
|
|
2532
1352
|
|
|
1353
|
+
// Handle _rowGrouping=a,b,c
|
|
1354
|
+
if (param.startsWith('_rowGrouping=')) {
|
|
1355
|
+
const value = param.slice('_rowGrouping='.length);
|
|
1356
|
+
if (value.startsWith('[')) {
|
|
1357
|
+
return param;
|
|
1358
|
+
}
|
|
1359
|
+
return `_rowGrouping=[${value}]`;
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
// _aggregation, _pivot, _filters — pass through (no bracket conversion needed)
|
|
1363
|
+
if (param.startsWith('_aggregation=') || param.startsWith('_pivot=') || param.startsWith('_filters=')) {
|
|
1364
|
+
return param;
|
|
1365
|
+
}
|
|
1366
|
+
|
|
2533
1367
|
// Handle field.operator=value (dot notation for filters)
|
|
2534
1368
|
const dotMatch = param.match(/^([^.]+)\.([a-zA-Z_]+)=(.*)$/);
|
|
2535
1369
|
if (dotMatch) {
|
|
@@ -2572,9 +1406,10 @@ const getDecodedSearchFromUrl = (search, columns) => {
|
|
|
2572
1406
|
const hasPaginationDotNotation = /_pagination=[^&[]+\.[^&]+/.test(searchWithoutLeadingQuestion);
|
|
2573
1407
|
const hasPinnedWithoutBrackets = /(_pinnedColumnsLeft|_pinnedColumnsRight)=[^&[]*(&|$)/.test(searchWithoutLeadingQuestion);
|
|
2574
1408
|
const hasVisibilityWithoutBrackets = /_columnVisibility=[^&[]*(&|$)/.test(searchWithoutLeadingQuestion);
|
|
2575
|
-
const hasColumnOrderWithoutBrackets = /_columnOrder=[^&[
|
|
1409
|
+
const hasColumnOrderWithoutBrackets = /_columnOrder=[^&[]*(&|$)/.test(searchWithoutLeadingQuestion);
|
|
1410
|
+
const hasRowGroupingWithoutBrackets = /_rowGrouping=[^&[]*(&|$)/.test(searchWithoutLeadingQuestion);
|
|
2576
1411
|
const hasBracketNotation = /\[.*\]=/.test(searchWithoutLeadingQuestion);
|
|
2577
|
-
const isDisplayFormat = (hasDotNotationFilter || hasEmptySortColumn || hasSortDotNotation || hasPaginationDotNotation || hasPinnedWithoutBrackets || hasVisibilityWithoutBrackets || hasColumnOrderWithoutBrackets) && !hasBracketNotation;
|
|
1412
|
+
const isDisplayFormat = (hasDotNotationFilter || hasEmptySortColumn || hasSortDotNotation || hasPaginationDotNotation || hasPinnedWithoutBrackets || hasVisibilityWithoutBrackets || hasColumnOrderWithoutBrackets || hasRowGroupingWithoutBrackets) && !hasBracketNotation;
|
|
2578
1413
|
if (isDisplayFormat) {
|
|
2579
1414
|
return '?' + convertFromDisplayFormat(searchWithoutLeadingQuestion, columns);
|
|
2580
1415
|
}
|
|
@@ -2730,7 +1565,7 @@ const isValueValid = (value, field, columns, operator) => {
|
|
|
2730
1565
|
|
|
2731
1566
|
// example:
|
|
2732
1567
|
// unicodeDomain[contains]=a&unicodeDomain[contains]=dsa&logicOperator=and&tab=ignored
|
|
2733
|
-
const getFilterModelFromString = (searchString, columns) => {
|
|
1568
|
+
const getFilterModelFromString = (searchString, columns, previousModel) => {
|
|
2734
1569
|
if (!searchString) {
|
|
2735
1570
|
return 'invalid';
|
|
2736
1571
|
}
|
|
@@ -2743,7 +1578,7 @@ const getFilterModelFromString = (searchString, columns) => {
|
|
|
2743
1578
|
let hasFilterMeta = false;
|
|
2744
1579
|
const searchParams = new URLSearchParams();
|
|
2745
1580
|
for (const [key, value] of new URLSearchParams(searchString)) {
|
|
2746
|
-
if (key.startsWith('_') && !['_logicOperator', '_sortColumn', '_pinnedColumnsLeft', '_pinnedColumnsRight', '_columnVisibility', '_pagination', '_quickFilterValues', '_columnOrder', '_density', '_filters'].includes(key)) {
|
|
1581
|
+
if (key.startsWith('_') && !['_logicOperator', '_sortColumn', '_pinnedColumnsLeft', '_pinnedColumnsRight', '_columnVisibility', '_pagination', '_quickFilterValues', '_columnOrder', '_rowGrouping', '_aggregation', '_pivot', '_density', '_filters'].includes(key)) {
|
|
2747
1582
|
searchParams.set(key, value);
|
|
2748
1583
|
}
|
|
2749
1584
|
if (key === '_logicOperator') {
|
|
@@ -2760,6 +1595,21 @@ const getFilterModelFromString = (searchString, columns) => {
|
|
|
2760
1595
|
}
|
|
2761
1596
|
}
|
|
2762
1597
|
let id = 5000;
|
|
1598
|
+
|
|
1599
|
+
// Positional id-reuse map keyed by `${field}|${operator}` (decoded operator, matching
|
|
1600
|
+
// the item we push below). FIFO per key so duplicate field+operator items map by order.
|
|
1601
|
+
// Reusing the id of a previously parsed/emitted item keeps `item.id` stable across the
|
|
1602
|
+
// URL write→parse roundtrip (the URL never carries the id), so MUI's GridFilterForm
|
|
1603
|
+
// React key does not change and the filter panel input keeps focus. (DS-81)
|
|
1604
|
+
const previousIdsByKey = new Map();
|
|
1605
|
+
if (previousModel) {
|
|
1606
|
+
for (const prev of previousModel.items) {
|
|
1607
|
+
if (prev.id === undefined) continue;
|
|
1608
|
+
const key = `${prev.field}|${prev.operator}`;
|
|
1609
|
+
const bucket = previousIdsByKey.get(key);
|
|
1610
|
+
if (bucket) bucket.push(prev.id);else previousIdsByKey.set(key, [prev.id]);
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
2763
1613
|
const fields = columns.map(column => column.field);
|
|
2764
1614
|
let isInvalid = false;
|
|
2765
1615
|
const items = [];
|
|
@@ -2795,10 +1645,13 @@ const getFilterModelFromString = (searchString, columns) => {
|
|
|
2795
1645
|
isInvalid = true;
|
|
2796
1646
|
return;
|
|
2797
1647
|
}
|
|
1648
|
+
const finalOperator = columnType === 'number' && Object.keys(numberOperatorDecoder).includes(operator) ? numberOperatorDecoder[operator] : operator;
|
|
1649
|
+
const reuseBucket = previousIdsByKey.get(`${field}|${finalOperator}`);
|
|
1650
|
+
const stableId = reuseBucket && reuseBucket.length > 0 ? reuseBucket.shift() : id;
|
|
2798
1651
|
items.push({
|
|
2799
1652
|
field,
|
|
2800
|
-
operator:
|
|
2801
|
-
id,
|
|
1653
|
+
operator: finalOperator,
|
|
1654
|
+
id: stableId,
|
|
2802
1655
|
value: listOperators.includes(operator) && decodedValue === '' ? [] : decodedValue,
|
|
2803
1656
|
type
|
|
2804
1657
|
});
|
|
@@ -2892,7 +1745,7 @@ const getSearchParamsFromFilterModel = filterModel => {
|
|
|
2892
1745
|
// - if we have something in the URL, use that info
|
|
2893
1746
|
// - if we don't have that, use the localStorage and update the URL
|
|
2894
1747
|
// - if we don't have that, return an empty FilterModel
|
|
2895
|
-
const getFilterModel = (search, columns, localStorageFilters, setLocalStorageFilters, initialState, isNewVersion) => {
|
|
1748
|
+
const getFilterModel = (search, columns, localStorageFilters, setLocalStorageFilters, initialState, isNewVersion, previousModel) => {
|
|
2896
1749
|
const defaultValue = initialState && initialState.filter && initialState.filter.filterModel ? initialState.filter.filterModel : {
|
|
2897
1750
|
items: [],
|
|
2898
1751
|
logicOperator: GridLogicOperator.And
|
|
@@ -2910,7 +1763,7 @@ const getFilterModel = (search, columns, localStorageFilters, setLocalStorageFil
|
|
|
2910
1763
|
persistDefaultFilters();
|
|
2911
1764
|
return defaultValue;
|
|
2912
1765
|
}
|
|
2913
|
-
const filterModelFromSearch = getFilterModelFromString(search, columns);
|
|
1766
|
+
const filterModelFromSearch = getFilterModelFromString(search, columns, previousModel);
|
|
2914
1767
|
if (filterModelFromSearch !== 'invalid') {
|
|
2915
1768
|
const searchFromFilterModel = getSearchParamsFromFilterModel(filterModelFromSearch);
|
|
2916
1769
|
const searchString = urlSearchParamsToString(searchFromFilterModel);
|
|
@@ -3093,8 +1946,8 @@ const getColumnVisibilityFromString = (searchString, columns) => {
|
|
|
3093
1946
|
// by 12.5.5-muiv8-alpha.5/alpha.6 (replaced by the URL-safe `!` form below — see
|
|
3094
1947
|
// getSearchParamsFromColumnVisibility). Still parsed so any localStorage entry
|
|
3095
1948
|
// persisted by those alphas keeps working; never written anymore. The two sets are
|
|
3096
|
-
// split on the fixed `];h:[` separator, so a `[` or `]` inside a field name
|
|
3097
|
-
// not break parsing.
|
|
1949
|
+
// split on the fixed `];h:[` separator, so a `[` or `]` inside a pivot field name
|
|
1950
|
+
// (e.g. `["gmail"]>->email_volume`) does not break parsing.
|
|
3098
1951
|
if (value.startsWith('v:[') && value.endsWith(']') && value.includes('];h:[')) {
|
|
3099
1952
|
const inner = value.slice('v:['.length, -1);
|
|
3100
1953
|
const separatorIndex = inner.indexOf('];h:[');
|
|
@@ -3184,14 +2037,14 @@ const getSearchParamsFromColumnVisibility = (columnVisibility, columns) => {
|
|
|
3184
2037
|
}, columnVisibility);
|
|
3185
2038
|
|
|
3186
2039
|
// Serialise a single comma list over the static columns plus any extra keys present
|
|
3187
|
-
// in the model (dynamically-generated fields, preserved in model order).
|
|
3188
|
-
// fields are prefixed `!`; visible fields are bare. This URL-safe form
|
|
3189
|
-
// idempotently through `URLSearchParams.toString()` percent-encoding —
|
|
3190
|
-
// `v:[..];h:[..]` form did NOT (its `:`/`;` were percent-encoded and
|
|
3191
|
-
// read-back, driving an unbounded `history.replace` loop, ODM-3033).
|
|
3192
|
-
// the compression sentinel — compression.ts COMPRESSED_PREFIX)
|
|
3193
|
-
// hidden field can't be mistaken for a compressed value.
|
|
3194
|
-
// explicit, so deselected dynamic columns survive reloads.
|
|
2040
|
+
// in the model (dynamically-generated pivot fields, preserved in model order).
|
|
2041
|
+
// Hidden fields are prefixed `!`; visible fields are bare. This URL-safe form
|
|
2042
|
+
// round-trips idempotently through `URLSearchParams.toString()` percent-encoding —
|
|
2043
|
+
// the earlier `v:[..];h:[..]` form did NOT (its `:`/`;` were percent-encoded and
|
|
2044
|
+
// mis-parsed on read-back, driving an unbounded `history.replace` loop, ODM-3033).
|
|
2045
|
+
// `!` (not `~`, which is the compression sentinel — compression.ts COMPRESSED_PREFIX)
|
|
2046
|
+
// is used so a leading hidden field can't be mistaken for a compressed value.
|
|
2047
|
+
// The hidden set is still explicit, so deselected dynamic columns survive reloads.
|
|
3195
2048
|
const allFields = [...fields];
|
|
3196
2049
|
for (const field of Object.keys(finalColumnVisibility)) {
|
|
3197
2050
|
if (!allFields.includes(field)) {
|
|
@@ -3354,8 +2207,7 @@ const getSearchParamsFromDensity = density => {
|
|
|
3354
2207
|
return searchParams;
|
|
3355
2208
|
};
|
|
3356
2209
|
const getDensityModel = (search, localStorageDensity, setLocalStorageDensity, initialState, isNewVersion) => {
|
|
3357
|
-
//
|
|
3358
|
-
// can still pass it through. Honour it when provided, otherwise fall back to 'compact'.
|
|
2210
|
+
// Default density: honour initialState.density if valid, otherwise fall back to 'compact'
|
|
3359
2211
|
const initialDensity = initialState === null || initialState === void 0 ? void 0 : initialState.density;
|
|
3360
2212
|
const defaultValue = initialDensity && VALID_DENSITIES.includes(initialDensity) ? initialDensity : 'compact';
|
|
3361
2213
|
|
|
@@ -3408,29 +2260,6 @@ const getSearchParamsFromColumnOrder = columnOrder => {
|
|
|
3408
2260
|
}
|
|
3409
2261
|
return searchParams;
|
|
3410
2262
|
};
|
|
3411
|
-
|
|
3412
|
-
/**
|
|
3413
|
-
* Builds the `v=<version>` search param the grid uses to detect stale URLs.
|
|
3414
|
-
*
|
|
3415
|
-
* Use this when constructing a deep link or share URL outside the grid (e.g. via
|
|
3416
|
-
* `getSearchParamsFromFilterModel` + `buildQueryParamsString`). The grid itself
|
|
3417
|
-
* always includes `v` in URLs it writes via `getFinalSearch`, but external helpers
|
|
3418
|
-
* do not — include this when you want a stale `localStorageVersion` bump to invalidate
|
|
3419
|
-
* the link. Omitting `v` is also safe: a missing `v` is treated as "current version"
|
|
3420
|
-
* and the URL state is applied as-is.
|
|
3421
|
-
*
|
|
3422
|
-
* @example
|
|
3423
|
-
* const params = new URLSearchParams([
|
|
3424
|
-
* ...getSearchParamsFromFilterModel(filterModel),
|
|
3425
|
-
* ...getSearchParamsFromVersion(1),
|
|
3426
|
-
* ]);
|
|
3427
|
-
* const url = `/my-grid${buildQueryParamsString(urlSearchParamsToString(params))}`;
|
|
3428
|
-
*/
|
|
3429
|
-
const getSearchParamsFromVersion = version => {
|
|
3430
|
-
const searchParams = new URLSearchParams();
|
|
3431
|
-
searchParams.set('v', String(version));
|
|
3432
|
-
return searchParams;
|
|
3433
|
-
};
|
|
3434
2263
|
const getColumnOrder = (search, columns, localStorageColumnOrder, setLocalStorageColumnOrder, initialState, isNewVersion) => {
|
|
3435
2264
|
var _initialState$columns4, _initialState$columns5;
|
|
3436
2265
|
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);
|
|
@@ -3461,46 +2290,345 @@ const getColumnOrder = (search, columns, localStorageColumnOrder, setLocalStorag
|
|
|
3461
2290
|
persistDefault();
|
|
3462
2291
|
return defaultValue;
|
|
3463
2292
|
};
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
} = _ref;
|
|
3478
|
-
const filterModelSearch = getSearchParamsFromFilterModel(filterModel);
|
|
3479
|
-
const sortModelSearch = getSearchParamsFromSorting(sortModel);
|
|
3480
|
-
const paginationModelSearch = getSearchParamsFromPagination(paginationModel);
|
|
3481
|
-
const columnVisibilityModelSearch = getSearchParamsFromColumnVisibility(columnsVisibilityModel, columns);
|
|
3482
|
-
const pinnedColumnsModelSearch = getSearchParamsFromPinnedColumns(pinnedColumnsModel);
|
|
3483
|
-
const densitySearch = getSearchParamsFromDensity(density);
|
|
3484
|
-
// Only include _columnOrder in URL when it differs from the default
|
|
3485
|
-
const columnOrderSearch = columnOrderModel.length !== defaultColumnOrder.length || columnOrderModel.some((field, i) => field !== defaultColumnOrder[i]) ? getSearchParamsFromColumnOrder(columnOrderModel) : new URLSearchParams();
|
|
3486
|
-
const tabSearch = getSearchParamsFromTab(search);
|
|
2293
|
+
|
|
2294
|
+
/** ROW GROUPING */
|
|
2295
|
+
|
|
2296
|
+
const getRowGroupingFromString = searchString => {
|
|
2297
|
+
if (!searchString) return 'invalid';
|
|
2298
|
+
const searchParams = new URLSearchParams(searchString);
|
|
2299
|
+
const value = searchParams.get('_rowGrouping');
|
|
2300
|
+
if (value === '' || value === null || value === '[]') return 'invalid';
|
|
2301
|
+
const inner = value.startsWith('[') && value.endsWith(']') ? value.slice(1, -1) : value;
|
|
2302
|
+
if (!inner) return 'invalid';
|
|
2303
|
+
return inner.split(',').filter(Boolean);
|
|
2304
|
+
};
|
|
2305
|
+
const getSearchParamsFromRowGrouping = rowGrouping => {
|
|
3487
2306
|
const searchParams = new URLSearchParams();
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
2307
|
+
if (rowGrouping.length > 0) {
|
|
2308
|
+
searchParams.set('_rowGrouping', `[${rowGrouping.join(',')}]`);
|
|
2309
|
+
}
|
|
2310
|
+
return searchParams;
|
|
2311
|
+
};
|
|
2312
|
+
const getRowGroupingModel = (search, localStorageRowGrouping, setLocalStorageRowGrouping, initialState, isNewVersion) => {
|
|
2313
|
+
var _initialState$rowGrou, _initialState$rowGrou2;
|
|
2314
|
+
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 : [];
|
|
2315
|
+
const persistDefault = () => {
|
|
2316
|
+
const searchFromDefault = getSearchParamsFromRowGrouping(defaultValue);
|
|
2317
|
+
const searchString = urlSearchParamsToString(searchFromDefault);
|
|
2318
|
+
if (searchString !== localStorageRowGrouping) {
|
|
2319
|
+
setLocalStorageRowGrouping(searchString);
|
|
2320
|
+
}
|
|
2321
|
+
};
|
|
2322
|
+
if (isNewVersion) {
|
|
2323
|
+
persistDefault();
|
|
2324
|
+
return defaultValue;
|
|
2325
|
+
}
|
|
2326
|
+
const fromUrl = getRowGroupingFromString(search);
|
|
2327
|
+
if (fromUrl !== 'invalid') {
|
|
2328
|
+
const searchFromModel = getSearchParamsFromRowGrouping(fromUrl);
|
|
2329
|
+
const searchString = urlSearchParamsToString(searchFromModel);
|
|
2330
|
+
if (searchString !== localStorageRowGrouping) {
|
|
2331
|
+
setLocalStorageRowGrouping(searchString);
|
|
3491
2332
|
}
|
|
2333
|
+
return fromUrl;
|
|
3492
2334
|
}
|
|
3493
|
-
|
|
2335
|
+
const fromLocalStorage = getRowGroupingFromString(localStorageRowGrouping);
|
|
2336
|
+
if (fromLocalStorage !== 'invalid') {
|
|
2337
|
+
return fromLocalStorage;
|
|
2338
|
+
}
|
|
2339
|
+
persistDefault();
|
|
2340
|
+
return defaultValue;
|
|
2341
|
+
};
|
|
3494
2342
|
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
2343
|
+
/** AGGREGATION */
|
|
2344
|
+
|
|
2345
|
+
const getAggregationFromString = searchString => {
|
|
2346
|
+
if (!searchString) return 'invalid';
|
|
2347
|
+
const searchParams = new URLSearchParams(searchString);
|
|
2348
|
+
const value = searchParams.get('_aggregation');
|
|
2349
|
+
if (value === '' || value === null) return 'invalid';
|
|
2350
|
+
|
|
2351
|
+
// Format: field1.sum,field2.avg or [field1.sum,field2.avg]
|
|
2352
|
+
const inner = value.startsWith('[') && value.endsWith(']') ? value.slice(1, -1) : value;
|
|
2353
|
+
if (!inner) return 'invalid';
|
|
2354
|
+
const model = {};
|
|
2355
|
+
for (const entry of inner.split(',')) {
|
|
2356
|
+
const dotIndex = entry.lastIndexOf('.');
|
|
2357
|
+
if (dotIndex <= 0) return 'invalid';
|
|
2358
|
+
const field = entry.slice(0, dotIndex);
|
|
2359
|
+
const aggFunc = entry.slice(dotIndex + 1);
|
|
2360
|
+
if (!field || !aggFunc) return 'invalid';
|
|
2361
|
+
model[field] = aggFunc;
|
|
3499
2362
|
}
|
|
3500
|
-
return
|
|
2363
|
+
return Object.keys(model).length > 0 ? model : 'invalid';
|
|
2364
|
+
};
|
|
2365
|
+
const getSearchParamsFromAggregation = aggregation => {
|
|
2366
|
+
const searchParams = new URLSearchParams();
|
|
2367
|
+
const entries = Object.entries(aggregation);
|
|
2368
|
+
if (entries.length > 0) {
|
|
2369
|
+
const value = entries.map(_ref => {
|
|
2370
|
+
let [field, aggFunc] = _ref;
|
|
2371
|
+
return `${field}.${aggFunc}`;
|
|
2372
|
+
}).join(',');
|
|
2373
|
+
searchParams.set('_aggregation', value);
|
|
2374
|
+
}
|
|
2375
|
+
return searchParams;
|
|
2376
|
+
};
|
|
2377
|
+
const getAggregationModel = (search, localStorageAggregation, setLocalStorageAggregation, initialState, isNewVersion) => {
|
|
2378
|
+
var _initialState$aggrega, _initialState$aggrega2;
|
|
2379
|
+
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 : {};
|
|
2380
|
+
const persistDefault = () => {
|
|
2381
|
+
const searchFromDefault = getSearchParamsFromAggregation(defaultValue);
|
|
2382
|
+
const searchString = urlSearchParamsToString(searchFromDefault);
|
|
2383
|
+
if (searchString !== localStorageAggregation) {
|
|
2384
|
+
setLocalStorageAggregation(searchString);
|
|
2385
|
+
}
|
|
2386
|
+
};
|
|
2387
|
+
if (isNewVersion) {
|
|
2388
|
+
persistDefault();
|
|
2389
|
+
return defaultValue;
|
|
2390
|
+
}
|
|
2391
|
+
const fromUrl = getAggregationFromString(search);
|
|
2392
|
+
if (fromUrl !== 'invalid') {
|
|
2393
|
+
const searchFromModel = getSearchParamsFromAggregation(fromUrl);
|
|
2394
|
+
const searchString = urlSearchParamsToString(searchFromModel);
|
|
2395
|
+
if (searchString !== localStorageAggregation) {
|
|
2396
|
+
setLocalStorageAggregation(searchString);
|
|
2397
|
+
}
|
|
2398
|
+
return fromUrl;
|
|
2399
|
+
}
|
|
2400
|
+
const fromLocalStorage = getAggregationFromString(localStorageAggregation);
|
|
2401
|
+
if (fromLocalStorage !== 'invalid') {
|
|
2402
|
+
return fromLocalStorage;
|
|
2403
|
+
}
|
|
2404
|
+
persistDefault();
|
|
2405
|
+
return defaultValue;
|
|
2406
|
+
};
|
|
2407
|
+
|
|
2408
|
+
/** PIVOT */
|
|
2409
|
+
|
|
2410
|
+
/** Convert MUI's GridPivotModel → our simplified PivotModel */
|
|
2411
|
+
const fromGridPivotModel = model => ({
|
|
2412
|
+
columns: model.columns.map(c => c.field),
|
|
2413
|
+
rows: model.rows.map(r => r.field),
|
|
2414
|
+
values: model.values.map(_ref2 => {
|
|
2415
|
+
let {
|
|
2416
|
+
field,
|
|
2417
|
+
aggFunc
|
|
2418
|
+
} = _ref2;
|
|
2419
|
+
return {
|
|
2420
|
+
field,
|
|
2421
|
+
aggFunc
|
|
2422
|
+
};
|
|
2423
|
+
})
|
|
2424
|
+
});
|
|
2425
|
+
|
|
2426
|
+
/**
|
|
2427
|
+
* Pivot format: `cols:f1,f2;rows:f3;vals:f4.sum,f5.avg`
|
|
2428
|
+
*/
|
|
2429
|
+
const getPivotFromString = searchString => {
|
|
2430
|
+
if (!searchString) return 'invalid';
|
|
2431
|
+
const searchParams = new URLSearchParams(searchString);
|
|
2432
|
+
const value = searchParams.get('_pivot');
|
|
2433
|
+
if (value === '' || value === null) return 'invalid';
|
|
2434
|
+
const model = {
|
|
2435
|
+
columns: [],
|
|
2436
|
+
rows: [],
|
|
2437
|
+
values: []
|
|
2438
|
+
};
|
|
2439
|
+
for (const segment of value.split(';')) {
|
|
2440
|
+
const colonIndex = segment.indexOf(':');
|
|
2441
|
+
if (colonIndex <= 0) return 'invalid';
|
|
2442
|
+
const key = segment.slice(0, colonIndex);
|
|
2443
|
+
const content = segment.slice(colonIndex + 1);
|
|
2444
|
+
if (key === 'cols') {
|
|
2445
|
+
model.columns = content ? content.split(',').filter(Boolean) : [];
|
|
2446
|
+
} else if (key === 'rows') {
|
|
2447
|
+
model.rows = content ? content.split(',').filter(Boolean) : [];
|
|
2448
|
+
} else if (key === 'vals') {
|
|
2449
|
+
if (!content) continue;
|
|
2450
|
+
for (const entry of content.split(',')) {
|
|
2451
|
+
const dotIndex = entry.lastIndexOf('.');
|
|
2452
|
+
if (dotIndex <= 0) return 'invalid';
|
|
2453
|
+
model.values.push({
|
|
2454
|
+
field: entry.slice(0, dotIndex),
|
|
2455
|
+
aggFunc: entry.slice(dotIndex + 1)
|
|
2456
|
+
});
|
|
2457
|
+
}
|
|
2458
|
+
}
|
|
2459
|
+
}
|
|
2460
|
+
|
|
2461
|
+
// At least one section must have content
|
|
2462
|
+
if (model.columns.length === 0 && model.rows.length === 0 && model.values.length === 0) {
|
|
2463
|
+
return 'invalid';
|
|
2464
|
+
}
|
|
2465
|
+
return model;
|
|
2466
|
+
};
|
|
2467
|
+
const getSearchParamsFromPivot = pivot => {
|
|
2468
|
+
const searchParams = new URLSearchParams();
|
|
2469
|
+
const hasContent = pivot.columns.length > 0 || pivot.rows.length > 0 || pivot.values.length > 0;
|
|
2470
|
+
if (hasContent) {
|
|
2471
|
+
const parts = [];
|
|
2472
|
+
parts.push(`cols:${pivot.columns.join(',')}`);
|
|
2473
|
+
parts.push(`rows:${pivot.rows.join(',')}`);
|
|
2474
|
+
if (pivot.values.length > 0) {
|
|
2475
|
+
parts.push(`vals:${pivot.values.map(v => `${v.field}.${v.aggFunc}`).join(',')}`);
|
|
2476
|
+
}
|
|
2477
|
+
searchParams.set('_pivot', parts.join(';'));
|
|
2478
|
+
}
|
|
2479
|
+
return searchParams;
|
|
2480
|
+
};
|
|
2481
|
+
const getPivotModel = (search, localStoragePivot, setLocalStoragePivot, initialState, isNewVersion) => {
|
|
2482
|
+
var _initialState$pivotin;
|
|
2483
|
+
const defaultValue = initialState !== null && initialState !== void 0 && (_initialState$pivotin = initialState.pivoting) !== null && _initialState$pivotin !== void 0 && _initialState$pivotin.model ? fromGridPivotModel(initialState.pivoting.model) : {
|
|
2484
|
+
columns: [],
|
|
2485
|
+
rows: [],
|
|
2486
|
+
values: []
|
|
2487
|
+
};
|
|
2488
|
+
const persistDefault = () => {
|
|
2489
|
+
const searchFromDefault = getSearchParamsFromPivot(defaultValue);
|
|
2490
|
+
const searchString = urlSearchParamsToString(searchFromDefault);
|
|
2491
|
+
if (searchString !== localStoragePivot) {
|
|
2492
|
+
setLocalStoragePivot(searchString);
|
|
2493
|
+
}
|
|
2494
|
+
};
|
|
2495
|
+
if (isNewVersion) {
|
|
2496
|
+
persistDefault();
|
|
2497
|
+
return defaultValue;
|
|
2498
|
+
}
|
|
2499
|
+
const fromUrl = getPivotFromString(search);
|
|
2500
|
+
if (fromUrl !== 'invalid') {
|
|
2501
|
+
const searchFromModel = getSearchParamsFromPivot(fromUrl);
|
|
2502
|
+
const searchString = urlSearchParamsToString(searchFromModel);
|
|
2503
|
+
if (searchString !== localStoragePivot) {
|
|
2504
|
+
setLocalStoragePivot(searchString);
|
|
2505
|
+
}
|
|
2506
|
+
return fromUrl;
|
|
2507
|
+
}
|
|
2508
|
+
const fromLocalStorage = getPivotFromString(localStoragePivot);
|
|
2509
|
+
if (fromLocalStorage !== 'invalid') {
|
|
2510
|
+
return fromLocalStorage;
|
|
2511
|
+
}
|
|
2512
|
+
persistDefault();
|
|
2513
|
+
return defaultValue;
|
|
2514
|
+
};
|
|
2515
|
+
|
|
2516
|
+
/** PIVOT ACTIVE */
|
|
2517
|
+
|
|
2518
|
+
const getPivotActiveFromString = searchString => {
|
|
2519
|
+
if (!searchString) return 'invalid';
|
|
2520
|
+
const searchParams = new URLSearchParams(searchString);
|
|
2521
|
+
const value = searchParams.get('_pivotActive');
|
|
2522
|
+
if (value === 'true') return true;
|
|
2523
|
+
if (value === 'false') return false;
|
|
2524
|
+
return 'invalid';
|
|
2525
|
+
};
|
|
2526
|
+
const getSearchParamsFromPivotActive = active => {
|
|
2527
|
+
const searchParams = new URLSearchParams();
|
|
2528
|
+
searchParams.set('_pivotActive', String(active));
|
|
2529
|
+
return searchParams;
|
|
2530
|
+
};
|
|
2531
|
+
|
|
2532
|
+
/**
|
|
2533
|
+
* Builds the `v=<version>` search param the grid uses to detect stale URLs.
|
|
2534
|
+
*
|
|
2535
|
+
* Use this when constructing a deep link or share URL outside the grid (e.g. via
|
|
2536
|
+
* `getSearchParamsFromFilterModel` + `buildQueryParamsString`). The grid itself
|
|
2537
|
+
* always includes `v` in URLs it writes via `getFinalSearch`, but external helpers
|
|
2538
|
+
* do not — include this when you want a stale `localStorageVersion` bump to invalidate
|
|
2539
|
+
* the link. Omitting `v` is also safe: a missing `v` is treated as "current version"
|
|
2540
|
+
* and the URL state is applied as-is.
|
|
2541
|
+
*
|
|
2542
|
+
* @example
|
|
2543
|
+
* const params = new URLSearchParams([
|
|
2544
|
+
* ...getSearchParamsFromFilterModel(filterModel),
|
|
2545
|
+
* ...getSearchParamsFromVersion(1),
|
|
2546
|
+
* ]);
|
|
2547
|
+
* const url = `/my-grid${buildQueryParamsString(urlSearchParamsToString(params))}`;
|
|
2548
|
+
*/
|
|
2549
|
+
const getSearchParamsFromVersion = version => {
|
|
2550
|
+
const searchParams = new URLSearchParams();
|
|
2551
|
+
searchParams.set('v', String(version));
|
|
2552
|
+
return searchParams;
|
|
2553
|
+
};
|
|
2554
|
+
const getPivotActive = (search, localStoragePivotActive, setLocalStoragePivotActive, initialState, isNewVersion) => {
|
|
2555
|
+
var _initialState$pivotin2, _initialState$pivotin3;
|
|
2556
|
+
const defaultValue = (_initialState$pivotin2 = initialState === null || initialState === void 0 ? void 0 : (_initialState$pivotin3 = initialState.pivoting) === null || _initialState$pivotin3 === void 0 ? void 0 : _initialState$pivotin3.enabled) !== null && _initialState$pivotin2 !== void 0 ? _initialState$pivotin2 : false;
|
|
2557
|
+
const persistDefault = () => {
|
|
2558
|
+
const searchFromDefault = getSearchParamsFromPivotActive(defaultValue);
|
|
2559
|
+
const searchString = urlSearchParamsToString(searchFromDefault);
|
|
2560
|
+
if (searchString !== localStoragePivotActive) {
|
|
2561
|
+
setLocalStoragePivotActive(searchString);
|
|
2562
|
+
}
|
|
2563
|
+
};
|
|
2564
|
+
if (isNewVersion) {
|
|
2565
|
+
persistDefault();
|
|
2566
|
+
return defaultValue;
|
|
2567
|
+
}
|
|
2568
|
+
const fromUrl = getPivotActiveFromString(search);
|
|
2569
|
+
if (fromUrl !== 'invalid') {
|
|
2570
|
+
const searchFromModel = getSearchParamsFromPivotActive(fromUrl);
|
|
2571
|
+
const searchString = urlSearchParamsToString(searchFromModel);
|
|
2572
|
+
if (searchString !== localStoragePivotActive) {
|
|
2573
|
+
setLocalStoragePivotActive(searchString);
|
|
2574
|
+
}
|
|
2575
|
+
return fromUrl;
|
|
2576
|
+
}
|
|
2577
|
+
const fromLocalStorage = getPivotActiveFromString(localStoragePivotActive);
|
|
2578
|
+
if (fromLocalStorage !== 'invalid') {
|
|
2579
|
+
return fromLocalStorage;
|
|
2580
|
+
}
|
|
2581
|
+
persistDefault();
|
|
2582
|
+
return defaultValue;
|
|
2583
|
+
};
|
|
2584
|
+
const getFinalSearch = _ref3 => {
|
|
2585
|
+
let {
|
|
2586
|
+
search,
|
|
2587
|
+
localStorageVersion,
|
|
2588
|
+
filterModel,
|
|
2589
|
+
sortModel,
|
|
2590
|
+
paginationModel,
|
|
2591
|
+
columnsVisibilityModel,
|
|
2592
|
+
pinnedColumnsModel,
|
|
2593
|
+
density,
|
|
2594
|
+
columnOrderModel,
|
|
2595
|
+
defaultColumnOrder,
|
|
2596
|
+
rowGroupingModel,
|
|
2597
|
+
aggregationModel,
|
|
2598
|
+
pivotModel,
|
|
2599
|
+
pivotActive,
|
|
2600
|
+
columns
|
|
2601
|
+
} = _ref3;
|
|
2602
|
+
const filterModelSearch = getSearchParamsFromFilterModel(filterModel);
|
|
2603
|
+
const sortModelSearch = getSearchParamsFromSorting(sortModel);
|
|
2604
|
+
const paginationModelSearch = getSearchParamsFromPagination(paginationModel);
|
|
2605
|
+
const columnVisibilityModelSearch = getSearchParamsFromColumnVisibility(columnsVisibilityModel, columns);
|
|
2606
|
+
const pinnedColumnsModelSearch = getSearchParamsFromPinnedColumns(pinnedColumnsModel);
|
|
2607
|
+
const densitySearch = getSearchParamsFromDensity(density);
|
|
2608
|
+
// Only include _columnOrder in URL when it differs from the default
|
|
2609
|
+
const columnOrderSearch = columnOrderModel.length !== defaultColumnOrder.length || columnOrderModel.some((field, i) => field !== defaultColumnOrder[i]) ? getSearchParamsFromColumnOrder(columnOrderModel) : new URLSearchParams();
|
|
2610
|
+
const rowGroupingSearch = getSearchParamsFromRowGrouping(rowGroupingModel);
|
|
2611
|
+
const aggregationSearch = getSearchParamsFromAggregation(aggregationModel);
|
|
2612
|
+
const pivotSearch = getSearchParamsFromPivot(pivotModel);
|
|
2613
|
+
const pivotActiveSearch = getSearchParamsFromPivotActive(pivotActive);
|
|
2614
|
+
const tabSearch = getSearchParamsFromTab(search);
|
|
2615
|
+
const searchParams = new URLSearchParams();
|
|
2616
|
+
for (const [key, value] of new URLSearchParams(search)) {
|
|
2617
|
+
if (!key.startsWith('_')) {
|
|
2618
|
+
searchParams.set(key, value);
|
|
2619
|
+
}
|
|
2620
|
+
}
|
|
2621
|
+
searchParams.set('v', `${localStorageVersion}`);
|
|
2622
|
+
|
|
2623
|
+
// Add quickFilterValues explicitly if present in filterModel
|
|
2624
|
+
if (filterModel.quickFilterValues && filterModel.quickFilterValues.length > 0) {
|
|
2625
|
+
// Encode array as JSON string to preserve all values in one param
|
|
2626
|
+
searchParams.set('_quickFilterValues', encodeURIComponent(JSON.stringify(filterModel.quickFilterValues)));
|
|
2627
|
+
}
|
|
2628
|
+
return new URLSearchParams([...searchParams, ...filterModelSearch, ...sortModelSearch, ...paginationModelSearch, ...tabSearch, ...pinnedColumnsModelSearch, ...columnVisibilityModelSearch, ...densitySearch, ...columnOrderSearch, ...rowGroupingSearch, ...aggregationSearch, ...pivotSearch, ...pivotActiveSearch]);
|
|
3501
2629
|
};
|
|
3502
2630
|
/** Return the state of the table given the URL and the local storage state */
|
|
3503
|
-
const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, columns, initialState, localStorage) => {
|
|
2631
|
+
const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, columns, initialState, localStorage, previousFilterModel) => {
|
|
3504
2632
|
var _initialState$columns6, _initialState$columns7;
|
|
3505
2633
|
// Decompress any compressed params in the search string before processing
|
|
3506
2634
|
const decompressedSearch = decompressSearchParams(search);
|
|
@@ -3537,15 +2665,27 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
|
|
|
3537
2665
|
localStorageDensity,
|
|
3538
2666
|
setLocalStorageDensity,
|
|
3539
2667
|
localStorageColumnOrder,
|
|
3540
|
-
setLocalStorageColumnOrder
|
|
2668
|
+
setLocalStorageColumnOrder,
|
|
2669
|
+
localStorageRowGrouping,
|
|
2670
|
+
setLocalStorageRowGrouping,
|
|
2671
|
+
localStorageAggregation,
|
|
2672
|
+
setLocalStorageAggregation,
|
|
2673
|
+
localStoragePivot,
|
|
2674
|
+
setLocalStoragePivot,
|
|
2675
|
+
localStoragePivotActive,
|
|
2676
|
+
setLocalStoragePivotActive
|
|
3541
2677
|
} = localStorage;
|
|
3542
|
-
const filterModel = getFilterModel(decodedSearch, columns, localStorageFilters, setLocalStorageFilters, initialState, isNewVersion);
|
|
2678
|
+
const filterModel = getFilterModel(decodedSearch, columns, localStorageFilters, setLocalStorageFilters, initialState, isNewVersion, previousFilterModel);
|
|
3543
2679
|
const sortModel = getSortModel(decodedSearch, columns, localStorageSorting, setLocalStorageSorting, initialState, isNewVersion);
|
|
3544
2680
|
const paginationModel = getPaginationModel(decodedSearch, localStoragePagination, setLocalStoragePagination, initialState, isNewVersion);
|
|
3545
2681
|
const columnVisibilityModel = getColumnsVisibility(decodedSearch, columns, localStorageColumnsVisibility, setLocalStorageColumnsVisibility, initialState, isNewVersion);
|
|
3546
2682
|
const pinnedColumnsModel = getPinnedColumns(decodedSearch, columns, localStoragePinnedColumns, setLocalStoragePinnedColumns, initialState, isNewVersion);
|
|
3547
2683
|
const density = getDensityModel(decodedSearch, localStorageDensity, setLocalStorageDensity, initialState, isNewVersion);
|
|
3548
2684
|
const columnOrderModel = getColumnOrder(decodedSearch, columns, localStorageColumnOrder, setLocalStorageColumnOrder, initialState, isNewVersion);
|
|
2685
|
+
const rowGroupingModel = getRowGroupingModel(decodedSearch, localStorageRowGrouping, setLocalStorageRowGrouping, initialState, isNewVersion);
|
|
2686
|
+
const aggregationModel = getAggregationModel(decodedSearch, localStorageAggregation, setLocalStorageAggregation, initialState, isNewVersion);
|
|
2687
|
+
const pivotModel = getPivotModel(decodedSearch, localStoragePivot, setLocalStoragePivot, initialState, isNewVersion);
|
|
2688
|
+
const pivotActive = getPivotActive(decodedSearch, localStoragePivotActive, setLocalStoragePivotActive, initialState, isNewVersion);
|
|
3549
2689
|
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);
|
|
3550
2690
|
const finalSearch = getFinalSearch({
|
|
3551
2691
|
localStorageVersion,
|
|
@@ -3558,6 +2698,10 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
|
|
|
3558
2698
|
density,
|
|
3559
2699
|
columnOrderModel,
|
|
3560
2700
|
defaultColumnOrder,
|
|
2701
|
+
rowGroupingModel,
|
|
2702
|
+
aggregationModel,
|
|
2703
|
+
pivotModel,
|
|
2704
|
+
pivotActive,
|
|
3561
2705
|
columns
|
|
3562
2706
|
});
|
|
3563
2707
|
const internalSearchString = urlSearchParamsToString(finalSearch);
|
|
@@ -3578,10 +2722,14 @@ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, column
|
|
|
3578
2722
|
pinnedColumnsModel,
|
|
3579
2723
|
density,
|
|
3580
2724
|
columnOrderModel,
|
|
2725
|
+
rowGroupingModel,
|
|
2726
|
+
aggregationModel,
|
|
2727
|
+
pivotModel,
|
|
2728
|
+
pivotActive,
|
|
3581
2729
|
pendingSearch
|
|
3582
2730
|
};
|
|
3583
2731
|
};
|
|
3584
|
-
const updateUrl = (
|
|
2732
|
+
const updateUrl = (_ref4, search, localStorageVersion, historyReplace, columns) => {
|
|
3585
2733
|
let {
|
|
3586
2734
|
filterModel,
|
|
3587
2735
|
sortModel,
|
|
@@ -3590,8 +2738,12 @@ const updateUrl = (_ref2, search, localStorageVersion, historyReplace, columns)
|
|
|
3590
2738
|
pinnedColumnsModel,
|
|
3591
2739
|
density,
|
|
3592
2740
|
columnOrderModel,
|
|
3593
|
-
defaultColumnOrder
|
|
3594
|
-
|
|
2741
|
+
defaultColumnOrder,
|
|
2742
|
+
rowGroupingModel,
|
|
2743
|
+
aggregationModel,
|
|
2744
|
+
pivotModel,
|
|
2745
|
+
pivotActive
|
|
2746
|
+
} = _ref4;
|
|
3595
2747
|
// Convert from display format to internal format if needed
|
|
3596
2748
|
const decodedSearch = getDecodedSearchFromUrl(search, columns);
|
|
3597
2749
|
const newSearch = getFinalSearch({
|
|
@@ -3605,6 +2757,10 @@ const updateUrl = (_ref2, search, localStorageVersion, historyReplace, columns)
|
|
|
3605
2757
|
density,
|
|
3606
2758
|
columnOrderModel,
|
|
3607
2759
|
defaultColumnOrder,
|
|
2760
|
+
rowGroupingModel,
|
|
2761
|
+
aggregationModel,
|
|
2762
|
+
pivotModel,
|
|
2763
|
+
pivotActive,
|
|
3608
2764
|
columns
|
|
3609
2765
|
});
|
|
3610
2766
|
const internalSearchString = urlSearchParamsToString(newSearch);
|
|
@@ -3797,6 +2953,26 @@ const useTableStates = (id, version) => {
|
|
|
3797
2953
|
version,
|
|
3798
2954
|
category: COLUMN_ORDER_MODEL_KEY
|
|
3799
2955
|
}));
|
|
2956
|
+
const [rowGroupingModel, setRowGroupingModel] = useFetchState('', buildStorageKey({
|
|
2957
|
+
id,
|
|
2958
|
+
version,
|
|
2959
|
+
category: ROW_GROUPING_MODEL_KEY
|
|
2960
|
+
}));
|
|
2961
|
+
const [aggregationModel, setAggregationModel] = useFetchState('', buildStorageKey({
|
|
2962
|
+
id,
|
|
2963
|
+
version,
|
|
2964
|
+
category: AGGREGATION_MODEL_KEY
|
|
2965
|
+
}));
|
|
2966
|
+
const [pivotModel, setPivotModel] = useFetchState('', buildStorageKey({
|
|
2967
|
+
id,
|
|
2968
|
+
version,
|
|
2969
|
+
category: PIVOT_MODEL_KEY
|
|
2970
|
+
}));
|
|
2971
|
+
const [pivotActive, setPivotActive] = useFetchState('', buildStorageKey({
|
|
2972
|
+
id,
|
|
2973
|
+
version,
|
|
2974
|
+
category: PIVOT_ACTIVE_KEY
|
|
2975
|
+
}));
|
|
3800
2976
|
return {
|
|
3801
2977
|
paginationModel,
|
|
3802
2978
|
setPaginationModel,
|
|
@@ -3813,10 +2989,55 @@ const useTableStates = (id, version) => {
|
|
|
3813
2989
|
densityModel,
|
|
3814
2990
|
setDensityModel,
|
|
3815
2991
|
columnOrderModel,
|
|
3816
|
-
setColumnOrderModel
|
|
2992
|
+
setColumnOrderModel,
|
|
2993
|
+
rowGroupingModel,
|
|
2994
|
+
setRowGroupingModel,
|
|
2995
|
+
aggregationModel,
|
|
2996
|
+
setAggregationModel,
|
|
2997
|
+
pivotModel,
|
|
2998
|
+
setPivotModel,
|
|
2999
|
+
pivotActive,
|
|
3000
|
+
setPivotActive
|
|
3817
3001
|
};
|
|
3818
3002
|
};
|
|
3819
3003
|
|
|
3004
|
+
/** Convert our simplified PivotModel → MUI's GridPivotModel */
|
|
3005
|
+
const toGridPivotModel = model => ({
|
|
3006
|
+
columns: model.columns.map(field => ({
|
|
3007
|
+
field
|
|
3008
|
+
})),
|
|
3009
|
+
rows: model.rows.map(field => ({
|
|
3010
|
+
field
|
|
3011
|
+
})),
|
|
3012
|
+
values: model.values.map(_ref => {
|
|
3013
|
+
let {
|
|
3014
|
+
field,
|
|
3015
|
+
aggFunc
|
|
3016
|
+
} = _ref;
|
|
3017
|
+
return {
|
|
3018
|
+
field,
|
|
3019
|
+
aggFunc
|
|
3020
|
+
};
|
|
3021
|
+
})
|
|
3022
|
+
});
|
|
3023
|
+
|
|
3024
|
+
/**
|
|
3025
|
+
* Deep-equal comparison for plain objects / arrays.
|
|
3026
|
+
* Used to stabilise parsed model references so that MUI v8 does not
|
|
3027
|
+
* reset pagination on every render.
|
|
3028
|
+
*/
|
|
3029
|
+
function isDeepEqual(a, b) {
|
|
3030
|
+
if (a === b) return true;
|
|
3031
|
+
if (a == null || b == null) return false;
|
|
3032
|
+
if (typeof a !== typeof b) return false;
|
|
3033
|
+
if (typeof a !== 'object') return false;
|
|
3034
|
+
const aObj = a;
|
|
3035
|
+
const bObj = b;
|
|
3036
|
+
const aKeys = Object.keys(aObj);
|
|
3037
|
+
const bKeys = Object.keys(bObj);
|
|
3038
|
+
if (aKeys.length !== bKeys.length) return false;
|
|
3039
|
+
return aKeys.every(key => isDeepEqual(aObj[key], bObj[key]));
|
|
3040
|
+
}
|
|
3820
3041
|
const useStatefulTable = props => {
|
|
3821
3042
|
var _initialState$columns, _initialState$columns2;
|
|
3822
3043
|
const {
|
|
@@ -3829,6 +3050,9 @@ const useStatefulTable = props => {
|
|
|
3829
3050
|
onPaginationModelChange: propsOnPaginationModelChange,
|
|
3830
3051
|
onPinnedColumnsChange: propsOnPinnedColumnsChange,
|
|
3831
3052
|
onSortModelChange: propsOnSortModelChange,
|
|
3053
|
+
onRowGroupingModelChange: propsOnRowGroupingModelChange,
|
|
3054
|
+
onAggregationModelChange: propsOnAggregationModelChange,
|
|
3055
|
+
onPivotModelChange: propsOnPivotModelChange,
|
|
3832
3056
|
useRouter,
|
|
3833
3057
|
localStorageVersion = 1,
|
|
3834
3058
|
previousLocalStorageVersions = []
|
|
@@ -3857,20 +3081,33 @@ const useStatefulTable = props => {
|
|
|
3857
3081
|
densityModel,
|
|
3858
3082
|
setDensityModel,
|
|
3859
3083
|
columnOrderModel: localStorageColumnOrder,
|
|
3860
|
-
setColumnOrderModel: setLocalStorageColumnOrder
|
|
3084
|
+
setColumnOrderModel: setLocalStorageColumnOrder,
|
|
3085
|
+
rowGroupingModel: localStorageRowGrouping,
|
|
3086
|
+
setRowGroupingModel: setLocalStorageRowGrouping,
|
|
3087
|
+
aggregationModel: localStorageAggregation,
|
|
3088
|
+
setAggregationModel: setLocalStorageAggregation,
|
|
3089
|
+
pivotModel: localStoragePivot,
|
|
3090
|
+
setPivotModel: setLocalStoragePivot,
|
|
3091
|
+
pivotActive: localStoragePivotActive,
|
|
3092
|
+
setPivotActive: setLocalStoragePivotActive
|
|
3861
3093
|
} = useTableStates(id, localStorageVersion);
|
|
3862
3094
|
|
|
3863
3095
|
// clearing up old version keys, triggering only on first render
|
|
3864
3096
|
useEffect(() => clearPreviousVersionStorage(id, previousLocalStorageVersions), [id, previousLocalStorageVersions]);
|
|
3865
|
-
const onColumnDimensionChange = useCallback(
|
|
3097
|
+
const onColumnDimensionChange = useCallback(_ref2 => {
|
|
3866
3098
|
let {
|
|
3867
3099
|
newWidth,
|
|
3868
3100
|
field
|
|
3869
|
-
} =
|
|
3101
|
+
} = _ref2;
|
|
3870
3102
|
setDimensionModel(_objectSpread2(_objectSpread2({}, dimensionModel), {}, {
|
|
3871
3103
|
[field]: newWidth
|
|
3872
3104
|
}));
|
|
3873
3105
|
}, [dimensionModel, setDimensionModel]);
|
|
3106
|
+
|
|
3107
|
+
// Source of ids for content-matching in the parser, so item.id is stable across the
|
|
3108
|
+
// URL write→parse roundtrip (DS-81). Holds MUI's just-emitted model (random placeholder
|
|
3109
|
+
// id) after onFilterModelChange, then the stabilised parsed model each render.
|
|
3110
|
+
const filterIdSourceRef = useRef(undefined);
|
|
3874
3111
|
const {
|
|
3875
3112
|
filterModel: filterParsed,
|
|
3876
3113
|
sortModel: sortModelParsed,
|
|
@@ -3879,6 +3116,10 @@ const useStatefulTable = props => {
|
|
|
3879
3116
|
pinnedColumnsModel,
|
|
3880
3117
|
density: densityParsed,
|
|
3881
3118
|
columnOrderModel: columnOrderParsed,
|
|
3119
|
+
rowGroupingModel: rowGroupingParsed,
|
|
3120
|
+
aggregationModel: aggregationParsed,
|
|
3121
|
+
pivotModel: pivotParsed,
|
|
3122
|
+
pivotActive: pivotActiveParsed,
|
|
3882
3123
|
pendingSearch
|
|
3883
3124
|
} = getModelsParsedOrUpdateLocalStorage(search || '', localStorageVersion, propsColumns, initialState, {
|
|
3884
3125
|
localStorageFilters,
|
|
@@ -3894,8 +3135,16 @@ const useStatefulTable = props => {
|
|
|
3894
3135
|
localStorageDensity: densityModel,
|
|
3895
3136
|
setLocalStorageDensity: setDensityModel,
|
|
3896
3137
|
localStorageColumnOrder,
|
|
3897
|
-
setLocalStorageColumnOrder
|
|
3898
|
-
|
|
3138
|
+
setLocalStorageColumnOrder,
|
|
3139
|
+
localStorageRowGrouping,
|
|
3140
|
+
setLocalStorageRowGrouping,
|
|
3141
|
+
localStorageAggregation,
|
|
3142
|
+
setLocalStorageAggregation,
|
|
3143
|
+
localStoragePivot,
|
|
3144
|
+
setLocalStoragePivot,
|
|
3145
|
+
localStoragePivotActive: localStoragePivotActive,
|
|
3146
|
+
setLocalStoragePivotActive: setLocalStoragePivotActive
|
|
3147
|
+
}, filterIdSourceRef.current);
|
|
3899
3148
|
|
|
3900
3149
|
// Sync URL in an effect rather than during render to comply with React rules
|
|
3901
3150
|
useEffect(() => {
|
|
@@ -3903,6 +3152,49 @@ const useStatefulTable = props => {
|
|
|
3903
3152
|
historyReplace(pendingSearch);
|
|
3904
3153
|
}
|
|
3905
3154
|
}, [pendingSearch, historyReplace]);
|
|
3155
|
+
|
|
3156
|
+
// Stabilise parsed model references to prevent MUI v8 from resetting
|
|
3157
|
+
// pagination on every render due to new object identity.
|
|
3158
|
+
const filterParsedRef = useRef(filterParsed);
|
|
3159
|
+
if (!isDeepEqual(filterParsedRef.current, filterParsed)) {
|
|
3160
|
+
filterParsedRef.current = filterParsed;
|
|
3161
|
+
}
|
|
3162
|
+
// Keep the id source in sync with the stabilised parsed model so re-parses triggered
|
|
3163
|
+
// by unrelated state (pagination/sort/visibility) reuse the same ids (DS-81). The parse
|
|
3164
|
+
// call above reads the ref before this write (read-before-write within the render).
|
|
3165
|
+
filterIdSourceRef.current = filterParsed;
|
|
3166
|
+
const sortModelParsedRef = useRef(sortModelParsed);
|
|
3167
|
+
if (!isDeepEqual(sortModelParsedRef.current, sortModelParsed)) {
|
|
3168
|
+
sortModelParsedRef.current = sortModelParsed;
|
|
3169
|
+
}
|
|
3170
|
+
const paginationModelParsedRef = useRef(paginationModelParsed);
|
|
3171
|
+
if (!isDeepEqual(paginationModelParsedRef.current, paginationModelParsed)) {
|
|
3172
|
+
paginationModelParsedRef.current = paginationModelParsed;
|
|
3173
|
+
}
|
|
3174
|
+
const visibilityModelRef = useRef(visibilityModel);
|
|
3175
|
+
if (!isDeepEqual(visibilityModelRef.current, visibilityModel)) {
|
|
3176
|
+
visibilityModelRef.current = visibilityModel;
|
|
3177
|
+
}
|
|
3178
|
+
const pinnedColumnsModelRef = useRef(pinnedColumnsModel);
|
|
3179
|
+
if (!isDeepEqual(pinnedColumnsModelRef.current, pinnedColumnsModel)) {
|
|
3180
|
+
pinnedColumnsModelRef.current = pinnedColumnsModel;
|
|
3181
|
+
}
|
|
3182
|
+
const columnOrderParsedRef = useRef(columnOrderParsed);
|
|
3183
|
+
if (!isDeepEqual(columnOrderParsedRef.current, columnOrderParsed)) {
|
|
3184
|
+
columnOrderParsedRef.current = columnOrderParsed;
|
|
3185
|
+
}
|
|
3186
|
+
const rowGroupingParsedRef = useRef(rowGroupingParsed);
|
|
3187
|
+
if (!isDeepEqual(rowGroupingParsedRef.current, rowGroupingParsed)) {
|
|
3188
|
+
rowGroupingParsedRef.current = rowGroupingParsed;
|
|
3189
|
+
}
|
|
3190
|
+
const aggregationParsedRef = useRef(aggregationParsed);
|
|
3191
|
+
if (!isDeepEqual(aggregationParsedRef.current, aggregationParsed)) {
|
|
3192
|
+
aggregationParsedRef.current = aggregationParsed;
|
|
3193
|
+
}
|
|
3194
|
+
const pivotParsedRef = useRef(pivotParsed);
|
|
3195
|
+
if (!isDeepEqual(pivotParsedRef.current, pivotParsed)) {
|
|
3196
|
+
pivotParsedRef.current = pivotParsed;
|
|
3197
|
+
}
|
|
3906
3198
|
const columns = useMemo(() => propsColumns.map(column => {
|
|
3907
3199
|
return _objectSpread2(_objectSpread2({}, column), {}, {
|
|
3908
3200
|
width: dimensionModel[column.field] || column.width || 100
|
|
@@ -3911,56 +3203,61 @@ const useStatefulTable = props => {
|
|
|
3911
3203
|
if (apiRef.current) {
|
|
3912
3204
|
/** Add resetPage method to apiRef. */
|
|
3913
3205
|
apiRef.current.resetPage = () => {
|
|
3914
|
-
|
|
3206
|
+
var _apiRef$current;
|
|
3207
|
+
(_apiRef$current = apiRef.current) === null || _apiRef$current === void 0 ? void 0 : _apiRef$current.setPage(0);
|
|
3915
3208
|
};
|
|
3916
3209
|
}
|
|
3917
3210
|
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);
|
|
3918
3211
|
|
|
3919
|
-
// Helper to build the current DataGridModel for updateUrl calls
|
|
3920
|
-
const buildModel = function () {
|
|
3921
|
-
var _apiRef$current$state, _apiRef$current;
|
|
3922
|
-
let overrides = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
3923
|
-
return _objectSpread2({
|
|
3924
|
-
filterModel: filterParsed,
|
|
3925
|
-
sortModel: sortModelParsed,
|
|
3926
|
-
paginationModel: paginationModelParsed,
|
|
3927
|
-
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 : {},
|
|
3928
|
-
pinnedColumnsModel: pinnedColumnsModel,
|
|
3929
|
-
density: densityParsed,
|
|
3930
|
-
columnOrderModel: columnOrderParsed,
|
|
3931
|
-
defaultColumnOrder
|
|
3932
|
-
}, overrides);
|
|
3933
|
-
};
|
|
3934
|
-
|
|
3935
3212
|
// Subscribe to density changes via stateChange event (MUI v6 has no densityChange event)
|
|
3936
3213
|
useEffect(() => {
|
|
3937
3214
|
const api = apiRef.current;
|
|
3938
3215
|
if (!(api !== null && api !== void 0 && api.subscribeEvent)) return;
|
|
3939
3216
|
let prevDensity = densityParsed;
|
|
3940
3217
|
const unsub = api.subscribeEvent('stateChange', () => {
|
|
3941
|
-
const currentDensity = api.state.density
|
|
3218
|
+
const currentDensity = api.state.density;
|
|
3942
3219
|
if (currentDensity !== prevDensity) {
|
|
3943
3220
|
prevDensity = currentDensity;
|
|
3944
|
-
updateUrl(
|
|
3221
|
+
updateUrl({
|
|
3222
|
+
filterModel: filterParsed,
|
|
3223
|
+
sortModel: sortModelParsed,
|
|
3224
|
+
paginationModel: paginationModelParsed,
|
|
3945
3225
|
columnsModel: api.state.columns.columnVisibilityModel,
|
|
3946
|
-
|
|
3947
|
-
|
|
3226
|
+
pinnedColumnsModel: pinnedColumnsModel,
|
|
3227
|
+
density: currentDensity,
|
|
3228
|
+
columnOrderModel: columnOrderParsed,
|
|
3229
|
+
defaultColumnOrder,
|
|
3230
|
+
rowGroupingModel: rowGroupingParsed,
|
|
3231
|
+
aggregationModel: aggregationParsed,
|
|
3232
|
+
pivotModel: pivotParsed,
|
|
3233
|
+
pivotActive: pivotActiveParsed
|
|
3234
|
+
}, search, localStorageVersion, historyReplace, columns);
|
|
3948
3235
|
}
|
|
3949
3236
|
});
|
|
3950
3237
|
return unsub;
|
|
3951
|
-
}, [apiRef, densityParsed, filterParsed, sortModelParsed, paginationModelParsed, pinnedColumnsModel, columnOrderParsed, defaultColumnOrder, search, localStorageVersion, historyReplace, columns]);
|
|
3238
|
+
}, [apiRef, densityParsed, filterParsed, sortModelParsed, paginationModelParsed, pinnedColumnsModel, columnOrderParsed, defaultColumnOrder, rowGroupingParsed, aggregationParsed, pivotParsed, pivotActiveParsed, search, localStorageVersion, historyReplace, columns]);
|
|
3952
3239
|
|
|
3953
3240
|
// Subscribe to column order changes via columnOrderChange (drag-drop) and columnIndexChange (programmatic setColumnIndex)
|
|
3954
3241
|
useEffect(() => {
|
|
3955
3242
|
const api = apiRef.current;
|
|
3956
3243
|
if (!(api !== null && api !== void 0 && api.subscribeEvent)) return;
|
|
3957
|
-
const isDeepEqual = (a, b) => JSON.stringify(a) === JSON.stringify(b);
|
|
3958
3244
|
const handleColumnOrderChange = () => {
|
|
3959
3245
|
const orderedFields = api.state.columns.orderedFields;
|
|
3960
3246
|
if (orderedFields && !isDeepEqual(orderedFields, columnOrderParsed)) {
|
|
3961
|
-
updateUrl(
|
|
3962
|
-
|
|
3963
|
-
|
|
3247
|
+
updateUrl({
|
|
3248
|
+
filterModel: filterParsed,
|
|
3249
|
+
sortModel: sortModelParsed,
|
|
3250
|
+
paginationModel: paginationModelParsed,
|
|
3251
|
+
columnsModel: api.state.columns.columnVisibilityModel,
|
|
3252
|
+
pinnedColumnsModel,
|
|
3253
|
+
density: densityParsed,
|
|
3254
|
+
columnOrderModel: orderedFields,
|
|
3255
|
+
defaultColumnOrder,
|
|
3256
|
+
rowGroupingModel: rowGroupingParsed,
|
|
3257
|
+
aggregationModel: aggregationParsed,
|
|
3258
|
+
pivotModel: pivotParsed,
|
|
3259
|
+
pivotActive: pivotActiveParsed
|
|
3260
|
+
}, search, localStorageVersion, historyReplace, columns);
|
|
3964
3261
|
}
|
|
3965
3262
|
};
|
|
3966
3263
|
const unsub1 = api.subscribeEvent('columnOrderChange', handleColumnOrderChange);
|
|
@@ -3969,69 +3266,124 @@ const useStatefulTable = props => {
|
|
|
3969
3266
|
unsub1();
|
|
3970
3267
|
unsub2();
|
|
3971
3268
|
};
|
|
3972
|
-
}, [apiRef, columnOrderParsed, defaultColumnOrder, filterParsed, sortModelParsed, paginationModelParsed, pinnedColumnsModel, densityParsed, search, localStorageVersion, historyReplace, columns]);
|
|
3269
|
+
}, [apiRef, columnOrderParsed, defaultColumnOrder, filterParsed, sortModelParsed, paginationModelParsed, pinnedColumnsModel, densityParsed, rowGroupingParsed, aggregationParsed, pivotParsed, pivotActiveParsed, search, localStorageVersion, historyReplace, columns]);
|
|
3270
|
+
|
|
3271
|
+
// Helper to build the current DataGridModel for updateUrl calls
|
|
3272
|
+
const buildModel = function () {
|
|
3273
|
+
var _apiRef$current$state, _apiRef$current2;
|
|
3274
|
+
let overrides = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
3275
|
+
return _objectSpread2({
|
|
3276
|
+
filterModel: filterParsed,
|
|
3277
|
+
sortModel: sortModelParsed,
|
|
3278
|
+
paginationModel: paginationModelParsed,
|
|
3279
|
+
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 : {},
|
|
3280
|
+
pinnedColumnsModel: pinnedColumnsModel,
|
|
3281
|
+
density: densityParsed,
|
|
3282
|
+
columnOrderModel: columnOrderParsed,
|
|
3283
|
+
defaultColumnOrder,
|
|
3284
|
+
rowGroupingModel: rowGroupingParsed,
|
|
3285
|
+
aggregationModel: aggregationParsed,
|
|
3286
|
+
pivotModel: pivotParsed,
|
|
3287
|
+
pivotActive: pivotActiveParsed
|
|
3288
|
+
}, overrides);
|
|
3289
|
+
};
|
|
3290
|
+
|
|
3291
|
+
// Stable GridPivotModel identity — only recompute when the simplified value changes.
|
|
3292
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3293
|
+
const pivotModelMui = useMemo(() => toGridPivotModel(pivotParsed), [JSON.stringify(pivotParsed)]);
|
|
3973
3294
|
|
|
3974
3295
|
// Track last emitted values for deep-equal guards to avoid feedback loops.
|
|
3296
|
+
// Initialised from the current parsed values; updated only when we actually fire.
|
|
3975
3297
|
const lastEmittedFilterRef = useRef(filterParsed);
|
|
3976
3298
|
const lastEmittedSortRef = useRef(sortModelParsed);
|
|
3977
3299
|
const lastEmittedPaginationRef = useRef(paginationModelParsed);
|
|
3978
|
-
const
|
|
3300
|
+
const lastEmittedPivotRef = useRef(pivotParsed);
|
|
3979
3301
|
return {
|
|
3980
3302
|
apiRef,
|
|
3981
3303
|
columns,
|
|
3982
3304
|
density: densityParsed,
|
|
3983
|
-
columnOrderModel:
|
|
3305
|
+
columnOrderModel: columnOrderParsedRef.current,
|
|
3306
|
+
rowGroupingModel: rowGroupingParsedRef.current,
|
|
3307
|
+
aggregationModel: aggregationParsedRef.current,
|
|
3308
|
+
pivotModel: pivotModelMui,
|
|
3309
|
+
pivotActive: pivotActiveParsed,
|
|
3984
3310
|
onFilterModelChange: (model, details) => {
|
|
3985
3311
|
const filterModel = _objectSpread2(_objectSpread2({}, model), {}, {
|
|
3986
3312
|
items: model.items.map(item => {
|
|
3987
|
-
|
|
3988
|
-
|
|
3313
|
+
var _apiRef$current3;
|
|
3314
|
+
const column = (_apiRef$current3 = apiRef.current) === null || _apiRef$current3 === void 0 ? void 0 : _apiRef$current3.getColumn(item.field);
|
|
3315
|
+
item.type = (column === null || column === void 0 ? void 0 : column.type) || 'string';
|
|
3989
3316
|
return item;
|
|
3990
3317
|
}),
|
|
3991
3318
|
quickFilterValues: model.quickFilterValues || []
|
|
3992
3319
|
});
|
|
3993
|
-
if (
|
|
3320
|
+
if (isDeepEqual(filterModel, lastEmittedFilterRef.current)) return;
|
|
3994
3321
|
lastEmittedFilterRef.current = filterModel;
|
|
3995
|
-
|
|
3322
|
+
// Capture MUI's just-emitted model (carrying the placeholder's random id) so the
|
|
3323
|
+
// next render's URL re-parse reuses that id and the GridFilterForm key — and thus
|
|
3324
|
+
// the value input's focus — survives the write→parse roundtrip (DS-81).
|
|
3325
|
+
filterIdSourceRef.current = filterModel;
|
|
3996
3326
|
updateUrl(buildModel({
|
|
3997
3327
|
filterModel
|
|
3998
3328
|
}), search, localStorageVersion, historyReplace, columns);
|
|
3329
|
+
propsOnFilterModelChange === null || propsOnFilterModelChange === void 0 ? void 0 : propsOnFilterModelChange(filterModel, details);
|
|
3999
3330
|
},
|
|
4000
|
-
filterModel:
|
|
3331
|
+
filterModel: filterParsedRef.current,
|
|
4001
3332
|
onSortModelChange: (model, details) => {
|
|
4002
|
-
if (
|
|
3333
|
+
if (isDeepEqual(model, lastEmittedSortRef.current)) return;
|
|
4003
3334
|
lastEmittedSortRef.current = model;
|
|
4004
|
-
propsOnSortModelChange === null || propsOnSortModelChange === void 0 ? void 0 : propsOnSortModelChange(model, details);
|
|
4005
3335
|
updateUrl(buildModel({
|
|
4006
3336
|
sortModel: model
|
|
4007
3337
|
}), search, localStorageVersion, historyReplace, columns);
|
|
3338
|
+
propsOnSortModelChange === null || propsOnSortModelChange === void 0 ? void 0 : propsOnSortModelChange(model, details);
|
|
4008
3339
|
},
|
|
4009
|
-
sortModel:
|
|
3340
|
+
sortModel: sortModelParsedRef.current,
|
|
4010
3341
|
onPinnedColumnsChange: (pinnedColumns, details) => {
|
|
3342
|
+
var _apiRef$current$state2, _apiRef$current4, _apiRef$current4$stat, _apiRef$current4$stat2;
|
|
3343
|
+
// While pivot mode is active, MUI Premium emits synthetic pinned-column
|
|
3344
|
+
// models (e.g. `__row_group_by_columns_group__` for the grouping column)
|
|
3345
|
+
// that must not be persisted to the URL / localStorage. Read the live
|
|
3346
|
+
// grid state from apiRef rather than the parsed URL value because the
|
|
3347
|
+
// URL lags by a tick during pivot enable/disable transitions. Consumer
|
|
3348
|
+
// callbacks are always forwarded so observers can still react.
|
|
3349
|
+
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;
|
|
3350
|
+
if (!pivotActiveLive) {
|
|
3351
|
+
updateUrl(buildModel({
|
|
3352
|
+
pinnedColumnsModel: pinnedColumns
|
|
3353
|
+
}), search, localStorageVersion, historyReplace, columns);
|
|
3354
|
+
}
|
|
4011
3355
|
propsOnPinnedColumnsChange === null || propsOnPinnedColumnsChange === void 0 ? void 0 : propsOnPinnedColumnsChange(pinnedColumns, details);
|
|
4012
|
-
updateUrl(buildModel({
|
|
4013
|
-
pinnedColumnsModel: pinnedColumns
|
|
4014
|
-
}), search, localStorageVersion, historyReplace, columns);
|
|
4015
3356
|
},
|
|
4016
|
-
pinnedColumns:
|
|
4017
|
-
paginationModel:
|
|
3357
|
+
pinnedColumns: pinnedColumnsModelRef.current,
|
|
3358
|
+
paginationModel: paginationModelParsedRef.current,
|
|
4018
3359
|
onPaginationModelChange: (model, details) => {
|
|
4019
3360
|
const paginationModel = _objectSpread2(_objectSpread2({}, model), {}, {
|
|
4020
3361
|
direction: paginationModelParsed.page < model.page ? 'next' : 'back'
|
|
4021
3362
|
});
|
|
4022
|
-
if (
|
|
3363
|
+
if (isDeepEqual(paginationModel, lastEmittedPaginationRef.current)) return;
|
|
4023
3364
|
lastEmittedPaginationRef.current = paginationModel;
|
|
4024
|
-
propsOnPaginationModelChange === null || propsOnPaginationModelChange === void 0 ? void 0 : propsOnPaginationModelChange(paginationModel, details);
|
|
4025
3365
|
updateUrl(buildModel({
|
|
4026
3366
|
paginationModel
|
|
4027
3367
|
}), search, localStorageVersion, historyReplace, columns);
|
|
3368
|
+
propsOnPaginationModelChange === null || propsOnPaginationModelChange === void 0 ? void 0 : propsOnPaginationModelChange(paginationModel, details);
|
|
4028
3369
|
},
|
|
4029
|
-
columnVisibilityModel:
|
|
3370
|
+
columnVisibilityModel: visibilityModelRef.current,
|
|
4030
3371
|
onColumnVisibilityModelChange: (columnsVisibilityModel, details) => {
|
|
3372
|
+
var _apiRef$current$state3, _apiRef$current5, _apiRef$current5$stat, _apiRef$current5$stat2;
|
|
3373
|
+
// While pivot mode is active, MUI Premium emits synthetic visibility
|
|
3374
|
+
// models that whitelist only the pivot value fields (hiding every base
|
|
3375
|
+
// column). Persisting that to the URL would re-hide all base columns
|
|
3376
|
+
// on the next load (see getColumnVisibilityFromString whitelist logic).
|
|
3377
|
+
// Read the live grid state rather than the parsed URL value because the
|
|
3378
|
+
// URL lags by a tick during pivot enable/disable transitions. Consumer
|
|
3379
|
+
// callbacks are always forwarded.
|
|
3380
|
+
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;
|
|
3381
|
+
if (!pivotActiveLive) {
|
|
3382
|
+
updateUrl(buildModel({
|
|
3383
|
+
columnsModel: columnsVisibilityModel
|
|
3384
|
+
}), search, localStorageVersion, historyReplace, columns);
|
|
3385
|
+
}
|
|
4031
3386
|
propsOnColumnVisibilityModelChange === null || propsOnColumnVisibilityModelChange === void 0 ? void 0 : propsOnColumnVisibilityModelChange(columnsVisibilityModel, details);
|
|
4032
|
-
updateUrl(buildModel({
|
|
4033
|
-
columnsModel: columnsVisibilityModel
|
|
4034
|
-
}), search, localStorageVersion, historyReplace, columns);
|
|
4035
3387
|
},
|
|
4036
3388
|
onColumnWidthChange: (params, event, details) => {
|
|
4037
3389
|
propsOnColumnWidthChange === null || propsOnColumnWidthChange === void 0 ? void 0 : propsOnColumnWidthChange(params, event, details);
|
|
@@ -4039,11 +3391,38 @@ const useStatefulTable = props => {
|
|
|
4039
3391
|
newWidth: params.width,
|
|
4040
3392
|
field: params.colDef.field
|
|
4041
3393
|
});
|
|
3394
|
+
},
|
|
3395
|
+
onRowGroupingModelChange: (model, details) => {
|
|
3396
|
+
updateUrl(buildModel({
|
|
3397
|
+
rowGroupingModel: model
|
|
3398
|
+
}), search, localStorageVersion, historyReplace, columns);
|
|
3399
|
+
propsOnRowGroupingModelChange === null || propsOnRowGroupingModelChange === void 0 ? void 0 : propsOnRowGroupingModelChange(model, details);
|
|
3400
|
+
},
|
|
3401
|
+
onAggregationModelChange: (model, details) => {
|
|
3402
|
+
updateUrl(buildModel({
|
|
3403
|
+
aggregationModel: model
|
|
3404
|
+
}), search, localStorageVersion, historyReplace, columns);
|
|
3405
|
+
propsOnAggregationModelChange === null || propsOnAggregationModelChange === void 0 ? void 0 : propsOnAggregationModelChange(model, details);
|
|
3406
|
+
},
|
|
3407
|
+
onPivotModelChange: model => {
|
|
3408
|
+
const simplified = fromGridPivotModel(model);
|
|
3409
|
+
if (isDeepEqual(simplified, lastEmittedPivotRef.current)) return;
|
|
3410
|
+
lastEmittedPivotRef.current = simplified;
|
|
3411
|
+
updateUrl(buildModel({
|
|
3412
|
+
pivotModel: simplified
|
|
3413
|
+
}), search, localStorageVersion, historyReplace, columns);
|
|
3414
|
+
propsOnPivotModelChange === null || propsOnPivotModelChange === void 0 ? void 0 : propsOnPivotModelChange(model);
|
|
3415
|
+
},
|
|
3416
|
+
onPivotActiveChange: active => {
|
|
3417
|
+
if (active === pivotActiveParsed) return;
|
|
3418
|
+
updateUrl(buildModel({
|
|
3419
|
+
pivotActive: active
|
|
3420
|
+
}), search, localStorageVersion, historyReplace, columns);
|
|
4042
3421
|
}
|
|
4043
3422
|
};
|
|
4044
3423
|
};
|
|
4045
3424
|
|
|
4046
|
-
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"];
|
|
3425
|
+
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", "onRowGroupingModelChange", "onAggregationModelChange", "onPivotModelChange", "pagination", "paginationPlacement", "selectionBannerPlacement", "paginationProps", "rows", "pageSizeOptions", "sx", "theme", "useRouter", "paginationMode", "rowCount", "density", "dataSource", "filterMode", "sortingMode"];
|
|
4047
3426
|
const COMPONENT_NAME = 'DataGrid';
|
|
4048
3427
|
const CLASSNAME = 'redsift-datagrid';
|
|
4049
3428
|
|
|
@@ -4099,6 +3478,7 @@ const CLASSNAME = 'redsift-datagrid';
|
|
|
4099
3478
|
*/
|
|
4100
3479
|
|
|
4101
3480
|
const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
|
|
3481
|
+
var _ref7;
|
|
4102
3482
|
const datagridRef = ref || useRef();
|
|
4103
3483
|
const {
|
|
4104
3484
|
apiRef: propsApiRef,
|
|
@@ -4127,6 +3507,9 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
4127
3507
|
onColumnVisibilityModelChange: propsOnColumnVisibilityModelChange,
|
|
4128
3508
|
onPinnedColumnsChange: propsOnPinnedColumnsChange,
|
|
4129
3509
|
onSortModelChange: propsOnSortModelChange,
|
|
3510
|
+
onRowGroupingModelChange: propsOnRowGroupingModelChange,
|
|
3511
|
+
onAggregationModelChange: propsOnAggregationModelChange,
|
|
3512
|
+
onPivotModelChange: propsOnPivotModelChange,
|
|
4130
3513
|
pagination,
|
|
4131
3514
|
paginationPlacement = 'both',
|
|
4132
3515
|
selectionBannerPlacement = 'top',
|
|
@@ -4137,15 +3520,26 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
4137
3520
|
theme: propsTheme,
|
|
4138
3521
|
useRouter,
|
|
4139
3522
|
paginationMode = 'client',
|
|
4140
|
-
rowCount
|
|
3523
|
+
rowCount,
|
|
3524
|
+
density: _density,
|
|
3525
|
+
dataSource,
|
|
3526
|
+
filterMode: propsFilterMode,
|
|
3527
|
+
sortingMode: propsSortingMode
|
|
4141
3528
|
} = props,
|
|
4142
3529
|
forwardedProps = _objectWithoutProperties(props, _excluded);
|
|
4143
|
-
const theme = useTheme
|
|
3530
|
+
const theme = useTheme(propsTheme);
|
|
4144
3531
|
const _apiRef = useGridApiRef();
|
|
4145
3532
|
const apiRef = propsApiRef !== null && propsApiRef !== void 0 ? propsApiRef : _apiRef;
|
|
4146
|
-
const RenderedToolbar = slots !== null && slots !== void 0 && slots.toolbar ? slots.toolbar : Toolbar;
|
|
4147
3533
|
LicenseInfo.setLicenseKey(license);
|
|
4148
3534
|
const height = propsHeight !== null && propsHeight !== void 0 ? propsHeight : autoHeight ? undefined : '500px';
|
|
3535
|
+
|
|
3536
|
+
// When dataSource is present, MUI manages filter/sort/pagination internally.
|
|
3537
|
+
// We must not pass controlled models — only initialState (one-time) and
|
|
3538
|
+
// write-only onChange handlers for URL/localStorage persistence.
|
|
3539
|
+
const isDataSourceMode = Boolean(dataSource);
|
|
3540
|
+
const effectivePaginationMode = isDataSourceMode ? 'server' : paginationMode;
|
|
3541
|
+
const effectiveFilterMode = isDataSourceMode ? 'server' : propsFilterMode;
|
|
3542
|
+
const effectiveSortingMode = isDataSourceMode ? 'server' : propsSortingMode;
|
|
4149
3543
|
const {
|
|
4150
3544
|
onColumnVisibilityModelChange: controlledOnColumnVisibilityModelChange,
|
|
4151
3545
|
onFilterModelChange: controlledOnFilterModelChange,
|
|
@@ -4179,7 +3573,15 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
4179
3573
|
pinnedColumns,
|
|
4180
3574
|
sortModel,
|
|
4181
3575
|
onColumnWidthChange,
|
|
4182
|
-
columnOrderModel
|
|
3576
|
+
columnOrderModel,
|
|
3577
|
+
rowGroupingModel,
|
|
3578
|
+
aggregationModel,
|
|
3579
|
+
pivotModel,
|
|
3580
|
+
pivotActive,
|
|
3581
|
+
onRowGroupingModelChange,
|
|
3582
|
+
onAggregationModelChange,
|
|
3583
|
+
onPivotModelChange,
|
|
3584
|
+
onPivotActiveChange
|
|
4183
3585
|
} = useStatefulTable({
|
|
4184
3586
|
apiRef: apiRef,
|
|
4185
3587
|
initialState,
|
|
@@ -4190,6 +3592,9 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
4190
3592
|
onPaginationModelChange: controlledOnPaginationModelChange,
|
|
4191
3593
|
onPinnedColumnsChange: controlledOnPinnedColumnsChange,
|
|
4192
3594
|
onSortModelChange: controlledOnSortModelChange,
|
|
3595
|
+
onRowGroupingModelChange: propsOnRowGroupingModelChange,
|
|
3596
|
+
onAggregationModelChange: propsOnAggregationModelChange,
|
|
3597
|
+
onPivotModelChange: propsOnPivotModelChange,
|
|
4193
3598
|
useRouter: useRouter,
|
|
4194
3599
|
localStorageVersion,
|
|
4195
3600
|
previousLocalStorageVersions
|
|
@@ -4225,9 +3630,61 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
4225
3630
|
return column;
|
|
4226
3631
|
});
|
|
4227
3632
|
}, [columns, columnOrderModel]);
|
|
4228
|
-
|
|
3633
|
+
|
|
3634
|
+
// In dataSource mode, track pagination locally for the custom pagination slots
|
|
3635
|
+
// (rendered outside DataGridPremium). MUI owns the actual pagination state internally.
|
|
3636
|
+
const [dataSourcePaginationModel, setDataSourcePaginationModel] = useState(paginationModel);
|
|
3637
|
+
|
|
3638
|
+
// The pagination model to use for display in pagination slots
|
|
3639
|
+
const activePaginationModel = isDataSourceMode ? dataSourcePaginationModel : paginationModel;
|
|
3640
|
+
|
|
3641
|
+
// Wrap onPaginationModelChange to also track state locally in dataSource mode
|
|
3642
|
+
const wrappedOnPaginationModelChange = useCallback((model, details) => {
|
|
3643
|
+
if (isDataSourceMode) {
|
|
3644
|
+
setDataSourcePaginationModel(model);
|
|
3645
|
+
}
|
|
3646
|
+
onPaginationModelChange(model, details);
|
|
3647
|
+
}, [isDataSourceMode, onPaginationModelChange]);
|
|
3648
|
+
|
|
3649
|
+
// In dataSource mode, pagination changes from our custom pagination slots
|
|
3650
|
+
// (rendered outside MUI's pagination state) route through apiRef so MUI's
|
|
3651
|
+
// internal page state updates and dataSource.getRows() refetches with the
|
|
3652
|
+
// new params. The `paginationModelChange` subscription below picks up the
|
|
3653
|
+
// resulting state change and propagates it to URL/localStorage and local
|
|
3654
|
+
// React state via wrappedOnPaginationModelChange.
|
|
3655
|
+
const dataSourcePaginationChange = useCallback(model => {
|
|
3656
|
+
var _apiRef$current;
|
|
3657
|
+
(_apiRef$current = apiRef.current) === null || _apiRef$current === void 0 ? void 0 : _apiRef$current.setPaginationModel(model);
|
|
3658
|
+
}, [apiRef]);
|
|
3659
|
+
|
|
3660
|
+
// In dataSource mode, subscribe to MUI's `paginationModelChange` event so
|
|
3661
|
+
// URL state stays in sync with MUI's internal pagination regardless of how
|
|
3662
|
+
// it changed (slot click, apiRef.setPaginationModel from consumer code,
|
|
3663
|
+
// MUI internal updates, etc.). Relying on MUI's `onPaginationModelChange`
|
|
3664
|
+
// prop callback alone is not sufficient: in pivot/GroupedData strategy mode
|
|
3665
|
+
// and with `paginationModel` seeded via `initialState` (rather than as a
|
|
3666
|
+
// controlled prop), the prop callback can be missed under certain
|
|
3667
|
+
// re-render orderings. The event fires reliably whenever the internal
|
|
3668
|
+
// state changes via `setState('setPaginationModel')`, see
|
|
3669
|
+
// `useGridStateInitialization.setState` → `publishEvent(changeEvent, …)`.
|
|
3670
|
+
// The deep-equal guard inside `useStatefulTable.onPaginationModelChange`
|
|
3671
|
+
// dedupes any duplicate emits, so overlap with the prop callback is safe.
|
|
3672
|
+
useEffect(() => {
|
|
3673
|
+
if (!isDataSourceMode) return;
|
|
3674
|
+
const api = apiRef.current;
|
|
3675
|
+
if (!(api !== null && api !== void 0 && api.subscribeEvent)) return;
|
|
3676
|
+
return api.subscribeEvent('paginationModelChange', model => {
|
|
3677
|
+
wrappedOnPaginationModelChange({
|
|
3678
|
+
page: model.page,
|
|
3679
|
+
pageSize: model.pageSize
|
|
3680
|
+
}, {
|
|
3681
|
+
reason: 'paginationModelChange'
|
|
3682
|
+
});
|
|
3683
|
+
});
|
|
3684
|
+
}, [isDataSourceMode, apiRef, wrappedOnPaginationModelChange]);
|
|
3685
|
+
const [rowSelectionModel, setRowSelectionModel] = useState(() => normalizeRowSelectionModel(propsRowSelectionModel));
|
|
4229
3686
|
useEffect(() => {
|
|
4230
|
-
setRowSelectionModel(propsRowSelectionModel
|
|
3687
|
+
setRowSelectionModel(normalizeRowSelectionModel(propsRowSelectionModel));
|
|
4231
3688
|
}, [propsRowSelectionModel]);
|
|
4232
3689
|
const onRowSelectionModelChange = (selectionModel, details) => {
|
|
4233
3690
|
setRowSelectionModel(selectionModel);
|
|
@@ -4241,25 +3698,49 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
4241
3698
|
pageSize: paginationModel.pageSize
|
|
4242
3699
|
});
|
|
4243
3700
|
|
|
3701
|
+
// Version counter to force re-renders when selectionStatus ref changes
|
|
3702
|
+
const [, forceSelectionUpdate] = useState(0);
|
|
3703
|
+
|
|
4244
3704
|
// The checkboxSelectionVisibleOnly should only be applied to client-side pagination,
|
|
4245
3705
|
// for server-side pagination it produces inconsistent behavior when selecting all rows in pages 2 and beyond
|
|
4246
|
-
const checkboxSelectionVisibleOnly = Boolean(pagination) && Boolean(
|
|
3706
|
+
const checkboxSelectionVisibleOnly = Boolean(pagination) && Boolean(effectivePaginationMode != 'server');
|
|
4247
3707
|
|
|
4248
3708
|
// Banner and pager placements are independent. `belowToolbar` (for either) renders
|
|
4249
|
-
// in the toolbar
|
|
3709
|
+
// in a row inside the toolbar slot, and only applies when pagination is on.
|
|
4250
3710
|
const bannerAtTop = selectionBannerPlacement === 'top';
|
|
4251
3711
|
const bannerAtBottom = selectionBannerPlacement === 'bottom';
|
|
4252
3712
|
const bannerBelowToolbar = selectionBannerPlacement === 'belowToolbar' && Boolean(pagination);
|
|
4253
3713
|
const pagerBelowToolbar = paginationPlacement === 'belowToolbar' && Boolean(pagination);
|
|
3714
|
+
const belowToolbarActive = bannerBelowToolbar || pagerBelowToolbar;
|
|
3715
|
+
|
|
3716
|
+
// Track when the grid API is ready to ensure top pagination renders correctly
|
|
3717
|
+
const [gridReady, setGridReady] = useState(false);
|
|
3718
|
+
|
|
3719
|
+
// Force re-render when the grid API becomes ready (for top pagination)
|
|
3720
|
+
useEffect(() => {
|
|
3721
|
+
if (apiRef.current && !gridReady) {
|
|
3722
|
+
setGridReady(true);
|
|
3723
|
+
}
|
|
3724
|
+
});
|
|
3725
|
+
|
|
3726
|
+
// Sync persisted density via apiRef — initialState only applies on mount,
|
|
3727
|
+
// so this handles SPA back/forward navigation where controlledDensity changes after mount
|
|
3728
|
+
useEffect(() => {
|
|
3729
|
+
if (apiRef.current) {
|
|
3730
|
+
apiRef.current.setDensity(controlledDensity);
|
|
3731
|
+
}
|
|
3732
|
+
}, [controlledDensity, apiRef]);
|
|
4254
3733
|
|
|
4255
3734
|
// in server-side pagination we want to update the selection status
|
|
4256
3735
|
// every time we navigate between pages, resize our page or select something
|
|
4257
3736
|
useEffect(() => {
|
|
4258
|
-
if (
|
|
4259
|
-
onServerSideSelectionStatusChange(
|
|
3737
|
+
if (effectivePaginationMode == 'server') {
|
|
3738
|
+
onServerSideSelectionStatusChange(rowSelectionModel, apiRef, selectionStatusRef, forceSelectionUpdate, isRowSelectable, activePaginationModel.page, activePaginationModel.pageSize);
|
|
4260
3739
|
}
|
|
4261
|
-
}, [rowSelectionModel,
|
|
4262
|
-
|
|
3740
|
+
}, [rowSelectionModel, activePaginationModel.page, activePaginationModel.pageSize, rows]);
|
|
3741
|
+
|
|
3742
|
+
// In dataSource mode MUI provides rows internally; skip the guard.
|
|
3743
|
+
if (!isDataSourceMode && !Array.isArray(rows)) {
|
|
4263
3744
|
return null;
|
|
4264
3745
|
}
|
|
4265
3746
|
|
|
@@ -4268,9 +3749,15 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
4268
3749
|
// receive the fresh value in the same render cycle — no extra re-render needed.
|
|
4269
3750
|
// The ref is kept in sync for the onRowSelectionModelChange callback's deselect logic.
|
|
4270
3751
|
let selectionStatus = selectionStatusRef.current;
|
|
4271
|
-
if (pagination &&
|
|
3752
|
+
if (pagination && effectivePaginationMode !== 'server' && getSelectionCount(rowSelectionModel) > 0) {
|
|
4272
3753
|
try {
|
|
4273
|
-
|
|
3754
|
+
// Use manual page slicing instead of gridPaginatedVisibleSorted* selectors.
|
|
3755
|
+
// MUI's paginated selectors use apiRef internal state which may be stale when
|
|
3756
|
+
// paginationModel prop changes — our React state is always up to date.
|
|
3757
|
+
const allFilteredEntries = gridFilteredSortedRowEntriesSelector(apiRef);
|
|
3758
|
+
const pageStart = activePaginationModel.page * activePaginationModel.pageSize;
|
|
3759
|
+
const pageEntries = allFilteredEntries.slice(pageStart, pageStart + activePaginationModel.pageSize);
|
|
3760
|
+
const selectableRowsInPage = isRowSelectable ? pageEntries.filter(_ref2 => {
|
|
4274
3761
|
let {
|
|
4275
3762
|
model
|
|
4276
3763
|
} = _ref2;
|
|
@@ -4282,24 +3769,29 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
4282
3769
|
id
|
|
4283
3770
|
} = _ref3;
|
|
4284
3771
|
return id;
|
|
4285
|
-
}) :
|
|
3772
|
+
}) : pageEntries.map(_ref4 => {
|
|
3773
|
+
let {
|
|
3774
|
+
id
|
|
3775
|
+
} = _ref4;
|
|
3776
|
+
return id;
|
|
3777
|
+
});
|
|
4286
3778
|
const numberOfSelectableRowsInPage = selectableRowsInPage.length;
|
|
4287
|
-
const selectableRowsInTable = isRowSelectable ?
|
|
3779
|
+
const selectableRowsInTable = isRowSelectable ? allFilteredEntries.filter(_ref5 => {
|
|
4288
3780
|
let {
|
|
4289
3781
|
model
|
|
4290
|
-
} =
|
|
3782
|
+
} = _ref5;
|
|
4291
3783
|
return isRowSelectable({
|
|
4292
3784
|
row: model
|
|
4293
3785
|
});
|
|
4294
|
-
}).map(
|
|
3786
|
+
}).map(_ref6 => {
|
|
4295
3787
|
let {
|
|
4296
3788
|
id
|
|
4297
|
-
} =
|
|
3789
|
+
} = _ref6;
|
|
4298
3790
|
return id;
|
|
4299
3791
|
}) : gridFilteredSortedRowIdsSelector(apiRef);
|
|
4300
3792
|
const numberOfSelectableRowsInTable = selectableRowsInTable.length;
|
|
4301
|
-
const numberOfSelectedRows = rowSelectionModel
|
|
4302
|
-
const selectedOnCurrentPage = selectableRowsInPage.filter(id => rowSelectionModel
|
|
3793
|
+
const numberOfSelectedRows = getSelectionCount(rowSelectionModel);
|
|
3794
|
+
const selectedOnCurrentPage = selectableRowsInPage.filter(id => isRowSelected(rowSelectionModel, id));
|
|
4303
3795
|
if (numberOfSelectedRows === numberOfSelectableRowsInTable && numberOfSelectableRowsInPage < numberOfSelectableRowsInTable) {
|
|
4304
3796
|
selectionStatus = {
|
|
4305
3797
|
type: 'table',
|
|
@@ -4324,7 +3816,7 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
4324
3816
|
} catch {
|
|
4325
3817
|
// apiRef may not be initialized on first render
|
|
4326
3818
|
}
|
|
4327
|
-
} else if (pagination &&
|
|
3819
|
+
} else if (pagination && effectivePaginationMode !== 'server') {
|
|
4328
3820
|
selectionStatus = {
|
|
4329
3821
|
type: 'none',
|
|
4330
3822
|
numberOfSelectedRows: 0
|
|
@@ -4343,6 +3835,48 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
4343
3835
|
}
|
|
4344
3836
|
}
|
|
4345
3837
|
}), [theme]);
|
|
3838
|
+
|
|
3839
|
+
// Per-render data for the stable `BelowToolbar`/`BottomPagination` slots, injected via
|
|
3840
|
+
// `slotProps` so the slot identities stay constant and their subtrees are re-rendered, not
|
|
3841
|
+
// remounted (remounting the toolbar dropped quick-search focus on every keystroke). Typed as
|
|
3842
|
+
// ToolbarWrapper props so mistakes are caught here; cast to MUI's slot types at the injection
|
|
3843
|
+
// sites below. See ../DataGrid/defaultSlots.
|
|
3844
|
+
const belowToolbarSlotProps = {
|
|
3845
|
+
RenderedToolbar: (_ref7 = slots === null || slots === void 0 ? void 0 : slots.toolbar) !== null && _ref7 !== void 0 ? _ref7 : Toolbar,
|
|
3846
|
+
hideToolbar,
|
|
3847
|
+
filterModel,
|
|
3848
|
+
onFilterModelChange,
|
|
3849
|
+
pagination,
|
|
3850
|
+
paginationMode: effectivePaginationMode,
|
|
3851
|
+
displaySelection: bannerBelowToolbar,
|
|
3852
|
+
displayPagination: pagerBelowToolbar,
|
|
3853
|
+
displayRowsPerPage: pagerBelowToolbar,
|
|
3854
|
+
selectionStatus,
|
|
3855
|
+
apiRef,
|
|
3856
|
+
isRowSelectable,
|
|
3857
|
+
paginationModel: activePaginationModel,
|
|
3858
|
+
onPaginationModelChange: isDataSourceMode ? dataSourcePaginationChange : onPaginationModelChange,
|
|
3859
|
+
pageSizeOptions: pageSizeOptions,
|
|
3860
|
+
paginationProps,
|
|
3861
|
+
rowCount
|
|
3862
|
+
};
|
|
3863
|
+
const bottomPaginationSlotProps = {
|
|
3864
|
+
pagination,
|
|
3865
|
+
paginationMode: effectivePaginationMode,
|
|
3866
|
+
displaySelection: bannerAtBottom,
|
|
3867
|
+
displayRowsPerPage: ['bottom', 'both'].includes(paginationPlacement),
|
|
3868
|
+
displayPagination: ['bottom', 'both'].includes(paginationPlacement),
|
|
3869
|
+
selectionStatus,
|
|
3870
|
+
paginationModel: activePaginationModel,
|
|
3871
|
+
// Bottom pager routes non-dataSource changes through the wrapped handler (the
|
|
3872
|
+
// belowToolbar/top pagers use the unwrapped one) — preserved from the previous inline slot.
|
|
3873
|
+
onPaginationModelChange: isDataSourceMode ? dataSourcePaginationChange : wrappedOnPaginationModelChange,
|
|
3874
|
+
apiRef,
|
|
3875
|
+
isRowSelectable,
|
|
3876
|
+
pageSizeOptions: pageSizeOptions,
|
|
3877
|
+
paginationProps,
|
|
3878
|
+
rowCount
|
|
3879
|
+
};
|
|
4346
3880
|
return /*#__PURE__*/React__default.createElement(ThemeProvider, {
|
|
4347
3881
|
value: {
|
|
4348
3882
|
theme
|
|
@@ -4353,117 +3887,172 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
4353
3887
|
ref: datagridRef,
|
|
4354
3888
|
className: classNames(StatefulDataGrid.className, className),
|
|
4355
3889
|
$height: height
|
|
4356
|
-
}, /*#__PURE__*/React__default.createElement(
|
|
3890
|
+
}, pagination && gridReady && (bannerAtTop || ['top', 'both'].includes(paginationPlacement)) ? effectivePaginationMode == 'server' ? /*#__PURE__*/React__default.createElement(ServerSideControlledPagination, {
|
|
3891
|
+
displaySelection: bannerAtTop,
|
|
3892
|
+
displayRowsPerPage: ['top', 'both'].includes(paginationPlacement),
|
|
3893
|
+
displayPagination: ['top', 'both'].includes(paginationPlacement),
|
|
3894
|
+
selectionStatus: selectionStatus,
|
|
3895
|
+
paginationModel: activePaginationModel,
|
|
3896
|
+
onPaginationModelChange: isDataSourceMode ? dataSourcePaginationChange : onPaginationModelChange,
|
|
3897
|
+
pageSizeOptions: pageSizeOptions,
|
|
3898
|
+
paginationProps: paginationProps,
|
|
3899
|
+
rowCount: rowCount
|
|
3900
|
+
}) : /*#__PURE__*/React__default.createElement(ControlledPagination, {
|
|
3901
|
+
displaySelection: bannerAtTop,
|
|
3902
|
+
displayRowsPerPage: ['top', 'both'].includes(paginationPlacement),
|
|
3903
|
+
displayPagination: ['top', 'both'].includes(paginationPlacement),
|
|
3904
|
+
selectionStatus: selectionStatus,
|
|
3905
|
+
apiRef: apiRef,
|
|
3906
|
+
isRowSelectable: isRowSelectable,
|
|
3907
|
+
paginationModel: activePaginationModel,
|
|
3908
|
+
onPaginationModelChange: onPaginationModelChange,
|
|
3909
|
+
pageSizeOptions: pageSizeOptions,
|
|
3910
|
+
paginationProps: paginationProps
|
|
3911
|
+
}) : null, /*#__PURE__*/React__default.createElement(DataGridPremium, _extends({}, forwardedProps, {
|
|
4357
3912
|
apiRef: apiRef,
|
|
3913
|
+
dataSource: dataSource,
|
|
4358
3914
|
columns: orderedColumns,
|
|
4359
|
-
columnVisibilityModel: columnVisibilityModel,
|
|
4360
|
-
density: controlledDensity,
|
|
4361
|
-
filterModel: filterModel,
|
|
4362
3915
|
onColumnVisibilityModelChange: onColumnVisibilityModelChange,
|
|
4363
|
-
onFilterModelChange: onFilterModelChange,
|
|
4364
|
-
onPaginationModelChange: onPaginationModelChange,
|
|
4365
3916
|
onPinnedColumnsChange: onPinnedColumnsChange,
|
|
4366
|
-
onSortModelChange: onSortModelChange,
|
|
4367
|
-
paginationModel: paginationModel,
|
|
4368
|
-
pinnedColumns: pinnedColumns,
|
|
4369
|
-
sortModel: sortModel,
|
|
4370
3917
|
pageSizeOptions: pageSizeOptions,
|
|
4371
3918
|
onColumnWidthChange: onColumnWidthChange,
|
|
3919
|
+
onRowGroupingModelChange: onRowGroupingModelChange,
|
|
3920
|
+
onAggregationModelChange: onAggregationModelChange,
|
|
3921
|
+
onPivotModelChange: onPivotModelChange,
|
|
3922
|
+
pivotActive: pivotActive,
|
|
3923
|
+
onPivotActiveChange: onPivotActiveChange
|
|
3924
|
+
// In dataSource mode: models are uncontrolled (MUI owns them),
|
|
3925
|
+
// onChange handlers are write-only for URL/localStorage persistence,
|
|
3926
|
+
// and initialState seeds MUI on mount from the persisted URL state.
|
|
3927
|
+
// columnVisibilityModel / pinnedColumns / rowGroupingModel /
|
|
3928
|
+
// aggregationModel / pivotModel are also uncontrolled here to
|
|
3929
|
+
// avoid a controlled re-render race with consumer-side
|
|
3930
|
+
// microtask-deferred history updates (otherwise user toggles
|
|
3931
|
+
// flip back when MUI re-emits with the stale controlled value).
|
|
3932
|
+
// pivotModel specifically also carries `hidden`/`sort` field
|
|
3933
|
+
// metadata that our simplified URL representation strips — so
|
|
3934
|
+
// controlling it would prevent users from unchecking fields in
|
|
3935
|
+
// the pivot panel (the controlled prop would immediately re-add
|
|
3936
|
+
// them). Consumers needing programmatic changes should use the
|
|
3937
|
+
// apiRef imperative API.
|
|
3938
|
+
}, isDataSourceMode ? {
|
|
3939
|
+
onFilterModelChange: onFilterModelChange,
|
|
3940
|
+
onSortModelChange: onSortModelChange,
|
|
3941
|
+
onPaginationModelChange: wrappedOnPaginationModelChange,
|
|
3942
|
+
initialState: _objectSpread2(_objectSpread2({}, initialState), {}, {
|
|
3943
|
+
density: controlledDensity,
|
|
3944
|
+
columns: _objectSpread2(_objectSpread2({}, initialState === null || initialState === void 0 ? void 0 : initialState.columns), {}, {
|
|
3945
|
+
orderedFields: columnOrderModel,
|
|
3946
|
+
columnVisibilityModel
|
|
3947
|
+
}),
|
|
3948
|
+
pinnedColumns,
|
|
3949
|
+
rowGrouping: _objectSpread2(_objectSpread2({}, initialState === null || initialState === void 0 ? void 0 : initialState.rowGrouping), {}, {
|
|
3950
|
+
model: rowGroupingModel
|
|
3951
|
+
}),
|
|
3952
|
+
aggregation: _objectSpread2(_objectSpread2({}, initialState === null || initialState === void 0 ? void 0 : initialState.aggregation), {}, {
|
|
3953
|
+
model: aggregationModel
|
|
3954
|
+
}),
|
|
3955
|
+
filter: {
|
|
3956
|
+
filterModel
|
|
3957
|
+
},
|
|
3958
|
+
sorting: {
|
|
3959
|
+
sortModel
|
|
3960
|
+
},
|
|
3961
|
+
pagination: {
|
|
3962
|
+
paginationModel
|
|
3963
|
+
},
|
|
3964
|
+
pivoting: _objectSpread2(_objectSpread2({}, initialState === null || initialState === void 0 ? void 0 : initialState.pivoting), {}, {
|
|
3965
|
+
model: pivotModel,
|
|
3966
|
+
enabled: pivotActive
|
|
3967
|
+
})
|
|
3968
|
+
})
|
|
3969
|
+
} : {
|
|
3970
|
+
columnVisibilityModel,
|
|
3971
|
+
pinnedColumns,
|
|
3972
|
+
rowGroupingModel,
|
|
3973
|
+
aggregationModel,
|
|
3974
|
+
filterModel,
|
|
3975
|
+
sortModel,
|
|
3976
|
+
paginationModel,
|
|
3977
|
+
pivotModel,
|
|
3978
|
+
onFilterModelChange: onFilterModelChange,
|
|
3979
|
+
onSortModelChange: onSortModelChange,
|
|
3980
|
+
onPaginationModelChange: wrappedOnPaginationModelChange,
|
|
4372
3981
|
initialState: _objectSpread2(_objectSpread2({}, initialState), {}, {
|
|
3982
|
+
density: controlledDensity,
|
|
4373
3983
|
columns: _objectSpread2(_objectSpread2({}, initialState === null || initialState === void 0 ? void 0 : initialState.columns), {}, {
|
|
4374
3984
|
orderedFields: columnOrderModel
|
|
4375
3985
|
})
|
|
4376
|
-
})
|
|
3986
|
+
})
|
|
3987
|
+
}, {
|
|
4377
3988
|
isRowSelectable: isRowSelectable,
|
|
4378
3989
|
pagination: pagination,
|
|
4379
|
-
paginationMode:
|
|
4380
|
-
|
|
4381
|
-
|
|
3990
|
+
paginationMode: effectivePaginationMode,
|
|
3991
|
+
filterMode: effectiveFilterMode,
|
|
3992
|
+
sortingMode: effectiveSortingMode,
|
|
3993
|
+
keepNonExistentRowsSelected: effectivePaginationMode == 'server',
|
|
3994
|
+
rows: isDataSourceMode ? [] : rows,
|
|
4382
3995
|
rowCount: rowCount,
|
|
4383
3996
|
autoHeight: autoHeight,
|
|
4384
3997
|
checkboxSelectionVisibleOnly: checkboxSelectionVisibleOnly,
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
toolbar: ToolbarWrapper,
|
|
3998
|
+
disableRowSelectionExcludeModel: true,
|
|
3999
|
+
showToolbar: !hideToolbar || belowToolbarActive,
|
|
4000
|
+
slots: _objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({}, baseGridSlots), slots), belowToolbarActive ? {
|
|
4001
|
+
toolbar: BelowToolbar
|
|
4002
|
+
} : {}), {}, {
|
|
4391
4003
|
pagination: BottomPagination
|
|
4392
4004
|
}),
|
|
4393
|
-
slotProps: _objectSpread2(_objectSpread2({}, slotProps),
|
|
4394
|
-
toolbar: _objectSpread2({
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
filterModel,
|
|
4398
|
-
onFilterModelChange,
|
|
4399
|
-
pagination,
|
|
4400
|
-
displaySelection: bannerAtTop || bannerBelowToolbar,
|
|
4401
|
-
displayPagination: ['top', 'both'].includes(paginationPlacement) || pagerBelowToolbar,
|
|
4402
|
-
displayRowsPerPage: pagerBelowToolbar,
|
|
4403
|
-
selectionStatus,
|
|
4404
|
-
apiRef,
|
|
4405
|
-
isRowSelectable,
|
|
4406
|
-
paginationModel,
|
|
4407
|
-
onPaginationModelChange,
|
|
4408
|
-
pageSizeOptions,
|
|
4409
|
-
paginationProps,
|
|
4410
|
-
paginationMode,
|
|
4411
|
-
rowCount
|
|
4412
|
-
}, slotProps === null || slotProps === void 0 ? void 0 : slotProps.toolbar),
|
|
4413
|
-
// Per-render data for the stable `BottomPagination` slot. Consumer slot props are
|
|
4414
|
-
// spread first; the DS layout data wins. Cast at the MUI boundary because these are
|
|
4415
|
-
// ToolbarWrapper props, not the MUI slot prop types.
|
|
4416
|
-
pagination: _objectSpread2(_objectSpread2({}, slotProps === null || slotProps === void 0 ? void 0 : slotProps.pagination), {}, {
|
|
4417
|
-
pagination,
|
|
4418
|
-
paginationMode,
|
|
4419
|
-
displaySelection: bannerAtBottom,
|
|
4420
|
-
displayRowsPerPage: ['bottom', 'both'].includes(paginationPlacement),
|
|
4421
|
-
displayPagination: ['bottom', 'both'].includes(paginationPlacement),
|
|
4422
|
-
selectionStatus,
|
|
4423
|
-
paginationModel,
|
|
4424
|
-
onPaginationModelChange,
|
|
4425
|
-
apiRef,
|
|
4426
|
-
isRowSelectable,
|
|
4427
|
-
pageSizeOptions,
|
|
4428
|
-
paginationProps,
|
|
4429
|
-
rowCount
|
|
4430
|
-
})
|
|
4005
|
+
slotProps: _objectSpread2(_objectSpread2(_objectSpread2({}, slotProps), belowToolbarActive ? {
|
|
4006
|
+
toolbar: _objectSpread2(_objectSpread2({}, slotProps === null || slotProps === void 0 ? void 0 : slotProps.toolbar), belowToolbarSlotProps)
|
|
4007
|
+
} : {}), {}, {
|
|
4008
|
+
pagination: _objectSpread2(_objectSpread2({}, slotProps === null || slotProps === void 0 ? void 0 : slotProps.pagination), bottomPaginationSlotProps)
|
|
4431
4009
|
}),
|
|
4432
4010
|
rowSelectionModel: rowSelectionModel,
|
|
4433
4011
|
onRowSelectionModelChange: (newSelectionModel, details) => {
|
|
4434
|
-
if (pagination &&
|
|
4435
|
-
|
|
4012
|
+
if (pagination && effectivePaginationMode != 'server') {
|
|
4013
|
+
// Use manual page slicing instead of gridPaginatedVisibleSorted* selectors
|
|
4014
|
+
// to avoid stale apiRef pagination state.
|
|
4015
|
+
const allFilteredEntries = gridFilteredSortedRowEntriesSelector(apiRef);
|
|
4016
|
+
const pageStart = activePaginationModel.page * activePaginationModel.pageSize;
|
|
4017
|
+
const pageEntries = allFilteredEntries.slice(pageStart, pageStart + activePaginationModel.pageSize);
|
|
4018
|
+
const selectableRowsInPage = isRowSelectable ? pageEntries.filter(_ref8 => {
|
|
4436
4019
|
let {
|
|
4437
4020
|
model
|
|
4438
|
-
} =
|
|
4021
|
+
} = _ref8;
|
|
4439
4022
|
return isRowSelectable({
|
|
4440
4023
|
row: model
|
|
4441
4024
|
});
|
|
4442
|
-
}).map(
|
|
4025
|
+
}).map(_ref9 => {
|
|
4026
|
+
let {
|
|
4027
|
+
id
|
|
4028
|
+
} = _ref9;
|
|
4029
|
+
return id;
|
|
4030
|
+
}) : pageEntries.map(_ref10 => {
|
|
4443
4031
|
let {
|
|
4444
4032
|
id
|
|
4445
|
-
} =
|
|
4033
|
+
} = _ref10;
|
|
4446
4034
|
return id;
|
|
4447
|
-
})
|
|
4035
|
+
});
|
|
4448
4036
|
const numberOfSelectableRowsInPage = selectableRowsInPage.length;
|
|
4449
|
-
const selectableRowsInTable = isRowSelectable ?
|
|
4037
|
+
const selectableRowsInTable = isRowSelectable ? allFilteredEntries.filter(_ref11 => {
|
|
4450
4038
|
let {
|
|
4451
4039
|
model
|
|
4452
|
-
} =
|
|
4040
|
+
} = _ref11;
|
|
4453
4041
|
return isRowSelectable({
|
|
4454
4042
|
row: model
|
|
4455
4043
|
});
|
|
4456
|
-
}).map(
|
|
4044
|
+
}).map(_ref12 => {
|
|
4457
4045
|
let {
|
|
4458
4046
|
id
|
|
4459
|
-
} =
|
|
4047
|
+
} = _ref12;
|
|
4460
4048
|
return id;
|
|
4461
4049
|
}) : gridFilteredSortedRowIdsSelector(apiRef);
|
|
4462
4050
|
const numberOfSelectableRowsInTable = selectableRowsInTable.length;
|
|
4463
|
-
const numberOfSelectedRows = newSelectionModel
|
|
4051
|
+
const numberOfSelectedRows = getSelectionCount(newSelectionModel);
|
|
4464
4052
|
if (selectionStatusRef.current.type === 'table' && numberOfSelectedRows === numberOfSelectableRowsInTable - numberOfSelectableRowsInPage || selectionStatusRef.current.type === 'table' && numberOfSelectedRows === numberOfSelectableRowsInTable || selectionStatusRef.current.type === 'page' && numberOfSelectedRows === numberOfSelectableRowsInPage) {
|
|
4465
4053
|
setTimeout(() => {
|
|
4466
|
-
|
|
4054
|
+
var _apiRef$current2;
|
|
4055
|
+
(_apiRef$current2 = apiRef.current) === null || _apiRef$current2 === void 0 ? void 0 : _apiRef$current2.selectRows([], true, true);
|
|
4467
4056
|
}, 0);
|
|
4468
4057
|
}
|
|
4469
4058
|
if (numberOfSelectedRows === numberOfSelectableRowsInPage && numberOfSelectableRowsInPage < numberOfSelectableRowsInTable) {
|
|
@@ -4487,6 +4076,7 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
4487
4076
|
numberOfSelectedRows
|
|
4488
4077
|
};
|
|
4489
4078
|
}
|
|
4079
|
+
forceSelectionUpdate(v => v + 1);
|
|
4490
4080
|
}
|
|
4491
4081
|
onRowSelectionModelChange === null || onRowSelectionModelChange === void 0 ? void 0 : onRowSelectionModelChange(newSelectionModel, details);
|
|
4492
4082
|
},
|
|
@@ -4504,5 +4094,5 @@ const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
4504
4094
|
StatefulDataGrid.className = CLASSNAME;
|
|
4505
4095
|
StatefulDataGrid.displayName = COMPONENT_NAME;
|
|
4506
4096
|
|
|
4507
|
-
export {
|
|
4097
|
+
export { buildStorageKey as $, ARRAY_IS_EMPTY as A, IS as B, CONTAINS_ANY_OF as C, DOES_NOT_CONTAIN as D, ENDS_WITH_ANY_OF as E, IS_NOT as F, getGridStringOperators as G, HAS_WITH_SELECT as H, IS_ANY_OF as I, getGridStringArrayOperators as J, getGridStringArrayOperatorsWithSelect as K, getGridStringArrayOperatorsWithSelectOnStringArrayColumns as L, FILTER_MODEL_KEY as M, SORT_MODEL_KEY as N, PINNED_COLUMNS as O, PAGINATION_MODEL_KEY as P, DIMENSION_MODEL_KEY as Q, FILTER_SEARCH_KEY as R, STARTS_WITH_ANY_OF as S, DENSITY_MODEL_KEY as T, COLUMN_ORDER_MODEL_KEY as U, VISIBILITY_MODEL_KEY as V, ROW_GROUPING_MODEL_KEY as W, AGGREGATION_MODEL_KEY as X, PIVOT_MODEL_KEY as Y, PIVOT_ACTIVE_KEY as Z, CATEGORIES as _, DOES_NOT_EQUAL as a, clearPreviousVersionStorage as a0, clearAllVersionStorage as a1, resetStatefulDataGridState as a2, resetColumnVisibility as a3, convertToDisplayFormat as a4, convertFromDisplayFormat as a5, getDecodedSearchFromUrl as a6, buildQueryParamsString as a7, areSearchStringsEqual as a8, decodeValue as a9, getSearchParamsFromAggregation as aA, fromGridPivotModel as aB, getPivotFromString as aC, getSearchParamsFromPivot as aD, getPivotActiveFromString as aE, getSearchParamsFromPivotActive as aF, getSearchParamsFromVersion as aG, getFinalSearch as aH, getModelsParsedOrUpdateLocalStorage as aI, updateUrl as aJ, areFilterModelsEquivalent as aK, StatefulDataGrid as aL, encodeValue as aa, urlSearchParamsToString as ab, numberOperatorEncoder as ac, numberOperatorDecoder as ad, isOperatorValueValid as ae, isValueValid as af, getFilterModelFromString as ag, normalizeDateValue as ah, getSearchParamsFromFilterModel as ai, getSortingFromString as aj, getSearchParamsFromSorting as ak, getPaginationFromString as al, getSearchParamsFromPagination as am, getColumnVisibilityFromString as an, getSearchParamsFromColumnVisibility as ao, getPinnedColumnsFromString as ap, getSearchParamsFromPinnedColumns as aq, getSearchParamsFromTab as ar, getDensityFromString as as, getSearchParamsFromDensity as at, getDensityModel as au, getColumnOrderFromString as av, getSearchParamsFromColumnOrder as aw, getRowGroupingFromString as ax, getSearchParamsFromRowGrouping as ay, getAggregationFromString 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 };
|
|
4508
4098
|
//# sourceMappingURL=StatefulDataGrid2.js.map
|