From 17891f5579e7f1fdc5b674de65649e4db2636e58 Mon Sep 17 00:00:00 2001 From: Dan Percic Date: Thu, 30 Nov 2023 15:06:02 +0200 Subject: [PATCH] RED-7989 update edit entity form --- apps/red-ui/src/app/guards/guards-utils.ts | 5 +++ .../src/app/guards/if-logged-in.guard.ts | 9 ++-- .../src/app/guards/if-not-logged-in.guard.ts | 17 ++++--- .../entity-info/entity-info.component.ts | 14 +++--- .../add-edit-entity.component.ts | 19 ++++---- .../entity-services/dictionary.service.ts | 44 +++++-------------- 6 files changed, 49 insertions(+), 59 deletions(-) create mode 100644 apps/red-ui/src/app/guards/guards-utils.ts diff --git a/apps/red-ui/src/app/guards/guards-utils.ts b/apps/red-ui/src/app/guards/guards-utils.ts new file mode 100644 index 000000000..250ecbab8 --- /dev/null +++ b/apps/red-ui/src/app/guards/guards-utils.ts @@ -0,0 +1,5 @@ +export function getRouteTenant() { + const pathParams = location.pathname.split('/').filter(Boolean); + const uiPathIndex = pathParams.indexOf('ui'); + return pathParams[uiPathIndex + 1]; +} diff --git a/apps/red-ui/src/app/guards/if-logged-in.guard.ts b/apps/red-ui/src/app/guards/if-logged-in.guard.ts index a043f7a6c..f92675e8a 100644 --- a/apps/red-ui/src/app/guards/if-logged-in.guard.ts +++ b/apps/red-ui/src/app/guards/if-logged-in.guard.ts @@ -1,5 +1,6 @@ import { inject } from '@angular/core'; import { ActivatedRouteSnapshot, Router } from '@angular/router'; +import { getRouteTenant } from '@guards/guards-utils'; import { AsyncGuard } from '@iqser/common-ui'; import { keycloakInitializer, KeycloakStatusService, TenantsService } from '@iqser/common-ui/lib/tenants'; import { LicenseService } from '@services/license.service'; @@ -25,9 +26,7 @@ export function ifLoggedIn(): AsyncGuard { const keycloakStatusService = inject(KeycloakStatusService); const keycloakInstance = keycloakService.getKeycloakInstance(); - const pathParams = location.pathname.split('/').filter(Boolean); - const uiPathIndex = pathParams.indexOf('ui'); - const tenant = pathParams[uiPathIndex + 1]; + const tenant = getRouteTenant(); const queryParams = new URLSearchParams(window.location.search); const username = queryParams.get('username'); const router = inject(Router); @@ -54,9 +53,7 @@ export function ifLoggedIn(): AsyncGuard { } } - const isLoggedIn = await keycloakService.isLoggedIn(); - - if (isLoggedIn) { + if (keycloakService.isLoggedIn()) { logger.info('[ROUTES] Is logged in, continuing'); return true; } diff --git a/apps/red-ui/src/app/guards/if-not-logged-in.guard.ts b/apps/red-ui/src/app/guards/if-not-logged-in.guard.ts index 2591aa847..25549b62c 100644 --- a/apps/red-ui/src/app/guards/if-not-logged-in.guard.ts +++ b/apps/red-ui/src/app/guards/if-not-logged-in.guard.ts @@ -1,17 +1,24 @@ -import { CanActivateFn, Router } from '@angular/router'; import { inject } from '@angular/core'; -import { NGXLogger } from 'ngx-logger'; +import { CanActivateFn, Router } from '@angular/router'; +import { getRouteTenant } from '@guards/guards-utils'; import { KeycloakService } from 'keycloak-angular'; +import { NGXLogger } from 'ngx-logger'; export function ifNotLoggedIn(): CanActivateFn { return async () => { const logger = inject(NGXLogger); const router = inject(Router); const keycloakService = inject(KeycloakService); + if (!keycloakService.getKeycloakInstance()) { + const tenant = getRouteTenant(); + if (tenant) { + logger.warn('[ROUTES] Tenant ' + tenant + ' found in route, redirecting to /main'); + await router.navigate(['main']); + return false; + } + } - const isLoggedIn = await keycloakService.isLoggedIn(); - - if (!isLoggedIn) { + if (!keycloakService.isLoggedIn()) { logger.info('[ROUTES] Not logged in, continuing to selected route'); return true; } diff --git a/apps/red-ui/src/app/modules/admin/screens/entities/screens/entity-info/entity-info.component.ts b/apps/red-ui/src/app/modules/admin/screens/entities/screens/entity-info/entity-info.component.ts index dac54c423..a98e7f510 100644 --- a/apps/red-ui/src/app/modules/admin/screens/entities/screens/entity-info/entity-info.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/entities/screens/entity-info/entity-info.component.ts @@ -1,13 +1,13 @@ import { ChangeDetectionStrategy, Component, HostListener, ViewChild } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { getConfig, IconButtonTypes } from '@iqser/common-ui'; +import { IqserEventTarget } from '@iqser/common-ui/lib/utils'; import { Dictionary, DOSSIER_TEMPLATE_ID, ENTITY_TYPE } from '@red/domain'; import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service'; -import { ActivatedRoute } from '@angular/router'; -import { getCurrentUser } from '@users/user.service'; import { PermissionsService } from '@services/permissions.service'; import { AddEditEntityComponent } from '@shared/components/add-edit-entity/add-edit-entity.component'; -import { getConfig, IconButtonTypes } from '@iqser/common-ui'; +import { getCurrentUser } from '@users/user.service'; import { Observable } from 'rxjs'; -import { IqserEventTarget } from '@iqser/common-ui/lib/utils'; @Component({ selector: 'redaction-entity-info', @@ -23,7 +23,11 @@ export class EntityInfoComponent { readonly config = getConfig(); readonly iconButtonTypes = IconButtonTypes; - constructor(route: ActivatedRoute, dictionariesMapService: DictionariesMapService, readonly permissionsService: PermissionsService) { + constructor( + route: ActivatedRoute, + dictionariesMapService: DictionariesMapService, + readonly permissionsService: PermissionsService, + ) { this.dossierTemplateId = route.parent.snapshot.paramMap.get(DOSSIER_TEMPLATE_ID); const entityType = route.parent.snapshot.paramMap.get(ENTITY_TYPE); this.entity$ = dictionariesMapService.watch$(this.dossierTemplateId, entityType); diff --git a/apps/red-ui/src/app/modules/shared/components/add-edit-entity/add-edit-entity.component.ts b/apps/red-ui/src/app/modules/shared/components/add-edit-entity/add-edit-entity.component.ts index d4f38a378..95d951bd8 100644 --- a/apps/red-ui/src/app/modules/shared/components/add-edit-entity/add-edit-entity.component.ts +++ b/apps/red-ui/src/app/modules/shared/components/add-edit-entity/add-edit-entity.component.ts @@ -6,7 +6,7 @@ import { Dictionary, IDictionary } from '@red/domain'; import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service'; import { DictionaryService } from '@services/entity-services/dictionary.service'; import { toSnakeCase } from '@utils/functions'; -import { firstValueFrom, Observable } from 'rxjs'; +import { Observable } from 'rxjs'; import { map, startWith } from 'rxjs/operators'; const REDACTION_FIELDS = ['defaultReason']; @@ -20,7 +20,7 @@ interface Color { } @Component({ - selector: 'redaction-add-edit-entity [entity] [dossierTemplateId]', + selector: 'redaction-add-edit-entity', templateUrl: './add-edit-entity.component.html', styleUrls: ['./add-edit-entity.component.scss'], }) @@ -82,16 +82,13 @@ export class AddEditEntityComponent extends BaseFormComponent implements OnInit async save(): Promise { this._loadingService.start(); const dictionary = this.#formToObject(); + const isEditMode = !!this.entity; try { - if (this.entity) { - // edit mode - await firstValueFrom( - this._dictionaryService.updateDictionary(dictionary, this.dossierTemplateId, dictionary.type, this.dossierId), - ); + if (isEditMode) { + await this._dictionaryService.update(dictionary, this.dossierTemplateId, dictionary.type, this.dossierId); this._toaster.success(_('add-edit-entity.success.edit')); } else { - // create mode - await firstValueFrom(this._dictionaryService.addDictionary({ ...dictionary, dossierTemplateId: this.dossierTemplateId })); + await this._dictionaryService.add({ ...dictionary, dossierTemplateId: this.dossierTemplateId }); this._toaster.success(_('add-edit-entity.success.create')); } this.initialFormValue = this.form.getRawValue(); @@ -149,7 +146,7 @@ export class AddEditEntityComponent extends BaseFormComponent implements OnInit caseSensitive: [{ value: !this.entity?.caseInsensitive, disabled: this.#isSystemManaged }], manageEntriesInDictionaryEditorOnly: [ { - value: !this.entity?.addToDictionaryAction, + value: this.entity?.addToDictionaryAction, disabled: this.#isSystemManaged && !this.#isDossierRedaction, }, ], @@ -216,7 +213,7 @@ export class AddEditEntityComponent extends BaseFormComponent implements OnInit #formToObject(): IDictionary { // Fields which aren't set for hints, need additional check - const addToDictionaryAction = !this.form.get('manageEntriesInDictionaryEditorOnly')?.value; + const addToDictionaryAction = !!this.form.get('manageEntriesInDictionaryEditorOnly')?.value; const hasDictionary = !!this.form.get('hasDictionary')?.value; const dossierDictionaryOnly = !!this.form.get('dossierDictionaryOnly')?.value; diff --git a/apps/red-ui/src/app/services/entity-services/dictionary.service.ts b/apps/red-ui/src/app/services/entity-services/dictionary.service.ts index 7b4f4f4c1..af917e439 100644 --- a/apps/red-ui/src/app/services/entity-services/dictionary.service.ts +++ b/apps/red-ui/src/app/services/entity-services/dictionary.service.ts @@ -39,10 +39,6 @@ export class DictionaryService extends EntitiesService return firstValueFrom(this._getOne([type, dossierTemplateId], this._defaultModelPath, queryParams)); } - /** - * Deletes entry types - */ - deleteDictionaries(dictionaryIds: List, dossierTemplateId: string, dossierId?: string): Observable { const queryParams = dossierId ? [{ key: 'dossierId', value: dossierId }] : undefined; const url = `${this._defaultModelPath}/type/${dossierTemplateId}/delete`; @@ -52,10 +48,6 @@ export class DictionaryService extends EntitiesService ); } - /** - * Retrieve all entry types - */ - getAllDictionaries(dossierTemplateId: string, dossierId?: string) { const queryParams = dossierId ? [{ key: 'dossierId', value: dossierId }] : undefined; return this._getOne<{ types: IDictionary[] }>(['type', dossierTemplateId], this._defaultModelPath, queryParams); @@ -65,27 +57,27 @@ export class DictionaryService extends EntitiesService * Updates colors, hint and caseInsensitive of an entry type. */ - updateDictionary(body: IUpdateDictionary, dossierTemplateId: string, type: string, dossierId?: string): Observable { + async update(body: IUpdateDictionary, dossierTemplateId: string, type: string, dossierId?: string): Promise { const url = `${this._defaultModelPath}/type/${type}/${dossierTemplateId}`; const queryParams = dossierId ? [{ key: 'dossierId', value: dossierId }] : undefined; - return this._post(body, url, queryParams).pipe( + const request = this._post(body, url, queryParams).pipe( catchError((error: unknown) => this.#addUpdateDictionaryErrorToast(error)), switchMap(() => this.loadDictionaryDataForDossierTemplate(dossierTemplateId)), switchMap(() => this._dossierTemplateStatsService.getFor([dossierTemplateId])), ); + + return await firstValueFrom(request); } - /** - * Creates entry type with colors, hint and caseInsensitive - */ - - addDictionary(dictionary: IDictionary, dossierId?: string): Observable { + async add(dictionary: IDictionary, dossierId?: string): Promise { const queryParams = dossierId ? [{ key: 'dossierId', value: dossierId }] : undefined; - return this._post(dictionary, `${this._defaultModelPath}/type`, queryParams).pipe( + const request = this._post(dictionary, `${this._defaultModelPath}/type`, queryParams).pipe( catchError((error: unknown) => this.#addUpdateDictionaryErrorToast(error)), switchMap(() => this.loadDictionaryDataForDossierTemplate(dictionary.dossierTemplateId)), switchMap(() => this._dossierTemplateStatsService.getFor([dictionary.dossierTemplateId])), ); + + return await firstValueFrom(request); } async saveEntries( @@ -118,10 +110,10 @@ export class DictionaryService extends EntitiesService try { if (deletedEntries.length) { - await this._deleteEntries(deletedEntries, dossierTemplateId, type, dictionaryEntryType, dossierId); + await this.#deleteEntries(deletedEntries, dossierTemplateId, type, dictionaryEntryType, dossierId); } if (entriesToAdd.length) { - await this._addEntries(entriesToAdd, dossierTemplateId, type, dictionaryEntryType, dossierId); + await this.#addEntries(entriesToAdd, dossierTemplateId, type, dictionaryEntryType, dossierId); } if (showToast) { @@ -284,13 +276,7 @@ export class DictionaryService extends EntitiesService * Add dictionary entries with entry type. */ - private _addEntries( - entries: List, - dossierTemplateId: string, - type: string, - dictionaryEntryType: DictionaryEntryType, - dossierId: string, - ) { + #addEntries(entries: List, dossierTemplateId: string, type: string, dictionaryEntryType: DictionaryEntryType, dossierId: string) { const queryParams: List = [ { key: 'dossierId', value: dossierId }, { key: 'dictionaryEntryType', value: dictionaryEntryType }, @@ -303,13 +289,7 @@ export class DictionaryService extends EntitiesService * Delete dictionary entries with entry type. */ - private _deleteEntries( - entries: List, - dossierTemplateId: string, - type: string, - dictionaryEntryType: DictionaryEntryType, - dossierId: string, - ) { + #deleteEntries(entries: List, dossierTemplateId: string, type: string, dictionaryEntryType: DictionaryEntryType, dossierId: string) { const queryParams = [ { key: 'dossierId', value: dossierId }, { key: 'dictionaryEntryType', value: dictionaryEntryType },