@redsift/table 11.6.0-muiv5-alpha.5 → 11.6.0-muiv5-alpha.7
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 +3 -3
- package/_internal/BaseTextField.js +24 -13
- package/_internal/DataGrid.js +1 -5
- package/_internal/DataGrid2.js +329 -3
- package/_internal/GridToolbarFilterSemanticField.js +1 -4
- package/_internal/GridToolbarFilterSemanticField2.js +5575 -9
- package/_internal/Pagination.js +2 -7
- package/_internal/StatefulDataGrid.js +2 -6
- package/_internal/StatefulDataGrid2.js +1419 -16
- package/_internal/TextCell.js +1 -2
- package/_internal/TextCell2.js +59 -23
- package/_internal/Toolbar.js +1 -3
- package/_internal/Toolbar2.js +76 -47
- package/_internal/ToolbarWrapper.js +2 -6
- package/_internal/ToolbarWrapper2.js +56 -22
- package/index.d.ts +629 -0
- package/index.js +14 -401
- package/package.json +2 -2
- package/_internal/ServerSideControlledPagination.js +0 -39
- package/_internal/types.js +0 -35
- package/_internal/types2.js +0 -39
|
@@ -1,19 +1,1422 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
import { _ as _objectSpread2, b as _objectWithoutProperties, a as _extends } from './_rollupPluginBabelHelpers.js';
|
|
2
|
+
import React__default, { useCallback, useEffect, useMemo, forwardRef, useRef, useState } from 'react';
|
|
3
|
+
import classNames from 'classnames';
|
|
4
|
+
import { useTheme, ThemeProvider, RedsiftColorBlueN, RedsiftColorNeutralXDarkGrey, RedsiftColorNeutralWhite } from '@redsift/design-system';
|
|
5
|
+
import { GridLinkOperator, useGridApiRef, DataGridPro, gridPaginatedVisibleSortedGridRowEntriesSelector, gridPaginatedVisibleSortedGridRowIdsSelector, gridFilteredSortedRowEntriesSelector, gridFilteredSortedRowIdsSelector } from '@mui/x-data-grid-pro';
|
|
6
|
+
import { o as operatorList, L as LicenseInfo, G as useControlledDatagridState, T as ThemeProvider$1, J as StyledDataGrid, f as customColumnTypes } from './useControlledDatagridState.js';
|
|
7
|
+
import { g as createTheme } from './Portal.js';
|
|
8
|
+
import { T as Toolbar } from './Toolbar2.js';
|
|
9
|
+
import { o as onServerSideSelectionStatusChange, S as ServerSideControlledPagination, C as ControlledPagination } from './ControlledPagination.js';
|
|
10
|
+
import { B as BaseButton, a as BaseCheckbox, c as BasePopper, b as BaseIcon } from './BasePopper.js';
|
|
11
|
+
import { T as ToolbarWrapper } from './ToolbarWrapper2.js';
|
|
12
|
+
|
|
13
|
+
const PAGINATION_MODEL_KEY = 'paginationModel';
|
|
14
|
+
const FILTER_MODEL_KEY = 'filterModel';
|
|
15
|
+
const SORT_MODEL_KEY = 'sortModel';
|
|
16
|
+
const VISIBILITY_MODEL_KEY = 'visibilityModel';
|
|
17
|
+
const PINNED_COLUMNS = 'pinnedColumns';
|
|
18
|
+
const DIMENSION_MODEL_KEY = 'dimension';
|
|
19
|
+
const FILTER_SEARCH_KEY = 'searchModel';
|
|
20
|
+
const CATEGORIES = [PAGINATION_MODEL_KEY, FILTER_MODEL_KEY, SORT_MODEL_KEY, VISIBILITY_MODEL_KEY, DIMENSION_MODEL_KEY, FILTER_SEARCH_KEY, PINNED_COLUMNS];
|
|
21
|
+
const buildStorageKey = _ref => {
|
|
22
|
+
let {
|
|
23
|
+
id,
|
|
24
|
+
version,
|
|
25
|
+
category
|
|
26
|
+
} = _ref;
|
|
27
|
+
return `${id}:${version}:${category}`;
|
|
28
|
+
};
|
|
29
|
+
const clearPreviousVersionStorage = (id, previousLocalStorageVersions) => {
|
|
30
|
+
for (const version of previousLocalStorageVersions) {
|
|
31
|
+
const keysToDelete = [buildStorageKey({
|
|
32
|
+
id,
|
|
33
|
+
version,
|
|
34
|
+
category: PAGINATION_MODEL_KEY
|
|
35
|
+
}), buildStorageKey({
|
|
36
|
+
id,
|
|
37
|
+
version,
|
|
38
|
+
category: SORT_MODEL_KEY
|
|
39
|
+
}), buildStorageKey({
|
|
40
|
+
id,
|
|
41
|
+
version,
|
|
42
|
+
category: FILTER_MODEL_KEY
|
|
43
|
+
}), buildStorageKey({
|
|
44
|
+
id,
|
|
45
|
+
version,
|
|
46
|
+
category: VISIBILITY_MODEL_KEY
|
|
47
|
+
}), buildStorageKey({
|
|
48
|
+
id,
|
|
49
|
+
version,
|
|
50
|
+
category: PINNED_COLUMNS
|
|
51
|
+
}), buildStorageKey({
|
|
52
|
+
id,
|
|
53
|
+
version,
|
|
54
|
+
category: FILTER_SEARCH_KEY
|
|
55
|
+
}), buildStorageKey({
|
|
56
|
+
id,
|
|
57
|
+
version,
|
|
58
|
+
category: DIMENSION_MODEL_KEY
|
|
59
|
+
})];
|
|
60
|
+
for (const keyToDelete of keysToDelete) {
|
|
61
|
+
try {
|
|
62
|
+
window.localStorage.removeItem(keyToDelete);
|
|
63
|
+
} catch (e) {
|
|
64
|
+
// Ignore
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// reference value: https://www.w3schools.com/tags/ref_urlencode.ASP
|
|
71
|
+
const DECODER = {
|
|
72
|
+
'%20': ' ',
|
|
73
|
+
'%26': '&',
|
|
74
|
+
'%3D': '=',
|
|
75
|
+
'%3F': '?',
|
|
76
|
+
'%5B': '[',
|
|
77
|
+
'%5D': ']',
|
|
78
|
+
'%2C': ',',
|
|
79
|
+
'%3C': '<',
|
|
80
|
+
'%3E': '>',
|
|
81
|
+
'%21': '!',
|
|
82
|
+
'%22': '"'
|
|
83
|
+
};
|
|
84
|
+
const ENCODER = {
|
|
85
|
+
' ': '%20',
|
|
86
|
+
'&': '%26',
|
|
87
|
+
'=': '%3D',
|
|
88
|
+
'?': '%3F',
|
|
89
|
+
'[': '%5B',
|
|
90
|
+
']': '%5D',
|
|
91
|
+
',': '%2C',
|
|
92
|
+
'<': '%3C',
|
|
93
|
+
'>': '%3E',
|
|
94
|
+
'!': '%21',
|
|
95
|
+
'"': '%22'
|
|
96
|
+
};
|
|
97
|
+
const decodeValue = value => {
|
|
98
|
+
if (value === '') {
|
|
99
|
+
return '';
|
|
100
|
+
}
|
|
101
|
+
const re = new RegExp(Object.keys(DECODER).reduce((acc, curr) => `${acc}|${curr}`), 'g');
|
|
102
|
+
// decodeValue for lists:
|
|
103
|
+
if (value.startsWith('list[')) {
|
|
104
|
+
const arrayValues = value.split('[')[1].split(']')[0];
|
|
105
|
+
const arrayList = arrayValues.split(',').map(v => v.replace(re, encoded => DECODER[encoded])).filter(item => item);
|
|
106
|
+
return arrayList.length > 0 ? arrayList : [];
|
|
107
|
+
}
|
|
108
|
+
return value.replace(re, encoded => DECODER[encoded]);
|
|
109
|
+
};
|
|
110
|
+
const encodeValue = value => {
|
|
111
|
+
if (!value) {
|
|
112
|
+
return '';
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Array encoding for value:
|
|
116
|
+
// we are representing it as list[encoded], where encoded is the list comma separated
|
|
117
|
+
if (Array.isArray(value)) {
|
|
118
|
+
const encodedArray = value.map(entry => {
|
|
119
|
+
return String(entry).replace(/\s|&|=|\?|\[|\]/g, encoded => ENCODER[encoded]);
|
|
120
|
+
}).join(',');
|
|
121
|
+
return `list[${encodedArray}]`;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// we might also pass integers
|
|
125
|
+
const castedValue = String(value);
|
|
126
|
+
return castedValue.replace(/\s|&|=|\?|\[|\]/g, encoded => ENCODER[encoded]);
|
|
127
|
+
};
|
|
128
|
+
const urlSearchParamsToString = searchParams => {
|
|
129
|
+
let searchString = '';
|
|
130
|
+
for (const [key, value] of searchParams) {
|
|
131
|
+
searchString = searchString + `${key}=${value}&`;
|
|
132
|
+
}
|
|
133
|
+
return searchString.slice(0, searchString.length - 1);
|
|
134
|
+
};
|
|
135
|
+
const numberOperatorEncoder = {
|
|
136
|
+
'=': 'eq',
|
|
137
|
+
'!=': 'ne',
|
|
138
|
+
'>': 'gt',
|
|
139
|
+
'>=': 'gte',
|
|
140
|
+
'<': 'lt',
|
|
141
|
+
'<=': 'lte'
|
|
142
|
+
};
|
|
143
|
+
const numberOperatorDecoder = {
|
|
144
|
+
eq: '=',
|
|
145
|
+
ne: '!=',
|
|
146
|
+
gt: '>',
|
|
147
|
+
gte: '>=',
|
|
148
|
+
lt: '<',
|
|
149
|
+
lte: '<='
|
|
150
|
+
};
|
|
151
|
+
const isOperatorValueValid = (columnField, operatorValue, columns) => {
|
|
152
|
+
const column = columns.find(column => column.field === columnField);
|
|
153
|
+
if (!column) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
const columnType = (column === null || column === void 0 ? void 0 : column.type) || 'string';
|
|
157
|
+
const operators = operatorList[columnType];
|
|
158
|
+
if (!operators) {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
if ('filterOperators' in operators) {
|
|
162
|
+
return !!operators.filterOperators.find(op => columnType === 'number' && Object.keys(numberOperatorEncoder).includes(op.value) ? numberOperatorEncoder[op.value] === operatorValue : op['value'] === operatorValue);
|
|
163
|
+
}
|
|
164
|
+
return !!operators.find(op => ['number', 'rsNumber'].includes(columnType) && Object.keys(numberOperatorEncoder).includes(op.value) ? numberOperatorEncoder[op.value] === operatorValue : op['value'] === operatorValue);
|
|
165
|
+
};
|
|
166
|
+
const listOperators = ['containsAnyOf', 'doesNotContainAnyOf', 'endsWithAnyOf', 'doesNotEndWithAnyOf', 'hasAnyOf', 'doesNotHaveAnyOf', 'isAnyOf', 'isNotAnyOf', 'startsWithAnyOf', 'doesNotStartWithAnyOf'];
|
|
167
|
+
|
|
168
|
+
// Check if the value doesn't break
|
|
169
|
+
const isValueValid = (value, columnField, columns, operatorValue) => {
|
|
170
|
+
var _column$type;
|
|
171
|
+
// every field accepts undefined as value for default
|
|
172
|
+
if (value === undefined || value === '') {
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// xxxAnyOf accepts as value only lists, and we are declearing them in the
|
|
177
|
+
// URL as `list=[...]`
|
|
178
|
+
if (listOperators.includes(operatorValue)) {
|
|
179
|
+
return Array.isArray(value) || value === '';
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// We are accepting arrays only if they are of the 'xxxAnyOf' type
|
|
183
|
+
if (Array.isArray(value) && !listOperators.includes(operatorValue)) {
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
const column = columns.find(column => column.field === columnField);
|
|
187
|
+
if (!column) {
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
const type = (_column$type = column['type']) !== null && _column$type !== void 0 ? _column$type : 'string';
|
|
191
|
+
|
|
192
|
+
// Only date and rating fail with 500s, other set themselves as undefined
|
|
193
|
+
if (type !== 'date' && type !== 'rating') {
|
|
194
|
+
return true;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// just checking that rating is a number.
|
|
198
|
+
if (type === 'rating') {
|
|
199
|
+
return !isNaN(Number(value));
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// format: YYYY-MM-DD
|
|
203
|
+
// just verifying that the 3 values are numbers to avoid 500s,
|
|
204
|
+
// If the value is invalid the form will appear as undefined
|
|
205
|
+
if (type === 'date') {
|
|
206
|
+
const dateSplitted = value.split('-');
|
|
207
|
+
if (dateSplitted.length !== 3) {
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
const [YYYY, MM, DD] = dateSplitted;
|
|
211
|
+
return !isNaN(parseInt(YYYY)) && !isNaN(parseInt(MM)) && !isNaN(parseInt(DD));
|
|
212
|
+
}
|
|
213
|
+
return false;
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
/** FILTERS */
|
|
217
|
+
|
|
218
|
+
// example:
|
|
219
|
+
// unicodeDomain[contains]=a&unicodeDomain[contains]=dsa&logicOperator=and&tab=ignored
|
|
220
|
+
const getFilterModelFromString = (searchString, columns) => {
|
|
221
|
+
if (!searchString) {
|
|
222
|
+
return 'invalid';
|
|
223
|
+
}
|
|
224
|
+
let linkOperator = GridLinkOperator.And;
|
|
225
|
+
let quickFilterValues = [];
|
|
226
|
+
const searchParams = new URLSearchParams();
|
|
227
|
+
for (const [key, value] of new URLSearchParams(searchString)) {
|
|
228
|
+
if (key.startsWith('_') && !['_logicOperator', '_sortColumn', '_pinnedColumnsLeft', '_pinnedColumnsRight', '_columnVisibility', '_pagination', '_quickFilterValues'].includes(key)) {
|
|
229
|
+
searchParams.set(key, value);
|
|
230
|
+
}
|
|
231
|
+
if (key === '_logicOperator') {
|
|
232
|
+
linkOperator = value;
|
|
233
|
+
}
|
|
234
|
+
if (key === '_quickFilterValues') {
|
|
235
|
+
try {
|
|
236
|
+
quickFilterValues = JSON.parse(decodeURIComponent(value));
|
|
237
|
+
} catch {
|
|
238
|
+
quickFilterValues = [];
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
let id = 5000;
|
|
243
|
+
const fields = columns.map(column => column.field);
|
|
244
|
+
let isInvalid = false;
|
|
245
|
+
const items = [];
|
|
246
|
+
searchParams.forEach((value, key) => {
|
|
247
|
+
var _columns$find;
|
|
248
|
+
if (isInvalid) {
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
const field = key.split('[')[0].slice(1); // Slice to remove the _ at the beginning
|
|
252
|
+
if (!fields.includes(field)) {
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
const columnType = (_columns$find = columns.find(column => column.field === field)) === null || _columns$find === void 0 ? void 0 : _columns$find.type;
|
|
256
|
+
const left = key.split(']')[0];
|
|
257
|
+
if (left.split('[').length < 2) {
|
|
258
|
+
isInvalid = true;
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
const splitRight = key.split('[')[1].split(']')[0].split(',');
|
|
262
|
+
const type = splitRight[1];
|
|
263
|
+
if (type !== columnType) {
|
|
264
|
+
isInvalid = true;
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
const operator = splitRight[0];
|
|
268
|
+
// if the operator is not part of the valid operators invalidate the URL
|
|
269
|
+
if (!isOperatorValueValid(field, operator, columns) || Array.isArray(operator)) {
|
|
270
|
+
isInvalid = true;
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
id += 1;
|
|
274
|
+
const decodedValue = decodeValue(value);
|
|
275
|
+
if (!isValueValid(decodedValue, field, columns, operator)) {
|
|
276
|
+
isInvalid = true;
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
items.push({
|
|
280
|
+
columnField: field,
|
|
281
|
+
operatorValue: ['number', 'rsNumber'].includes(columnType) && Object.keys(numberOperatorDecoder).includes(operator) ? numberOperatorDecoder[operator] : operator,
|
|
282
|
+
id,
|
|
283
|
+
value: listOperators.includes(operator) && decodedValue === '' ? [] : decodedValue,
|
|
284
|
+
type
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
// If we found some condition that results in an invalid URL,
|
|
289
|
+
// return the empty filterModel (this will trigger the localStorage)
|
|
290
|
+
// and will pick up the last valid search
|
|
291
|
+
if (isInvalid) {
|
|
292
|
+
return 'invalid';
|
|
293
|
+
}
|
|
294
|
+
return {
|
|
295
|
+
items,
|
|
296
|
+
linkOperator,
|
|
297
|
+
quickFilterValues
|
|
298
|
+
};
|
|
299
|
+
};
|
|
300
|
+
const getSearchParamsFromFilterModel = filterModel => {
|
|
301
|
+
var _filterModel$quickFil;
|
|
302
|
+
const searchParams = new URLSearchParams();
|
|
303
|
+
searchParams.set('_logicOperator', filterModel['linkOperator'] || '');
|
|
304
|
+
filterModel['items'].forEach(item => {
|
|
305
|
+
const {
|
|
306
|
+
columnField,
|
|
307
|
+
operatorValue,
|
|
308
|
+
value,
|
|
309
|
+
type
|
|
310
|
+
} = item;
|
|
311
|
+
if (Object.keys(numberOperatorEncoder).includes(operatorValue)) {
|
|
312
|
+
searchParams.set(`_${columnField}[${numberOperatorEncoder[operatorValue]},${encodeValue(type)}]`, encodeValue(value));
|
|
313
|
+
} else {
|
|
314
|
+
searchParams.set(`_${columnField}[${encodeValue(operatorValue)},${encodeValue(type)}]`, encodeValue(value));
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
if ((_filterModel$quickFil = filterModel.quickFilterValues) !== null && _filterModel$quickFil !== void 0 && _filterModel$quickFil.length) {
|
|
318
|
+
searchParams.set('_quickFilterValues', encodeURIComponent(JSON.stringify(filterModel.quickFilterValues)));
|
|
319
|
+
}
|
|
320
|
+
return searchParams;
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
// Rules:
|
|
324
|
+
// - if we have something in the URL, use that info
|
|
325
|
+
// - if we don't have that, use the localStorage and update the URL
|
|
326
|
+
// - if we don't have that, return an empty FilterModel
|
|
327
|
+
const getFilterModel = (search, columns, localStorageFilters, setLocalStorageFilters, initialState, isNewVersion) => {
|
|
328
|
+
const defaultValue = initialState && initialState.filter && initialState.filter.filterModel ? initialState.filter.filterModel : {
|
|
329
|
+
items: [],
|
|
330
|
+
linkOperator: GridLinkOperator.And
|
|
331
|
+
};
|
|
332
|
+
if (isNewVersion) {
|
|
333
|
+
return defaultValue;
|
|
334
|
+
}
|
|
335
|
+
const filterModelFromSearch = getFilterModelFromString(search, columns);
|
|
336
|
+
if (filterModelFromSearch !== 'invalid') {
|
|
337
|
+
const searchFromFilterModel = getSearchParamsFromFilterModel(filterModelFromSearch);
|
|
338
|
+
const searchString = urlSearchParamsToString(searchFromFilterModel);
|
|
339
|
+
if (searchString !== localStorageFilters) {
|
|
340
|
+
setLocalStorageFilters(searchString);
|
|
341
|
+
}
|
|
342
|
+
return filterModelFromSearch;
|
|
343
|
+
}
|
|
344
|
+
const filterModelFromLocalStorage = getFilterModelFromString(localStorageFilters, columns);
|
|
345
|
+
if (filterModelFromLocalStorage !== 'invalid') {
|
|
346
|
+
return filterModelFromLocalStorage;
|
|
347
|
+
}
|
|
348
|
+
return defaultValue;
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
/** SORT */
|
|
352
|
+
|
|
353
|
+
const getSortingFromString = (searchString, columns) => {
|
|
354
|
+
if (!searchString) {
|
|
355
|
+
return 'invalid';
|
|
356
|
+
}
|
|
357
|
+
const searchParams = new URLSearchParams(searchString);
|
|
358
|
+
const value = searchParams.get('_sortColumn');
|
|
359
|
+
if (value === '' || value === null || value === '[]') {
|
|
360
|
+
return [];
|
|
361
|
+
}
|
|
362
|
+
const fields = columns.map(column => column.field);
|
|
363
|
+
const [column, order] = value.slice(1, value.length - 1).split(',');
|
|
364
|
+
if (fields.includes(column) && (order === 'asc' || order === 'desc')) {
|
|
365
|
+
return [{
|
|
366
|
+
field: column,
|
|
367
|
+
sort: order
|
|
368
|
+
}];
|
|
369
|
+
}
|
|
370
|
+
return 'invalid';
|
|
371
|
+
};
|
|
372
|
+
const getSearchParamsFromSorting = sorting => {
|
|
373
|
+
const searchParams = new URLSearchParams();
|
|
374
|
+
searchParams.set('_sortColumn', sorting.length > 0 && sorting[0].sort ? `[${encodeValue(sorting[0].field)},${encodeValue(sorting[0].sort)}]` : '[]');
|
|
375
|
+
return searchParams;
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
// Rules:
|
|
379
|
+
// - if we have something in the URL, use that info
|
|
380
|
+
// - if we don't have that, use the localStorage and update the URL
|
|
381
|
+
// - if we don't have that, return an empty SortModel
|
|
382
|
+
const getSortModel = (search, columns, localStorageSorting, setLocalStorageSorting, initialState, isNewVersion) => {
|
|
383
|
+
var _initialState$sorting;
|
|
384
|
+
const defaultValue = initialState !== null && initialState !== void 0 && (_initialState$sorting = initialState.sorting) !== null && _initialState$sorting !== void 0 && _initialState$sorting.sortModel ? initialState.sorting.sortModel : [];
|
|
385
|
+
if (isNewVersion) {
|
|
386
|
+
return defaultValue;
|
|
387
|
+
}
|
|
388
|
+
const sorting = getSortingFromString(search, columns);
|
|
389
|
+
if (sorting !== 'invalid') {
|
|
390
|
+
const searchFromSortModel = getSearchParamsFromSorting(sorting);
|
|
391
|
+
const searchString = urlSearchParamsToString(searchFromSortModel);
|
|
392
|
+
if (searchString !== localStorageSorting) {
|
|
393
|
+
setLocalStorageSorting(searchString);
|
|
394
|
+
}
|
|
395
|
+
return sorting;
|
|
396
|
+
}
|
|
397
|
+
const sortModelFromLocalStorage = getSortingFromString(localStorageSorting, columns);
|
|
398
|
+
if (sortModelFromLocalStorage !== 'invalid') {
|
|
399
|
+
return sortModelFromLocalStorage;
|
|
400
|
+
}
|
|
401
|
+
return defaultValue;
|
|
402
|
+
};
|
|
403
|
+
|
|
404
|
+
/** PAGINATION */
|
|
405
|
+
|
|
406
|
+
const getPaginationFromString = searchString => {
|
|
407
|
+
if (!searchString) {
|
|
408
|
+
return 'invalid';
|
|
409
|
+
}
|
|
410
|
+
const searchParams = new URLSearchParams(searchString);
|
|
411
|
+
const value = searchParams.get('_pagination');
|
|
412
|
+
if (value === '' || value === null || value === '[]') {
|
|
413
|
+
return 'invalid';
|
|
414
|
+
}
|
|
415
|
+
const pagination = value.slice(1, value.length - 1).split(',');
|
|
416
|
+
const page = parseFloat(pagination[0]);
|
|
417
|
+
const pageSize = parseFloat(pagination[1]);
|
|
418
|
+
const direction = pagination[2];
|
|
419
|
+
if (!Number.isNaN(page) && !Number.isNaN(pageSize) && direction && ['next', 'back'].includes(direction)) {
|
|
420
|
+
return {
|
|
421
|
+
page,
|
|
422
|
+
pageSize,
|
|
423
|
+
direction: direction
|
|
10
424
|
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
425
|
+
}
|
|
426
|
+
return 'invalid';
|
|
427
|
+
};
|
|
428
|
+
const getSearchParamsFromPagination = pagination => {
|
|
429
|
+
const searchParams = new URLSearchParams();
|
|
430
|
+
searchParams.set('_pagination', `[${pagination.page},${pagination.pageSize},${pagination.direction}]`);
|
|
431
|
+
return searchParams;
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
// Rules:
|
|
435
|
+
// - if we have something in the URL, use that info
|
|
436
|
+
// - if we don't have that, use the localStorage and update the URL
|
|
437
|
+
// - if we don't have that, return an empty PaginationModel
|
|
438
|
+
const getPaginationModel = (search, localStoragePagination, setLocalStoragePagination, initialState, isNewVersion) => {
|
|
439
|
+
const defaultValue = initialState !== null && initialState !== void 0 && initialState.pagination ? _objectSpread2({
|
|
440
|
+
page: 0,
|
|
441
|
+
pageSize: 25,
|
|
442
|
+
direction: 'next'
|
|
443
|
+
}, initialState.pagination) : {
|
|
444
|
+
page: 0,
|
|
445
|
+
pageSize: 25,
|
|
446
|
+
direction: 'next'
|
|
447
|
+
};
|
|
448
|
+
if (isNewVersion) {
|
|
449
|
+
return defaultValue;
|
|
450
|
+
}
|
|
451
|
+
const pagination = getPaginationFromString(search);
|
|
452
|
+
if (pagination !== 'invalid') {
|
|
453
|
+
const searchFromPaginationModel = getSearchParamsFromPagination(pagination);
|
|
454
|
+
const searchString = urlSearchParamsToString(searchFromPaginationModel);
|
|
455
|
+
if (searchString !== localStoragePagination) {
|
|
456
|
+
setLocalStoragePagination(searchString);
|
|
457
|
+
}
|
|
458
|
+
return pagination;
|
|
459
|
+
}
|
|
460
|
+
const paginationModelFromLocalStorage = getPaginationFromString(localStoragePagination);
|
|
461
|
+
if (paginationModelFromLocalStorage !== 'invalid') {
|
|
462
|
+
return paginationModelFromLocalStorage;
|
|
463
|
+
}
|
|
464
|
+
return defaultValue;
|
|
465
|
+
};
|
|
466
|
+
|
|
467
|
+
/** COLUMN VISIBILITY */
|
|
468
|
+
|
|
469
|
+
const getSearchParamsFromColumnVisibility = (columnVisibility, columns) => {
|
|
470
|
+
const searchParams = new URLSearchParams();
|
|
471
|
+
const columnFields = columns.map(column => column.field);
|
|
472
|
+
|
|
473
|
+
// if column visibility model is empty, show all columns
|
|
474
|
+
if (Object.keys(columnVisibility).length == 0) {
|
|
475
|
+
searchParams.set('_columnVisibility', `[${columnFields.join(',')}]`);
|
|
476
|
+
return searchParams;
|
|
477
|
+
}
|
|
478
|
+
const finalColumnVisibility = columns.filter(c => {
|
|
479
|
+
var _c$hideable;
|
|
480
|
+
return !((_c$hideable = c === null || c === void 0 ? void 0 : c.hideable) !== null && _c$hideable !== void 0 ? _c$hideable : true);
|
|
481
|
+
}).map(c => c.field).reduce((acc, colName) => {
|
|
482
|
+
return _objectSpread2(_objectSpread2({}, acc), {}, {
|
|
483
|
+
[colName]: true
|
|
484
|
+
});
|
|
485
|
+
}, columnVisibility);
|
|
486
|
+
const visibleColumns = Object.entries(finalColumnVisibility)
|
|
487
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
488
|
+
.filter(_ref => {
|
|
489
|
+
let [_, visible] = _ref;
|
|
490
|
+
return visible;
|
|
491
|
+
})
|
|
492
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
493
|
+
.map(_ref2 => {
|
|
494
|
+
let [column, _] = _ref2;
|
|
495
|
+
return encodeValue(column);
|
|
496
|
+
});
|
|
497
|
+
searchParams.set('_columnVisibility', `[${visibleColumns.join(',')}]`);
|
|
498
|
+
return searchParams;
|
|
499
|
+
};
|
|
500
|
+
const getColumnVisibilityFromString = (notParsed, tableColumns) => {
|
|
501
|
+
if (!notParsed || notParsed.length === 1 && notParsed[0] === '?') {
|
|
502
|
+
return 'invalid';
|
|
503
|
+
}
|
|
504
|
+
// remove the initial ? if present
|
|
505
|
+
const parsed = notParsed[0] === '?' ? notParsed.slice(1) : notParsed;
|
|
506
|
+
const visibility = {};
|
|
507
|
+
let exist = false;
|
|
508
|
+
let visibleColumnsCount = 0;
|
|
509
|
+
for (const item of parsed.split('&')) {
|
|
510
|
+
// if it's not column visibility field, skip
|
|
511
|
+
const fieldURL = item.split('=')[0];
|
|
512
|
+
if (fieldURL !== '_columnVisibility') {
|
|
513
|
+
continue;
|
|
514
|
+
}
|
|
515
|
+
// e.g. item = _columnVisibility[abc,def]
|
|
516
|
+
const left = item.split(']')[0];
|
|
517
|
+
if (left.split('[').length < 2) {
|
|
518
|
+
continue;
|
|
519
|
+
}
|
|
520
|
+
const encodedValues = item.split('[')[1].split(']')[0];
|
|
521
|
+
if (typeof encodedValues !== 'string') {
|
|
522
|
+
continue;
|
|
523
|
+
}
|
|
524
|
+
exist = true;
|
|
525
|
+
const columnFields = tableColumns.map(column => column.field);
|
|
526
|
+
// TODO: Add validation that , is present
|
|
527
|
+
const columns = encodedValues.split(',').map(value => decodeValue(value));
|
|
528
|
+
|
|
529
|
+
// for each column, check if it's visible and add it to visibility model
|
|
530
|
+
for (const column of columnFields) {
|
|
531
|
+
const isColumnVisible = columns.includes(column);
|
|
532
|
+
visibility[column] = isColumnVisible;
|
|
533
|
+
if (isColumnVisible) {
|
|
534
|
+
visibleColumnsCount += 1;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
if (visibleColumnsCount === 0 && !exist) {
|
|
539
|
+
return 'invalid';
|
|
540
|
+
}
|
|
541
|
+
return visibility;
|
|
542
|
+
};
|
|
543
|
+
|
|
544
|
+
// Rules:
|
|
545
|
+
// - if we have something in the URL, use that info
|
|
546
|
+
// - if we don't have that, use the localStorage and update the URL
|
|
547
|
+
// - if we don't have that, return an empty ColumnVisibilityModel (which is all columns)
|
|
548
|
+
// NOTE: the `defaultHidden` is a custom field and not standard DataGrid
|
|
549
|
+
// The reason is the following bug: https://github.com/mui/mui-x/issues/8407
|
|
550
|
+
const getColumnsVisibility = (search, columns, localStorageColumnsVisibility, setLocalStorageColumnsVisibility, initialState, isNewVersion) => {
|
|
551
|
+
var _initialState$columns3;
|
|
552
|
+
const defaultValue = {};
|
|
553
|
+
for (const column of columns) {
|
|
554
|
+
var _initialState$columns, _initialState$columns2;
|
|
555
|
+
const field = column.field;
|
|
556
|
+
if ((initialState === null || initialState === void 0 ? void 0 : (_initialState$columns = initialState.columns) === null || _initialState$columns === void 0 ? void 0 : (_initialState$columns2 = _initialState$columns.columnVisibilityModel) === null || _initialState$columns2 === void 0 ? void 0 : _initialState$columns2[field]) !== undefined) {
|
|
557
|
+
defaultValue[field] = initialState.columns.columnVisibilityModel[field];
|
|
558
|
+
} else {
|
|
559
|
+
defaultValue[field] = column.defaultHidden !== true; // undefined will be true
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
if (isNewVersion) {
|
|
564
|
+
return defaultValue;
|
|
565
|
+
}
|
|
566
|
+
const columnVisibility = getColumnVisibilityFromString(search, columns);
|
|
567
|
+
if (columnVisibility !== 'invalid') {
|
|
568
|
+
const searchColumnVisibility = getSearchParamsFromColumnVisibility(columnVisibility, columns);
|
|
569
|
+
if (searchColumnVisibility.toString() !== localStorageColumnsVisibility) {
|
|
570
|
+
setLocalStorageColumnsVisibility(searchColumnVisibility.toString());
|
|
571
|
+
}
|
|
572
|
+
return columnVisibility;
|
|
573
|
+
}
|
|
574
|
+
const columnVisibilityFromLocalStorage = getColumnVisibilityFromString(localStorageColumnsVisibility, columns);
|
|
575
|
+
if (columnVisibilityFromLocalStorage !== 'invalid') {
|
|
576
|
+
return columnVisibilityFromLocalStorage;
|
|
577
|
+
}
|
|
578
|
+
if (initialState !== null && initialState !== void 0 && (_initialState$columns3 = initialState.columns) !== null && _initialState$columns3 !== void 0 && _initialState$columns3.columnVisibilityModel) {
|
|
579
|
+
return initialState.columns.columnVisibilityModel;
|
|
580
|
+
}
|
|
581
|
+
return defaultValue;
|
|
582
|
+
};
|
|
583
|
+
const getPinnedColumnsFromString = (notParsed, tableColumns) => {
|
|
584
|
+
if (!notParsed || notParsed.length === 1 && notParsed[0] === '?') {
|
|
585
|
+
return 'invalid';
|
|
586
|
+
}
|
|
587
|
+
// remove the initial ? if present
|
|
588
|
+
const parsed = notParsed[0] === '?' ? notParsed.slice(1) : notParsed;
|
|
589
|
+
const pinnedColumns = {};
|
|
590
|
+
for (const item of parsed.split('&')) {
|
|
591
|
+
const fieldURL = item.split('=')[0];
|
|
592
|
+
if (fieldURL !== '_pinnedColumnsLeft' && fieldURL !== '_pinnedColumnsRight') {
|
|
593
|
+
continue;
|
|
594
|
+
}
|
|
595
|
+
const left = item.split(']')[0];
|
|
596
|
+
if (left.split('[').length < 2) {
|
|
597
|
+
continue;
|
|
598
|
+
}
|
|
599
|
+
const encodedValues = item.split('[')[1].split(']')[0];
|
|
600
|
+
if (typeof encodedValues !== 'string') {
|
|
601
|
+
continue;
|
|
602
|
+
}
|
|
603
|
+
const columnFields = [...tableColumns.map(column => column.field), '__check__'];
|
|
604
|
+
const columns = encodedValues.split(',').map(value => decodeValue(value)).filter(val => typeof val === 'string' && columnFields.includes(val));
|
|
605
|
+
if (fieldURL === '_pinnedColumnsLeft') {
|
|
606
|
+
pinnedColumns['left'] = columns;
|
|
607
|
+
}
|
|
608
|
+
if (fieldURL === '_pinnedColumnsRight') {
|
|
609
|
+
pinnedColumns['right'] = columns;
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
return pinnedColumns['left'] || pinnedColumns['right'] ? {
|
|
613
|
+
left: pinnedColumns['left'] || [],
|
|
614
|
+
right: pinnedColumns['right'] || []
|
|
615
|
+
} : 'invalid';
|
|
616
|
+
};
|
|
617
|
+
const getSearchParamsFromPinnedColumns = pinnedColumns => {
|
|
618
|
+
var _pinnedColumns$left, _pinnedColumns$right;
|
|
619
|
+
const searchParams = new URLSearchParams();
|
|
620
|
+
const pinnedColumnLeft = ((_pinnedColumns$left = pinnedColumns.left) === null || _pinnedColumns$left === void 0 ? void 0 : _pinnedColumns$left.map(val => encodeValue(val))) || [];
|
|
621
|
+
const pinnedColumnRight = ((_pinnedColumns$right = pinnedColumns.right) === null || _pinnedColumns$right === void 0 ? void 0 : _pinnedColumns$right.map(val => encodeValue(val))) || [];
|
|
622
|
+
searchParams.set('_pinnedColumnsLeft', `[${pinnedColumnLeft.join(',')}]`);
|
|
623
|
+
searchParams.set('_pinnedColumnsRight', `[${pinnedColumnRight.join(',')}]`);
|
|
624
|
+
return searchParams;
|
|
625
|
+
};
|
|
626
|
+
|
|
627
|
+
// Rules:
|
|
628
|
+
// - if we have something in the URL, use that info
|
|
629
|
+
// - if we don't have that, use the localStorage and update the URL
|
|
630
|
+
// - if we don't have that, return an empty ColumnVisibilityModel (which is all columns)
|
|
631
|
+
const getPinnedColumns = (search, columns, localStoragePinnedColumns, setLocalStoragePinnedColumns, initialState, isNewVersion) => {
|
|
632
|
+
const defaultValue = initialState !== null && initialState !== void 0 && initialState.pinnedColumns ? {
|
|
633
|
+
left: (initialState === null || initialState === void 0 ? void 0 : initialState.pinnedColumns['left']) || [],
|
|
634
|
+
right: (initialState === null || initialState === void 0 ? void 0 : initialState.pinnedColumns['right']) || []
|
|
635
|
+
} : {
|
|
636
|
+
left: [],
|
|
637
|
+
right: []
|
|
638
|
+
};
|
|
639
|
+
if (isNewVersion) {
|
|
640
|
+
return defaultValue;
|
|
641
|
+
}
|
|
642
|
+
const pinnedColumns = getPinnedColumnsFromString(search, columns);
|
|
643
|
+
if (pinnedColumns !== 'invalid') {
|
|
644
|
+
const searchPinnedColumns = getSearchParamsFromPinnedColumns(pinnedColumns);
|
|
645
|
+
if (searchPinnedColumns.toString() !== localStoragePinnedColumns) {
|
|
646
|
+
setLocalStoragePinnedColumns(searchPinnedColumns.toString());
|
|
647
|
+
}
|
|
648
|
+
return pinnedColumns;
|
|
649
|
+
}
|
|
650
|
+
const pinnedColumnsFromLocalStorage = getPinnedColumnsFromString(localStoragePinnedColumns, columns);
|
|
651
|
+
if (pinnedColumnsFromLocalStorage !== 'invalid') {
|
|
652
|
+
return pinnedColumnsFromLocalStorage;
|
|
653
|
+
}
|
|
654
|
+
return defaultValue;
|
|
655
|
+
};
|
|
656
|
+
const getSearchParamsFromTab = search => {
|
|
657
|
+
const searchParams = new URLSearchParams();
|
|
658
|
+
const openTab = new URLSearchParams(search).get('tab');
|
|
659
|
+
if (openTab) {
|
|
660
|
+
searchParams.set('tab', openTab);
|
|
661
|
+
}
|
|
662
|
+
return searchParams;
|
|
663
|
+
};
|
|
664
|
+
const getFinalSearch = _ref3 => {
|
|
665
|
+
let {
|
|
666
|
+
search,
|
|
667
|
+
localStorageVersion,
|
|
668
|
+
filterModel,
|
|
669
|
+
sortModel,
|
|
670
|
+
paginationModel,
|
|
671
|
+
columnsVisibilityModel,
|
|
672
|
+
pinnedColumnsModel,
|
|
673
|
+
columns
|
|
674
|
+
} = _ref3;
|
|
675
|
+
const filterModelSearch = getSearchParamsFromFilterModel(filterModel);
|
|
676
|
+
const sortModelSearch = getSearchParamsFromSorting(sortModel);
|
|
677
|
+
const paginationModelSearch = getSearchParamsFromPagination(paginationModel);
|
|
678
|
+
const columnVisibilityModelSearch = getSearchParamsFromColumnVisibility(columnsVisibilityModel, columns);
|
|
679
|
+
const pinnedColumnsModelSearch = getSearchParamsFromPinnedColumns(pinnedColumnsModel);
|
|
680
|
+
const tabSearch = getSearchParamsFromTab(search);
|
|
681
|
+
const searchParams = new URLSearchParams();
|
|
682
|
+
for (const [key, value] of new URLSearchParams(search)) {
|
|
683
|
+
if (!key.startsWith('_')) {
|
|
684
|
+
searchParams.set(key, value);
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
searchParams.set('v', `${localStorageVersion}`);
|
|
688
|
+
|
|
689
|
+
// Add quickFilterValues explicitly if present in filterModel
|
|
690
|
+
if (filterModel.quickFilterValues && filterModel.quickFilterValues.length > 0) {
|
|
691
|
+
// Encode array as JSON string to preserve all values in one param
|
|
692
|
+
searchParams.set('_quickFilterValues', encodeURIComponent(JSON.stringify(filterModel.quickFilterValues)));
|
|
693
|
+
}
|
|
694
|
+
return new URLSearchParams([...searchParams, ...filterModelSearch, ...sortModelSearch, ...paginationModelSearch, ...tabSearch, ...pinnedColumnsModelSearch, ...columnVisibilityModelSearch]);
|
|
695
|
+
};
|
|
696
|
+
/** Return the state of the table given the URL and the local storage state */
|
|
697
|
+
const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, columns, historyReplace, initialState, localStorage) => {
|
|
698
|
+
const currentVersion = new URLSearchParams(search).get('v');
|
|
699
|
+
const isNewVersion = !currentVersion || Number(currentVersion) !== localStorageVersion;
|
|
700
|
+
const {
|
|
701
|
+
localStorageFilters,
|
|
702
|
+
setLocalStorageFilters,
|
|
703
|
+
localStorageSorting,
|
|
704
|
+
setLocalStorageSorting,
|
|
705
|
+
localStoragePagination,
|
|
706
|
+
setLocalStoragePagination,
|
|
707
|
+
localStorageColumnsVisibility,
|
|
708
|
+
setLocalStorageColumnsVisibility,
|
|
709
|
+
localStoragePinnedColumns,
|
|
710
|
+
setLocalStoragePinnedColumns
|
|
711
|
+
} = localStorage;
|
|
712
|
+
const filterModel = getFilterModel(search, columns, localStorageFilters, setLocalStorageFilters, initialState, isNewVersion);
|
|
713
|
+
const sortModel = getSortModel(search, columns, localStorageSorting, setLocalStorageSorting, initialState, isNewVersion);
|
|
714
|
+
const paginationModel = getPaginationModel(search, localStoragePagination, setLocalStoragePagination, initialState, isNewVersion);
|
|
715
|
+
const columnVisibilityModel = getColumnsVisibility(search, columns, localStorageColumnsVisibility, setLocalStorageColumnsVisibility, initialState, isNewVersion);
|
|
716
|
+
const pinnedColumnsModel = getPinnedColumns(search, columns, localStoragePinnedColumns, setLocalStoragePinnedColumns, initialState, isNewVersion);
|
|
717
|
+
const finalSearch = getFinalSearch({
|
|
718
|
+
localStorageVersion,
|
|
719
|
+
search,
|
|
720
|
+
filterModel,
|
|
721
|
+
sortModel,
|
|
722
|
+
paginationModel,
|
|
723
|
+
columnsVisibilityModel: columnVisibilityModel,
|
|
724
|
+
pinnedColumnsModel,
|
|
725
|
+
columns
|
|
726
|
+
});
|
|
727
|
+
const searchString = urlSearchParamsToString(finalSearch);
|
|
728
|
+
if (searchString !== search) {
|
|
729
|
+
historyReplace(searchString);
|
|
730
|
+
}
|
|
731
|
+
return {
|
|
732
|
+
filterModel,
|
|
733
|
+
sortModel,
|
|
734
|
+
paginationModel,
|
|
735
|
+
columnVisibilityModel,
|
|
736
|
+
pinnedColumnsModel
|
|
737
|
+
};
|
|
738
|
+
};
|
|
739
|
+
const updateUrl = (_ref4, search, localStorageVersion, historyReplace, columns) => {
|
|
740
|
+
let {
|
|
741
|
+
filterModel,
|
|
742
|
+
sortModel,
|
|
743
|
+
paginationModel,
|
|
744
|
+
columnsModel: columnsVisibilityModel,
|
|
745
|
+
pinnedColumnsModel
|
|
746
|
+
} = _ref4;
|
|
747
|
+
const newSearch = getFinalSearch({
|
|
748
|
+
search,
|
|
749
|
+
localStorageVersion,
|
|
750
|
+
filterModel,
|
|
751
|
+
sortModel,
|
|
752
|
+
paginationModel,
|
|
753
|
+
columnsVisibilityModel,
|
|
754
|
+
pinnedColumnsModel,
|
|
755
|
+
columns
|
|
756
|
+
});
|
|
757
|
+
const searchString = urlSearchParamsToString(newSearch);
|
|
758
|
+
if (searchString !== search) {
|
|
759
|
+
historyReplace(searchString);
|
|
760
|
+
}
|
|
761
|
+
};
|
|
762
|
+
|
|
763
|
+
// Note: this is a comparator to sort the filters, not pure comparison
|
|
764
|
+
// do not use it for equivalence (e.g. with value `3` and undefined we
|
|
765
|
+
// will get 0).
|
|
766
|
+
const compareFilters = (firstFilter, secondFilter) => {
|
|
767
|
+
if (firstFilter.columnField < secondFilter.columnField) {
|
|
768
|
+
return -1;
|
|
769
|
+
} else if (firstFilter.columnField > secondFilter.columnField) {
|
|
770
|
+
return 1;
|
|
771
|
+
}
|
|
772
|
+
if (firstFilter.operatorValue === undefined || secondFilter.operatorValue === undefined) {
|
|
773
|
+
return 0;
|
|
774
|
+
}
|
|
775
|
+
if (firstFilter.operatorValue < secondFilter.operatorValue) {
|
|
776
|
+
return -1;
|
|
777
|
+
} else if (firstFilter.operatorValue > secondFilter.operatorValue) {
|
|
778
|
+
return 1;
|
|
779
|
+
}
|
|
780
|
+
if (firstFilter.value < secondFilter.value) {
|
|
781
|
+
return -1;
|
|
782
|
+
} else if (firstFilter.value > secondFilter.value) {
|
|
783
|
+
return 1;
|
|
784
|
+
}
|
|
785
|
+
return 0;
|
|
786
|
+
};
|
|
787
|
+
const areFiltersEquivalent = (firstFilter, secondFilter) => {
|
|
788
|
+
return firstFilter.columnField === secondFilter.columnField && firstFilter.operatorValue === secondFilter.operatorValue && firstFilter.value === secondFilter.value;
|
|
789
|
+
};
|
|
790
|
+
const areFilterModelsEquivalent = (filterModel, filterModelToMatch) => {
|
|
791
|
+
const {
|
|
792
|
+
items,
|
|
793
|
+
linkOperator
|
|
794
|
+
} = filterModel;
|
|
795
|
+
const {
|
|
796
|
+
items: itemsToMatch,
|
|
797
|
+
linkOperator: linkOperatorToMatch
|
|
798
|
+
} = filterModelToMatch;
|
|
799
|
+
if (linkOperator !== linkOperatorToMatch) {
|
|
800
|
+
return false;
|
|
801
|
+
}
|
|
802
|
+
if (items.length !== itemsToMatch.length) {
|
|
803
|
+
return false;
|
|
804
|
+
}
|
|
805
|
+
items.sort(compareFilters);
|
|
806
|
+
itemsToMatch.sort(compareFilters);
|
|
807
|
+
for (let i = 0; i < items.length; i++) {
|
|
808
|
+
const filter = items[i];
|
|
809
|
+
const filterToCompare = itemsToMatch[i];
|
|
810
|
+
|
|
811
|
+
// compareFilters return 0 if and only if the filters have the same
|
|
812
|
+
// columnField, operatorValue, and value
|
|
813
|
+
if (!areFiltersEquivalent(filter, filterToCompare)) {
|
|
814
|
+
return false;
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
return true;
|
|
818
|
+
};
|
|
819
|
+
|
|
820
|
+
// Get and Set data from LocalStorage WITHOUT useState
|
|
821
|
+
|
|
822
|
+
// triggering a state update and consecutive re-render
|
|
823
|
+
const useFetchState = (defaultValue, key) => {
|
|
824
|
+
let stickyValue = null;
|
|
825
|
+
try {
|
|
826
|
+
stickyValue = window.localStorage.getItem(key);
|
|
827
|
+
} catch (e) {
|
|
828
|
+
console.error('StatefulDataGrid: error getting item from local storage: ', e);
|
|
829
|
+
}
|
|
830
|
+
let parsedValue = stickyValue !== null && stickyValue !== undefined && stickyValue !== 'undefined' ? JSON.parse(stickyValue) : defaultValue;
|
|
831
|
+
|
|
832
|
+
// TODO: temporary workaround to avoid clashes when someone had sorting on the now-removed screenshot field (renamed to num_annotations)
|
|
833
|
+
// Consider upgrading the Datagrid component library as the exception handling was added in this PR: https://github.com/mui-org/material-ui-x/pull/3224
|
|
834
|
+
if (parsedValue instanceof Array) {
|
|
835
|
+
const fields = (parsedValue || []).map(item => item.field);
|
|
836
|
+
if (fields.includes('screenshot') || fields.includes('diffs')) {
|
|
837
|
+
parsedValue = defaultValue;
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
const updateValue = useCallback(value => {
|
|
841
|
+
try {
|
|
842
|
+
window.localStorage.setItem(key, JSON.stringify(value));
|
|
843
|
+
} catch (e) {
|
|
844
|
+
console.error('StatefulDataGrid: error setting item into local storage: ', e);
|
|
845
|
+
}
|
|
846
|
+
}, [key]);
|
|
847
|
+
return [parsedValue, updateValue];
|
|
848
|
+
};
|
|
849
|
+
|
|
850
|
+
const useTableStates = (id, version) => {
|
|
851
|
+
const [paginationModel, setPaginationModel] = useFetchState('', buildStorageKey({
|
|
852
|
+
id,
|
|
853
|
+
version,
|
|
854
|
+
category: PAGINATION_MODEL_KEY
|
|
855
|
+
}));
|
|
856
|
+
const [sortModel, setSortModel] = useFetchState('', buildStorageKey({
|
|
857
|
+
id,
|
|
858
|
+
version,
|
|
859
|
+
category: SORT_MODEL_KEY
|
|
860
|
+
}));
|
|
861
|
+
const [localStorageFilters, setLocalStorageFilters] = useFetchState('', buildStorageKey({
|
|
862
|
+
id,
|
|
863
|
+
version,
|
|
864
|
+
category: FILTER_SEARCH_KEY
|
|
865
|
+
}));
|
|
866
|
+
const [visibilityModelLocalStorage, setVisibilityModelLocalStorage] = useFetchState('', buildStorageKey({
|
|
867
|
+
id,
|
|
868
|
+
version,
|
|
869
|
+
category: VISIBILITY_MODEL_KEY
|
|
870
|
+
}));
|
|
871
|
+
const [pinnedColumns, setPinnedColumns] = useFetchState('_pinnedColumnsLeft=[]&_pinnedColumnsRight=[]', buildStorageKey({
|
|
872
|
+
id,
|
|
873
|
+
version,
|
|
874
|
+
category: PINNED_COLUMNS
|
|
875
|
+
}));
|
|
876
|
+
const [dimensionModel, setDimensionModel] = useFetchState({}, buildStorageKey({
|
|
877
|
+
id,
|
|
878
|
+
version,
|
|
879
|
+
category: DIMENSION_MODEL_KEY
|
|
880
|
+
}));
|
|
881
|
+
return {
|
|
882
|
+
paginationModel,
|
|
883
|
+
setPaginationModel,
|
|
884
|
+
sortModel,
|
|
885
|
+
setSortModel,
|
|
886
|
+
localStorageFilters,
|
|
887
|
+
setLocalStorageFilters,
|
|
888
|
+
visibilityModelLocalStorage,
|
|
889
|
+
setVisibilityModelLocalStorage,
|
|
890
|
+
pinnedColumns,
|
|
891
|
+
setPinnedColumns,
|
|
892
|
+
dimensionModel,
|
|
893
|
+
setDimensionModel
|
|
894
|
+
};
|
|
895
|
+
};
|
|
896
|
+
|
|
897
|
+
const useStatefulTable = props => {
|
|
898
|
+
const {
|
|
899
|
+
// density = 'standard',
|
|
900
|
+
apiRef,
|
|
901
|
+
initialState,
|
|
902
|
+
columns: propsColumns,
|
|
903
|
+
onColumnVisibilityModelChange: propsOnColumnVisibilityModelChange,
|
|
904
|
+
onColumnWidthChange: propsOnColumnWidthChange,
|
|
905
|
+
onFilterModelChange: propsOnFilterModelChange,
|
|
906
|
+
onPageChange: propsOnPageChange,
|
|
907
|
+
onPageSizeChange: propsOnPageSizeChange,
|
|
908
|
+
onPinnedColumnsChange: propsOnPinnedColumnsChange,
|
|
909
|
+
onSortModelChange: propsOnSortModelChange,
|
|
910
|
+
useRouter,
|
|
911
|
+
localStorageVersion = 1,
|
|
912
|
+
previousLocalStorageVersions = []
|
|
913
|
+
} = props;
|
|
914
|
+
const {
|
|
915
|
+
search,
|
|
916
|
+
pathname,
|
|
917
|
+
historyReplace
|
|
918
|
+
} = useRouter();
|
|
919
|
+
const id = pathname;
|
|
920
|
+
|
|
921
|
+
// States and setters persisted in the local storage for this table
|
|
922
|
+
const {
|
|
923
|
+
paginationModel,
|
|
924
|
+
setPaginationModel,
|
|
925
|
+
sortModel,
|
|
926
|
+
setSortModel,
|
|
927
|
+
localStorageFilters,
|
|
928
|
+
setLocalStorageFilters,
|
|
929
|
+
visibilityModelLocalStorage,
|
|
930
|
+
setVisibilityModelLocalStorage,
|
|
931
|
+
pinnedColumns,
|
|
932
|
+
setPinnedColumns,
|
|
933
|
+
dimensionModel,
|
|
934
|
+
setDimensionModel
|
|
935
|
+
} = useTableStates(id, localStorageVersion);
|
|
936
|
+
|
|
937
|
+
// clearing up old version keys
|
|
938
|
+
useEffect(() => clearPreviousVersionStorage(id, previousLocalStorageVersions), [id, previousLocalStorageVersions]);
|
|
939
|
+
const onColumnDimensionChange = useCallback(_ref => {
|
|
940
|
+
let {
|
|
941
|
+
newWidth,
|
|
942
|
+
field
|
|
943
|
+
} = _ref;
|
|
944
|
+
setDimensionModel(_objectSpread2(_objectSpread2({}, dimensionModel), {}, {
|
|
945
|
+
[field]: newWidth
|
|
946
|
+
}));
|
|
947
|
+
}, [dimensionModel, setDimensionModel]);
|
|
948
|
+
const {
|
|
949
|
+
filterModel: filterParsed,
|
|
950
|
+
sortModel: sortModelParsed,
|
|
951
|
+
paginationModel: paginationModelParsed,
|
|
952
|
+
columnVisibilityModel: visibilityModel,
|
|
953
|
+
pinnedColumnsModel
|
|
954
|
+
} = getModelsParsedOrUpdateLocalStorage(search || '', localStorageVersion, propsColumns, historyReplace, initialState, {
|
|
955
|
+
localStorageFilters,
|
|
956
|
+
setLocalStorageFilters,
|
|
957
|
+
localStorageSorting: sortModel,
|
|
958
|
+
setLocalStorageSorting: setSortModel,
|
|
959
|
+
localStoragePagination: paginationModel,
|
|
960
|
+
setLocalStoragePagination: setPaginationModel,
|
|
961
|
+
localStorageColumnsVisibility: visibilityModelLocalStorage,
|
|
962
|
+
setLocalStorageColumnsVisibility: setVisibilityModelLocalStorage,
|
|
963
|
+
localStoragePinnedColumns: pinnedColumns,
|
|
964
|
+
setLocalStoragePinnedColumns: setPinnedColumns
|
|
965
|
+
});
|
|
966
|
+
const columns = useMemo(() => propsColumns.map(column => {
|
|
967
|
+
column.width = dimensionModel[column.field] || column.width || 100;
|
|
968
|
+
return column;
|
|
969
|
+
}), [propsColumns, dimensionModel]);
|
|
970
|
+
|
|
971
|
+
/** Add resetPage method to apiRef. */
|
|
972
|
+
apiRef.current.resetPage = () => {
|
|
973
|
+
apiRef.current.setPage(0);
|
|
974
|
+
};
|
|
975
|
+
return {
|
|
976
|
+
apiRef,
|
|
977
|
+
columns,
|
|
978
|
+
onFilterModelChange: (model, details) => {
|
|
979
|
+
const filterModel = _objectSpread2(_objectSpread2({}, model), {}, {
|
|
980
|
+
items: model.items.map(item => {
|
|
981
|
+
const column = apiRef.current.getColumn(item.columnField);
|
|
982
|
+
item.type = column.type || 'string';
|
|
983
|
+
return item;
|
|
984
|
+
}),
|
|
985
|
+
quickFilterValues: model.quickFilterValues || []
|
|
986
|
+
});
|
|
987
|
+
propsOnFilterModelChange === null || propsOnFilterModelChange === void 0 ? void 0 : propsOnFilterModelChange(filterModel, details);
|
|
988
|
+
updateUrl({
|
|
989
|
+
filterModel: filterModel,
|
|
990
|
+
sortModel: sortModelParsed,
|
|
991
|
+
paginationModel: paginationModelParsed,
|
|
992
|
+
columnsModel: apiRef.current.state.columns.columnVisibilityModel,
|
|
993
|
+
pinnedColumnsModel: pinnedColumnsModel
|
|
994
|
+
}, search, localStorageVersion, historyReplace, columns);
|
|
995
|
+
},
|
|
996
|
+
filterModel: filterParsed,
|
|
997
|
+
onSortModelChange: (model, details) => {
|
|
998
|
+
propsOnSortModelChange === null || propsOnSortModelChange === void 0 ? void 0 : propsOnSortModelChange(model, details);
|
|
999
|
+
updateUrl({
|
|
1000
|
+
filterModel: filterParsed,
|
|
1001
|
+
sortModel: model,
|
|
1002
|
+
paginationModel: paginationModelParsed,
|
|
1003
|
+
columnsModel: apiRef.current.state.columns.columnVisibilityModel,
|
|
1004
|
+
pinnedColumnsModel: pinnedColumnsModel
|
|
1005
|
+
}, search, localStorageVersion, historyReplace, columns);
|
|
1006
|
+
},
|
|
1007
|
+
sortModel: sortModelParsed,
|
|
1008
|
+
onPinnedColumnsChange: (pinnedColumns, details) => {
|
|
1009
|
+
propsOnPinnedColumnsChange === null || propsOnPinnedColumnsChange === void 0 ? void 0 : propsOnPinnedColumnsChange(pinnedColumns, details);
|
|
1010
|
+
updateUrl({
|
|
1011
|
+
filterModel: filterParsed,
|
|
1012
|
+
sortModel: sortModelParsed,
|
|
1013
|
+
paginationModel: paginationModelParsed,
|
|
1014
|
+
columnsModel: apiRef.current.state.columns.columnVisibilityModel,
|
|
1015
|
+
pinnedColumnsModel: pinnedColumns
|
|
1016
|
+
}, search, localStorageVersion, historyReplace, columns);
|
|
1017
|
+
},
|
|
1018
|
+
pinnedColumns: pinnedColumnsModel,
|
|
1019
|
+
page: paginationModelParsed.page,
|
|
1020
|
+
pageSize: paginationModelParsed.pageSize,
|
|
1021
|
+
onPageChange: (page, details) => {
|
|
1022
|
+
const direction = paginationModelParsed.page < page ? 'next' : 'back';
|
|
1023
|
+
propsOnPageChange === null || propsOnPageChange === void 0 ? void 0 : propsOnPageChange(page, details);
|
|
1024
|
+
updateUrl({
|
|
1025
|
+
filterModel: filterParsed,
|
|
1026
|
+
sortModel: sortModelParsed,
|
|
1027
|
+
paginationModel: {
|
|
1028
|
+
page,
|
|
1029
|
+
pageSize: paginationModelParsed.pageSize,
|
|
1030
|
+
direction
|
|
1031
|
+
},
|
|
1032
|
+
columnsModel: apiRef.current.state.columns.columnVisibilityModel,
|
|
1033
|
+
pinnedColumnsModel: pinnedColumnsModel
|
|
1034
|
+
}, search, localStorageVersion, historyReplace, columns);
|
|
1035
|
+
},
|
|
1036
|
+
onPageSizeChange: (pageSize, details) => {
|
|
1037
|
+
propsOnPageSizeChange === null || propsOnPageSizeChange === void 0 ? void 0 : propsOnPageSizeChange(pageSize, details);
|
|
1038
|
+
updateUrl({
|
|
1039
|
+
filterModel: filterParsed,
|
|
1040
|
+
sortModel: sortModelParsed,
|
|
1041
|
+
paginationModel: {
|
|
1042
|
+
page: paginationModelParsed.page,
|
|
1043
|
+
pageSize,
|
|
1044
|
+
direction: paginationModelParsed.direction
|
|
1045
|
+
},
|
|
1046
|
+
columnsModel: apiRef.current.state.columns.columnVisibilityModel,
|
|
1047
|
+
pinnedColumnsModel: pinnedColumnsModel
|
|
1048
|
+
}, search, localStorageVersion, historyReplace, columns);
|
|
1049
|
+
},
|
|
1050
|
+
columnVisibilityModel: visibilityModel,
|
|
1051
|
+
onColumnVisibilityModelChange: (columnsVisibilityModel, details) => {
|
|
1052
|
+
propsOnColumnVisibilityModelChange === null || propsOnColumnVisibilityModelChange === void 0 ? void 0 : propsOnColumnVisibilityModelChange(columnsVisibilityModel, details);
|
|
1053
|
+
updateUrl({
|
|
1054
|
+
filterModel: filterParsed,
|
|
1055
|
+
sortModel: sortModelParsed,
|
|
1056
|
+
paginationModel: paginationModelParsed,
|
|
1057
|
+
columnsModel: columnsVisibilityModel,
|
|
1058
|
+
pinnedColumnsModel: pinnedColumnsModel
|
|
1059
|
+
}, search, localStorageVersion, historyReplace, columns);
|
|
1060
|
+
},
|
|
1061
|
+
onColumnWidthChange: (params, event, details) => {
|
|
1062
|
+
propsOnColumnWidthChange === null || propsOnColumnWidthChange === void 0 ? void 0 : propsOnColumnWidthChange(params, event, details);
|
|
1063
|
+
onColumnDimensionChange({
|
|
1064
|
+
newWidth: params.width,
|
|
1065
|
+
field: params.colDef.field
|
|
1066
|
+
});
|
|
1067
|
+
}
|
|
1068
|
+
};
|
|
1069
|
+
};
|
|
1070
|
+
|
|
1071
|
+
const _excluded = ["apiRef", "autoHeight", "className", "columns", "columnTypes", "components", "componentsProps", "filterModel", "columnVisibilityModel", "pinnedColumns", "sortModel", "page", "pageSize", "height", "hideToolbar", "initialState", "isRowSelectable", "license", "localStorageVersion", "previousLocalStorageVersions", "onFilterModelChange", "selectionModel", "onColumnWidthChange", "onPageChange", "onPageSizeChange", "onSelectionModelChange", "onColumnVisibilityModelChange", "onPinnedColumnsChange", "onSortModelChange", "pagination", "paginationPlacement", "paginationProps", "rows", "rowsPerPageOptions", "sx", "theme", "useRouter", "paginationMode", "rowCount"];
|
|
1072
|
+
const COMPONENT_NAME = 'DataGrid';
|
|
1073
|
+
const CLASSNAME = 'redsift-datagrid';
|
|
1074
|
+
const StatefulDataGrid = /*#__PURE__*/forwardRef((props, ref) => {
|
|
1075
|
+
const datagridRef = ref || useRef();
|
|
1076
|
+
const {
|
|
1077
|
+
apiRef: propsApiRef,
|
|
1078
|
+
autoHeight,
|
|
1079
|
+
className,
|
|
1080
|
+
columns,
|
|
1081
|
+
columnTypes: propsColumnTypes,
|
|
1082
|
+
components,
|
|
1083
|
+
componentsProps,
|
|
1084
|
+
filterModel: propsFilterModel,
|
|
1085
|
+
columnVisibilityModel: propsColumnVisibilityModel,
|
|
1086
|
+
pinnedColumns: propsPinnedColumns,
|
|
1087
|
+
sortModel: propsSortModel,
|
|
1088
|
+
page: propsPage,
|
|
1089
|
+
pageSize: propsPageSize,
|
|
1090
|
+
height: propsHeight,
|
|
1091
|
+
hideToolbar,
|
|
1092
|
+
initialState,
|
|
1093
|
+
isRowSelectable,
|
|
1094
|
+
license = process.env.MUI_LICENSE_KEY,
|
|
1095
|
+
localStorageVersion,
|
|
1096
|
+
previousLocalStorageVersions,
|
|
1097
|
+
onFilterModelChange: propsOnFilterModelChange,
|
|
1098
|
+
selectionModel: propsSelectionModel,
|
|
1099
|
+
onColumnWidthChange: propsOnColumnWidthChange,
|
|
1100
|
+
onPageChange: propsOnPageChange,
|
|
1101
|
+
onPageSizeChange: propsOnPageSizeChange,
|
|
1102
|
+
onSelectionModelChange: propsOnSelectionModelChange,
|
|
1103
|
+
onColumnVisibilityModelChange: propsOnColumnVisibilityModelChange,
|
|
1104
|
+
onPinnedColumnsChange: propsOnPinnedColumnsChange,
|
|
1105
|
+
onSortModelChange: propsOnSortModelChange,
|
|
1106
|
+
pagination,
|
|
1107
|
+
paginationPlacement = 'both',
|
|
1108
|
+
paginationProps,
|
|
1109
|
+
rows,
|
|
1110
|
+
rowsPerPageOptions,
|
|
1111
|
+
sx,
|
|
1112
|
+
theme: propsTheme,
|
|
1113
|
+
useRouter,
|
|
1114
|
+
paginationMode = 'client',
|
|
1115
|
+
rowCount
|
|
1116
|
+
} = props,
|
|
1117
|
+
forwardedProps = _objectWithoutProperties(props, _excluded);
|
|
1118
|
+
const theme = useTheme(propsTheme);
|
|
1119
|
+
const _apiRef = useGridApiRef();
|
|
1120
|
+
const apiRef = propsApiRef !== null && propsApiRef !== void 0 ? propsApiRef : _apiRef;
|
|
1121
|
+
const RenderedToolbar = components !== null && components !== void 0 && components.Toolbar ? components.Toolbar : Toolbar;
|
|
1122
|
+
LicenseInfo.setLicenseKey(license);
|
|
1123
|
+
const height = propsHeight !== null && propsHeight !== void 0 ? propsHeight : autoHeight ? undefined : '500px';
|
|
1124
|
+
const {
|
|
1125
|
+
onColumnVisibilityModelChange: controlledOnColumnVisibilityModelChange,
|
|
1126
|
+
onFilterModelChange: controlledOnFilterModelChange,
|
|
1127
|
+
onPageChange: controlledOnPageChange,
|
|
1128
|
+
onPageSizeChange: controlledOnPageSizeChange,
|
|
1129
|
+
onPinnedColumnsChange: controlledOnPinnedColumnsChange,
|
|
1130
|
+
onSortModelChange: controlledOnSortModelChange
|
|
1131
|
+
} = useControlledDatagridState({
|
|
1132
|
+
initialState,
|
|
1133
|
+
rowsPerPageOptions,
|
|
1134
|
+
propsColumnVisibilityModel,
|
|
1135
|
+
propsFilterModel,
|
|
1136
|
+
propsOnColumnVisibilityModelChange,
|
|
1137
|
+
propsOnFilterModelChange,
|
|
1138
|
+
propsOnPinnedColumnsChange,
|
|
1139
|
+
propsOnSortModelChange,
|
|
1140
|
+
propsPage,
|
|
1141
|
+
propsPageSize,
|
|
1142
|
+
propsPinnedColumns,
|
|
1143
|
+
propsSortModel,
|
|
1144
|
+
propsOnPageChange,
|
|
1145
|
+
propsOnPageSizeChange
|
|
1146
|
+
});
|
|
1147
|
+
const {
|
|
1148
|
+
columnVisibilityModel,
|
|
1149
|
+
filterModel,
|
|
1150
|
+
onColumnVisibilityModelChange,
|
|
1151
|
+
onFilterModelChange,
|
|
1152
|
+
onPageChange,
|
|
1153
|
+
onPageSizeChange,
|
|
1154
|
+
onPinnedColumnsChange,
|
|
1155
|
+
onSortModelChange,
|
|
1156
|
+
page,
|
|
1157
|
+
pageSize,
|
|
1158
|
+
pinnedColumns,
|
|
1159
|
+
sortModel,
|
|
1160
|
+
onColumnWidthChange
|
|
1161
|
+
} = useStatefulTable({
|
|
1162
|
+
apiRef: apiRef,
|
|
1163
|
+
initialState,
|
|
1164
|
+
columns,
|
|
1165
|
+
onColumnVisibilityModelChange: controlledOnColumnVisibilityModelChange,
|
|
1166
|
+
onColumnWidthChange: propsOnColumnWidthChange,
|
|
1167
|
+
onFilterModelChange: controlledOnFilterModelChange,
|
|
1168
|
+
onPageChange: controlledOnPageChange,
|
|
1169
|
+
onPageSizeChange: controlledOnPageSizeChange,
|
|
1170
|
+
onPinnedColumnsChange: controlledOnPinnedColumnsChange,
|
|
1171
|
+
onSortModelChange: controlledOnSortModelChange,
|
|
1172
|
+
useRouter: useRouter,
|
|
1173
|
+
localStorageVersion,
|
|
1174
|
+
previousLocalStorageVersions
|
|
1175
|
+
});
|
|
1176
|
+
const [selectionModel, setSelectionModel] = useState(propsSelectionModel !== null && propsSelectionModel !== void 0 ? propsSelectionModel : []);
|
|
1177
|
+
useEffect(() => {
|
|
1178
|
+
setSelectionModel(propsSelectionModel !== null && propsSelectionModel !== void 0 ? propsSelectionModel : []);
|
|
1179
|
+
}, [propsSelectionModel]);
|
|
1180
|
+
const onSelectionModelChange = (selectionModel, details) => {
|
|
1181
|
+
if (propsOnSelectionModelChange) {
|
|
1182
|
+
propsOnSelectionModelChange(selectionModel, details);
|
|
1183
|
+
} else {
|
|
1184
|
+
setSelectionModel(selectionModel);
|
|
1185
|
+
}
|
|
1186
|
+
};
|
|
1187
|
+
const selectionStatus = useRef({
|
|
1188
|
+
type: 'none',
|
|
1189
|
+
numberOfSelectedRows: 0,
|
|
1190
|
+
numberOfSelectedRowsInPage: 0,
|
|
1191
|
+
page,
|
|
1192
|
+
pageSize: pageSize
|
|
1193
|
+
});
|
|
16
1194
|
|
|
17
|
-
|
|
1195
|
+
// in server-side pagination we want to update the selection status
|
|
1196
|
+
// every time we navigate between pages, resize our page or select something
|
|
1197
|
+
useEffect(() => {
|
|
1198
|
+
if (paginationMode == 'server') {
|
|
1199
|
+
onServerSideSelectionStatusChange(Array.isArray(selectionModel) ? selectionModel : [selectionModel], apiRef, selectionStatus, isRowSelectable, page, pageSize);
|
|
1200
|
+
}
|
|
1201
|
+
}, [selectionModel, page, pageSize]);
|
|
1202
|
+
if (!Array.isArray(rows)) {
|
|
1203
|
+
return null;
|
|
1204
|
+
}
|
|
1205
|
+
const muiTheme = useMemo(() => createTheme({
|
|
1206
|
+
palette: {
|
|
1207
|
+
mode: theme,
|
|
1208
|
+
primary: {
|
|
1209
|
+
main: RedsiftColorBlueN
|
|
1210
|
+
},
|
|
1211
|
+
background: {
|
|
1212
|
+
default: theme === 'dark' ? RedsiftColorNeutralXDarkGrey : RedsiftColorNeutralWhite,
|
|
1213
|
+
paper: theme === 'dark' ? RedsiftColorNeutralXDarkGrey : RedsiftColorNeutralWhite
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
}), [theme]);
|
|
1217
|
+
return /*#__PURE__*/React__default.createElement(ThemeProvider, {
|
|
1218
|
+
value: {
|
|
1219
|
+
theme
|
|
1220
|
+
}
|
|
1221
|
+
}, /*#__PURE__*/React__default.createElement(ThemeProvider$1, {
|
|
1222
|
+
theme: muiTheme
|
|
1223
|
+
}, /*#__PURE__*/React__default.createElement(StyledDataGrid, {
|
|
1224
|
+
ref: datagridRef,
|
|
1225
|
+
className: classNames(StatefulDataGrid.className, className),
|
|
1226
|
+
$height: height
|
|
1227
|
+
}, /*#__PURE__*/React__default.createElement(DataGridPro, _extends({}, forwardedProps, {
|
|
1228
|
+
apiRef: apiRef,
|
|
1229
|
+
columns: columns,
|
|
1230
|
+
columnVisibilityModel: columnVisibilityModel,
|
|
1231
|
+
filterModel: filterModel,
|
|
1232
|
+
onColumnVisibilityModelChange: onColumnVisibilityModelChange,
|
|
1233
|
+
onFilterModelChange: onFilterModelChange,
|
|
1234
|
+
onPageChange: onPageChange,
|
|
1235
|
+
onPageSizeChange: onPageSizeChange,
|
|
1236
|
+
onPinnedColumnsChange: onPinnedColumnsChange,
|
|
1237
|
+
onSortModelChange: onSortModelChange,
|
|
1238
|
+
page: page,
|
|
1239
|
+
pageSize: pageSize,
|
|
1240
|
+
pinnedColumns: pinnedColumns,
|
|
1241
|
+
sortModel: sortModel,
|
|
1242
|
+
rowsPerPageOptions: rowsPerPageOptions,
|
|
1243
|
+
onColumnWidthChange: onColumnWidthChange,
|
|
1244
|
+
initialState: initialState,
|
|
1245
|
+
isRowSelectable: isRowSelectable,
|
|
1246
|
+
pagination: pagination,
|
|
1247
|
+
paginationMode: paginationMode,
|
|
1248
|
+
keepNonExistentRowsSelected: paginationMode == 'server',
|
|
1249
|
+
rows: rows,
|
|
1250
|
+
rowCount: rowCount,
|
|
1251
|
+
autoHeight: autoHeight,
|
|
1252
|
+
checkboxSelectionVisibleOnly: Boolean(pagination),
|
|
1253
|
+
columnTypes: _objectSpread2(_objectSpread2({}, customColumnTypes), propsColumnTypes),
|
|
1254
|
+
components: _objectSpread2(_objectSpread2({
|
|
1255
|
+
BaseButton,
|
|
1256
|
+
BaseCheckbox,
|
|
1257
|
+
// BaseTextField,
|
|
1258
|
+
BasePopper,
|
|
1259
|
+
ColumnFilteredIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
|
|
1260
|
+
displayName: "ColumnFilteredIcon"
|
|
1261
|
+
})),
|
|
1262
|
+
ColumnSelectorIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
|
|
1263
|
+
displayName: "ColumnSelectorIcon"
|
|
1264
|
+
})),
|
|
1265
|
+
ColumnSortedAscendingIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
|
|
1266
|
+
displayName: "ColumnSortedAscendingIcon"
|
|
1267
|
+
})),
|
|
1268
|
+
ColumnSortedDescendingIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
|
|
1269
|
+
displayName: "ColumnSortedDescendingIcon"
|
|
1270
|
+
})),
|
|
1271
|
+
DensityCompactIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
|
|
1272
|
+
displayName: "DensityCompactIcon"
|
|
1273
|
+
})),
|
|
1274
|
+
DensityStandardIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
|
|
1275
|
+
displayName: "DensityStandardIcon"
|
|
1276
|
+
})),
|
|
1277
|
+
DensityComfortableIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
|
|
1278
|
+
displayName: "DensityComfortableIcon"
|
|
1279
|
+
})),
|
|
1280
|
+
DetailPanelCollapseIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
|
|
1281
|
+
displayName: "DetailPanelCollapseIcon"
|
|
1282
|
+
})),
|
|
1283
|
+
DetailPanelExpandIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
|
|
1284
|
+
displayName: "DetailPanelExpandIcon"
|
|
1285
|
+
})),
|
|
1286
|
+
ExportIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({}, props, {
|
|
1287
|
+
displayName: "ExportIcon"
|
|
1288
|
+
})),
|
|
1289
|
+
OpenFilterButtonIcon: props => /*#__PURE__*/React__default.createElement(BaseIcon, _extends({
|
|
1290
|
+
displayName: "OpenFilterButtonIcon"
|
|
1291
|
+
}, props))
|
|
1292
|
+
}, components), {}, {
|
|
1293
|
+
Toolbar: ToolbarWrapper,
|
|
1294
|
+
Pagination: props => {
|
|
1295
|
+
return pagination ? paginationMode == 'server' ? /*#__PURE__*/React__default.createElement(ServerSideControlledPagination, _extends({}, props, {
|
|
1296
|
+
displaySelection: false,
|
|
1297
|
+
displayRowsPerPage: ['bottom', 'both'].includes(paginationPlacement),
|
|
1298
|
+
displayPagination: ['bottom', 'both'].includes(paginationPlacement),
|
|
1299
|
+
selectionStatus: selectionStatus.current,
|
|
1300
|
+
page: page,
|
|
1301
|
+
pageSize: pageSize,
|
|
1302
|
+
onPageChange: onPageChange,
|
|
1303
|
+
onPageSizeChange: onPageSizeChange,
|
|
1304
|
+
rowsPerPageOptions: rowsPerPageOptions,
|
|
1305
|
+
paginationProps: paginationProps,
|
|
1306
|
+
paginationMode: paginationMode,
|
|
1307
|
+
rowCount: rowCount
|
|
1308
|
+
})) : /*#__PURE__*/React__default.createElement(ControlledPagination, _extends({}, props, {
|
|
1309
|
+
displaySelection: false,
|
|
1310
|
+
displayRowsPerPage: ['bottom', 'both'].includes(paginationPlacement),
|
|
1311
|
+
displayPagination: ['bottom', 'both'].includes(paginationPlacement),
|
|
1312
|
+
selectionStatus: selectionStatus.current,
|
|
1313
|
+
apiRef: apiRef,
|
|
1314
|
+
isRowSelectable: isRowSelectable,
|
|
1315
|
+
page: page,
|
|
1316
|
+
pageSize: pageSize,
|
|
1317
|
+
onPageChange: onPageChange,
|
|
1318
|
+
onPageSizeChange: onPageSizeChange,
|
|
1319
|
+
rowsPerPageOptions: rowsPerPageOptions,
|
|
1320
|
+
paginationProps: paginationProps,
|
|
1321
|
+
paginationMode: paginationMode
|
|
1322
|
+
})) : null;
|
|
1323
|
+
}
|
|
1324
|
+
}),
|
|
1325
|
+
componentsProps: _objectSpread2(_objectSpread2({}, componentsProps), {}, {
|
|
1326
|
+
toolbar: _objectSpread2({
|
|
1327
|
+
hideToolbar,
|
|
1328
|
+
RenderedToolbar,
|
|
1329
|
+
filterModel,
|
|
1330
|
+
onFilterModelChange,
|
|
1331
|
+
pagination,
|
|
1332
|
+
paginationPlacement,
|
|
1333
|
+
selectionStatus,
|
|
1334
|
+
apiRef,
|
|
1335
|
+
isRowSelectable,
|
|
1336
|
+
page,
|
|
1337
|
+
pageSize,
|
|
1338
|
+
onPageChange,
|
|
1339
|
+
onPageSizeChange,
|
|
1340
|
+
rowsPerPageOptions,
|
|
1341
|
+
paginationProps,
|
|
1342
|
+
paginationMode,
|
|
1343
|
+
rowCount
|
|
1344
|
+
}, componentsProps === null || componentsProps === void 0 ? void 0 : componentsProps.toolbar)
|
|
1345
|
+
}),
|
|
1346
|
+
selectionModel: selectionModel,
|
|
1347
|
+
onSelectionModelChange: (newSelectionModel, details) => {
|
|
1348
|
+
if (pagination && paginationMode != 'server') {
|
|
1349
|
+
const selectableRowsInPage = isRowSelectable ? gridPaginatedVisibleSortedGridRowEntriesSelector(apiRef).filter(_ref => {
|
|
1350
|
+
let {
|
|
1351
|
+
model
|
|
1352
|
+
} = _ref;
|
|
1353
|
+
return isRowSelectable({
|
|
1354
|
+
row: model
|
|
1355
|
+
});
|
|
1356
|
+
}).map(_ref2 => {
|
|
1357
|
+
let {
|
|
1358
|
+
id
|
|
1359
|
+
} = _ref2;
|
|
1360
|
+
return id;
|
|
1361
|
+
}) : gridPaginatedVisibleSortedGridRowIdsSelector(apiRef);
|
|
1362
|
+
const numberOfSelectableRowsInPage = selectableRowsInPage.length;
|
|
1363
|
+
const selectableRowsInTable = isRowSelectable ? gridFilteredSortedRowEntriesSelector(apiRef).filter(_ref3 => {
|
|
1364
|
+
let {
|
|
1365
|
+
model
|
|
1366
|
+
} = _ref3;
|
|
1367
|
+
return isRowSelectable({
|
|
1368
|
+
row: model
|
|
1369
|
+
});
|
|
1370
|
+
}).map(_ref4 => {
|
|
1371
|
+
let {
|
|
1372
|
+
id
|
|
1373
|
+
} = _ref4;
|
|
1374
|
+
return id;
|
|
1375
|
+
}) : gridFilteredSortedRowIdsSelector(apiRef);
|
|
1376
|
+
const numberOfSelectableRowsInTable = selectableRowsInTable.length;
|
|
1377
|
+
const numberOfSelectedRows = newSelectionModel.length;
|
|
1378
|
+
if (selectionStatus.current.type === 'table' && numberOfSelectedRows === numberOfSelectableRowsInTable - numberOfSelectableRowsInPage || selectionStatus.current.type === 'table' && numberOfSelectedRows === numberOfSelectableRowsInTable || selectionStatus.current.type === 'page' && numberOfSelectedRows === numberOfSelectableRowsInPage) {
|
|
1379
|
+
setTimeout(() => {
|
|
1380
|
+
apiRef.current.selectRows([], true, true);
|
|
1381
|
+
}, 0);
|
|
1382
|
+
}
|
|
1383
|
+
if (numberOfSelectedRows === numberOfSelectableRowsInPage && numberOfSelectableRowsInPage < numberOfSelectableRowsInTable) {
|
|
1384
|
+
selectionStatus.current = {
|
|
1385
|
+
type: 'page',
|
|
1386
|
+
numberOfSelectedRows
|
|
1387
|
+
};
|
|
1388
|
+
} else if (numberOfSelectedRows === numberOfSelectableRowsInTable && numberOfSelectableRowsInPage < numberOfSelectableRowsInTable) {
|
|
1389
|
+
selectionStatus.current = {
|
|
1390
|
+
type: 'table',
|
|
1391
|
+
numberOfSelectedRows
|
|
1392
|
+
};
|
|
1393
|
+
} else if (numberOfSelectedRows > 0) {
|
|
1394
|
+
selectionStatus.current = {
|
|
1395
|
+
type: 'other',
|
|
1396
|
+
numberOfSelectedRows
|
|
1397
|
+
};
|
|
1398
|
+
} else {
|
|
1399
|
+
selectionStatus.current = {
|
|
1400
|
+
type: 'none',
|
|
1401
|
+
numberOfSelectedRows
|
|
1402
|
+
};
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
onSelectionModelChange === null || onSelectionModelChange === void 0 ? void 0 : onSelectionModelChange(newSelectionModel, details);
|
|
1406
|
+
},
|
|
1407
|
+
sx: _objectSpread2(_objectSpread2({}, sx), {}, {
|
|
1408
|
+
'.MuiDataGrid-columnHeaders': {
|
|
1409
|
+
flexDirection: 'column',
|
|
1410
|
+
alignItems: 'normal'
|
|
1411
|
+
},
|
|
1412
|
+
'.MuiDataGrid-selectedRowCount': {
|
|
1413
|
+
margin: 'none'
|
|
1414
|
+
}
|
|
1415
|
+
})
|
|
1416
|
+
})))));
|
|
1417
|
+
});
|
|
1418
|
+
StatefulDataGrid.className = CLASSNAME;
|
|
1419
|
+
StatefulDataGrid.displayName = COMPONENT_NAME;
|
|
18
1420
|
|
|
19
|
-
export {
|
|
1421
|
+
export { CATEGORIES as C, DIMENSION_MODEL_KEY as D, FILTER_MODEL_KEY as F, PAGINATION_MODEL_KEY as P, SORT_MODEL_KEY as S, VISIBILITY_MODEL_KEY as V, PINNED_COLUMNS as a, FILTER_SEARCH_KEY as b, buildStorageKey as c, clearPreviousVersionStorage as d, decodeValue as e, encodeValue as f, numberOperatorDecoder as g, getFilterModelFromString as h, getSearchParamsFromFilterModel as i, getSortingFromString as j, getSearchParamsFromSorting as k, getPaginationFromString as l, getSearchParamsFromPagination as m, numberOperatorEncoder as n, getSearchParamsFromColumnVisibility as o, getColumnVisibilityFromString as p, getPinnedColumnsFromString as q, getSearchParamsFromPinnedColumns as r, getSearchParamsFromTab as s, getFinalSearch as t, urlSearchParamsToString as u, getModelsParsedOrUpdateLocalStorage as v, updateUrl as w, areFilterModelsEquivalent as x, StatefulDataGrid as y };
|
|
1422
|
+
//# sourceMappingURL=StatefulDataGrid2.js.map
|