@controleonline/ui-default 1.0.263 → 1.0.265

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 (61) hide show
  1. package/AGENTS.md +47 -45
  2. package/package.json +20 -20
  3. package/src/react/components/errors/DefaultErrors.js +307 -325
  4. package/src/react/components/files/DefaultFile.js +46 -46
  5. package/src/react/components/filters/CompactFilterSelector.js +78 -24
  6. package/src/react/components/filters/CompactFilterSelector.styles.js +17 -5
  7. package/src/react/components/filters/DefaultColumnFilter.js +191 -57
  8. package/src/react/components/filters/DefaultExternalFilters.js +245 -182
  9. package/src/react/components/filters/DefaultSearch.js +131 -92
  10. package/src/react/components/filters/DefaultSearch.styles.js +65 -70
  11. package/src/react/components/form/DefaultForm.js +172 -151
  12. package/src/react/components/form/DefaultForm.styles.js +71 -66
  13. package/src/react/components/help/DefaultTooltip.js +87 -87
  14. package/src/react/components/help/DefaultTooltip.styles.js +61 -61
  15. package/src/react/components/inputs/DefaultDateInput.js +150 -0
  16. package/src/react/components/inputs/DefaultInput.js +162 -127
  17. package/src/react/components/inputs/DefaultInput.styles.js +6 -0
  18. package/src/react/components/inputs/DefaultSelect.js +320 -152
  19. package/src/react/components/inputs/defaultInputUtils.js +40 -19
  20. package/src/react/components/map/DefaultGoogleMap.styles.js +115 -9
  21. package/src/react/components/map/DefaultGoogleMap.web.js +560 -446
  22. package/src/react/components/map/DefaultMap.native.js +73 -71
  23. package/src/react/components/map/DefaultMap.styles.js +16 -16
  24. package/src/react/components/map/DefaultMap.web.js +68 -66
  25. package/src/react/components/map/DefaultNativeMap.native.js +307 -183
  26. package/src/react/components/map/DefaultNativeMap.shared.js +439 -340
  27. package/src/react/components/map/DefaultNativeMap.styles.js +156 -122
  28. package/src/react/components/table/DefaultColumnMenu.js +108 -0
  29. package/src/react/components/table/DefaultDebug.js +233 -0
  30. package/src/react/components/table/DefaultFiltersModal.js +142 -0
  31. package/src/react/components/table/DefaultModalButton.js +18 -0
  32. package/src/react/components/table/DefaultSearchModal.js +49 -0
  33. package/src/react/components/table/DefaultTable.js +345 -1846
  34. package/src/react/components/table/DefaultTable.styles.js +247 -136
  35. package/src/react/components/table/DefaultTable.utils.js +502 -0
  36. package/src/react/components/table/DefaultTableBody.js +26 -0
  37. package/src/react/components/table/DefaultTableCards.js +171 -0
  38. package/src/react/components/table/DefaultTableControls.js +208 -0
  39. package/src/react/components/table/DefaultTableEmptyState.js +22 -0
  40. package/src/react/components/table/DefaultTableFooter.js +172 -0
  41. package/src/react/components/table/DefaultTableInput.js +145 -0
  42. package/src/react/components/table/DefaultTableRows.js +340 -0
  43. package/src/react/components/table/DefaultTableSearch.js +100 -0
  44. package/src/react/components/table/DefaultTableToolbar.js +98 -0
  45. package/src/react/components/table/DefaultToolbarAction.js +56 -0
  46. package/src/react/components/table/useDefaultTablePagination.js +370 -0
  47. package/src/react/components/table/useDefaultTableSorting.js +126 -0
  48. package/src/react/components/table/useDefaultTableTheme.js +58 -0
  49. package/src/react/index.js +10 -10
  50. package/src/react/utils/tableVisibleColumnsPreferences.js +239 -211
  51. package/src/store/default/actions.js +51 -13
  52. package/src/store/default/getters.js +10 -8
  53. package/src/store/default/mutation_types.js +4 -2
  54. package/src/store/default/mutations.js +10 -1
  55. package/src/tests/react/components/errors/DefaultErrors.test.js +162 -162
  56. package/src/tests/react/components/files/DefaultFile.test.js +80 -80
  57. package/src/tests/react/components/form/DefaultForm.test.js +81 -0
  58. package/src/tests/react/components/inputs/DefaultSelect.test.js +185 -0
  59. package/src/tests/react/components/table/DefaultTable.test.js +1183 -0
  60. package/src/tests/react/store/defaultActions.test.js +59 -0
  61. package/src/tests/react/utils/tableVisibleColumnsPreferences.test.js +247 -168
