diff --git a/apps/isa-app/src/app/store/root-state.service.ts b/apps/isa-app/src/app/store/root-state.service.ts index 59e437a85..32c99dc3d 100644 --- a/apps/isa-app/src/app/store/root-state.service.ts +++ b/apps/isa-app/src/app/store/root-state.service.ts @@ -1,18 +1,18 @@ -import { Injectable } from '@angular/core'; -import { Logger, LogLevel } from '@core/logger'; -import { Store } from '@ngrx/store'; -import { debounceTime, switchMap, takeUntil } from 'rxjs/operators'; -import { RootState } from './root.state'; -import packageInfo from 'packageJson'; -import { environment } from '../../environments/environment'; -import { Subject } from 'rxjs'; -import { AuthService } from '@core/auth'; -import { injectStorage, UserStorageProvider } from '@isa/core/storage'; -import { isEqual } from 'lodash'; +import { Injectable } from "@angular/core"; +import { Logger, LogLevel } from "@core/logger"; +import { Store } from "@ngrx/store"; +import { debounceTime, switchMap, takeUntil } from "rxjs/operators"; +import { RootState } from "./root.state"; +import packageInfo from "packageJson"; +import { environment } from "../../environments/environment"; +import { Subject } from "rxjs"; +import { AuthService } from "@core/auth"; +import { injectStorage, UserStorageProvider } from "@isa/core/storage"; +import { isEqual } from "lodash"; -@Injectable({ providedIn: 'root' }) +@Injectable({ providedIn: "root" }) export class RootStateService { - static LOCAL_STORAGE_KEY = 'ISA_APP_INITIALSTATE'; + static LOCAL_STORAGE_KEY = "ISA_APP_INITIALSTATE"; #storage = injectStorage(UserStorageProvider); @@ -29,14 +29,17 @@ export class RootStateService { ); } - window['clearUserState'] = () => { + window["clearUserState"] = () => { this.clear(); }; } async init() { await this.load(); - this._store.dispatch({ type: 'HYDRATE', payload: RootStateService.LoadFromLocalStorage() }); + this._store.dispatch({ + type: "HYDRATE", + payload: RootStateService.LoadFromLocalStorage(), + }); this.initSave(); } @@ -50,14 +53,10 @@ export class RootStateService { const data = { ...state, version: packageInfo.version, - sub: this._authService.getClaimByKey('sub'), + sub: this._authService.getClaimByKey("sub"), }; RootStateService.SaveToLocalStorageRaw(JSON.stringify(data)); - return this.#storage.set('state', { - ...state, - version: packageInfo.version, - sub: this._authService.getClaimByKey('sub'), - }); + return this.#storage.set("state", data); }), ) .subscribe(); @@ -68,7 +67,7 @@ export class RootStateService { */ async load(): Promise { try { - const res = await this.#storage.get('state'); + const res = await this.#storage.get("state"); const storageContent = RootStateService.LoadFromLocalStorageRaw(); @@ -88,7 +87,7 @@ export class RootStateService { async clear() { try { this._cancelSave.next(); - await this.#storage.clear('state'); + await this.#storage.clear("state"); await new Promise((resolve) => setTimeout(resolve, 100)); RootStateService.RemoveFromLocalStorage(); await new Promise((resolve) => setTimeout(resolve, 100)); @@ -112,7 +111,7 @@ export class RootStateService { try { return JSON.parse(raw); } catch (error) { - console.error('Error parsing local storage:', error); + console.error("Error parsing local storage:", error); this.RemoveFromLocalStorage(); } } diff --git a/libs/core/storage/src/lib/user.storage-provider.ts b/libs/core/storage/src/lib/user.storage-provider.ts index 04f330e05..9dc3be7ed 100644 --- a/libs/core/storage/src/lib/user.storage-provider.ts +++ b/libs/core/storage/src/lib/user.storage-provider.ts @@ -1,27 +1,42 @@ -import { inject, Injectable } from '@angular/core'; -import { StorageProvider } from './storage-provider'; -import { UserStateService } from '@generated/swagger/isa-api'; -import { firstValueFrom, map, shareReplay } from 'rxjs'; +import { inject, Injectable } from "@angular/core"; +import { StorageProvider } from "./storage-provider"; +import { UserStateService } from "@generated/swagger/isa-api"; +import { catchError, firstValueFrom, map, of } from "rxjs"; +import { isEmpty } from "lodash"; -@Injectable({ providedIn: 'root' }) +@Injectable({ providedIn: "root" }) export class UserStorageProvider implements StorageProvider { #userStateService = inject(UserStateService); private state$ = this.#userStateService.UserStateGetUserState().pipe( map((res) => { - if (res.result?.content) { + if (res?.result?.content) { return JSON.parse(res.result.content); } return {}; }), - shareReplay(1), + catchError((err) => { + console.warn( + "No UserStateGetUserState found, returning empty object:", + err, + ); + return of({}); // Return empty state fallback + }), + // shareReplay(1), #5249, #5270 Würde beim Fehlerfall den fehlerhaften Zustand behalten + // Aktuell wird nun jedes mal 2 mal der UserState aufgerufen (GET + POST) + // Damit bei der set Funktion immer der aktuelle Zustand verwendet wird ); - async set(key: string, value: unknown): Promise { + async set(key: string, value: Record): Promise { const current = await firstValueFrom(this.state$); - firstValueFrom( + const content = + current && !isEmpty(current) + ? { ...current, [key]: value } + : { [key]: value }; + + await firstValueFrom( this.#userStateService.UserStateSetUserState({ - content: JSON.stringify({ ...current, [key]: value }), + content: JSON.stringify(content), }), ); } @@ -32,7 +47,6 @@ export class UserStorageProvider implements StorageProvider { } async clear(key: string): Promise { - const current = await firstValueFrom(this.state$); delete current[key]; firstValueFrom(this.#userStateService.UserStateResetUserState());