diff --git a/apps/red-ui/src/app/app.component.html b/apps/red-ui/src/app/app.component.html index 7115e458f..3ac47a12a 100644 --- a/apps/red-ui/src/app/app.component.html +++ b/apps/red-ui/src/app/app.component.html @@ -1,4 +1,4 @@ diff --git a/apps/red-ui/src/app/app.component.ts b/apps/red-ui/src/app/app.component.ts index 711e2bffb..8660f6cb6 100644 --- a/apps/red-ui/src/app/app.component.ts +++ b/apps/red-ui/src/app/app.component.ts @@ -1,6 +1,5 @@ import { Component } from '@angular/core'; -import { AppLoadStateService } from '@services/app-load-state.service'; -import { RouterHistoryService } from '@services/router-history.service'; +import { LoadingService } from '@services/loading.service'; @Component({ selector: 'redaction-root', @@ -8,8 +7,5 @@ import { RouterHistoryService } from '@services/router-history.service'; styleUrls: ['./app.component.scss'] }) export class AppComponent { - constructor( - public appLoadStateService: AppLoadStateService, - private readonly _routerHistoryService: RouterHistoryService - ) {} + constructor(readonly loadingService: LoadingService) {} } diff --git a/apps/red-ui/src/app/guards/composite-route.guard.ts b/apps/red-ui/src/app/guards/composite-route.guard.ts index 131502de7..174b2632c 100644 --- a/apps/red-ui/src/app/guards/composite-route.guard.ts +++ b/apps/red-ui/src/app/guards/composite-route.guard.ts @@ -1,26 +1,19 @@ -import { - ActivatedRouteSnapshot, - CanActivate, - Router, - RouterStateSnapshot, - UrlTree -} from '@angular/router'; +import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot, UrlTree } from '@angular/router'; import { Injectable, Injector } from '@angular/core'; import { from, of } from 'rxjs'; -import { AppLoadStateService } from '@services/app-load-state.service'; +import { LoadingService } from '@services/loading.service'; @Injectable({ providedIn: 'root' }) export class CompositeRouteGuard implements CanActivate { constructor( - protected readonly _router: Router, protected readonly _injector: Injector, - private readonly _appLoadStateService: AppLoadStateService + private readonly _loadingService: LoadingService ) {} async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise { - this._appLoadStateService.pushLoadingEvent(true); + this._loadingService.start(); const routeGuards = route.data.routeGuards; @@ -40,13 +33,13 @@ export class CompositeRouteGuard implements CanActivate { const result = await canActivateResult.toPromise(); if (!result) { - this._appLoadStateService.pushLoadingEvent(false); + this._loadingService.stop(); return false; } } } - this._appLoadStateService.pushLoadingEvent(false); + this._loadingService.stop(); return true; } diff --git a/apps/red-ui/src/app/modules/admin/components/dossier-template-actions/dossier-template-actions.component.ts b/apps/red-ui/src/app/modules/admin/components/dossier-template-actions/dossier-template-actions.component.ts index 4136e2197..9d2710da0 100644 --- a/apps/red-ui/src/app/modules/admin/components/dossier-template-actions/dossier-template-actions.component.ts +++ b/apps/red-ui/src/app/modules/admin/components/dossier-template-actions/dossier-template-actions.component.ts @@ -40,18 +40,16 @@ export class DossierTemplateActionsComponent { ); } - openDeleteDossierTemplateDialog($event: any) { - this._dialogService.openDeleteDossierTemplateDialog( - $event, - this.dossierTemplate, - async () => { - await this._appStateService.loadAllDossierTemplates(); - await this._appStateService.loadDictionaryData(); - await this._router.navigate(['main', 'admin']); - if (this.loadDossierTemplatesData) { - this.loadDossierTemplatesData.emit(); - } + openDeleteDossierTemplateDialog($event?: MouseEvent) { + $event?.stopPropagation(); + + this._dialogService.openDeleteDossierTemplateDialog(this.dossierTemplate, async () => { + await this._appStateService.loadAllDossierTemplates(); + await this._appStateService.loadDictionaryData(); + await this._router.navigate(['main', 'admin']); + if (this.loadDossierTemplatesData) { + this.loadDossierTemplatesData.emit(); } - ); + }); } } diff --git a/apps/red-ui/src/app/modules/admin/dialogs/add-edit-dictionary-dialog/add-edit-dictionary-dialog.component.html b/apps/red-ui/src/app/modules/admin/dialogs/add-edit-dictionary-dialog/add-edit-dictionary-dialog.component.html index 459ff3d45..88843ac2c 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/add-edit-dictionary-dialog/add-edit-dictionary-dialog.component.html +++ b/apps/red-ui/src/app/modules/admin/dialogs/add-edit-dictionary-dialog/add-edit-dictionary-dialog.component.html @@ -1,19 +1,14 @@
- {{ - (dictionary ? 'add-edit-dictionary.title.edit' : 'add-edit-dictionary.title.new') - | translate: { name: dictionary?.type | humanize } - }} + {{ dialogHeader }}
- -
- - {{ dictionary.label }} -
-
+
+ + {{ dictionary.label }} +
@@ -53,13 +48,7 @@ [style.background]="dictionaryForm.get('hexColor').value" class="input-icon" > - +
@@ -81,11 +70,11 @@
- {{ 'add-edit-dictionary.form.redaction' | translate }} + {{ 'add-edit-dictionary.form.redaction' | translate }} + - {{ 'add-edit-dictionary.form.hint' | translate }} + {{ 'add-edit-dictionary.form.hint' | translate }} +
diff --git a/apps/red-ui/src/app/modules/admin/dialogs/add-edit-dictionary-dialog/add-edit-dictionary-dialog.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/add-edit-dictionary-dialog/add-edit-dictionary-dialog.component.ts index e435c3a0f..9f3c732e1 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/add-edit-dictionary-dialog/add-edit-dictionary-dialog.component.ts +++ b/apps/red-ui/src/app/modules/admin/dialogs/add-edit-dictionary-dialog/add-edit-dictionary-dialog.component.ts @@ -1,5 +1,4 @@ import { Component, Inject } from '@angular/core'; -import { AppStateService } from '@state/app-state.service'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { DictionaryControllerService, TypeValue } from '@redaction/red-ui-http'; @@ -7,6 +6,7 @@ import { Observable } from 'rxjs'; import { NotificationService, NotificationType } from '@services/notification.service'; import { TranslateService } from '@ngx-translate/core'; import { TypeValueWrapper } from '../../../../models/file/type-value.wrapper'; +import { humanize } from '../../../../utils/functions'; @Component({ selector: 'redaction-add-edit-dictionary-dialog', @@ -20,17 +20,16 @@ export class AddEditDictionaryDialogComponent { constructor( private readonly _dictionaryControllerService: DictionaryControllerService, - private readonly _appStateService: AppStateService, private readonly _formBuilder: FormBuilder, private readonly _notificationService: NotificationService, private readonly _translateService: TranslateService, - public dialogRef: MatDialogRef, + private readonly _dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) - public data: { dictionary: TypeValueWrapper; dossierTemplateId: string } + private readonly _data: { dictionary: TypeValueWrapper; dossierTemplateId: string } ) { - this.dictionary = data.dictionary; - this._dossierTemplateId = data.dossierTemplateId; - this.dictionaryForm = this._formBuilder.group({ + this.dictionary = _data.dictionary; + this._dossierTemplateId = _data.dossierTemplateId; + this.dictionaryForm = _formBuilder.group({ type: [this.dictionary?.type, [Validators.required, Validators.minLength(3)]], description: [this.dictionary?.description], rank: [this.dictionary?.rank, Validators.required], @@ -41,7 +40,19 @@ export class AddEditDictionaryDialogComponent { }); } - get dictCaseSensitive() { + get dialogHeader(): string { + const i18nString = 'add-edit-dictionary.title.' + (this.dictionary ? 'edit' : 'new'); + return this._translateService.instant(i18nString, { + name: humanize(this.dictionary?.type) + }); + } + + get hasColor(): boolean { + const hexColorValue = this.dictionaryForm.get('hexColor').value; + return !hexColorValue || hexColorValue?.length === 0; + } + + get dictCaseSensitive(): boolean { return this.dictionary ? !this.dictionary.caseInsensitive : false; } @@ -63,14 +74,14 @@ export class AddEditDictionaryDialogComponent { async saveDictionary() { const typeValue: TypeValue = this._formToObject(); - let observable: Observable; + if (this.dictionary) { // edit mode observable = this._dictionaryControllerService.updateType( typeValue, - typeValue.type, - this._dossierTemplateId + this._dossierTemplateId, + typeValue.type ); } else { // create mode @@ -79,9 +90,7 @@ export class AddEditDictionaryDialogComponent { } observable.subscribe( - () => { - this.dialogRef.close({ dictionary: this.dictionary ? null : typeValue }); - }, + () => this._dialogRef.close(this.dictionary ? null : typeValue), error => { if (error.status === 409) { this._notifyError('add-edit-dictionary.error.dictionary-already-exists'); diff --git a/apps/red-ui/src/app/modules/admin/dialogs/add-edit-dossier-template-dialog/add-edit-dossier-template-dialog.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/add-edit-dossier-template-dialog/add-edit-dossier-template-dialog.component.ts index e60398154..712d9405f 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/add-edit-dossier-template-dialog/add-edit-dossier-template-dialog.component.ts +++ b/apps/red-ui/src/app/modules/admin/dialogs/add-edit-dossier-template-dialog/add-edit-dossier-template-dialog.component.ts @@ -115,7 +115,7 @@ export class AddEditDossierTemplateDialogComponent { .toPromise(); await this._appStateService.loadAllDossierTemplates(); await this._appStateService.loadDictionaryData(); - this.dialogRef.close({ dossierTemplate }); + this.dialogRef.close(dossierTemplate); } private _applyValidityIntervalConstraints(value): boolean { diff --git a/apps/red-ui/src/app/modules/admin/dialogs/edit-color-dialog/edit-color-dialog.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/edit-color-dialog/edit-color-dialog.component.ts index 94d786725..274d9789f 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/edit-color-dialog/edit-color-dialog.component.ts +++ b/apps/red-ui/src/app/modules/admin/dialogs/edit-color-dialog/edit-color-dialog.component.ts @@ -22,14 +22,14 @@ export class EditColorDialogComponent { private readonly _dictionaryControllerService: DictionaryControllerService, private readonly _notificationService: NotificationService, private readonly _translateService: TranslateService, - public dialogRef: MatDialogRef, + private readonly _dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) - public data: { colors: Colors; colorKey: string; dossierTemplateId: string } + private readonly _data: { colors: Colors; colorKey: string; dossierTemplateId: string } ) { - this.colors = data.colors; - this.colorKey = data.colorKey; - this._dossierTemplateId = data.dossierTemplateId; - this._initialColor = data.colors[this.colorKey]; + this.colors = _data.colors; + this.colorKey = _data.colorKey; + this._dossierTemplateId = _data.dossierTemplateId; + this._initialColor = _data.colors[this.colorKey]; this.colorForm = this._formBuilder.group({ color: [this.colors[this.colorKey], [Validators.required, Validators.minLength(7)]] @@ -50,7 +50,7 @@ export class EditColorDialogComponent { await this._dictionaryControllerService .setColors(colors, this._dossierTemplateId) .toPromise(); - this.dialogRef.close(true); + this._dialogRef.close(true); this._notificationService.showToastNotification( this._translateService.instant('edit-color-dialog.success', { color: this._translateService.instant( diff --git a/apps/red-ui/src/app/modules/admin/screens/default-colors/default-colors-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/default-colors/default-colors-screen.component.ts index 371f7e7cc..02b4f2aee 100644 --- a/apps/red-ui/src/app/modules/admin/screens/default-colors/default-colors-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/default-colors/default-colors-screen.component.ts @@ -28,25 +28,17 @@ export class DefaultColorsScreenComponent extends BaseListingComponent<{ protected readonly _injector: Injector ) { super(_injector); - this._appStateService.activateDossierTemplate( - _activatedRoute.snapshot.params.dossierTemplateId - ); + _appStateService.activateDossierTemplate(_activatedRoute.snapshot.params.dossierTemplateId); this._loadColors(); } - async loadDossierTemplatesData(): Promise { - await this._appStateService.loadAllDossierTemplates(); - } - openEditColorDialog($event: any, color: { key: string; value: string }) { $event.stopPropagation(); this._dialogService.openEditColorsDialog( this._colorsObj, color.key, this._appStateService.activeDossierTemplateId, - async () => { - this._loadColors(); - } + async () => this._loadColors() ); } diff --git a/apps/red-ui/src/app/modules/admin/screens/dictionary-listing/dictionary-listing-screen.component.html b/apps/red-ui/src/app/modules/admin/screens/dictionary-listing/dictionary-listing-screen.component.html index e0f1fd189..a7372ec7a 100644 --- a/apps/red-ui/src/app/modules/admin/screens/dictionary-listing/dictionary-listing-screen.component.html +++ b/apps/red-ui/src/app/modules/admin/screens/dictionary-listing/dictionary-listing-screen.component.html @@ -30,23 +30,16 @@ - {{ - 'dictionary-listing.table-header.title' - | translate: { length: displayedEntities.length } - }} + {{ tableHeader }} - - - - - +
-
+
- + > - + >
@@ -199,7 +188,3 @@
- - diff --git a/apps/red-ui/src/app/modules/admin/screens/dictionary-listing/dictionary-listing-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/dictionary-listing/dictionary-listing-screen.component.ts index a691cb394..d3952653f 100644 --- a/apps/red-ui/src/app/modules/admin/screens/dictionary-listing/dictionary-listing-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/dictionary-listing/dictionary-listing-screen.component.ts @@ -9,6 +9,15 @@ import { ActivatedRoute } from '@angular/router'; import { AdminDialogService } from '../../services/admin-dialog.service'; import { BaseListingComponent } from '@shared/base/base-listing.component'; import { TypeValueWrapper } from '../../../../models/file/type-value.wrapper'; +import { TranslateService } from '@ngx-translate/core'; +import { LoadingService } from '../../../../services/loading.service'; + +const toChartConfig = (dict: TypeValueWrapper): DoughnutChartConfig => ({ + value: dict.entries ? dict.entries.length : 0, + color: dict.hexColor, + label: dict.label, + key: dict.type +}); @Component({ selector: 'redaction-dictionary-listing-screen', @@ -19,9 +28,7 @@ export class DictionaryListingScreenComponent extends BaseListingComponent implements OnInit { - viewReady = false; chartData: DoughnutChartConfig[] = []; - loading = false; protected readonly _searchKey = 'label'; protected readonly _selectionKey = 'type'; protected readonly _sortKey = 'dictionary-listing'; @@ -31,13 +38,20 @@ export class DictionaryListingScreenComponent private readonly _dictionaryControllerService: DictionaryControllerService, private readonly _activatedRoute: ActivatedRoute, private readonly _appStateService: AppStateService, + private readonly _loadingService: LoadingService, + private readonly _translateService: TranslateService, readonly permissionsService: PermissionsService, protected readonly _injector: Injector ) { super(_injector); - this._appStateService.activateDossierTemplate( - _activatedRoute.snapshot.params.dossierTemplateId - ); + _loadingService.start(); + _appStateService.activateDossierTemplate(_activatedRoute.snapshot.params.dossierTemplateId); + } + + get tableHeader(): string { + return this._translateService.instant('dictionary-listing.table-header.title', { + length: this.displayedEntities.length + }); } ngOnInit(): void { @@ -47,15 +61,15 @@ export class DictionaryListingScreenComponent openDeleteDictionariesDialog($event?: MouseEvent, types = this.selectedEntitiesIds) { $event?.stopPropagation(); this._dialogService.openDeleteDictionariesDialog( - $event, types, this._appStateService.activeDossierTemplateId, async () => { this.selectedEntitiesIds = []; - this.loading = true; + this._loadingService.start(); await this._appStateService.loadDictionaryData(); - this._loadDictionaryData(); - this.loading = false; + this._loadDictionaryData(false); + this._calculateData(); + this._loadingService.stop(); } ); } @@ -67,27 +81,37 @@ export class DictionaryListingScreenComponent this._appStateService.activeDossierTemplateId, async newDictionary => { if (newDictionary) { + this._loadingService.start(); await this._appStateService.loadDictionaryData(); - this._loadDictionaryData(); + this._loadDictionaryData(false); + this._calculateData(); + this._loadingService.stop(); } } ); } - private _loadDictionaryData() { + private _loadDictionaryData(loadEntries = true): void { const appStateDictionaryData = this._appStateService.dictionaryData[this._appStateService.activeDossierTemplateId]; - this.allEntities = Object.keys(appStateDictionaryData) - .map(key => appStateDictionaryData[key]) - .filter(d => !d.virtual); + const entities = Object.values(appStateDictionaryData).filter(d => !d.virtual); + + if (!loadEntries) + this.allEntities = entities.map(dict => { + dict.entries = this.allEntities.find(d => d.type === dict.type)?.entries || []; + return dict; + }); + else this.allEntities = entities; + this.displayedEntities = [...this.allEntities]; + + if (!loadEntries) return; + const dataObs = this.allEntities.map(dict => this._dictionaryControllerService .getDictionaryForType(this._appStateService.activeDossierTemplateId, dict.type) .pipe( - tap(values => { - dict.entries = values.entries ? values.entries : []; - }), + tap(values => (dict.entries = values.entries ?? [])), catchError(() => { console.log('error'); dict.entries = []; @@ -95,24 +119,15 @@ export class DictionaryListingScreenComponent }) ) ); + forkJoin(dataObs) .pipe(defaultIfEmpty(null)) - .subscribe(() => { - this._calculateData(); - }); + .subscribe(() => this._calculateData()); } - private _calculateData() { - this.chartData = []; - for (const dict of this.allEntities) { - this.chartData.push({ - value: dict.entries ? dict.entries.length : 0, - color: dict.hexColor, - label: dict.label, - key: dict.type - }); - } + private _calculateData(): void { + this.chartData = this.allEntities.map(dict => toChartConfig(dict)); this.chartData.sort((a, b) => (a.label < b.label ? -1 : 1)); - this.viewReady = true; + this._loadingService.stop(); } } diff --git a/apps/red-ui/src/app/modules/admin/screens/dictionary-overview/dictionary-overview-screen.component.html b/apps/red-ui/src/app/modules/admin/screens/dictionary-overview/dictionary-overview-screen.component.html index be552ccfa..e59658806 100644 --- a/apps/red-ui/src/app/modules/admin/screens/dictionary-overview/dictionary-overview-screen.component.html +++ b/apps/red-ui/src/app/modules/admin/screens/dictionary-overview/dictionary-overview-screen.component.html @@ -10,8 +10,7 @@ tooltip="dictionary-overview.action.delete" tooltipPosition="below" type="dark-bg" - > - + > - + > { await this._appStateService.loadDictionaryData(); - this._router.navigate([ + await this._router.navigate([ '/main', 'admin', 'dossier-templates', diff --git a/apps/red-ui/src/app/modules/admin/screens/dossier-template-listing/dossier-templates-listing-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/dossier-template-listing/dossier-templates-listing-screen.component.ts index c484b2a36..e19c5ed1c 100644 --- a/apps/red-ui/src/app/modules/admin/screens/dossier-template-listing/dossier-templates-listing-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/dossier-template-listing/dossier-templates-listing-screen.component.ts @@ -36,8 +36,8 @@ export class DossierTemplatesListingScreenComponent openDeleteTemplatesDialog($event?: MouseEvent) { $event?.stopPropagation(); + this._dialogService.openBulkDeleteDossierTemplatesDialog( - $event, this.selectedEntitiesIds, async () => { this.selectedEntitiesIds = []; diff --git a/apps/red-ui/src/app/modules/admin/services/admin-dialog.service.ts b/apps/red-ui/src/app/modules/admin/services/admin-dialog.service.ts index 29aa5ffb1..57219f61a 100644 --- a/apps/red-ui/src/app/modules/admin/services/admin-dialog.service.ts +++ b/apps/red-ui/src/app/modules/admin/services/admin-dialog.service.ts @@ -7,20 +7,16 @@ import { DossierTemplateModel, FileAttributeConfig, FileAttributesConfig, - FileManagementControllerService, - ManualRedactionControllerService, SMTPConfigurationModel, + TypeValue, User } from '@redaction/red-ui-http'; import { AddEditFileAttributeDialogComponent } from '../dialogs/add-edit-file-attribute-dialog/add-edit-file-attribute-dialog.component'; import { AddEditDictionaryDialogComponent } from '../dialogs/add-edit-dictionary-dialog/add-edit-dictionary-dialog.component'; import { AddEditDossierTemplateDialogComponent } from '../dialogs/add-edit-dossier-template-dialog/add-edit-dossier-template-dialog.component'; -import { NotificationService } from '@services/notification.service'; import { ConfirmationDialogComponent } from '@shared/dialogs/confirmation-dialog/confirmation-dialog.component'; -import { AppStateService } from '@state/app-state.service'; import { ConfirmDeleteFileAttributeDialogComponent } from '../dialogs/confirm-delete-file-attribute-dialog/confirm-delete-file-attribute-dialog.component'; import { EditColorDialogComponent } from '../dialogs/edit-color-dialog/edit-color-dialog.component'; -import { TranslateService } from '@ngx-translate/core'; import { SmtpAuthDialogComponent } from '../dialogs/smtp-auth-dialog/smtp-auth-dialog.component'; import { AddEditUserDialogComponent } from '../dialogs/add-edit-user-dialog/add-edit-user-dialog.component'; import { ConfirmDeleteUsersDialogComponent } from '../dialogs/confirm-delete-users-dialog/confirm-delete-users-dialog.component'; @@ -44,22 +40,15 @@ const dialogConfig = { export class AdminDialogService { constructor( private readonly _dialog: MatDialog, - private readonly _translateService: TranslateService, - private readonly _appStateService: AppStateService, private readonly _dossierTemplateControllerService: DossierTemplateControllerService, - private readonly _dictionaryControllerService: DictionaryControllerService, - private readonly _fileManagementControllerService: FileManagementControllerService, - private readonly _notificationService: NotificationService, - private readonly _manualRedactionControllerService: ManualRedactionControllerService + private readonly _dictionaryControllerService: DictionaryControllerService ) {} openDeleteDictionariesDialog( - $event: MouseEvent, dictionaryTypes: string[], dossierTemplateId: string, - cb?: Function + cb?: () => void ): MatDialogRef { - $event.stopPropagation(); const ref = this._dialog.open(ConfirmationDialogComponent, dialogConfig); ref.afterClosed().subscribe(async result => { if (result) { @@ -73,11 +62,9 @@ export class AdminDialogService { } openDeleteDossierTemplateDialog( - $event: MouseEvent, dossierTemplate: DossierTemplateModel, - cb?: Function + cb?: () => void ): MatDialogRef { - $event.stopPropagation(); const ref = this._dialog.open(ConfirmationDialogComponent, dialogConfig); ref.afterClosed().subscribe(async result => { if (result) { @@ -88,11 +75,9 @@ export class AdminDialogService { } openBulkDeleteDossierTemplatesDialog( - $event: MouseEvent, dossierTemplateIds: string[], cb?: Function ): MatDialogRef { - $event.stopPropagation(); const ref = this._dialog.open(ConfirmationDialogComponent, dialogConfig); ref.afterClosed().subscribe(async result => { if (result) { @@ -105,7 +90,7 @@ export class AdminDialogService { openAddEditDictionaryDialog( dictionary: TypeValueWrapper, dossierTemplateId: string, - cb?: Function + cb?: (newDictionary: TypeValue | null) => void ): MatDialogRef { const ref = this._dialog.open(AddEditDictionaryDialogComponent, { ...dialogConfig, @@ -113,10 +98,9 @@ export class AdminDialogService { autoFocus: true }); - ref.afterClosed().subscribe(result => { - if (result && cb) { - cb(result); - } + ref.afterClosed().subscribe((newDictionary: TypeValue) => { + if (newDictionary && cb) cb(newDictionary); + else if (cb) cb(null); }); return ref; @@ -126,7 +110,7 @@ export class AdminDialogService { colors: Colors, colorKey: string, dossierTemplateId: string, - cb?: Function + cb?: (result: boolean) => void ): MatDialogRef { const ref = this._dialog.open(EditColorDialogComponent, { ...dialogConfig, @@ -134,7 +118,7 @@ export class AdminDialogService { autoFocus: true }); - ref.afterClosed().subscribe(result => { + ref.afterClosed().subscribe((result: boolean) => { if (result && cb) { cb(result); } diff --git a/apps/red-ui/src/app/modules/auth/auth.guard.ts b/apps/red-ui/src/app/modules/auth/auth.guard.ts index e680cd274..b073f9500 100644 --- a/apps/red-ui/src/app/modules/auth/auth.guard.ts +++ b/apps/red-ui/src/app/modules/auth/auth.guard.ts @@ -2,7 +2,6 @@ import { Inject, Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, Router, RouterStateSnapshot } from '@angular/router'; import { KeycloakAuthGuard, KeycloakService } from 'keycloak-angular'; import { UserService } from '@services/user.service'; -import { AppLoadStateService } from '@services/app-load-state.service'; import { AppConfigKey, AppConfigService } from '@app-config/app-config.service'; import { BASE_HREF } from '../../tokens'; @@ -15,7 +14,6 @@ export class AuthGuard extends KeycloakAuthGuard { protected readonly _router: Router, protected readonly _keycloak: KeycloakService, private readonly _appConfigService: AppConfigService, - private readonly _appLoadStateService: AppLoadStateService, private readonly _userService: UserService ) { super(_router, _keycloak); diff --git a/apps/red-ui/src/app/modules/auth/red-role.guard.ts b/apps/red-ui/src/app/modules/auth/red-role.guard.ts index 5935ff6f6..6ce704eb7 100644 --- a/apps/red-ui/src/app/modules/auth/red-role.guard.ts +++ b/apps/red-ui/src/app/modules/auth/red-role.guard.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router'; import { UserService } from '@services/user.service'; -import { AppLoadStateService } from '@services/app-load-state.service'; +import { LoadingService } from '@services/loading.service'; import { Observable } from 'rxjs'; @Injectable({ @@ -10,7 +10,7 @@ import { Observable } from 'rxjs'; export class RedRoleGuard implements CanActivate { constructor( protected readonly _router: Router, - private readonly _appLoadStateService: AppLoadStateService, + private readonly _loadingService: LoadingService, private readonly _userService: UserService ) {} @@ -18,7 +18,7 @@ export class RedRoleGuard implements CanActivate { return new Observable(obs => { if (!this._userService.user.hasAnyREDRoles) { this._router.navigate(['/auth-error']); - this._appLoadStateService.pushLoadingEvent(false); + this._loadingService.stop(); obs.next(false); obs.complete(); } else { diff --git a/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.ts b/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.ts index 9e68c723f..73a37074e 100644 --- a/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.ts +++ b/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.ts @@ -162,14 +162,13 @@ export class DictionaryManagerComponent implements OnChanges, OnInit { } private _applySearchDecorations() { - this._searchDecorations = this._codeEditor?.deltaDecorations(this._searchDecorations, []); + this._searchDecorations = + this._codeEditor?.deltaDecorations(this._searchDecorations, []) || []; const decorations = this.findMatches.map(match => this._getSearchDecoration(match)); - this._searchDecorations = this._codeEditor?.deltaDecorations( - this._searchDecorations, - decorations - ); + this._searchDecorations = + this._codeEditor?.deltaDecorations(this._searchDecorations, decorations) || []; } private _getMatches(text: string): FindMatch[] { diff --git a/apps/red-ui/src/app/services/app-load-state.service.ts b/apps/red-ui/src/app/services/app-load-state.service.ts deleted file mode 100644 index 2647e5699..000000000 --- a/apps/red-ui/src/app/services/app-load-state.service.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { EventEmitter, Injectable } from '@angular/core'; -import { Observable } from 'rxjs'; - -@Injectable({ - providedIn: 'root' -}) -export class AppLoadStateService { - private _loadingEvent = new EventEmitter(); - - get loading(): Observable { - return this._loadingEvent; - } - - pushLoadingEvent(event: boolean) { - this._loadingEvent.next(event); - } -} diff --git a/apps/red-ui/src/app/services/loading.service.ts b/apps/red-ui/src/app/services/loading.service.ts new file mode 100644 index 000000000..0f8287988 --- /dev/null +++ b/apps/red-ui/src/app/services/loading.service.ts @@ -0,0 +1,33 @@ +import { EventEmitter, Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; + +const MIN_LOADING_TIME = 300; + +@Injectable({ + providedIn: 'root' +}) +export class LoadingService { + private readonly _loadingEvent = new EventEmitter(); + private _loadingStarted: number; + + get isLoading(): Observable { + return this._loadingEvent; + } + + start(): void { + this._loadingEvent.next(true); + this._loadingStarted = new Date().getTime(); + } + + stop(): void { + const timeDelta = new Date().getTime() - this._loadingStarted; + if (timeDelta < MIN_LOADING_TIME) { + setTimeout(() => { + this._loadingEvent.next(false); + }, MIN_LOADING_TIME - timeDelta); + return; + } + + this._loadingEvent.next(false); + } +} diff --git a/apps/red-ui/src/app/services/sorting.service.ts b/apps/red-ui/src/app/services/sorting.service.ts index a51a79607..8b4495971 100644 --- a/apps/red-ui/src/app/services/sorting.service.ts +++ b/apps/red-ui/src/app/services/sorting.service.ts @@ -17,7 +17,7 @@ export type ScreenName = providedIn: 'root' }) export class SortingService { - private _options: { [key: string]: SortingOption } = { + private readonly _options: { [key: string]: SortingOption } = { 'dossier-listing': { column: 'dossier.dossierName', order: 'asc' }, 'dossier-overview': { column: 'filename', order: 'asc' }, 'dictionary-listing': { column: 'label', order: 'asc' }, @@ -26,8 +26,6 @@ export class SortingService { 'file-attributes-listing': { column: 'label', order: 'asc' } }; - constructor() {} - toggleSort(screen: ScreenName, column: string) { if (this._options[screen].column === column) { const currentOrder = this._options[screen].order;