@redsift/table 11.5.0-muiv5 → 11.6.0-muiv5-alpha.0

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.
Files changed (180) hide show
  1. package/_virtual/_commonjsHelpers.js +6 -0
  2. package/_virtual/_commonjsHelpers.js.map +1 -0
  3. package/_virtual/_rollupPluginBabelHelpers.js +93 -0
  4. package/_virtual/_rollupPluginBabelHelpers.js.map +1 -0
  5. package/_virtual/index.js +4 -0
  6. package/_virtual/index.js.map +1 -0
  7. package/_virtual/index2.js +4 -0
  8. package/_virtual/index2.js.map +1 -0
  9. package/_virtual/index3.js +4 -0
  10. package/_virtual/index3.js.map +1 -0
  11. package/_virtual/jsx-runtime.js +4 -0
  12. package/_virtual/jsx-runtime.js.map +1 -0
  13. package/_virtual/react-is.development.js +4 -0
  14. package/_virtual/react-is.development.js.map +1 -0
  15. package/_virtual/react-is.development2.js +4 -0
  16. package/_virtual/react-is.development2.js.map +1 -0
  17. package/_virtual/react-is.production.min.js +4 -0
  18. package/_virtual/react-is.production.min.js.map +1 -0
  19. package/_virtual/react-is.production.min2.js +4 -0
  20. package/_virtual/react-is.production.min2.js.map +1 -0
  21. package/_virtual/react-jsx-runtime.development.js +4 -0
  22. package/_virtual/react-jsx-runtime.development.js.map +1 -0
  23. package/_virtual/react-jsx-runtime.production.min.js +4 -0
  24. package/_virtual/react-jsx-runtime.production.min.js.map +1 -0
  25. package/components/BaseComponents/BaseButton.d.ts +5 -0
  26. package/components/BaseComponents/BaseButton.js +41 -0
  27. package/components/BaseComponents/BaseButton.js.map +1 -0
  28. package/components/BaseComponents/BaseCheckbox.d.ts +5 -0
  29. package/components/BaseComponents/BaseCheckbox.js +24 -0
  30. package/components/BaseComponents/BaseCheckbox.js.map +1 -0
  31. package/components/BaseComponents/BaseIcon.d.ts +7 -0
  32. package/components/BaseComponents/BaseIcon.js +33 -0
  33. package/components/BaseComponents/BaseIcon.js.map +1 -0
  34. package/components/BaseComponents/BasePopper.d.ts +5 -0
  35. package/components/BaseComponents/BasePopper.js +13 -0
  36. package/components/BaseComponents/BasePopper.js.map +1 -0
  37. package/components/BaseComponents/BaseTextField.d.ts +5 -0
  38. package/components/BaseComponents/BaseTextField.js +26 -0
  39. package/components/BaseComponents/BaseTextField.js.map +1 -0
  40. package/components/DataGrid/DataGrid.d.ts +6 -0
  41. package/components/DataGrid/DataGrid.js +340 -0
  42. package/components/DataGrid/DataGrid.js.map +1 -0
  43. package/components/DataGrid/styles.js +74 -0
  44. package/components/DataGrid/styles.js.map +1 -0
  45. package/components/DataGrid/types.d.ts +36 -0
  46. package/components/GridToolbarFilterSemanticField/GridToolbarFilterSemanticField.d.ts +15 -0
  47. package/components/GridToolbarFilterSemanticField/GridToolbarFilterSemanticField.js +183 -0
  48. package/components/GridToolbarFilterSemanticField/GridToolbarFilterSemanticField.js.map +1 -0
  49. package/components/GridToolbarFilterSemanticField/styles.js +20 -0
  50. package/components/GridToolbarFilterSemanticField/styles.js.map +1 -0
  51. package/components/GridToolbarFilterSemanticField/types.d.ts +39 -0
  52. package/components/Pagination/ControlledPagination.d.ts +21 -0
  53. package/components/Pagination/ControlledPagination.js +74 -0
  54. package/components/Pagination/ControlledPagination.js.map +1 -0
  55. package/components/Pagination/ServerSideControlledPagination.d.ts +23 -0
  56. package/components/Pagination/ServerSideControlledPagination.js +102 -0
  57. package/components/Pagination/ServerSideControlledPagination.js.map +1 -0
  58. package/components/StatefulDataGrid/StatefulDataGrid.d.ts +6 -0
  59. package/components/StatefulDataGrid/StatefulDataGrid.js +373 -0
  60. package/components/StatefulDataGrid/StatefulDataGrid.js.map +1 -0
  61. package/components/StatefulDataGrid/types.d.ts +16 -0
  62. package/components/TextCell/TextCell.d.ts +9 -0
  63. package/components/TextCell/TextCell.js +48 -0
  64. package/components/TextCell/TextCell.js.map +1 -0
  65. package/components/TextCell/styles.js +22 -0
  66. package/components/TextCell/styles.js.map +1 -0
  67. package/components/TextCell/types.d.ts +25 -0
  68. package/components/Toolbar/Toolbar.d.ts +20 -0
  69. package/components/Toolbar/Toolbar.js +72 -0
  70. package/components/Toolbar/Toolbar.js.map +1 -0
  71. package/components/Toolbar/styles.js +17 -0
  72. package/components/Toolbar/styles.js.map +1 -0
  73. package/components/Toolbar/types.d.ts +40 -0
  74. package/components/ToolbarWrapper/ToolbarWrapper.d.ts +25 -0
  75. package/components/ToolbarWrapper/ToolbarWrapper.js +60 -0
  76. package/components/ToolbarWrapper/ToolbarWrapper.js.map +1 -0
  77. package/hooks/useControlledDatagridState.js +109 -0
  78. package/hooks/useControlledDatagridState.js.map +1 -0
  79. package/hooks/useFetchState.js +34 -0
  80. package/hooks/useFetchState.js.map +1 -0
  81. package/hooks/useStatefulTable.d.ts +12 -0
  82. package/hooks/useStatefulTable.js +182 -0
  83. package/hooks/useStatefulTable.js.map +1 -0
  84. package/hooks/useTableStates.js +52 -0
  85. package/hooks/useTableStates.js.map +1 -0
  86. package/index.d.ts +39 -628
  87. package/index.js +36 -28375
  88. package/index.js.map +1 -1
  89. package/package.json +4 -4
  90. package/packages/design-system/src/components/theme/context.js +7 -0
  91. package/packages/design-system/src/components/theme/context.js.map +1 -0
  92. package/packages/popovers/src/components/tooltip/Tooltip.js +60 -0
  93. package/packages/popovers/src/components/tooltip/Tooltip.js.map +1 -0
  94. package/packages/popovers/src/components/tooltip/context.js +6 -0
  95. package/packages/popovers/src/components/tooltip/context.js.map +1 -0
  96. package/packages/popovers/src/components/tooltip/types.js +28 -0
  97. package/packages/popovers/src/components/tooltip/types.js.map +1 -0
  98. package/packages/popovers/src/components/tooltip/useTooltip.js +78 -0
  99. package/packages/popovers/src/components/tooltip/useTooltip.js.map +1 -0
  100. package/packages/popovers/src/components/tooltip/useTooltipContext.js +13 -0
  101. package/packages/popovers/src/components/tooltip/useTooltipContext.js.map +1 -0
  102. package/packages/popovers/src/components/tooltip-content/TooltipContent.js +79 -0
  103. package/packages/popovers/src/components/tooltip-content/TooltipContent.js.map +1 -0
  104. package/packages/popovers/src/components/tooltip-content/styles.js +127 -0
  105. package/packages/popovers/src/components/tooltip-content/styles.js.map +1 -0
  106. package/packages/popovers/src/components/tooltip-trigger/TooltipTrigger.js +47 -0
  107. package/packages/popovers/src/components/tooltip-trigger/TooltipTrigger.js.map +1 -0
  108. package/utils/columnTypes/index.d.ts +78 -0
  109. package/utils/columnTypes/index.js +49 -0
  110. package/utils/columnTypes/index.js.map +1 -0
  111. package/utils/columns/detailPanelToggleColDef.d.ts +5 -0
  112. package/utils/columns/detailPanelToggleColDef.js +8 -0
  113. package/utils/columns/detailPanelToggleColDef.js.map +1 -0
  114. package/utils/fields/InputNumberInterval.js +85 -0
  115. package/utils/fields/InputNumberInterval.js.map +1 -0
  116. package/utils/gpt.d.ts +3 -0
  117. package/utils/gpt.js +33 -0
  118. package/utils/gpt.js.map +1 -0
  119. package/utils/localStorage.d.ts +17 -0
  120. package/utils/localStorage.js +59 -0
  121. package/utils/localStorage.js.map +1 -0
  122. package/utils/operators/index.d.ts +68 -0
  123. package/utils/operators/index.js +52 -0
  124. package/utils/operators/index.js.map +1 -0
  125. package/utils/operators/numeric/getGridNumericOperators.d.ts +5 -0
  126. package/utils/operators/numeric/getGridNumericOperators.js +7 -0
  127. package/utils/operators/numeric/getGridNumericOperators.js.map +1 -0
  128. package/utils/operators/numeric/isBetween.d.ts +10 -0
  129. package/utils/operators/numeric/isBetween.js +28 -0
  130. package/utils/operators/numeric/isBetween.js.map +1 -0
  131. package/utils/operators/string/doesNotContain.d.ts +10 -0
  132. package/utils/operators/string/doesNotContain.js +25 -0
  133. package/utils/operators/string/doesNotContain.js.map +1 -0
  134. package/utils/operators/string/doesNotEqual.d.ts +10 -0
  135. package/utils/operators/string/doesNotEqual.js +25 -0
  136. package/utils/operators/string/doesNotEqual.js.map +1 -0
  137. package/utils/operators/string/doesNotHave.d.ts +16 -0
  138. package/utils/operators/string/doesNotHave.js +24 -0
  139. package/utils/operators/string/doesNotHave.js.map +1 -0
  140. package/utils/operators/string/getGridStringOperators.d.ts +5 -0
  141. package/utils/operators/string/getGridStringOperators.js +9 -0
  142. package/utils/operators/string/getGridStringOperators.js.map +1 -0
  143. package/utils/operators/string/has.d.ts +16 -0
  144. package/utils/operators/string/has.js +24 -0
  145. package/utils/operators/string/has.js.map +1 -0
  146. package/utils/operators/string/hasOnly.d.ts +16 -0
  147. package/utils/operators/string/hasOnly.js +24 -0
  148. package/utils/operators/string/hasOnly.js.map +1 -0
  149. package/utils/operators/string/is.d.ts +16 -0
  150. package/utils/operators/string/is.js +26 -0
  151. package/utils/operators/string/is.js.map +1 -0
  152. package/utils/operators/string/isNot.d.ts +16 -0
  153. package/utils/operators/string/isNot.js +26 -0
  154. package/utils/operators/string/isNot.js.map +1 -0
  155. package/utils/operators/string-array/containsAnyOf.d.ts +16 -0
  156. package/utils/operators/string-array/containsAnyOf.js +56 -0
  157. package/utils/operators/string-array/containsAnyOf.js.map +1 -0
  158. package/utils/operators/string-array/doesNotHaveAnyOf.js +26 -0
  159. package/utils/operators/string-array/doesNotHaveAnyOf.js.map +1 -0
  160. package/utils/operators/string-array/endsWithAnyOf.d.ts +10 -0
  161. package/utils/operators/string-array/endsWithAnyOf.js +31 -0
  162. package/utils/operators/string-array/endsWithAnyOf.js.map +1 -0
  163. package/utils/operators/string-array/getGridStringArrayOperators.d.ts +7 -0
  164. package/utils/operators/string-array/getGridStringArrayOperators.js +19 -0
  165. package/utils/operators/string-array/getGridStringArrayOperators.js.map +1 -0
  166. package/utils/operators/string-array/hasAnyOf.d.ts +16 -0
  167. package/utils/operators/string-array/hasAnyOf.js +28 -0
  168. package/utils/operators/string-array/hasAnyOf.js.map +1 -0
  169. package/utils/operators/string-array/isAnyOf.d.ts +16 -0
  170. package/utils/operators/string-array/isAnyOf.js +32 -0
  171. package/utils/operators/string-array/isAnyOf.js.map +1 -0
  172. package/utils/operators/string-array/isNotAnyOf.d.ts +10 -0
  173. package/utils/operators/string-array/isNotAnyOf.js +28 -0
  174. package/utils/operators/string-array/isNotAnyOf.js.map +1 -0
  175. package/utils/operators/string-array/startsWithAnyOf.d.ts +10 -0
  176. package/utils/operators/string-array/startsWithAnyOf.js +31 -0
  177. package/utils/operators/string-array/startsWithAnyOf.js.map +1 -0
  178. package/utils/urlLocalStorageSync.d.ts +73 -0
  179. package/utils/urlLocalStorageSync.js +756 -0
  180. package/utils/urlLocalStorageSync.js.map +1 -0
