From db3526df4832aae3746c223d0f39642db3ceabac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20B=C3=BChler?= Date: Wed, 15 Sep 2021 14:15:19 +0200 Subject: [PATCH] feat(org-selector): Remember the last selected org and order the list. (#2343) This remembers the last selected org in localstorage instead of session storage to improve the UX. Furthermore, the list of organizations is ordered by name instead of just the returned result set. --- console/src/app/app.component.ts | 4 +-- console/src/app/services/grpc-auth.service.ts | 7 ++--- console/src/app/services/storage.service.ts | 26 ++++++++++++++----- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/console/src/app/app.component.ts b/console/src/app/app.component.ts index 15a7a2717..bc6d37a53 100644 --- a/console/src/app/app.component.ts +++ b/console/src/app/app.component.ts @@ -10,7 +10,6 @@ import { ActivatedRoute, Router, RouterOutlet } from '@angular/router'; import { LangChangeEvent, TranslateService } from '@ngx-translate/core'; import { BehaviorSubject, from, Observable, of, Subject } from 'rxjs'; import { catchError, debounceTime, finalize, map, take, takeUntil } from 'rxjs/operators'; - import { accountCard, adminLineAnimation, navAnimations, routeAnimations, toolbarAnimation } from './animations'; import { TextQueryMethod } from './proto/generated/zitadel/object_pb'; import { Org, OrgNameQuery, OrgQuery } from './proto/generated/zitadel/org_pb'; @@ -22,6 +21,7 @@ import { ManagementService } from './services/mgmt.service'; import { ThemeService } from './services/theme.service'; import { UpdateService } from './services/update.service'; + @Component({ selector: 'app-root', templateUrl: './app.component.html', @@ -307,7 +307,7 @@ export class AppComponent implements OnDestroy { this.orgLoading$.next(true); this.orgs$ = from(this.authService.listMyProjectOrgs(10, 0, query ? [query] : undefined)).pipe( map(resp => { - return resp.resultList; + return resp.resultList.sort((left, right) => left.name.localeCompare(right.name)); }), catchError(() => of([])), finalize(() => { diff --git a/console/src/app/services/grpc-auth.service.ts b/console/src/app/services/grpc-auth.service.ts index 19e3e88a0..6f0696448 100644 --- a/console/src/app/services/grpc-auth.service.ts +++ b/console/src/app/services/grpc-auth.service.ts @@ -82,7 +82,8 @@ import { ListQuery } from '../proto/generated/zitadel/object_pb'; import { Org, OrgQuery } from '../proto/generated/zitadel/org_pb'; import { Gender, MembershipQuery, User, WebAuthNVerification } from '../proto/generated/zitadel/user_pb'; import { GrpcService } from './grpc.service'; -import { StorageKey, StorageService } from './storage.service'; +import { StorageKey, StorageLocation, StorageService } from './storage.service'; + @Injectable({ @@ -163,7 +164,7 @@ export class GrpcAuthService { this.cachedOrgs = orgs; } - const org = this.storage.getItem(StorageKey.organization); + const org = this.storage.getItem(StorageKey.organization, StorageLocation.local); if (org && orgs.find(tmp => tmp.id === org.id)) { return org; } @@ -186,7 +187,7 @@ export class GrpcAuthService { } public setActiveOrg(org: Org.AsObject): void { - this.storage.setItem(StorageKey.organization, org); + this.storage.setItem(StorageKey.organization, org, StorageLocation.local); this._activeOrgChanged.next(org); } diff --git a/console/src/app/services/storage.service.ts b/console/src/app/services/storage.service.ts index 25d60901d..51fa796a1 100644 --- a/console/src/app/services/storage.service.ts +++ b/console/src/app/services/storage.service.ts @@ -7,29 +7,36 @@ const STORAGE_PREFIX = 'zitadel'; providedIn: 'root', }) export class StorageService implements OAuthStorage { - private storage: Storage = window.sessionStorage; + private sessionStorage: Storage = window.sessionStorage; + private localStorage: Storage = window.localStorage; constructor() { } - public setItem(key: string, value: TValue): void { - this.storage.setItem(this.getPrefixedKey(key), JSON.stringify(value)); + public setItem(key: string, value: TValue, location: StorageLocation = StorageLocation.session): void { + this.getStorage(location).setItem(this.getPrefixedKey(key), JSON.stringify(value)); } - public getItem(key: string): TResult | null { - const result = this.storage.getItem(this.getPrefixedKey(key)); + public getItem(key: string, location: StorageLocation = StorageLocation.session): TResult | null { + const result = this.getStorage(location).getItem(this.getPrefixedKey(key)); if (result) { return JSON.parse(result); } return null; } - public removeItem(key: string): void { - this.storage.removeItem(this.getPrefixedKey(key)); + public removeItem(key: string, location: StorageLocation = StorageLocation.session): void { + this.getStorage(location).removeItem(this.getPrefixedKey(key)); } public getPrefixedKey(key: string): string { return `${STORAGE_PREFIX}:${key}`; } + + private getStorage(location: StorageLocation): Storage { + return location === StorageLocation.session + ? this.sessionStorage + : this.localStorage; + } } export class StorageConfig { @@ -40,3 +47,8 @@ export class StorageConfig { export enum StorageKey { organization = 'organization', } + +export enum StorageLocation { + session, + local, +}