From 04a69f5e689cf4d90efbd550cbf6938ae7c0a200 Mon Sep 17 00:00:00 2001 From: Dan Percic Date: Tue, 8 Aug 2023 11:28:38 +0300 Subject: [PATCH] remove emails from stored tenants --- src/lib/tenants/services/tenants.service.ts | 31 +++++++---------- .../tenant-select.component.html | 6 ++-- .../tenant-select.component.scss | 28 +++++++++++++++ .../tenant-select/tenant-select.component.ts | 34 +++++++++++-------- src/lib/tenants/tenants.module.ts | 24 +++++++------ 5 files changed, 76 insertions(+), 47 deletions(-) diff --git a/src/lib/tenants/services/tenants.service.ts b/src/lib/tenants/services/tenants.service.ts index 54ebee1..9fdbfd0 100644 --- a/src/lib/tenants/services/tenants.service.ts +++ b/src/lib/tenants/services/tenants.service.ts @@ -1,11 +1,10 @@ import { inject, Injectable, signal } from '@angular/core'; +import dayjs from 'dayjs'; import { NGXLogger } from 'ngx-logger'; import { List } from '../../utils'; -import dayjs from 'dayjs'; export interface IStoredTenantId { readonly tenantId: string; - readonly email: string; readonly created: string; } @@ -24,7 +23,7 @@ export class TenantsService { removeItem: localStorage.removeItem.bind(localStorage), key: localStorage.key.bind(localStorage), }; - readonly #activeTenantId = signal(''); + readonly #activeTenantId = signal(''); protected readonly _serviceName: string = 'tenant-user-management'; get activeTenantId() { @@ -37,15 +36,10 @@ export class TenantsService { return true; } - storeTenant(emailOrUsername: string) { - if (!emailOrUsername) { - this.#logger.warn('[TENANTS] Email or username is null, skip storing'); - return; - } - + storeTenant() { const storedTenants = this.getStoredTenants(); const activeTenantId = this.#activeTenantId(); - const existing = storedTenants.find(s => s.email === emailOrUsername && s.tenantId === activeTenantId); + const existing = storedTenants.find(s => s.tenantId === activeTenantId); if (existing) { this.#logger.info('[TENANTS] Stored tenant exists: ', storedTenants); return; @@ -56,7 +50,7 @@ export class TenantsService { return; } - storedTenants.push({ tenantId: activeTenantId, email: emailOrUsername, created: new Date().toISOString() }); + storedTenants.push({ tenantId: activeTenantId, created: new Date().toISOString() }); this.#storageReference.setItem(STORED_TENANTS_KEY, JSON.stringify(storedTenants)); this.#logger.info('[TENANTS] Stored tenants: ', storedTenants); } @@ -72,8 +66,8 @@ export class TenantsService { const diff = date2.diff(date1, 'days'); const is90DaysOld = diff >= 90; if (is90DaysOld) { - this.#logger.warn(`[TENANTS] Saved tenant ${s.tenantId} - ${s.email} is 90 days old, delete it`); - this.removeStored(s.email); + this.#logger.warn(`[TENANTS] Saved tenant ${s.tenantId} is 90 days old, delete it`); + this.removeStored(s.tenantId); continue; } @@ -83,17 +77,16 @@ export class TenantsService { return validStoredTenants; } - removeStored(email: string) { - if (!email) { - this.#logger.warn('[TENANTS] Email is null, skip storing'); + removeStored(tenantId: string) { + if (!tenantId) { + this.#logger.warn('[TENANTS] Tenant Id is null, skip removing'); return; } const storedTenants = this.getStoredTenants(); - const activeTenantId = this.#activeTenantId(); - const existing = storedTenants.find(s => s.email === email && s.tenantId === activeTenantId); + const existing = storedTenants.find(s => s.tenantId === tenantId); if (!existing) { - this.#logger.info('[TENANTS] No stored tenant for ', email); + this.#logger.info('[TENANTS] No stored tenant for ', tenantId); return; } diff --git a/src/lib/tenants/tenant-select/tenant-select.component.html b/src/lib/tenants/tenant-select/tenant-select.component.html index 7637f3c..2916df5 100644 --- a/src/lib/tenants/tenant-select/tenant-select.component.html +++ b/src/lib/tenants/tenant-select/tenant-select.component.html @@ -17,7 +17,7 @@
@@ -25,10 +25,12 @@
{{ stored.tenantId }} - {{ stored.email }}
+
+ +
diff --git a/src/lib/tenants/tenant-select/tenant-select.component.scss b/src/lib/tenants/tenant-select/tenant-select.component.scss index 0b7ed9e..1734e66 100644 --- a/src/lib/tenants/tenant-select/tenant-select.component.scss +++ b/src/lib/tenants/tenant-select/tenant-select.component.scss @@ -23,6 +23,13 @@ .stored-tenant-card { width: 450px; height: 90px; + position: relative; + + &:hover { + .remove { + display: flex; + } + } } .card { @@ -66,3 +73,24 @@ line-height: 29px; font-family: 'Inter', sans-serif; } + +.remove { + display: none; + + width: 16px; + height: 16px; + border-radius: 50%; + background-color: var(--iqser-accent); + color: var(--iqser-white); + position: absolute; + right: -8px; + top: -8px; + line-height: 6px; + justify-content: center; + align-items: center; + + mat-icon { + width: 6px; + height: 8px; + } +} diff --git a/src/lib/tenants/tenant-select/tenant-select.component.ts b/src/lib/tenants/tenant-select/tenant-select.component.ts index 7453227..4909b81 100644 --- a/src/lib/tenants/tenant-select/tenant-select.component.ts +++ b/src/lib/tenants/tenant-select/tenant-select.component.ts @@ -1,14 +1,14 @@ import { ChangeDetectionStrategy, Component, inject, Input } from '@angular/core'; import { FormBuilder, Validators } from '@angular/forms'; -import { TenantsService } from '../services'; -import { LoadingService } from '../../loading'; import { Title } from '@angular/platform-browser'; import { KeycloakService } from 'keycloak-angular'; +import { NGXLogger } from 'ngx-logger'; +import { LoadingService } from '../../loading'; +import { getConfig } from '../../services'; import { BASE_HREF } from '../../utils'; import { getKeycloakOptions } from '../keycloak-initializer'; +import { IStoredTenantId, TenantsService } from '../services'; import { KeycloakStatusService } from '../services/keycloak-status.service'; -import { NGXLogger } from 'ngx-logger'; -import { getConfig } from '../../services'; @Component({ templateUrl: './tenant-select.component.html', @@ -18,9 +18,8 @@ import { getConfig } from '../../services'; export class TenantSelectComponent { protected readonly baseHref = inject(BASE_HREF); protected readonly logger = inject(NGXLogger); - protected readonly storedTenants = inject(TenantsService) - .getStoredTenants() - .sort((a, b) => a.tenantId.localeCompare(b.tenantId)); + protected readonly tenantsService = inject(TenantsService); + protected storedTenants: IStoredTenantId[] = []; protected readonly titleService = inject(Title); protected readonly config = getConfig(); protected readonly loadingService = inject(LoadingService); @@ -32,6 +31,10 @@ export class TenantSelectComponent { }); @Input() isLoggedOut = false; + constructor() { + this.#loadStoredTenants(); + } + updateTenantSelection() { const tenantId = this.form.controls.tenantId.value; if (!tenantId) { @@ -39,12 +42,10 @@ export class TenantSelectComponent { } this.loadingService.start(); - - const email = this.#getEmail(tenantId); - return this.select(tenantId, email); + return this.select(tenantId); } - async select(tenantId: string, email?: string) { + async select(tenantId: string) { try { this.logger.info('[KEYCLOAK] Initializing keycloak for tenant', tenantId); await this.keycloakService.init(getKeycloakOptions(this.baseHref, this.config, tenantId)); @@ -55,15 +56,18 @@ export class TenantSelectComponent { const url = this.keycloakService.getKeycloakInstance().createLoginUrl({ redirectUri: this.keycloakStatusService.createLoginUrl(tenantId), idpHint: this.config.OAUTH_IDP_HINT, - loginHint: email ?? undefined, }); this.logger.info('[KEYCLOAK] Init succeeded. Logout and redirect to', url); return this.keycloakService.logout(url); } - #getEmail(tenantId: string) { - const existingStored = this.storedTenants.filter(s => s.tenantId === tenantId); - return existingStored.length === 1 ? existingStored[0].email : undefined; + removeStored(tenantId: string) { + this.tenantsService.removeStored(tenantId); + this.#loadStoredTenants(); + } + + #loadStoredTenants() { + this.storedTenants = this.tenantsService.getStoredTenants().sort((a, b) => a.tenantId.localeCompare(b.tenantId)); } } diff --git a/src/lib/tenants/tenants.module.ts b/src/lib/tenants/tenants.module.ts index 7fedf45..104c679 100644 --- a/src/lib/tenants/tenants.module.ts +++ b/src/lib/tenants/tenants.module.ts @@ -1,20 +1,21 @@ -import { ModuleWithProviders, NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { TranslateModule } from '@ngx-translate/core'; +import { HTTP_INTERCEPTORS } from '@angular/common/http'; +import { ModuleWithProviders, NgModule } from '@angular/core'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; import { MatDialogModule } from '@angular/material/dialog'; -import { CircleButtonComponent, IconButtonComponent } from '../buttons'; -import { TenantSelectComponent } from './tenant-select/tenant-select.component'; +import { MatIconModule } from '@angular/material/icon'; import { MatInputModule } from '@angular/material/input'; import { MatSelectModule } from '@angular/material/select'; -import { ReactiveFormsModule } from '@angular/forms'; -import { TenantIdInterceptor, TenantIdResponseInterceptor } from './services'; -import { HTTP_INTERCEPTORS } from '@angular/common/http'; -import { MatCardModule } from '@angular/material/card'; +import { RouterLink } from '@angular/router'; +import { TranslateModule } from '@ngx-translate/core'; +import { CircleButtonComponent, IconButtonComponent } from '../buttons'; +import { StopPropagationDirective } from '../directives'; import { LogoComponent } from '../shared'; import { SpacerComponent } from '../shared/spacer/spacer.component'; -import { MatIconModule } from '@angular/material/icon'; -import { MatButtonModule } from '@angular/material/button'; -import { RouterLink } from '@angular/router'; +import { TenantIdInterceptor, TenantIdResponseInterceptor } from './services'; +import { TenantSelectComponent } from './tenant-select/tenant-select.component'; @NgModule({ declarations: [TenantSelectComponent], @@ -33,6 +34,7 @@ import { RouterLink } from '@angular/router'; MatIconModule, MatButtonModule, RouterLink, + StopPropagationDirective, ], exports: [TenantSelectComponent], })