diff --git a/projects/common/src/preference/preference.service.ts b/projects/common/src/preference/preference.service.ts index 198ab646a..3e92c76e6 100644 --- a/projects/common/src/preference/preference.service.ts +++ b/projects/common/src/preference/preference.service.ts @@ -1,21 +1,30 @@ import { Injectable } from '@angular/core'; import { Observable, of, throwError } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; +import { AbstractStorage } from '../utilities/browser/storage/abstract-storage'; import { LocalStorage } from '../utilities/browser/storage/local-storage'; +import { SessionStorage } from '../utilities/browser/storage/session-storage'; import { BooleanCoercer } from '../utilities/coercers/boolean-coercer'; import { NumberCoercer } from '../utilities/coercers/number-coercer'; +export const enum StorageType { + Local = 'local', + Session = 'session' +} + @Injectable({ providedIn: 'root' }) export class PreferenceService { + private static readonly DEFAULT_STORAGE_TYPE: StorageType = StorageType.Local; + private static readonly PREFERENCE_STORAGE_NAMESPACE: string = 'preference'; private static readonly SEPARATOR_CHAR: string = '.'; private static readonly SEPARATOR_REGEX: RegExp = /\.(.+)/; private readonly numberCoercer: NumberCoercer = new NumberCoercer(); private readonly booleanCoercer: BooleanCoercer = new BooleanCoercer(); - public constructor(private readonly preferenceStorage: LocalStorage) {} + public constructor(private readonly localStorage: LocalStorage, private readonly sessionStorage: SessionStorage) {} /** * Returns the current storage value if defined, else the default value. The observable @@ -23,20 +32,30 @@ export class PreferenceService { * preference becomes unset. If default value is not provided, the observable will * throw in the case the preference is unset. */ - public get(key: PreferenceKey, defaultValue?: T): Observable { - return this.preferenceStorage.watch(this.asStorageKey(key)).pipe( - map(storedValue => this.fromStorageValue(storedValue) ?? defaultValue), - switchMap(value => - value === undefined - ? throwError(Error(`No value found or default provided for preferenceKey: ${key}`)) - : of(value) - ) - ); + public get( + key: PreferenceKey, + defaultValue?: T, + type: StorageType = PreferenceService.DEFAULT_STORAGE_TYPE + ): Observable { + return this.preferenceStorage(type) + .watch(this.asStorageKey(key)) + .pipe( + map(storedValue => this.fromStorageValue(storedValue) ?? defaultValue), + switchMap(value => + value === undefined + ? throwError(Error(`No value found or default provided for preferenceKey: ${key}`)) + : of(value) + ) + ); } - public set(key: PreferenceKey, value: PreferenceValue): void { + public set( + key: PreferenceKey, + value: PreferenceValue, + type: StorageType = PreferenceService.DEFAULT_STORAGE_TYPE + ): void { const val = this.asStorageValue(value); - this.preferenceStorage.set(this.asStorageKey(key), val); + this.preferenceStorage(type).set(this.asStorageKey(key), val); } private asStorageKey(key: PreferenceKey): PreferenceStorageKey { @@ -70,6 +89,16 @@ export class PreferenceService { return undefined; } } + + private preferenceStorage(type: StorageType): AbstractStorage { + switch (type) { + case StorageType.Session: + return this.sessionStorage; + case StorageType.Local: + default: + return this.localStorage; + } + } } type PreferenceStorageKey = string; diff --git a/projects/common/src/utilities/browser/storage/session-storage.ts b/projects/common/src/utilities/browser/storage/session-storage.ts new file mode 100644 index 000000000..da1f9d1c9 --- /dev/null +++ b/projects/common/src/utilities/browser/storage/session-storage.ts @@ -0,0 +1,9 @@ +import { Injectable } from '@angular/core'; +import { AbstractStorage } from './abstract-storage'; + +@Injectable({ providedIn: 'root' }) +export class SessionStorage extends AbstractStorage { + public constructor() { + super(sessionStorage); + } +} diff --git a/projects/components/src/multi-select/multi-select.component.ts b/projects/components/src/multi-select/multi-select.component.ts index 307d0bcb7..efa296a07 100644 --- a/projects/components/src/multi-select/multi-select.component.ts +++ b/projects/components/src/multi-select/multi-select.component.ts @@ -10,7 +10,7 @@ import { QueryList } from '@angular/core'; import { IconType } from '@hypertrace/assets-library'; -import { queryListAndChanges$, SubscriptionLifecycle } from '@hypertrace/common'; +import { queryListAndChanges$ } from '@hypertrace/common'; import { BehaviorSubject, combineLatest, EMPTY, Observable, of, Subject } from 'rxjs'; import { map } from 'rxjs/operators'; import { ButtonRole, ButtonStyle } from '../button/button'; @@ -24,7 +24,6 @@ import { MultiSelectJustify } from './multi-select-justify'; selector: 'ht-multi-select', styleUrls: ['./multi-select.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, - providers: [SubscriptionLifecycle], template: `
{ return isNonEmptyString(this.model.viewId) - ? this.preferenceService.get(this.model.viewId, {}).pipe(first()) + ? this.preferenceService.get(this.model.viewId, {}, StorageType.Session).pipe(first()) : of({}); } private setViewPreferences(preferences: TableWidgetViewPreferences): void { if (isNonEmptyString(this.model.viewId)) { - this.preferenceService.set(this.model.viewId, preferences); + this.preferenceService.set(this.model.viewId, preferences, StorageType.Session); } } @@ -562,13 +563,15 @@ export class TableWidgetRendererComponent defaultPreferences: TableWidgetPreferences = TableWidgetRendererComponent.DEFAULT_PREFERENCES ): Observable { return isNonEmptyString(this.model.getId()) - ? this.preferenceService.get(this.model.getId()!, defaultPreferences).pipe(first()) + ? this.preferenceService + .get(this.model.getId()!, defaultPreferences, StorageType.Session) + .pipe(first()) : of(defaultPreferences); } private setPreferences(preferences: TableWidgetPreferences): void { if (isNonEmptyString(this.model.getId())) { - this.preferenceService.set(this.model.getId()!, preferences); + this.preferenceService.set(this.model.getId()!, preferences, StorageType.Session); } }