@@ -0,0 +1,756 @@
1
+ import { objectSpread2 as _objectSpread2 } from '../_virtual/_rollupPluginBabelHelpers.js';
2
+ import { GridLinkOperator } from '@mui/x-data-grid-pro';
3
+ import { operatorList } from './operators/index.js';
4
+
5
+ // reference value: https://www.w3schools.com/tags/ref_urlencode.ASP
6
+ const DECODER = {
7
+ '%20': ' ',
8
+ '%26': '&',
9
+ '%3D': '=',
10
+ '%3F': '?',
11
+ '%5B': '[',
12
+ '%5D': ']',
13
+ '%2C': ',',
14
+ '%3C': '<',
15
+ '%3E': '>',
16
+ '%21': '!',
17
+ '%22': '"'
18
+ };
19
+ const ENCODER = {
20
+ ' ': '%20',
21
+ '&': '%26',
22
+ '=': '%3D',
23
+ '?': '%3F',
24
+ '[': '%5B',
25
+ ']': '%5D',
26
+ ',': '%2C',
27
+ '<': '%3C',
28
+ '>': '%3E',
29
+ '!': '%21',
30
+ '"': '%22'
31
+ };
32
+ const decodeValue = value => {
33
+ if (value === '') {
34
+ return '';
35
+ }
36
+ const re = new RegExp(Object.keys(DECODER).reduce((acc, curr) => `${acc}|${curr}`), 'g');
37
+ // decodeValue for lists:
38
+ if (value.startsWith('list[')) {
39
+ const arrayValues = value.split('[')[1].split(']')[0];
40
+ const arrayList = arrayValues.split(',').map(v => v.replace(re, encoded => DECODER[encoded])).filter(item => item);
41
+ return arrayList.length > 0 ? arrayList : [];
42
+ }
43
+ return value.replace(re, encoded => DECODER[encoded]);
44
+ };
45
+ const encodeValue = value => {
46
+ if (!value) {
47
+ return '';
48
+ }
49
+
50
+ // Array encoding for value:
51
+ // we are representing it as list[encoded], where encoded is the list comma separated
52
+ if (Array.isArray(value)) {
53
+ const encodedArray = value.map(entry => {
54
+ return String(entry).replace(/\s|&|=|\?|\[|\]/g, encoded => ENCODER[encoded]);
55
+ }).join(',');
56
+ return `list[${encodedArray}]`;
57
+ }
58
+
59
+ // we might also pass integers
60
+ const castedValue = String(value);
61
+ return castedValue.replace(/\s|&|=|\?|\[|\]/g, encoded => ENCODER[encoded]);
62
+ };
63
+ const urlSearchParamsToString = searchParams => {
64
+ let searchString = '';
65
+ for (const [key, value] of searchParams) {
66
+ searchString = searchString + `${key}=${value}&`;
67
+ }
68
+ return searchString.slice(0, searchString.length - 1);
69
+ };
70
+ const numberOperatorEncoder = {
71
+ '=': 'eq',
72
+ '!=': 'ne',
73
+ '>': 'gt',
74
+ '>=': 'gte',
75
+ '<': 'lt',
76
+ '<=': 'lte'
77
+ };
78
+ const numberOperatorDecoder = {
79
+ eq: '=',
80
+ ne: '!=',
81
+ gt: '>',
82
+ gte: '>=',
83
+ lt: '<',
84
+ lte: '<='
85
+ };
86
+ const isOperatorValueValid = (columnField, operatorValue, columns) => {
87
+ const column = columns.find(column => column.field === columnField);
88
+ if (!column) {
89
+ return false;
90
+ }
91
+ const columnType = (column === null || column === void 0 ? void 0 : column.type) || 'string';
92
+ const operators = operatorList[columnType];
93
+ if (!operators) {
94
+ return false;
95
+ }
96
+ if ('filterOperators' in operators) {
97
+ return !!operators.filterOperators.find(op => columnType === 'number' && Object.keys(numberOperatorEncoder).includes(op.value) ? numberOperatorEncoder[op.value] === operatorValue : op['value'] === operatorValue);
98
+ }
99
+ return !!operators.find(op => ['number', 'rsNumber'].includes(columnType) && Object.keys(numberOperatorEncoder).includes(op.value) ? numberOperatorEncoder[op.value] === operatorValue : op['value'] === operatorValue);
100
+ };
101
+ const listOperators = ['containsAnyOf', 'doesNotContainAnyOf', 'endsWithAnyOf', 'doesNotEndWithAnyOf', 'hasAnyOf', 'doesNotHaveAnyOf', 'isAnyOf', 'isNotAnyOf', 'startsWithAnyOf', 'doesNotStartWithAnyOf'];
102
+
103
+ // Check if the value doesn't break
104
+ const isValueValid = (value, columnField, columns, operatorValue) => {
105
+ var _column$type;
106
+ // every field accepts undefined as value for default
107
+ if (value === undefined || value === '') {
108
+ return true;
109
+ }
110
+
111
+ // xxxAnyOf accepts as value only lists, and we are declearing them in the
112
+ // URL as `list=[...]`
113
+ if (listOperators.includes(operatorValue)) {
114
+ return Array.isArray(value) || value === '';
115
+ }
116
+
117
+ // We are accepting arrays only if they are of the 'xxxAnyOf' type
118
+ if (Array.isArray(value) && !listOperators.includes(operatorValue)) {
119
+ return false;
120
+ }
121
+ const column = columns.find(column => column.field === columnField);
122
+ if (!column) {
123
+ return false;
124
+ }
125
+ const type = (_column$type = column['type']) !== null && _column$type !== void 0 ? _column$type : 'string';
126
+
127
+ // Only date and rating fail with 500s, other set themselves as undefined
128
+ if (type !== 'date' && type !== 'rating') {
129
+ return true;
130
+ }
131
+
132
+ // just checking that rating is a number.
133
+ if (type === 'rating') {
134
+ return !isNaN(Number(value));
135
+ }
136
+
137
+ // format: YYYY-MM-DD
138
+ // just verifying that the 3 values are numbers to avoid 500s,
139
+ // If the value is invalid the form will appear as undefined
140
+ if (type === 'date') {
141
+ const dateSplitted = value.split('-');
142
+ if (dateSplitted.length !== 3) {
143
+ return false;
144
+ }
145
+ const [YYYY, MM, DD] = dateSplitted;
146
+ return !isNaN(parseInt(YYYY)) && !isNaN(parseInt(MM)) && !isNaN(parseInt(DD));
147
+ }
148
+ return false;
149
+ };
150
+
151
+ /** FILTERS */
152
+
153
+ // example:
154
+ // unicodeDomain[contains]=a&unicodeDomain[contains]=dsa&logicOperator=and&tab=ignored
155
+ const getFilterModelFromString = (searchString, columns) => {
156
+ if (!searchString) {
157
+ return 'invalid';
158
+ }
159
+ let linkOperator = GridLinkOperator.And;
160
+ let quickFilterValues = [];
161
+ const searchParams = new URLSearchParams();
162
+ for (const [key, value] of new URLSearchParams(searchString)) {
163
+ if (key.startsWith('_') && !['_logicOperator', '_sortColumn', '_pinnedColumnsLeft', '_pinnedColumnsRight', '_columnVisibility', '_pagination', '_quickFilterValues'].includes(key)) {
164
+ searchParams.set(key, value);
165
+ }
166
+ if (key === '_logicOperator') {
167
+ linkOperator = value;
168
+ }
169
+ if (key === '_quickFilterValues') {
170
+ try {
171
+ quickFilterValues = JSON.parse(decodeURIComponent(value));
172
+ } catch {
173
+ quickFilterValues = [];
174
+ }
175
+ }
176
+ }
177
+ let id = 5000;
178
+ const fields = columns.map(column => column.field);
179
+ let isInvalid = false;
180
+ const items = [];
181
+ searchParams.forEach((value, key) => {
182
+ var _columns$find;
183
+ if (isInvalid) {
184
+ return;
185
+ }
186
+ const field = key.split('[')[0].slice(1); // Slice to remove the _ at the beginning
187
+ if (!fields.includes(field)) {
188
+ return;
189
+ }
190
+ const columnType = (_columns$find = columns.find(column => column.field === field)) === null || _columns$find === void 0 ? void 0 : _columns$find.type;
191
+ const left = key.split(']')[0];
192
+ if (left.split('[').length < 2) {
193
+ isInvalid = true;
194
+ return;
195
+ }
196
+ const splitRight = key.split('[')[1].split(']')[0].split(',');
197
+ const type = splitRight[1];
198
+ if (type !== columnType) {
199
+ isInvalid = true;
200
+ return;
201
+ }
202
+ const operator = splitRight[0];
203
+ // if the operator is not part of the valid operators invalidate the URL
204
+ if (!isOperatorValueValid(field, operator, columns) || Array.isArray(operator)) {
205
+ isInvalid = true;
206
+ return;
207
+ }
208
+ id += 1;
209
+ const decodedValue = decodeValue(value);
210
+ if (!isValueValid(decodedValue, field, columns, operator)) {
211
+ isInvalid = true;
212
+ return;
213
+ }
214
+ items.push({
215
+ columnField: field,
216
+ operatorValue: ['number', 'rsNumber'].includes(columnType) && Object.keys(numberOperatorDecoder).includes(operator) ? numberOperatorDecoder[operator] : operator,
217
+ id,
218
+ value: listOperators.includes(operator) && decodedValue === '' ? [] : decodedValue,
219
+ type
220
+ });
221
+ });
222
+
223
+ // If we found some condition that results in an invalid URL,
224
+ // return the empty filterModel (this will trigger the localStorage)
225
+ // and will pick up the last valid search
226
+ if (isInvalid) {
227
+ return 'invalid';
228
+ }
229
+ return {
230
+ items,
231
+ linkOperator,
232
+ quickFilterValues
233
+ };
234
+ };
235
+ const getSearchParamsFromFilterModel = filterModel => {
236
+ var _filterModel$quickFil;
237
+ const searchParams = new URLSearchParams();
238
+ searchParams.set('_logicOperator', filterModel['linkOperator'] || '');
239
+ filterModel['items'].forEach(item => {
240
+ const {
241
+ columnField,
242
+ operatorValue,
243
+ value,
244
+ type
245
+ } = item;
246
+ if (Object.keys(numberOperatorEncoder).includes(operatorValue)) {
247
+ searchParams.set(`_${columnField}[${numberOperatorEncoder[operatorValue]},${encodeValue(type)}]`, encodeValue(value));
248
+ } else {
249
+ searchParams.set(`_${columnField}[${encodeValue(operatorValue)},${encodeValue(type)}]`, encodeValue(value));
250
+ }
251
+ });
252
+ if ((_filterModel$quickFil = filterModel.quickFilterValues) !== null && _filterModel$quickFil !== void 0 && _filterModel$quickFil.length) {
253
+ searchParams.set('_quickFilterValues', encodeURIComponent(JSON.stringify(filterModel.quickFilterValues)));
254
+ }
255
+ return searchParams;
256
+ };
257
+
258
+ // Rules:
259
+ // - if we have something in the URL, use that info
260
+ // - if we don't have that, use the localStorage and update the URL
261
+ // - if we don't have that, return an empty FilterModel
262
+ const getFilterModel = (search, columns, localStorageFilters, setLocalStorageFilters, initialState, isNewVersion) => {
263
+ const defaultValue = initialState && initialState.filter && initialState.filter.filterModel ? initialState.filter.filterModel : {
264
+ items: [],
265
+ linkOperator: GridLinkOperator.And
266
+ };
267
+ if (isNewVersion) {
268
+ return defaultValue;
269
+ }
270
+ const filterModelFromSearch = getFilterModelFromString(search, columns);
271
+ if (filterModelFromSearch !== 'invalid') {
272
+ const searchFromFilterModel = getSearchParamsFromFilterModel(filterModelFromSearch);
273
+ const searchString = urlSearchParamsToString(searchFromFilterModel);
274
+ if (searchString !== localStorageFilters) {
275
+ setLocalStorageFilters(searchString);
276
+ }
277
+ return filterModelFromSearch;
278
+ }
279
+ const filterModelFromLocalStorage = getFilterModelFromString(localStorageFilters, columns);
280
+ if (filterModelFromLocalStorage !== 'invalid') {
281
+ return filterModelFromLocalStorage;
282
+ }
283
+ return defaultValue;
284
+ };
285
+
286
+ /** SORT */
287
+
288
+ const getSortingFromString = (searchString, columns) => {
289
+ if (!searchString) {
290
+ return 'invalid';
291
+ }
292
+ const searchParams = new URLSearchParams(searchString);
293
+ const value = searchParams.get('_sortColumn');
294
+ if (value === '' || value === null || value === '[]') {
295
+ return [];
296
+ }
297
+ const fields = columns.map(column => column.field);
298
+ const [column, order] = value.slice(1, value.length - 1).split(',');
299
+ if (fields.includes(column) && (order === 'asc' || order === 'desc')) {
300
+ return [{
301
+ field: column,
302
+ sort: order
303
+ }];
304
+ }
305
+ return 'invalid';
306
+ };
307
+ const getSearchParamsFromSorting = sorting => {
308
+ const searchParams = new URLSearchParams();
309
+ searchParams.set('_sortColumn', sorting.length > 0 && sorting[0].sort ? `[${encodeValue(sorting[0].field)},${encodeValue(sorting[0].sort)}]` : '[]');
310
+ return searchParams;
311
+ };
312
+
313
+ // Rules:
314
+ // - if we have something in the URL, use that info
315
+ // - if we don't have that, use the localStorage and update the URL
316
+ // - if we don't have that, return an empty SortModel
317
+ const getSortModel = (search, columns, localStorageSorting, setLocalStorageSorting, initialState, isNewVersion) => {
318
+ var _initialState$sorting;
319
+ const defaultValue = initialState !== null && initialState !== void 0 && (_initialState$sorting = initialState.sorting) !== null && _initialState$sorting !== void 0 && _initialState$sorting.sortModel ? initialState.sorting.sortModel : [];
320
+ if (isNewVersion) {
321
+ return defaultValue;
322
+ }
323
+ const sorting = getSortingFromString(search, columns);
324
+ if (sorting !== 'invalid') {
325
+ const searchFromSortModel = getSearchParamsFromSorting(sorting);
326
+ const searchString = urlSearchParamsToString(searchFromSortModel);
327
+ if (searchString !== localStorageSorting) {
328
+ setLocalStorageSorting(searchString);
329
+ }
330
+ return sorting;
331
+ }
332
+ const sortModelFromLocalStorage = getSortingFromString(localStorageSorting, columns);
333
+ if (sortModelFromLocalStorage !== 'invalid') {
334
+ return sortModelFromLocalStorage;
335
+ }
336
+ return defaultValue;
337
+ };
338
+
339
+ /** PAGINATION */
340
+
341
+ const getPaginationFromString = searchString => {
342
+ if (!searchString) {
343
+ return 'invalid';
344
+ }
345
+ const searchParams = new URLSearchParams(searchString);
346
+ const value = searchParams.get('_pagination');
347
+ if (value === '' || value === null || value === '[]') {
348
+ return 'invalid';
349
+ }
350
+ const pagination = value.slice(1, value.length - 1).split(',');
351
+ const page = parseFloat(pagination[0]);
352
+ const pageSize = parseFloat(pagination[1]);
353
+ const direction = pagination[2];
354
+ if (!Number.isNaN(page) && !Number.isNaN(pageSize) && direction && ['next', 'back'].includes(direction)) {
355
+ return {
356
+ page,
357
+ pageSize,
358
+ direction: direction
359
+ };
360
+ }
361
+ return 'invalid';
362
+ };
363
+ const getSearchParamsFromPagination = pagination => {
364
+ const searchParams = new URLSearchParams();
365
+ searchParams.set('_pagination', `[${pagination.page},${pagination.pageSize},${pagination.direction}]`);
366
+ return searchParams;
367
+ };
368
+
369
+ // Rules:
370
+ // - if we have something in the URL, use that info
371
+ // - if we don't have that, use the localStorage and update the URL
372
+ // - if we don't have that, return an empty PaginationModel
373
+ const getPaginationModel = (search, localStoragePagination, setLocalStoragePagination, initialState, isNewVersion) => {
374
+ const defaultValue = initialState !== null && initialState !== void 0 && initialState.pagination ? _objectSpread2({
375
+ page: 0,
376
+ pageSize: 25,
377
+ direction: 'next'
378
+ }, initialState.pagination) : {
379
+ page: 0,
380
+ pageSize: 25,
381
+ direction: 'next'
382
+ };
383
+ if (isNewVersion) {
384
+ return defaultValue;
385
+ }
386
+ const pagination = getPaginationFromString(search);
387
+ if (pagination !== 'invalid') {
388
+ const searchFromPaginationModel = getSearchParamsFromPagination(pagination);
389
+ const searchString = urlSearchParamsToString(searchFromPaginationModel);
390
+ if (searchString !== localStoragePagination) {
391
+ setLocalStoragePagination(searchString);
392
+ }
393
+ return pagination;
394
+ }
395
+ const paginationModelFromLocalStorage = getPaginationFromString(localStoragePagination);
396
+ if (paginationModelFromLocalStorage !== 'invalid') {
397
+ return paginationModelFromLocalStorage;
398
+ }
399
+ return defaultValue;
400
+ };
401
+
402
+ /** COLUMN VISIBILITY */
403
+
404
+ const getSearchParamsFromColumnVisibility = (columnVisibility, columns) => {
405
+ const searchParams = new URLSearchParams();
406
+ const columnFields = columns.map(column => column.field);
407
+
408
+ // if column visibility model is empty, show all columns
409
+ if (Object.keys(columnVisibility).length == 0) {
410
+ searchParams.set('_columnVisibility', `[${columnFields.join(',')}]`);
411
+ return searchParams;
412
+ }
413
+ const finalColumnVisibility = columns.filter(c => {
414
+ var _c$hideable;
415
+ return !((_c$hideable = c === null || c === void 0 ? void 0 : c.hideable) !== null && _c$hideable !== void 0 ? _c$hideable : true);
416
+ }).map(c => c.field).reduce((acc, colName) => {
417
+ return _objectSpread2(_objectSpread2({}, acc), {}, {
418
+ [colName]: true
419
+ });
420
+ }, columnVisibility);
421
+ const visibleColumns = Object.entries(finalColumnVisibility)
422
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
423
+ .filter(_ref => {
424
+ let [_, visible] = _ref;
425
+ return visible;
426
+ })
427
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
428
+ .map(_ref2 => {
429
+ let [column, _] = _ref2;
430
+ return encodeValue(column);
431
+ });
432
+ searchParams.set('_columnVisibility', `[${visibleColumns.join(',')}]`);
433
+ return searchParams;
434
+ };
435
+ const getColumnVisibilityFromString = (notParsed, tableColumns) => {
436
+ if (!notParsed || notParsed.length === 1 && notParsed[0] === '?') {
437
+ return 'invalid';
438
+ }
439
+ // remove the initial ? if present
440
+ const parsed = notParsed[0] === '?' ? notParsed.slice(1) : notParsed;
441
+ const visibility = {};
442
+ let exist = false;
443
+ let visibleColumnsCount = 0;
444
+ for (const item of parsed.split('&')) {
445
+ // if it's not column visibility field, skip
446
+ const fieldURL = item.split('=')[0];
447
+ if (fieldURL !== '_columnVisibility') {
448
+ continue;
449
+ }
450
+ // e.g. item = _columnVisibility[abc,def]
451
+ const left = item.split(']')[0];
452
+ if (left.split('[').length < 2) {
453
+ continue;
454
+ }
455
+ const encodedValues = item.split('[')[1].split(']')[0];
456
+ if (typeof encodedValues !== 'string') {
457
+ continue;
458
+ }
459
+ exist = true;
460
+ const columnFields = tableColumns.map(column => column.field);
461
+ // TODO: Add validation that , is present
462
+ const columns = encodedValues.split(',').map(value => decodeValue(value));
463
+
464
+ // for each column, check if it's visible and add it to visibility model
465
+ for (const column of columnFields) {
466
+ const isColumnVisible = columns.includes(column);
467
+ visibility[column] = isColumnVisible;
468
+ if (isColumnVisible) {
469
+ visibleColumnsCount += 1;
470
+ }
471
+ }
472
+ }
473
+ if (visibleColumnsCount === 0 && !exist) {
474
+ return 'invalid';
475
+ }
476
+ return visibility;
477
+ };
478
+
479
+ // Rules:
480
+ // - if we have something in the URL, use that info
481
+ // - if we don't have that, use the localStorage and update the URL
482
+ // - if we don't have that, return an empty ColumnVisibilityModel (which is all columns)
483
+ // NOTE: the `defaultHidden` is a custom field and not standard DataGrid
484
+ // The reason is the following bug: https://github.com/mui/mui-x/issues/8407
485
+ const getColumnsVisibility = (search, columns, localStorageColumnsVisibility, setLocalStorageColumnsVisibility, initialState, isNewVersion) => {
486
+ var _initialState$columns3;
487
+ const defaultValue = {};
488
+ for (const column of columns) {
489
+ var _initialState$columns, _initialState$columns2;
490
+ const field = column.field;
491
+ 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) {
492
+ defaultValue[field] = initialState.columns.columnVisibilityModel[field];
493
+ } else {
494
+ defaultValue[field] = column.defaultHidden !== true; // undefined will be true
495
+ }
496
+ }
497
+
498
+ if (isNewVersion) {
499
+ return defaultValue;
500
+ }
501
+ const columnVisibility = getColumnVisibilityFromString(search, columns);
502
+ if (columnVisibility !== 'invalid') {
503
+ const searchColumnVisibility = getSearchParamsFromColumnVisibility(columnVisibility, columns);
504
+ if (searchColumnVisibility.toString() !== localStorageColumnsVisibility) {
505
+ setLocalStorageColumnsVisibility(searchColumnVisibility.toString());
506
+ }
507
+ return columnVisibility;
508
+ }
509
+ const columnVisibilityFromLocalStorage = getColumnVisibilityFromString(localStorageColumnsVisibility, columns);
510
+ if (columnVisibilityFromLocalStorage !== 'invalid') {
511
+ return columnVisibilityFromLocalStorage;
512
+ }
513
+ if (initialState !== null && initialState !== void 0 && (_initialState$columns3 = initialState.columns) !== null && _initialState$columns3 !== void 0 && _initialState$columns3.columnVisibilityModel) {
514
+ return initialState.columns.columnVisibilityModel;
515
+ }
516
+ return defaultValue;
517
+ };
518
+ const getPinnedColumnsFromString = (notParsed, tableColumns) => {
519
+ if (!notParsed || notParsed.length === 1 && notParsed[0] === '?') {
520
+ return 'invalid';
521
+ }
522
+ // remove the initial ? if present
523
+ const parsed = notParsed[0] === '?' ? notParsed.slice(1) : notParsed;
524
+ const pinnedColumns = {};
525
+ for (const item of parsed.split('&')) {
526
+ const fieldURL = item.split('=')[0];
527
+ if (fieldURL !== '_pinnedColumnsLeft' && fieldURL !== '_pinnedColumnsRight') {
528
+ continue;
529
+ }
530
+ const left = item.split(']')[0];
531
+ if (left.split('[').length < 2) {
532
+ continue;
533
+ }
534
+ const encodedValues = item.split('[')[1].split(']')[0];
535
+ if (typeof encodedValues !== 'string') {
536
+ continue;
537
+ }
538
+ const columnFields = [...tableColumns.map(column => column.field), '__check__'];
539
+ const columns = encodedValues.split(',').map(value => decodeValue(value)).filter(val => typeof val === 'string' && columnFields.includes(val));
540
+ if (fieldURL === '_pinnedColumnsLeft') {
541
+ pinnedColumns['left'] = columns;
542
+ }
543
+ if (fieldURL === '_pinnedColumnsRight') {
544
+ pinnedColumns['right'] = columns;
545
+ }
546
+ }
547
+ return pinnedColumns['left'] || pinnedColumns['right'] ? {
548
+ left: pinnedColumns['left'] || [],
549
+ right: pinnedColumns['right'] || []
550
+ } : 'invalid';
551
+ };
552
+ const getSearchParamsFromPinnedColumns = pinnedColumns => {
553
+ var _pinnedColumns$left, _pinnedColumns$right;
554
+ const searchParams = new URLSearchParams();
555
+ const pinnedColumnLeft = ((_pinnedColumns$left = pinnedColumns.left) === null || _pinnedColumns$left === void 0 ? void 0 : _pinnedColumns$left.map(val => encodeValue(val))) || [];
556
+ const pinnedColumnRight = ((_pinnedColumns$right = pinnedColumns.right) === null || _pinnedColumns$right === void 0 ? void 0 : _pinnedColumns$right.map(val => encodeValue(val))) || [];
557
+ searchParams.set('_pinnedColumnsLeft', `[${pinnedColumnLeft.join(',')}]`);
558
+ searchParams.set('_pinnedColumnsRight', `[${pinnedColumnRight.join(',')}]`);
559
+ return searchParams;
560
+ };
561
+
562
+ // Rules:
563
+ // - if we have something in the URL, use that info
564
+ // - if we don't have that, use the localStorage and update the URL
565
+ // - if we don't have that, return an empty ColumnVisibilityModel (which is all columns)
566
+ const getPinnedColumns = (search, columns, localStoragePinnedColumns, setLocalStoragePinnedColumns, initialState, isNewVersion) => {
567
+ const defaultValue = initialState !== null && initialState !== void 0 && initialState.pinnedColumns ? {
568
+ left: (initialState === null || initialState === void 0 ? void 0 : initialState.pinnedColumns['left']) || [],
569
+ right: (initialState === null || initialState === void 0 ? void 0 : initialState.pinnedColumns['right']) || []
570
+ } : {
571
+ left: [],
572
+ right: []
573
+ };
574
+ if (isNewVersion) {
575
+ return defaultValue;
576
+ }
577
+ const pinnedColumns = getPinnedColumnsFromString(search, columns);
578
+ if (pinnedColumns !== 'invalid') {
579
+ const searchPinnedColumns = getSearchParamsFromPinnedColumns(pinnedColumns);
580
+ if (searchPinnedColumns.toString() !== localStoragePinnedColumns) {
581
+ setLocalStoragePinnedColumns(searchPinnedColumns.toString());
582
+ }
583
+ return pinnedColumns;
584
+ }
585
+ const pinnedColumnsFromLocalStorage = getPinnedColumnsFromString(localStoragePinnedColumns, columns);
586
+ if (pinnedColumnsFromLocalStorage !== 'invalid') {
587
+ return pinnedColumnsFromLocalStorage;
588
+ }
589
+ return defaultValue;
590
+ };
591
+ const getSearchParamsFromTab = search => {
592
+ const searchParams = new URLSearchParams();
593
+ const openTab = new URLSearchParams(search).get('tab');
594
+ if (openTab) {
595
+ searchParams.set('tab', openTab);
596
+ }
597
+ return searchParams;
598
+ };
599
+ const getFinalSearch = _ref3 => {
600
+ let {
601
+ search,
602
+ localStorageVersion,
603
+ filterModel,
604
+ sortModel,
605
+ paginationModel,
606
+ columnsVisibilityModel,
607
+ pinnedColumnsModel,
608
+ columns
609
+ } = _ref3;
610
+ const filterModelSearch = getSearchParamsFromFilterModel(filterModel);
611
+ const sortModelSearch = getSearchParamsFromSorting(sortModel);
612
+ const paginationModelSearch = getSearchParamsFromPagination(paginationModel);
613
+ const columnVisibilityModelSearch = getSearchParamsFromColumnVisibility(columnsVisibilityModel, columns);
614
+ const pinnedColumnsModelSearch = getSearchParamsFromPinnedColumns(pinnedColumnsModel);
615
+ const tabSearch = getSearchParamsFromTab(search);
616
+ const searchParams = new URLSearchParams();
617
+ for (const [key, value] of new URLSearchParams(search)) {
618
+ if (!key.startsWith('_')) {
619
+ searchParams.set(key, value);
620
+ }
621
+ }
622
+ searchParams.set('v', `${localStorageVersion}`);
623
+
624
+ // Add quickFilterValues explicitly if present in filterModel
625
+ if (filterModel.quickFilterValues && filterModel.quickFilterValues.length > 0) {
626
+ // Encode array as JSON string to preserve all values in one param
627
+ searchParams.set('_quickFilterValues', encodeURIComponent(JSON.stringify(filterModel.quickFilterValues)));
628
+ }
629
+ return new URLSearchParams([...searchParams, ...filterModelSearch, ...sortModelSearch, ...paginationModelSearch, ...tabSearch, ...pinnedColumnsModelSearch, ...columnVisibilityModelSearch]);
630
+ };
631
+ /** Return the state of the table given the URL and the local storage state */
632
+ const getModelsParsedOrUpdateLocalStorage = (search, localStorageVersion, columns, historyReplace, initialState, localStorage) => {
633
+ const currentVersion = new URLSearchParams(search).get('v');
634
+ const isNewVersion = !currentVersion || Number(currentVersion) !== localStorageVersion;
635
+ const {
636
+ localStorageFilters,
637
+ setLocalStorageFilters,
638
+ localStorageSorting,
639
+ setLocalStorageSorting,
640
+ localStoragePagination,
641
+ setLocalStoragePagination,
642
+ localStorageColumnsVisibility,
643
+ setLocalStorageColumnsVisibility,
644
+ localStoragePinnedColumns,
645
+ setLocalStoragePinnedColumns
646
+ } = localStorage;
647
+ const filterModel = getFilterModel(search, columns, localStorageFilters, setLocalStorageFilters, initialState, isNewVersion);
648
+ const sortModel = getSortModel(search, columns, localStorageSorting, setLocalStorageSorting, initialState, isNewVersion);
649
+ const paginationModel = getPaginationModel(search, localStoragePagination, setLocalStoragePagination, initialState, isNewVersion);
650
+ const columnVisibilityModel = getColumnsVisibility(search, columns, localStorageColumnsVisibility, setLocalStorageColumnsVisibility, initialState, isNewVersion);
651
+ const pinnedColumnsModel = getPinnedColumns(search, columns, localStoragePinnedColumns, setLocalStoragePinnedColumns, initialState, isNewVersion);
652
+ const finalSearch = getFinalSearch({
653
+ localStorageVersion,
654
+ search,
655
+ filterModel,
656
+ sortModel,
657
+ paginationModel,
658
+ columnsVisibilityModel: columnVisibilityModel,
659
+ pinnedColumnsModel,
660
+ columns
661
+ });
662
+ const searchString = urlSearchParamsToString(finalSearch);
663
+ if (searchString !== search) {
664
+ historyReplace(searchString);
665
+ }
666
+ return {
667
+ filterModel,
668
+ sortModel,
669
+ paginationModel,
670
+ columnVisibilityModel,
671
+ pinnedColumnsModel
672
+ };
673
+ };
674
+ const updateUrl = (_ref4, search, localStorageVersion, historyReplace, columns) => {
675
+ let {
676
+ filterModel,
677
+ sortModel,
678
+ paginationModel,
679
+ columnsModel: columnsVisibilityModel,
680
+ pinnedColumnsModel
681
+ } = _ref4;
682
+ const newSearch = getFinalSearch({
683
+ search,
684
+ localStorageVersion,
685
+ filterModel,
686
+ sortModel,
687
+ paginationModel,
688
+ columnsVisibilityModel,
689
+ pinnedColumnsModel,
690
+ columns
691
+ });
692
+ const searchString = urlSearchParamsToString(newSearch);
693
+ if (searchString !== search) {
694
+ historyReplace(searchString);
695
+ }
696
+ };
697
+
698
+ // Note: this is a comparator to sort the filters, not pure comparison
699
+ // do not use it for equivalence (e.g. with value `3` and undefined we
700
+ // will get 0).
701
+ const compareFilters = (firstFilter, secondFilter) => {
702
+ if (firstFilter.columnField < secondFilter.columnField) {
703
+ return -1;
704
+ } else if (firstFilter.columnField > secondFilter.columnField) {
705
+ return 1;
706
+ }
707
+ if (firstFilter.operatorValue === undefined || secondFilter.operatorValue === undefined) {
708
+ return 0;
709
+ }
710
+ if (firstFilter.operatorValue < secondFilter.operatorValue) {
711
+ return -1;
712
+ } else if (firstFilter.operatorValue > secondFilter.operatorValue) {
713
+ return 1;
714
+ }
715
+ if (firstFilter.value < secondFilter.value) {
716
+ return -1;
717
+ } else if (firstFilter.value > secondFilter.value) {
718
+ return 1;
719
+ }
720
+ return 0;
721
+ };
722
+ const areFiltersEquivalent = (firstFilter, secondFilter) => {
723
+ return firstFilter.columnField === secondFilter.columnField && firstFilter.operatorValue === secondFilter.operatorValue && firstFilter.value === secondFilter.value;
724
+ };
725
+ const areFilterModelsEquivalent = (filterModel, filterModelToMatch) => {
726
+ const {
727
+ items,
728
+ linkOperator
729
+ } = filterModel;
730
+ const {
731
+ items: itemsToMatch,
732
+ linkOperator: linkOperatorToMatch
733
+ } = filterModelToMatch;
734
+ if (linkOperator !== linkOperatorToMatch) {
735
+ return false;
736
+ }
737
+ if (items.length !== itemsToMatch.length) {
738
+ return false;
739
+ }
740
+ items.sort(compareFilters);
741
+ itemsToMatch.sort(compareFilters);
742
+ for (let i = 0; i < items.length; i++) {
743
+ const filter = items[i];
744
+ const filterToCompare = itemsToMatch[i];
745
+
746
+ // compareFilters return 0 if and only if the filters have the same
747
+ // columnField, operatorValue, and value
748
+ if (!areFiltersEquivalent(filter, filterToCompare)) {
749
+ return false;
750
+ }
751
+ }
752
+ return true;
753
+ };
754
+
755
+ export { areFilterModelsEquivalent, decodeValue, encodeValue, getColumnVisibilityFromString, getFilterModelFromString, getFinalSearch, getModelsParsedOrUpdateLocalStorage, getPaginationFromString, getPinnedColumnsFromString, getSearchParamsFromColumnVisibility, getSearchParamsFromFilterModel, getSearchParamsFromPagination, getSearchParamsFromPinnedColumns, getSearchParamsFromSorting, getSearchParamsFromTab, getSortingFromString, numberOperatorDecoder, numberOperatorEncoder, updateUrl, urlSearchParamsToString };
756
+ //# sourceMappingURL=urlLocalStorageSync.js.map