@@ -1,192 +1,233 @@
1
- export const TABLE_VISIBLE_COLUMNS_PREFERENCES_KEY = 'tableVisibleColumns';
2
- export const TABLE_VIEW_MODE_PREFERENCES_KEY = 'tableViewModes';
3
- export const TABLE_SORT_PREFERENCES_KEY = 'tableSorts';
4
- export const TABLE_SORT_FIELD_PREFERENCES_KEY = 'tableSortFields';
5
- export const TABLE_SORT_DIRECTION_PREFERENCES_KEY = 'tableSortDirections';
6
- export const DEFAULT_TABLE_PREFERENCES_STORAGE_KEY = 'DefaultTablePreferences';
7
-
8
- const isPlainObject = value =>
9
- !!value && typeof value === 'object' && !Array.isArray(value);
10
-
11
- const getColumnKey = column => column?.key || column?.name || '';
12
-
13
- const readStoredPreferences = () => {
14
- try {
15
- const rawValue = globalThis?.localStorage?.getItem?.(
16
- DEFAULT_TABLE_PREFERENCES_STORAGE_KEY,
17
- );
18
-
19
- if (!rawValue) {
20
- return {};
21
- }
22
-
23
- const parsedValue = JSON.parse(rawValue);
24
- return isPlainObject(parsedValue) ? parsedValue : {};
25
- } catch {
26
- return {};
27
- }
28
- };
29
-
30
- const writeStoredPreferences = preferences => {
31
- try {
32
- globalThis?.localStorage?.setItem?.(
33
- DEFAULT_TABLE_PREFERENCES_STORAGE_KEY,
34
- JSON.stringify(preferences),
35
- );
36
- } catch {
37
- // localStorage can be unavailable in some runtimes
38
- }
39
- };
40
-
41
- export const buildDefaultVisibleColumns = columns =>
42
- (Array.isArray(columns) ? columns : []).reduce((accumulator, column) => {
43
- const key = getColumnKey(column);
44
- if (key) {
45
- accumulator[key] = column?.visible !== false;
46
- }
47
- return accumulator;
48
- }, {});
49
-
50
- export const sanitizeVisibleColumnsPreference = ({
51
- columns = [],
52
- visibleColumns = null,
53
- }) => {
54
- const defaultVisibleColumns = buildDefaultVisibleColumns(columns);
55
-
56
- if (!isPlainObject(visibleColumns)) {
57
- return defaultVisibleColumns;
58
- }
59
-
60
- return Object.keys(defaultVisibleColumns).reduce((accumulator, key) => {
61
- accumulator[key] =
62
- typeof visibleColumns[key] === 'boolean'
63
- ? visibleColumns[key]
64
- : defaultVisibleColumns[key];
65
- return accumulator;
66
- }, {});
67
- };
68
-
69
- export const resolveStoredVisibleColumnsPreference = preferenceKey => {
70
- if (!preferenceKey) {
71
- return null;
72
- }
73
-
74
- const storedPreferences = readStoredPreferences();
75
- const tableVisibleColumns = storedPreferences[TABLE_VISIBLE_COLUMNS_PREFERENCES_KEY];
76
-
77
- if (!isPlainObject(tableVisibleColumns)) {
78
- return null;
79
- }
80
-
81
- const pagePreference = tableVisibleColumns[preferenceKey];
82
- return isPlainObject(pagePreference) ? pagePreference : null;
83
- };
84
-
85
- export const persistVisibleColumnsPreference = (
86
- preferenceKey = '',
87
- visibleColumns = {},
88
- ) => {
89
- if (!preferenceKey || !isPlainObject(visibleColumns)) {
90
- return;
91
- }
92
-
93
- const storedPreferences = readStoredPreferences();
94
- const tableVisibleColumns = isPlainObject(
95
- storedPreferences[TABLE_VISIBLE_COLUMNS_PREFERENCES_KEY],
96
- )
97
- ? storedPreferences[TABLE_VISIBLE_COLUMNS_PREFERENCES_KEY]
98
- : {};
99
-
100
- writeStoredPreferences({
101
- ...storedPreferences,
102
- [TABLE_VISIBLE_COLUMNS_PREFERENCES_KEY]: {
103
- ...tableVisibleColumns,
104
- [preferenceKey]: visibleColumns,
105
- },
106
- });
107
- };
108
-
109
- export const resolveStoredTableViewModePreference = (
110
- preferenceKey = '',
111
- fallbackViewMode = 'table',
112
- ) => {
113
- if (!preferenceKey) {
114
- return fallbackViewMode;
115
- }
116
-
117
- const storedPreferences = readStoredPreferences();
118
- const tableViewModes = storedPreferences[TABLE_VIEW_MODE_PREFERENCES_KEY];
119
-
120
- if (!isPlainObject(tableViewModes)) {
121
- return fallbackViewMode;
122
- }
123
-
124
- const resolvedViewMode = tableViewModes[preferenceKey];
125
- return resolvedViewMode === 'cards' || resolvedViewMode === 'table'
126
- ? resolvedViewMode
127
- : fallbackViewMode;
128
- };
129
-
130
- export const persistTableViewModePreference = (
1
+ export const TABLE_VISIBLE_COLUMNS_PREFERENCES_KEY = 'visibleColumns';
2
+ export const TABLE_VIEW_MODE_PREFERENCES_KEY = 'viewMode';
3
+ export const TABLE_SORT_PREFERENCES_KEY = 'sort';
4
+ export const TABLE_FILTER_PREFERENCES_KEY = 'filters';
5
+ export const DEFAULT_TABLE_PREFERENCES_STORAGE_KEY = 'default-table';
6
+
7
+ const isPlainObject = value =>
8
+ !!value && typeof value === 'object' && !Array.isArray(value);
9
+
10
+ const getColumnKey = column => column?.key || column?.name || '';
11
+
12
+ const normalizePreferenceSegment = value =>
13
+ String(value || '')
14
+ .trim()
15
+ .replace(/^\/+|\/+$/g, '')
16
+ .replace(/[/?#]+/g, '-')
17
+ .replace(/\s+/g, '-')
18
+ .replace(/-+/g, '-');
19
+
20
+ export const resolveDefaultTablePreferenceScope = ({
131
21
  preferenceKey = '',
132
- viewMode = 'table',
133
- ) => {
134
- if (!preferenceKey || (viewMode !== 'cards' && viewMode !== 'table')) {
135
- return;
136
- }
137
-
138
- const storedPreferences = readStoredPreferences();
139
- const tableViewModes = isPlainObject(
140
- storedPreferences[TABLE_VIEW_MODE_PREFERENCES_KEY],
141
- )
142
- ? storedPreferences[TABLE_VIEW_MODE_PREFERENCES_KEY]
143
- : {};
144
-
145
- writeStoredPreferences({
146
- ...storedPreferences,
147
- [TABLE_VIEW_MODE_PREFERENCES_KEY]: {
148
- ...tableViewModes,
149
- [preferenceKey]: viewMode,
150
- },
151
- });
22
+ route = null,
23
+ storeName = '',
24
+ } = {}) => {
25
+ const routeName =
26
+ normalizePreferenceSegment(preferenceKey) ||
27
+ normalizePreferenceSegment(globalThis?.location?.pathname) ||
28
+ normalizePreferenceSegment(route?.name) ||
29
+ normalizePreferenceSegment(route?.key) ||
30
+ 'unknown-route';
31
+
32
+ /*
33
+ * @agents DefaultTable preferences are saved as [store][route].
34
+ * The same store can back different screens, so filters, sort, view mode,
35
+ * and column visibility must never be keyed only by store or only by route.
36
+ */
37
+ return {
38
+ routeKey: routeName,
39
+ storeKey: normalizePreferenceSegment(storeName) || 'unknown-store',
40
+ };
152
41
  };
153
42
 
154
- export const resolveStoredTableSortPreference = (preferenceKey = '') => {
155
- if (!preferenceKey) {
43
+ const normalizePreferenceScope = scope => {
44
+ if (!isPlainObject(scope)) {
156
45
  return null;
157
46
  }
158
47
 
48
+ const storeKey = normalizePreferenceSegment(scope.storeKey);
49
+ const routeKey = normalizePreferenceSegment(scope.routeKey);
50
+
51
+ return storeKey && routeKey ? {storeKey, routeKey} : null;
52
+ };
53
+
54
+ const readStoredPreferences = () => {
55
+ try {
56
+ const rawValue = globalThis?.localStorage?.getItem?.(
57
+ DEFAULT_TABLE_PREFERENCES_STORAGE_KEY,
58
+ );
59
+
60
+ if (!rawValue) {
61
+ return {};
62
+ }
63
+
64
+ const parsedValue = JSON.parse(rawValue);
65
+ return isPlainObject(parsedValue) ? parsedValue : {};
66
+ } catch {
67
+ return {};
68
+ }
69
+ };
70
+
71
+ const writeStoredPreferences = preferences => {
72
+ try {
73
+ globalThis?.localStorage?.setItem?.(
74
+ DEFAULT_TABLE_PREFERENCES_STORAGE_KEY,
75
+ JSON.stringify(preferences),
76
+ );
77
+ } catch {
78
+ // localStorage can be unavailable in some runtimes.
79
+ }
80
+ };
81
+
82
+ const readScopedPreference = scope => {
83
+ const resolvedScope = normalizePreferenceScope(scope);
84
+ if (!resolvedScope) {
85
+ return {};
86
+ }
87
+
159
88
  const storedPreferences = readStoredPreferences();
160
- const tableSortFields =
161
- storedPreferences[TABLE_SORT_FIELD_PREFERENCES_KEY];
162
- const tableSortDirections =
163
- storedPreferences[TABLE_SORT_DIRECTION_PREFERENCES_KEY];
164
-
165
- const resolvedField = isPlainObject(tableSortFields)
166
- ? tableSortFields[preferenceKey]
167
- : '';
168
- const resolvedDirection = isPlainObject(tableSortDirections)
169
- ? tableSortDirections[preferenceKey]
170
- : '';
89
+ const storePreferences = storedPreferences[resolvedScope.storeKey];
90
+ const routePreferences = isPlainObject(storePreferences)
91
+ ? storePreferences[resolvedScope.routeKey]
92
+ : null;
171
93
 
172
- if (
173
- typeof resolvedField === 'string' &&
174
- resolvedField.trim() &&
175
- (resolvedDirection === 'asc' || resolvedDirection === 'desc')
176
- ) {
177
- return {
178
- direction: resolvedDirection,
179
- field: resolvedField.trim(),
180
- };
94
+ return isPlainObject(routePreferences) ? routePreferences : {};
95
+ };
96
+
97
+ const writeScopedPreference = (scope, nextValues = {}) => {
98
+ const resolvedScope = normalizePreferenceScope(scope);
99
+ if (!resolvedScope || !isPlainObject(nextValues)) {
100
+ return;
181
101
  }
182
102
 
183
- const tableSorts = storedPreferences[TABLE_SORT_PREFERENCES_KEY];
103
+ const storedPreferences = readStoredPreferences();
104
+ const storePreferences = isPlainObject(storedPreferences[resolvedScope.storeKey])
105
+ ? storedPreferences[resolvedScope.storeKey]
106
+ : {};
107
+ const routePreferences = isPlainObject(storePreferences[resolvedScope.routeKey])
108
+ ? storePreferences[resolvedScope.routeKey]
109
+ : {};
184
110
 
185
- if (!isPlainObject(tableSorts)) {
186
- return null;
111
+ writeStoredPreferences({
112
+ ...storedPreferences,
113
+ [resolvedScope.storeKey]: {
114
+ ...storePreferences,
115
+ [resolvedScope.routeKey]: {
116
+ ...routePreferences,
117
+ ...nextValues,
118
+ },
119
+ },
120
+ });
121
+ };
122
+
123
+ export const buildDefaultVisibleColumns = columns =>
124
+ (Array.isArray(columns) ? columns : []).reduce((accumulator, column) => {
125
+ const key = getColumnKey(column);
126
+ if (key) {
127
+ accumulator[key] = column?.visible !== false;
128
+ }
129
+ return accumulator;
130
+ }, {});
131
+
132
+ export const sanitizeVisibleColumnsPreference = ({
133
+ columns = [],
134
+ visibleColumns = null,
135
+ }) => {
136
+ const defaultVisibleColumns = buildDefaultVisibleColumns(columns);
137
+
138
+ if (!isPlainObject(visibleColumns)) {
139
+ return defaultVisibleColumns;
140
+ }
141
+
142
+ return Object.keys(defaultVisibleColumns).reduce((accumulator, key) => {
143
+ accumulator[key] =
144
+ typeof visibleColumns[key] === 'boolean'
145
+ ? visibleColumns[key]
146
+ : defaultVisibleColumns[key];
147
+ return accumulator;
148
+ }, {});
149
+ };
150
+
151
+ export const sanitizeTableFiltersPreference = ({
152
+ columns = [],
153
+ filters = null,
154
+ }) => {
155
+ if (!isPlainObject(filters)) {
156
+ return {};
187
157
  }
188
158
 
189
- const resolvedSort = tableSorts[preferenceKey];
159
+ const columnFields = new Set(
160
+ (Array.isArray(columns) ? columns : [])
161
+ .map(getColumnKey)
162
+ .filter(Boolean),
163
+ );
164
+ const blockedFields = new Set(
165
+ (Array.isArray(columns) ? columns : [])
166
+ .filter(column => column?.filter === false || column?.filters === false)
167
+ .map(getColumnKey)
168
+ .filter(Boolean),
169
+ );
170
+ const allowedSpecialFields = new Set(['search']);
171
+
172
+ return Object.keys(filters).reduce((accumulator, key) => {
173
+ if (
174
+ allowedSpecialFields.has(key) ||
175
+ (columnFields.has(key) && !blockedFields.has(key))
176
+ ) {
177
+ accumulator[key] = filters[key];
178
+ }
179
+
180
+ return accumulator;
181
+ }, {});
182
+ };
183
+
184
+ export const resolveStoredVisibleColumnsPreference = scope => {
185
+ const visibleColumns =
186
+ readScopedPreference(scope)[TABLE_VISIBLE_COLUMNS_PREFERENCES_KEY];
187
+
188
+ return isPlainObject(visibleColumns) ? visibleColumns : null;
189
+ };
190
+
191
+ export const persistVisibleColumnsPreference = (
192
+ scope = null,
193
+ visibleColumns = {},
194
+ ) => {
195
+ if (!isPlainObject(visibleColumns)) {
196
+ return;
197
+ }
198
+
199
+ writeScopedPreference(scope, {
200
+ [TABLE_VISIBLE_COLUMNS_PREFERENCES_KEY]: visibleColumns,
201
+ });
202
+ };
203
+
204
+ export const resolveStoredTableViewModePreference = (
205
+ scope = null,
206
+ fallbackViewMode = 'table',
207
+ ) => {
208
+ const resolvedViewMode =
209
+ readScopedPreference(scope)[TABLE_VIEW_MODE_PREFERENCES_KEY];
210
+
211
+ return resolvedViewMode === 'cards' || resolvedViewMode === 'table'
212
+ ? resolvedViewMode
213
+ : fallbackViewMode;
214
+ };
215
+
216
+ export const persistTableViewModePreference = (
217
+ scope = null,
218
+ viewMode = 'table',
219
+ ) => {
220
+ if (viewMode !== 'cards' && viewMode !== 'table') {
221
+ return;
222
+ }
223
+
224
+ writeScopedPreference(scope, {
225
+ [TABLE_VIEW_MODE_PREFERENCES_KEY]: viewMode,
226
+ });
227
+ };
228
+
229
+ export const resolveStoredTableSortPreference = (scope = null) => {
230
+ const resolvedSort = readScopedPreference(scope)[TABLE_SORT_PREFERENCES_KEY];
190
231
 
191
232
  if (!isPlainObject(resolvedSort)) {
192
233
  return null;
@@ -212,11 +253,10 @@ export const resolveStoredTableSortPreference = (preferenceKey = '') => {
212
253
  };
213
254
 
214
255
  export const persistTableSortPreference = (
215
- preferenceKey = '',
256
+ scope = null,
216
257
  sort = null,
217
258
  ) => {
218
259
  if (
219
- !preferenceKey ||
220
260
  !isPlainObject(sort) ||
221
261
  (sort.direction !== 'asc' && sort.direction !== 'desc') ||
222
262
  typeof sort.field !== 'string' ||
@@ -225,40 +265,28 @@ export const persistTableSortPreference = (
225
265
  return;
226
266
  }
227
267
 
228
- const storedPreferences = readStoredPreferences();
229
- const tableSortFields = isPlainObject(
230
- storedPreferences[TABLE_SORT_FIELD_PREFERENCES_KEY],
231
- )
232
- ? storedPreferences[TABLE_SORT_FIELD_PREFERENCES_KEY]
233
- : {};
234
- const tableSortDirections = isPlainObject(
235
- storedPreferences[TABLE_SORT_DIRECTION_PREFERENCES_KEY],
236
- )
237
- ? storedPreferences[TABLE_SORT_DIRECTION_PREFERENCES_KEY]
238
- : {};
239
- const legacyTableSorts = isPlainObject(
240
- storedPreferences[TABLE_SORT_PREFERENCES_KEY],
241
- )
242
- ? storedPreferences[TABLE_SORT_PREFERENCES_KEY]
243
- : {};
244
-
245
- writeStoredPreferences({
246
- ...storedPreferences,
247
- [TABLE_SORT_FIELD_PREFERENCES_KEY]: {
248
- ...tableSortFields,
249
- [preferenceKey]: sort.field.trim(),
250
- },
251
- [TABLE_SORT_DIRECTION_PREFERENCES_KEY]: {
252
- ...tableSortDirections,
253
- [preferenceKey]: sort.direction,
254
- },
268
+ writeScopedPreference(scope, {
255
269
  [TABLE_SORT_PREFERENCES_KEY]: {
256
- ...legacyTableSorts,
257
- [preferenceKey]: {
258
- direction: sort.direction,
259
- field: sort.field.trim(),
260
- },
270
+ direction: sort.direction,
271
+ field: sort.field.trim(),
261
272
  },
262
273
  });
263
274
  };
264
-
275
+
276
+ export const resolveStoredTableFiltersPreference = (scope = null) => {
277
+ const resolvedFilters = readScopedPreference(scope)[TABLE_FILTER_PREFERENCES_KEY];
278
+ return isPlainObject(resolvedFilters) ? resolvedFilters : null;
279
+ };
280
+
281
+ export const persistTableFiltersPreference = (
282
+ scope = null,
283
+ filters = {},
284
+ ) => {
285
+ if (!isPlainObject(filters)) {
286
+ return;
287
+ }
288
+
289
+ writeScopedPreference(scope, {
290
+ [TABLE_FILTER_PREFERENCES_KEY]: filters,
291
+ });
292
+ };
@@ -54,6 +54,30 @@ const resolveCollectionTotalItems = (response, items) =>
54
54
  const normalizeCollectionItemId = item =>
55
55
  normalizeText(item?.['@id'] || item?.id || '').replace(/\D+/g, '')
56
56
 
57
+ const normalizeSavedItemPatch = (data, patch) => {
58
+ if (!isPlainObject(patch)) {
59
+ return {}
60
+ }
61
+
62
+ return Object.entries(patch).reduce((normalizedPatch, [key, value]) => {
63
+ const incomingValue = data?.[key]
64
+ normalizedPatch[key] = isPlainObject(incomingValue) ? incomingValue : value
65
+
66
+ return normalizedPatch
67
+ }, {})
68
+ }
69
+
70
+ const mergeSavedItem = ({currentItem, data, storeMeta}) => {
71
+ const incomingItem = isPlainObject(data) ? {...data} : {}
72
+ delete incomingItem['@context']
73
+
74
+ return {
75
+ ...(isPlainObject(currentItem) ? currentItem : {}),
76
+ ...incomingItem,
77
+ ...normalizeSavedItemPatch(incomingItem, storeMeta.savedItemPatch),
78
+ }
79
+ }
80
+
57
81
  const appendCollectionItems = (currentItems, nextItems) => {
58
82
  const mergedItems = Array.isArray(currentItems) ? [...currentItems] : []
59
83
  const incomingItems = Array.isArray(nextItems) ? nextItems : []
@@ -148,6 +172,7 @@ export const getOfflineItems = ({commit, getters}, params = {}) => {
148
172
  commit(types.SET_ISLOADING, true);
149
173
  commit(types.SET_ERROR, null);
150
174
  commit(types.SET_SUMMARY, {});
175
+ commit(types.SET_DEBUG, {});
151
176
 
152
177
  db = new localDB(getters);
153
178
 
@@ -189,6 +214,7 @@ export const getOnlineItems = ({commit, getters}, params = {}) => {
189
214
  if (getters.items != null) commit(types.SET_ITEMS, []);
190
215
  commit(types.SET_TOTALITEMS, 0);
191
216
  commit(types.SET_SUMMARY, {});
217
+ commit(types.SET_DEBUG, {});
192
218
  }
193
219
  return api
194
220
  .fetch(getters.resourceEndpoint, {params: queryParams})
@@ -207,6 +233,7 @@ export const getOnlineItems = ({commit, getters}, params = {}) => {
207
233
  commit(types.SET_ITEMS, nextItems);
208
234
  commit(types.SET_TOTALITEMS, resolveCollectionTotalItems(data, nextItems));
209
235
  commit(types.SET_SUMMARY, data['summary'] || data?.['hydra:summary'] || {});
236
+ commit(types.SET_DEBUG, data?.debug || {});
210
237
  commit(types.SET_LAST_COMPLETED_REQUEST, {
211
238
  completedAt: Date.now(),
212
239
  requestKey,
@@ -290,18 +317,25 @@ export const save = ({commit, getters}, params) => {
290
317
  .fetch(getters.resourceEndpoint + (id ? '/' + id : ''), options)
291
318
  .then(data => {
292
319
  commit(types.SET_ERROR, null);
293
- delete data['@context'];
294
320
  let items = getters.items ? [...getters.items] : [];
295
- if (id) {
296
- const index = items.findIndex(i => {
297
- return i['@id'].replace(/\D/g, '') === id;
298
- });
299
- if (index >= 0) items[index] = data;
300
- else items.push(data);
301
- } else items.push(data);
302
- commit(types.SET_ITEMS, items);
303
- return data;
304
- })
321
+ if (id) {
322
+ const index = items.findIndex(i => {
323
+ return normalizeCollectionItemId(i) === id;
324
+ });
325
+ const nextItem = mergeSavedItem({
326
+ currentItem: index >= 0 ? items[index] : null,
327
+ data,
328
+ storeMeta,
329
+ });
330
+
331
+ if (index >= 0) items[index] = nextItem;
332
+ else items.push(nextItem);
333
+ } else {
334
+ items.push(mergeSavedItem({currentItem: null, data, storeMeta}));
335
+ }
336
+ commit(types.SET_ITEMS, items);
337
+ return data;
338
+ })
305
339
  .catch(e => {
306
340
  commitStoreError(commit, e, storeMeta)
307
341
  throw e;
@@ -385,8 +419,12 @@ export const setSummary = ({commit, getters}, summary) => {
385
419
  export const setColumns = ({commit, getters}, columns) => {
386
420
  commit(types.SET_COLUMNS, columns);
387
421
  };
388
-
389
- export const setResourceEndpoint = (
422
+
423
+ export const setConfigs = ({commit, getters}, configs) => {
424
+ commit(types.SET_CONFIGS, configs);
425
+ };
426
+
427
+ export const setResourceEndpoint = (
390
428
  {commit, getters},
391
429
  resourceEndpoint = null,
392
430
  ) => {
@@ -1,12 +1,14 @@
1
1
  export const error = state => state.error;
2
- export const isLoading = state => state.isLoading;
3
- export const isSaving = state => state.isSaving;
4
- export const totalItems = state => state.totalItems;
5
- export const summary = state => state.summary;
6
- export const items = state => state.items;
7
- export const item = state => state.item;
8
- export const columns = state => state.columns;
9
- export const filters = state => state.filters;
2
+ export const isLoading = state => state.isLoading;
3
+ export const isSaving = state => state.isSaving;
4
+ export const totalItems = state => state.totalItems;
5
+ export const summary = state => state.summary;
6
+ export const debug = state => state.debug || {};
7
+ export const items = state => state.items;
8
+ export const item = state => state.item;
9
+ export const columns = state => state.columns;
10
+ export const configs = state => state.configs || {};
11
+ export const filters = state => state.filters;
10
12
  export const resourceEndpoint = state => state.resourceEndpoint;
11
13
  export const selected = state => state.selected;
12
14
  export const visibleColumns = state => state.visibleColumns;
@@ -3,10 +3,12 @@ export const SET_ISLOADING = 'SET_ISLOADING';
3
3
  export const SET_ISSAVING = 'SET_ISSAVING';
4
4
  export const SET_TOTALITEMS = 'SET_TOTALITEMS';
5
5
  export const SET_SUMMARY = 'SET_SUMMARY';
6
+ export const SET_DEBUG = 'SET_DEBUG';
6
7
  export const SET_ITEMS = 'SET_ITEMS';
7
8
  export const SET_ITEM = 'SET_ITEM';
8
- export const SET_COLUMNS = 'SET_COLUMNS';
9
- export const SET_FILTERS = 'SET_FILTERS';
9
+ export const SET_COLUMNS = 'SET_COLUMNS';
10
+ export const SET_CONFIGS = 'SET_CONFIGS';
11
+ export const SET_FILTERS = 'SET_FILTERS';
10
12
  export const SET_RESOURCE_ENDPOINT = 'SET_RESOURCE_ENDPOINT';
11
13
  export const SET_SELECTED = 'SET_SELECTED';
12
14
  export const SET_VISIBLECOLUMNS = 'SET_VISIBLECOLUMNS';
@@ -37,6 +37,11 @@ export default {
37
37
  return 'summary';
38
38
  },
39
39
 
40
+ [types.SET_DEBUG](state, debug) {
41
+ state.debug = debug || {};
42
+ return 'debug';
43
+ },
44
+
40
45
  [types.SET_ITEMS](state, items) {
41
46
  state.items = items;
42
47
  return 'items';
@@ -74,7 +79,11 @@ export default {
74
79
  state.columns = columns;
75
80
  return 'columns';
76
81
  },
77
- [types.SET_OFFLINE](state, offline) {
82
+ [types.SET_CONFIGS](state, configs) {
83
+ state.configs = configs || {};
84
+ return 'configs';
85
+ },
86
+ [types.SET_OFFLINE](state, offline) {
78
87
  state.offline = offline;
79
88
  return 'offline';
80
89
  },