@edsis/ui 21.3.12 → 21.3.15

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.
@@ -22,12 +22,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
22
22
  }] });
23
23
 
24
24
  const DEFAULT_NAV_ID = 'default';
25
+ const PERSISTED_NAV_ID = 'main';
25
26
  const DEFAULT_VERTICAL_APPEARANCE = 'sidebar';
26
27
  const DEFAULT_HORIZONTAL_APPEARANCE = 'navbar';
27
28
  const DEFAULT_POSITION = 'left';
28
29
  const DEFAULT_DOCKBAR_MODE = 'sticky';
29
- const VERTICAL_APPEARANCE_STORAGE_KEY = 'nav-vertical-appearance';
30
- const HORIZONTAL_APPEARANCE_STORAGE_KEY = 'nav-horizontal-appearance';
30
+ const INSTANCE_STORAGE_PROPERTIES = ['orientation', 'appearance', 'position', 'collapsed', 'dockbar-mode'];
31
+ const PERSISTED_STORAGE_PROPERTIES = ['orientation', 'appearance', 'position'];
32
+ const APPEARANCE_MODE_STORAGE_KEY = 'nav-appearance-mode';
33
+ const LEGACY_NAV_STORAGE_KEYS = ['nav-vertical-appearance', 'nav-horizontal-appearance'];
34
+ const LEGACY_APPEARANCE_MODE_STORAGE_KEYS = ['nav-collapsed', 'nav-dockbar-mode'];
31
35
  class NavService {
32
36
  documentRef = inject(DOCUMENT, { optional: true });
33
37
  router = inject(Router, { optional: true });
@@ -49,7 +53,7 @@ class NavService {
49
53
  matrixParams: 'ignored',
50
54
  };
51
55
  constructor() {
52
- this.ensureAppearanceDefaults();
56
+ this.cleanupLegacyStorage();
53
57
  this.router?.events.pipe(takeUntilDestroyed()).subscribe((event) => {
54
58
  if (event instanceof NavigationEnd) {
55
59
  this.routerUrl.set(event.urlAfterRedirects);
@@ -57,7 +61,6 @@ class NavService {
57
61
  });
58
62
  }
59
63
  register(input) {
60
- this.ensureAppearanceDefaults();
61
64
  const state = this.resolveState(input);
62
65
  this.states.update((states) => ({ ...states, [state.id]: state }));
63
66
  this.persistState(state);
@@ -217,75 +220,83 @@ class NavService {
217
220
  resolveState(input) {
218
221
  const id = this.normalizeId(input.id);
219
222
  const orientation = input.orientation;
223
+ const appearance = this.resolveAppearance(id, orientation, input.appearance);
220
224
  return {
221
225
  id,
222
226
  orientation,
223
- appearance: this.resolveAppearance(id, orientation, input.appearance),
227
+ appearance,
224
228
  position: this.resolvePosition(id, input.position),
225
- collapsed: this.resolveCollapsed(id, input.collapsed),
226
- dockbarMode: this.resolveDockbarMode(id, input.dockbarMode),
229
+ collapsed: this.resolveCollapsed(id, appearance, input.collapsed),
230
+ dockbarMode: this.resolveDockbarMode(id, appearance, input.dockbarMode),
227
231
  };
228
232
  }
229
233
  resolveAppearance(id, orientation, appearance) {
230
234
  if (this.isAppearanceForOrientation(appearance, orientation)) {
231
235
  return appearance;
232
236
  }
233
- const stored = this.readStorage(this.instanceStorageKey(id, 'appearance'));
237
+ const stored = this.readInstanceStorage(id, 'appearance');
234
238
  if (this.isAppearanceForOrientation(stored, orientation)) {
235
239
  return stored;
236
240
  }
237
- return this.readOrientationAppearance(orientation);
241
+ return this.defaultAppearance(orientation);
238
242
  }
239
243
  resolvePosition(id, position) {
240
244
  if (this.isPosition(position)) {
241
245
  return position;
242
246
  }
243
- const stored = this.readStorage(this.instanceStorageKey(id, 'position'));
247
+ const stored = this.readInstanceStorage(id, 'position');
244
248
  return this.isPosition(stored) ? stored : DEFAULT_POSITION;
245
249
  }
246
- resolveCollapsed(id, collapsed) {
250
+ resolveCollapsed(id, appearance, collapsed) {
247
251
  if (typeof collapsed === 'boolean') {
248
252
  return collapsed;
249
253
  }
250
- const stored = this.readStorage(this.instanceStorageKey(id, 'collapsed'));
251
- if (stored === 'true') {
252
- return true;
253
- }
254
- if (stored === 'false') {
254
+ if (appearance !== 'sidebar') {
255
255
  return false;
256
256
  }
257
- return false;
257
+ return this.readPersistedAppearanceMode(id) === 'collapsed';
258
258
  }
259
- resolveDockbarMode(id, mode) {
259
+ resolveDockbarMode(id, appearance, mode) {
260
260
  if (this.isDockbarMode(mode)) {
261
261
  return mode;
262
262
  }
263
- const stored = this.readStorage(this.instanceStorageKey(id, 'dockbar-mode'));
263
+ if (appearance !== 'dockbar') {
264
+ return DEFAULT_DOCKBAR_MODE;
265
+ }
266
+ const stored = this.readPersistedAppearanceMode(id);
264
267
  return this.isDockbarMode(stored) ? stored : DEFAULT_DOCKBAR_MODE;
265
268
  }
266
269
  persistState(state) {
267
- this.writeStorage(this.instanceStorageKey(state.id, 'orientation'), state.orientation);
268
- this.writeStorage(this.instanceStorageKey(state.id, 'appearance'), state.appearance);
269
- this.writeStorage(this.instanceStorageKey(state.id, 'position'), state.position);
270
- this.writeStorage(this.instanceStorageKey(state.id, 'collapsed'), String(state.collapsed));
271
- this.writeStorage(this.instanceStorageKey(state.id, 'dockbar-mode'), state.dockbarMode);
272
- }
273
- readOrientationAppearance(orientation) {
274
- const key = orientation === 'vertical' ? VERTICAL_APPEARANCE_STORAGE_KEY : HORIZONTAL_APPEARANCE_STORAGE_KEY;
275
- const fallback = orientation === 'vertical' ? DEFAULT_VERTICAL_APPEARANCE : DEFAULT_HORIZONTAL_APPEARANCE;
276
- const stored = this.readStorage(key);
277
- if (this.isAppearanceForOrientation(stored, orientation)) {
278
- return stored;
270
+ if (!this.shouldPersistInstanceState(state.id)) {
271
+ this.clearInstanceStorage(state.id);
272
+ return;
279
273
  }
280
- this.writeStorage(key, fallback);
281
- return fallback;
274
+ this.writeStorage(this.persistedStorageKey('orientation'), state.orientation);
275
+ this.writeStorage(this.persistedStorageKey('appearance'), state.appearance);
276
+ this.writeStorage(this.persistedStorageKey('position'), state.position);
277
+ this.writeStorage(APPEARANCE_MODE_STORAGE_KEY, this.persistedAppearanceMode(state));
282
278
  }
283
- ensureAppearanceDefaults() {
284
- if (!this.isVerticalAppearance(this.readStorage(VERTICAL_APPEARANCE_STORAGE_KEY))) {
285
- this.writeStorage(VERTICAL_APPEARANCE_STORAGE_KEY, DEFAULT_VERTICAL_APPEARANCE);
279
+ defaultAppearance(orientation) {
280
+ return orientation === 'vertical' ? DEFAULT_VERTICAL_APPEARANCE : DEFAULT_HORIZONTAL_APPEARANCE;
281
+ }
282
+ cleanupLegacyStorage() {
283
+ this.migrateLegacyPersistedStorage();
284
+ for (const key of LEGACY_NAV_STORAGE_KEYS) {
285
+ this.removeStorage(key);
286
+ }
287
+ for (const key of LEGACY_APPEARANCE_MODE_STORAGE_KEYS) {
288
+ this.removeStorage(key);
286
289
  }
287
- if (!this.isHorizontalAppearance(this.readStorage(HORIZONTAL_APPEARANCE_STORAGE_KEY))) {
288
- this.writeStorage(HORIZONTAL_APPEARANCE_STORAGE_KEY, DEFAULT_HORIZONTAL_APPEARANCE);
290
+ const storage = this.storage();
291
+ const keysToRemove = [];
292
+ for (let index = 0; index < (storage?.length ?? 0); index += 1) {
293
+ const key = storage?.key(index);
294
+ if (key && this.isLegacyInstanceStorageKey(key)) {
295
+ keysToRemove.push(key);
296
+ }
297
+ }
298
+ for (const key of keysToRemove) {
299
+ this.removeStorage(key);
289
300
  }
290
301
  }
291
302
  storage() {
@@ -304,6 +315,19 @@ class NavService {
304
315
  return null;
305
316
  }
306
317
  }
318
+ readInstanceStorage(id, property) {
319
+ if (!this.shouldPersistInstanceState(id)) {
320
+ return null;
321
+ }
322
+ return this.readStorage(this.persistedStorageKey(property));
323
+ }
324
+ readPersistedAppearanceMode(id) {
325
+ if (!this.shouldPersistInstanceState(id)) {
326
+ return null;
327
+ }
328
+ const stored = this.readStorage(APPEARANCE_MODE_STORAGE_KEY);
329
+ return this.isPersistedAppearanceMode(stored) ? stored : null;
330
+ }
307
331
  writeStorage(key, value) {
308
332
  try {
309
333
  this.storage()?.setItem(key, value);
@@ -312,9 +336,81 @@ class NavService {
312
336
  return;
313
337
  }
314
338
  }
339
+ removeStorage(key) {
340
+ try {
341
+ this.storage()?.removeItem(key);
342
+ }
343
+ catch {
344
+ return;
345
+ }
346
+ }
347
+ clearInstanceStorage(id) {
348
+ for (const property of INSTANCE_STORAGE_PROPERTIES) {
349
+ this.removeStorage(this.instanceStorageKey(id, property));
350
+ }
351
+ }
352
+ migrateLegacyPersistedStorage() {
353
+ for (const property of PERSISTED_STORAGE_PROPERTIES) {
354
+ const nextKey = this.persistedStorageKey(property);
355
+ const legacyKey = this.instanceStorageKey(PERSISTED_NAV_ID, property);
356
+ const nextValue = this.readStorage(nextKey);
357
+ const legacyValue = this.readStorage(legacyKey);
358
+ if (nextValue === null && legacyValue !== null) {
359
+ this.writeStorage(nextKey, legacyValue);
360
+ }
361
+ }
362
+ if (this.readStorage(APPEARANCE_MODE_STORAGE_KEY) !== null) {
363
+ return;
364
+ }
365
+ const migratedAppearanceMode = this.resolveLegacyAppearanceMode();
366
+ if (migratedAppearanceMode !== null) {
367
+ this.writeStorage(APPEARANCE_MODE_STORAGE_KEY, migratedAppearanceMode);
368
+ }
369
+ }
315
370
  instanceStorageKey(id, property) {
316
371
  return `nav:${id}:${property}`;
317
372
  }
373
+ persistedStorageKey(property) {
374
+ return `nav-${property}`;
375
+ }
376
+ persistedAppearanceMode(state) {
377
+ if (state.appearance === 'dockbar') {
378
+ return state.dockbarMode;
379
+ }
380
+ return state.collapsed ? 'collapsed' : 'default';
381
+ }
382
+ resolveLegacyAppearanceMode() {
383
+ const appearance = this.readStorage(this.persistedStorageKey('appearance')) ??
384
+ this.readStorage(this.instanceStorageKey(PERSISTED_NAV_ID, 'appearance'));
385
+ const collapsed = this.readStorage('nav-collapsed') ?? this.readStorage(this.instanceStorageKey(PERSISTED_NAV_ID, 'collapsed'));
386
+ const dockbarMode = this.readStorage('nav-dockbar-mode') ??
387
+ this.readStorage(this.instanceStorageKey(PERSISTED_NAV_ID, 'dockbar-mode'));
388
+ if (appearance === 'dockbar' && this.isDockbarMode(dockbarMode)) {
389
+ return dockbarMode;
390
+ }
391
+ if (appearance === 'sidebar') {
392
+ return collapsed === 'true' ? 'collapsed' : 'default';
393
+ }
394
+ if (this.isDockbarMode(dockbarMode)) {
395
+ return dockbarMode;
396
+ }
397
+ if (collapsed === 'true') {
398
+ return 'collapsed';
399
+ }
400
+ if (collapsed === 'false') {
401
+ return 'default';
402
+ }
403
+ return null;
404
+ }
405
+ shouldPersistInstanceState(id) {
406
+ return id === PERSISTED_NAV_ID;
407
+ }
408
+ isLegacyInstanceStorageKey(key) {
409
+ return key.startsWith('nav:');
410
+ }
411
+ isPersistedAppearanceMode(value) {
412
+ return value === 'default' || value === 'collapsed' || this.isDockbarMode(value);
413
+ }
318
414
  normalizeId(id) {
319
415
  return id.trim() || DEFAULT_NAV_ID;
320
416
  }