From 5828597e71fce67f902833877e94ed31f0006e5d Mon Sep 17 00:00:00 2001 From: Dan Percic Date: Tue, 5 Oct 2021 00:10:13 +0300 Subject: [PATCH] move dossier templates related methods to own service --- .../admin-breadcrumbs.component.html | 42 ++++----- .../admin-breadcrumbs.component.ts | 4 +- .../dossier-template-actions.component.ts | 8 +- ...-edit-dossier-template-dialog.component.ts | 20 +++-- .../default-colors-screen.component.ts | 9 +- .../dictionary-listing-screen.component.ts | 11 +-- .../dictionary-overview-screen.component.html | 1 + .../dictionary-overview-screen.component.ts | 9 +- ...ier-attributes-listing-screen.component.ts | 5 +- ...sier-templates-listing-screen.component.ts | 17 ++-- ...ile-attributes-listing-screen.component.ts | 22 ++--- .../reports/reports-screen.component.ts | 63 +++++++------- .../screens/rules/rules-screen.component.ts | 10 +-- .../watermark/watermark-screen.component.ts | 13 +-- .../document-info/document-info.component.ts | 6 +- .../add-dossier-dialog.component.ts | 6 +- .../edit-dossier-general-info.component.ts | 6 +- .../dossier-details-stats.component.ts | 8 +- .../dossier-overview-screen.component.ts | 4 +- ...dossiers-listing-dossier-name.component.ts | 11 +-- .../dossiers-listing/config.service.ts | 6 +- .../services/dossier-templates.service.ts | 58 +++++++++++-- .../dossier/services/dossiers.service.ts | 22 ++--- .../file-actions/file-actions.component.ts | 2 +- .../dictionary-manager.component.html | 8 ++ .../dictionary-manager.component.ts | 1 + .../dossier-attributes.service.ts | 10 +-- apps/red-ui/src/app/state/app-state.guard.ts | 6 +- .../red-ui/src/app/state/app-state.service.ts | 86 +++---------------- apps/red-ui/src/app/utils/functions.ts | 7 ++ 30 files changed, 250 insertions(+), 231 deletions(-) diff --git a/apps/red-ui/src/app/modules/admin/components/breadcrumbs/admin-breadcrumbs.component.html b/apps/red-ui/src/app/modules/admin/components/breadcrumbs/admin-breadcrumbs.component.html index 414fa4fee..1afff1dac 100644 --- a/apps/red-ui/src/app/modules/admin/components/breadcrumbs/admin-breadcrumbs.component.html +++ b/apps/red-ui/src/app/modules/admin/components/breadcrumbs/admin-breadcrumbs.component.html @@ -1,35 +1,31 @@ diff --git a/apps/red-ui/src/app/modules/admin/components/breadcrumbs/admin-breadcrumbs.component.ts b/apps/red-ui/src/app/modules/admin/components/breadcrumbs/admin-breadcrumbs.component.ts index 31433aa88..4064b2f6f 100644 --- a/apps/red-ui/src/app/modules/admin/components/breadcrumbs/admin-breadcrumbs.component.ts +++ b/apps/red-ui/src/app/modules/admin/components/breadcrumbs/admin-breadcrumbs.component.ts @@ -2,6 +2,7 @@ import { Component, Input } from '@angular/core'; import { AppStateService } from '@state/app-state.service'; import { UserPreferenceService } from '@services/user-preference.service'; import { PermissionsService } from '@services/permissions.service'; +import { DossierTemplatesService } from '../../../dossier/services/dossier-templates.service'; @Component({ selector: 'redaction-admin-breadcrumbs', @@ -14,6 +15,7 @@ export class AdminBreadcrumbsComponent { constructor( readonly userPreferenceService: UserPreferenceService, readonly permissionService: PermissionsService, - readonly appStateService: AppStateService + readonly appStateService: AppStateService, + readonly dossierTemplatesService: DossierTemplatesService ) {} } 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 c85be54f3..baa6274f5 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 @@ -6,6 +6,7 @@ import { DossierTemplateControllerService } from '@redaction/red-ui-http'; import { CircleButtonTypes, LoadingService, Toaster } from '@iqser/common-ui'; import { UserService } from '@services/user.service'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; +import { DossierTemplatesService } from '../../../dossier/services/dossier-templates.service'; @Component({ selector: 'redaction-dossier-template-actions', @@ -25,16 +26,17 @@ export class DossierTemplateActionsComponent implements OnInit { private readonly _userService: UserService, private readonly _loadingService: LoadingService, private readonly _appStateService: AppStateService, + private readonly _dossierTemplatesService: DossierTemplatesService, private readonly _dialogService: AdminDialogService, private readonly _dossierTemplateControllerService: DossierTemplateControllerService ) {} get dossierTemplate() { - return this._appStateService.getDossierTemplateById(this.dossierTemplateId); + return this._dossierTemplatesService.find(this.dossierTemplateId); } ngOnInit() { - this.dossierTemplateId ??= this._appStateService.activeDossierTemplateId; + this.dossierTemplateId ??= this._dossierTemplatesService.activeDossierTemplateId; } openEditDossierTemplateDialog($event: any) { @@ -59,7 +61,7 @@ export class DossierTemplateActionsComponent implements OnInit { this._loadingService.stop(); }); await this._dossierTemplateControllerService.deleteDossierTemplates([this.dossierTemplateId]).toPromise(); - await this._appStateService.loadAllDossierTemplates(); + await this._dossierTemplatesService.loadAll(); await this._appStateService.loadDictionaryData(); await this._router.navigate(['main', 'admin']); this._loadingService.stop(); 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 33bb0f47a..e4cc1e8dc 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 @@ -1,12 +1,13 @@ -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 { 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 * as moment from 'moment'; -import {Moment} from 'moment'; -import {DossierTemplateControllerService, DownloadFileType, IDossierTemplate} from '@redaction/red-ui-http'; -import {applyIntervalConstraints} from '@utils/date-inputs-utils'; -import {downloadTypesTranslations} from '../../../../translations/download-types-translations'; +import { Moment } from 'moment'; +import { DossierTemplateControllerService, DownloadFileType, IDossierTemplate } from '@redaction/red-ui-http'; +import { applyIntervalConstraints } from '@utils/date-inputs-utils'; +import { downloadTypesTranslations } from '../../../../translations/download-types-translations'; +import { DossierTemplatesService } from '../../../dossier/services/dossier-templates.service'; @Component({ selector: 'redaction-add-edit-dossier-template-dialog', @@ -28,6 +29,7 @@ export class AddEditDossierTemplateDialogComponent { constructor( private readonly _appStateService: AppStateService, + private readonly _dossierTemplatesService: DossierTemplatesService, private readonly _formBuilder: FormBuilder, private readonly _dossierTemplateController: DossierTemplateControllerService, public dialogRef: MatDialogRef, @@ -98,7 +100,7 @@ export class AddEditDossierTemplateDialogComponent { validTo: this.hasValidTo ? this.dossierTemplateForm.get('validTo').value : null }; await this._dossierTemplateController.createOrUpdateDossierTemplate(dossierTemplate).toPromise(); - await this._appStateService.loadAllDossierTemplates(); + await this._dossierTemplatesService.loadAll(); await this._appStateService.loadDictionaryData(); this.dialogRef.close(true); } 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 fb6ac773b..132bd327c 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 @@ -16,6 +16,7 @@ import { defaultColorsTranslations } from '../../translations/default-colors-tra import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { UserService } from '@services/user.service'; import { DictionaryService } from '@shared/services/dictionary.service'; +import { DossierTemplatesService } from '../../../dossier/services/dossier-templates.service'; interface ListItem extends IListable { readonly key: string; @@ -45,11 +46,11 @@ export class DefaultColorsScreenComponent extends ListingComponent imp private readonly _loadingService: LoadingService, private readonly _activatedRoute: ActivatedRoute, private readonly _appStateService: AppStateService, + private readonly _dossierTemplatesService: DossierTemplatesService, private readonly _dialogService: AdminDialogService, private readonly _dictionaryService: DictionaryService ) { super(_injector); - _appStateService.activateDossierTemplate(_activatedRoute.snapshot.params.dossierTemplateId); } async ngOnInit() { @@ -63,18 +64,18 @@ export class DefaultColorsScreenComponent extends ListingComponent imp { colors: this._colorsObj, colorKey: color.key, - dossierTemplateId: this._appStateService.activeDossierTemplateId + dossierTemplateId: this._dossierTemplatesService.activeDossierTemplateId }, async () => { await this._loadColors(); - await this._appStateService.refreshDossierTemplate(this._appStateService.activeDossierTemplateId); + await this._appStateService.refreshDossierTemplate(this._dossierTemplatesService.activeDossierTemplateId); } ); } private async _loadColors() { this._loadingService.start(); - const data = await this._appStateService.loadColors(this._appStateService.activeDossierTemplateId).toPromise(); + const data = await this._appStateService.loadColors(this._dossierTemplatesService.activeDossierTemplateId).toPromise(); this._colorsObj = data; const entities = Object.keys(data) .map(key => ({ 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 cb7270617..9cbbe5781 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 @@ -18,6 +18,7 @@ import { AdminDialogService } from '../../services/admin-dialog.service'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { UserService } from '@services/user.service'; import { DictionaryService } from '@shared/services/dictionary.service'; +import { DossierTemplatesService } from '../../../dossier/services/dossier-templates.service'; const toChartConfig = (dict: TypeValue): DoughnutChartConfig => ({ value: dict.entries?.length ?? 0, @@ -49,13 +50,13 @@ export class DictionaryListingScreenComponent extends ListingComponent t.type), - this._appStateService.activeDossierTemplateId + this._dossierTemplatesService.activeDossierTemplateId ) .toPromise(); this.entitiesService.setSelected([]); @@ -85,7 +86,7 @@ export class DictionaryListingScreenComponent extends ListingComponent { this._loadingService.start(); @@ -98,7 +99,7 @@ export class DictionaryListingScreenComponent extends ListingComponent !d.virtual); if (!loadEntries) { @@ -117,7 +118,7 @@ export class DictionaryListingScreenComponent extends ListingComponent - this._dictionaryService.getFor(this._appStateService.activeDossierTemplateId, dict.type).pipe( + this._dictionaryService.getFor(this._dossierTemplatesService.activeDossierTemplateId, dict.type).pipe( tap(values => (dict.entries = [...values.entries] ?? [])), catchError(() => { dict.entries = []; 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 5d87d6716..5f9365cdc 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 @@ -57,6 +57,7 @@ #dictionaryManager (saveDictionary)="saveEntries($event)" [canEdit]="currentUser.isAdmin" + [filterByDossierTemplate]="true" [initialEntries]="entries" > diff --git a/apps/red-ui/src/app/modules/admin/screens/dictionary-overview/dictionary-overview-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/dictionary-overview/dictionary-overview-screen.component.ts index a16484207..f8efa69b6 100644 --- a/apps/red-ui/src/app/modules/admin/screens/dictionary-overview/dictionary-overview-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/dictionary-overview/dictionary-overview-screen.component.ts @@ -10,6 +10,7 @@ import { DictionaryService } from '@shared/services/dictionary.service'; import { TypeValue } from '@models/file/type-value'; import { CircleButtonTypes, LoadingService } from '@iqser/common-ui'; import { UserService } from '@services/user.service'; +import { DossierTemplatesService } from '../../../dossier/services/dossier-templates.service'; @Component({ templateUrl: './dictionary-overview-screen.component.html', @@ -32,6 +33,7 @@ export class DictionaryOverviewScreenComponent extends ComponentHasChanges imple private readonly _activatedRoute: ActivatedRoute, private readonly _loadingService: LoadingService, private readonly _appStateService: AppStateService, + private readonly _dossierTemplatesService: DossierTemplatesService, private readonly _dialogService: AdminDialogService, protected readonly _translateService: TranslateService, private readonly _dictionaryService: DictionaryService @@ -44,10 +46,7 @@ export class DictionaryOverviewScreenComponent extends ComponentHasChanges imple } async ngOnInit() { - await this._appStateService.activateDictionary( - this._activatedRoute.snapshot.params.type, - this._activatedRoute.snapshot.params.dossierTemplateId - ); + await this._appStateService.activateDictionary(this._activatedRoute.snapshot.params.type); this.dictionary = this._appStateService.activeDictionary; await this._loadEntries(); } @@ -79,7 +78,7 @@ export class DictionaryOverviewScreenComponent extends ComponentHasChanges imple '/main', 'admin', 'dossier-templates', - this._appStateService.activeDossierTemplateId, + this._dossierTemplatesService.activeDossierTemplateId, 'dictionaries' ]); }); diff --git a/apps/red-ui/src/app/modules/admin/screens/dossier-attributes-listing/dossier-attributes-listing-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/dossier-attributes-listing/dossier-attributes-listing-screen.component.ts index d087bb15a..e99aa2920 100644 --- a/apps/red-ui/src/app/modules/admin/screens/dossier-attributes-listing/dossier-attributes-listing-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/dossier-attributes-listing/dossier-attributes-listing-screen.component.ts @@ -16,6 +16,7 @@ import { dossierAttributeTypesTranslations } from '../../translations/dossier-at import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { UserService } from '@services/user.service'; import { DossierAttributeConfig } from '@state/model/dossier-attribute-config'; +import { DossierTemplatesService } from '../../../dossier/services/dossier-templates.service'; @Component({ templateUrl: './dossier-attributes-listing-screen.component.html', @@ -40,6 +41,7 @@ export class DossierAttributesListingScreenComponent extends ListingComponent DossierTemplatesListingScreenComponent) } ] }) @@ -44,6 +51,7 @@ export class DossierTemplatesListingScreenComponent extends ListingComponent d.dossierTemplateId)) { + private async _deleteTemplates(templateIds = this.entitiesService.selected.map(d => d.dossierTemplateId)) { await this._dossierTemplateControllerService .deleteDossierTemplates(templateIds) .toPromise() @@ -86,7 +93,7 @@ export class DossierTemplatesListingScreenComponent extends ListingComponent { this._loadingService.start(); await this._fileAttributesService - .setFileAttributesConfig(newValue, this._appStateService.activeDossierTemplateId) + .setFileAttributesConfig(newValue, this._dossierTemplatesService.activeDossierTemplateId) .toPromise(); - await this._appStateService.refreshDossierTemplate(this._appStateService.activeDossierTemplateId); + await this._appStateService.refreshDossierTemplate(this._dossierTemplatesService.activeDossierTemplateId); await this._loadData(); } ); @@ -85,19 +86,18 @@ export class FileAttributesListingScreenComponent extends ListingComponent { this._loadingService.start(); + const dossierTemplateId = this._dossierTemplatesService.activeDossierTemplateId; if (fileAttribute) { - await this._fileAttributesService - .deleteFileAttributes([fileAttribute.id], this._appStateService.activeDossierTemplateId) - .toPromise(); + await this._fileAttributesService.deleteFileAttributes([fileAttribute.id], dossierTemplateId).toPromise(); } else { await this._fileAttributesService .deleteFileAttributes( this.entitiesService.selected.map(f => f.id), - this._appStateService.activeDossierTemplateId + dossierTemplateId ) .toPromise(); } - await this._appStateService.refreshDossierTemplate(this._appStateService.activeDossierTemplateId); + await this._appStateService.refreshDossierTemplate(dossierTemplateId); await this._loadData(); }); } @@ -111,7 +111,7 @@ export class FileAttributesListingScreenComponent extends ListingComponent await this._loadData() @@ -123,7 +123,7 @@ export class FileAttributesListingScreenComponent extends ListingComponent new FileAttributeConfig(item)) || []; diff --git a/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen.component.ts index 13a3ac48b..7f1d79212 100644 --- a/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/reports/reports-screen.component.ts @@ -12,6 +12,7 @@ import { import { removeBraces } from '@utils/functions'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { AdminDialogService } from '../../services/admin-dialog.service'; +import { DossierTemplatesService } from '../../../dossier/services/dossier-templates.service'; interface Placeholder { placeholder: string; @@ -36,13 +37,13 @@ export class ReportsScreenComponent implements OnInit { constructor( private readonly _activatedRoute: ActivatedRoute, private readonly _appStateService: AppStateService, + private readonly _dossierTemplatesService: DossierTemplatesService, private readonly _reportTemplateService: ReportTemplateControllerService, private readonly _dialogService: AdminDialogService, private readonly _toaster: Toaster, private readonly _loadingService: LoadingService, readonly permissionsService: PermissionsService ) { - this._appStateService.activateDossierTemplate(_activatedRoute.snapshot.params.dossierTemplateId); } async ngOnInit() { @@ -84,36 +85,36 @@ export class ReportsScreenComponent implements OnInit { private async _uploadTemplate($event) { const file = $event.target.files[0]; - if (this._isValidFile(file)) { - if (this._isExcelFile(file)) { - const data = new ConfirmationDialogInput({ - title: _('confirmation-dialog.upload-report-template.title'), - question: _('confirmation-dialog.upload-report-template.question'), - confirmationText: _('confirmation-dialog.upload-report-template.confirmation-text'), - denyText: _('confirmation-dialog.upload-report-template.deny-text'), - alternativeConfirmationText: _('confirmation-dialog.upload-report-template.alternate-confirmation-text'), - translateParams: { - fileName: file.name - } - }); - this._dialogService.openDialog('confirm', null, data, null, async result => { - if (result) { - await this._reportTemplateService - .uploadTemplateForm(this._appStateService.activeDossierTemplateId, result > 1, file) - .toPromise(); - await this._loadReportTemplates(); - } - }); - } else { - await this._reportTemplateService - .uploadTemplateForm(this._appStateService.activeDossierTemplateId, false, file) - .toPromise(); - await this._loadReportTemplates(); - } - this._fileInput.nativeElement.value = null; - } else { + if (!this._isValidFile(file)) { this._toaster.error(_('reports-screen.invalid-upload')); + return; } + + const dossierTemplateId = this._dossierTemplatesService.activeDossierTemplateId; + if (this._isExcelFile(file)) { + const data = new ConfirmationDialogInput({ + title: _('confirmation-dialog.upload-report-template.title'), + question: _('confirmation-dialog.upload-report-template.question'), + confirmationText: _('confirmation-dialog.upload-report-template.confirmation-text'), + denyText: _('confirmation-dialog.upload-report-template.deny-text'), + alternativeConfirmationText: _('confirmation-dialog.upload-report-template.alternate-confirmation-text'), + translateParams: { + fileName: file.name + } + }); + this._dialogService.openDialog('confirm', null, data, null, async result => { + if (result) { + await this._reportTemplateService + .uploadTemplateForm(dossierTemplateId, result > 1, file) + .toPromise(); + await this._loadReportTemplates(); + } + }); + } else { + await this._reportTemplateService.uploadTemplateForm(dossierTemplateId, false, file).toPromise(); + await this._loadReportTemplates(); + } + this._fileInput.nativeElement.value = null; } private async _deleteTemplate(template: ReportTemplate) { @@ -123,13 +124,13 @@ export class ReportsScreenComponent implements OnInit { private async _loadReportTemplates() { this.availableTemplates = await this._reportTemplateService - .getAvailableReportTemplates(this._appStateService.activeDossierTemplateId) + .getAvailableReportTemplates(this._dossierTemplatesService.activeDossierTemplateId) .toPromise(); } private async _loadPlaceholders() { const placeholdersResponse: PlaceholdersResponse = await this._reportTemplateService - .getAvailablePlaceholders(this._appStateService.activeDossierTemplateId) + .getAvailablePlaceholders(this._dossierTemplatesService.activeDossierTemplateId) .toPromise(); this.placeholders = placeholderTypes.flatMap(type => placeholdersResponse[type].map(placeholder => ({ diff --git a/apps/red-ui/src/app/modules/admin/screens/rules/rules-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/rules/rules-screen.component.ts index 71c37a826..996e22b9f 100644 --- a/apps/red-ui/src/app/modules/admin/screens/rules/rules-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/rules/rules-screen.component.ts @@ -1,14 +1,14 @@ import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'; import { PermissionsService } from '@services/permissions.service'; import { RulesControllerService } from '@redaction/red-ui-http'; -import { Toaster } from '@iqser/common-ui'; +import { Debounce, IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui'; import { TranslateService } from '@ngx-translate/core'; import { saveAs } from 'file-saver'; import { ComponentHasChanges } from '@guards/can-deactivate.guard'; import { ActivatedRoute } from '@angular/router'; import { AppStateService } from '@state/app-state.service'; -import { Debounce, IconButtonTypes, LoadingService } from '@iqser/common-ui'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; +import { DossierTemplatesService } from '../../../dossier/services/dossier-templates.service'; import ICodeEditor = monaco.editor.ICodeEditor; import IModelDeltaDecoration = monaco.editor.IModelDeltaDecoration; import IStandaloneEditorConstructionOptions = monaco.editor.IStandaloneEditorConstructionOptions; @@ -40,13 +40,13 @@ export class RulesScreenComponent extends ComponentHasChanges implements OnInit readonly permissionsService: PermissionsService, private readonly _rulesControllerService: RulesControllerService, private readonly _appStateService: AppStateService, + private readonly _dossierTemplatesService: DossierTemplatesService, private readonly _toaster: Toaster, protected readonly _translateService: TranslateService, private readonly _activatedRoute: ActivatedRoute, private readonly _loadingService: LoadingService ) { super(_translateService); - _appStateService.activateDossierTemplate(_activatedRoute.snapshot.params.dossierTemplateId); } get hasChanges(): boolean { @@ -91,7 +91,7 @@ export class RulesScreenComponent extends ComponentHasChanges implements OnInit await this._rulesControllerService .uploadRules({ rules: this._codeEditor.getModel().getValue(), - dossierTemplateId: this._appStateService.activeDossierTemplateId + dossierTemplateId: this._dossierTemplatesService.activeDossierTemplateId }) .toPromise() .then( @@ -149,7 +149,7 @@ export class RulesScreenComponent extends ComponentHasChanges implements OnInit private async _initialize() { this._loadingService.start(); await this._rulesControllerService - .downloadRules(this._appStateService.activeDossierTemplateId) + .downloadRules(this._dossierTemplatesService.activeDossierTemplateId) .toPromise() .then( rules => { diff --git a/apps/red-ui/src/app/modules/admin/screens/watermark/watermark-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/watermark/watermark-screen.component.ts index d08bcdcc2..83de4efd6 100644 --- a/apps/red-ui/src/app/modules/admin/screens/watermark/watermark-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/watermark/watermark-screen.component.ts @@ -1,7 +1,6 @@ import { ChangeDetectorRef, Component, ElementRef, Inject, OnInit, ViewChild } from '@angular/core'; import { PermissionsService } from '@services/permissions.service'; import WebViewer, { WebViewerInstance } from '@pdftron/webviewer'; -import { AppStateService } from '@state/app-state.service'; import { environment } from '@environments/environment'; import { HttpClient } from '@angular/common/http'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; @@ -11,6 +10,7 @@ import { ActivatedRoute } from '@angular/router'; import { BASE_HREF } from '../../../../tokens'; import { stampPDFPage } from '@utils/page-stamper'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; +import { DossierTemplatesService } from '../../../dossier/services/dossier-templates.service'; export const DEFAULT_WATERMARK: WatermarkModel = { text: null, @@ -36,7 +36,6 @@ export class WatermarkScreenComponent implements OnInit { constructor( readonly permissionsService: PermissionsService, - readonly appStateService: AppStateService, @Inject(BASE_HREF) private readonly _baseHref: string, private readonly _watermarkControllerService: WatermarkControllerService, private readonly _toaster: Toaster, @@ -44,9 +43,9 @@ export class WatermarkScreenComponent implements OnInit { private readonly _changeDetectorRef: ChangeDetectorRef, private readonly _formBuilder: FormBuilder, private readonly _activatedRoute: ActivatedRoute, + private readonly _dossierTemplatesService: DossierTemplatesService, private readonly _loadingService: LoadingService ) { - appStateService.activateDossierTemplate(_activatedRoute.snapshot.params.dossierTemplateId); this._loadingService.start(); this._initForm(); } @@ -77,9 +76,11 @@ export class WatermarkScreenComponent implements OnInit { ...this.configForm.getRawValue() }; + const dossierTemplateId = this._dossierTemplatesService.activeDossierTemplateId; + const observable = watermark.text - ? this._watermarkControllerService.saveWatermark(watermark, this.appStateService.activeDossierTemplateId) - : this._watermarkControllerService.deleteWatermark(this.appStateService.activeDossierTemplateId); + ? this._watermarkControllerService.saveWatermark(watermark, dossierTemplateId) + : this._watermarkControllerService.deleteWatermark(dossierTemplateId); observable.toPromise().then( () => { @@ -107,7 +108,7 @@ export class WatermarkScreenComponent implements OnInit { } private _loadWatermark() { - this._watermarkControllerService.getWatermark(this.appStateService.activeDossierTemplateId).subscribe( + this._watermarkControllerService.getWatermark(this._dossierTemplatesService.activeDossierTemplateId).subscribe( watermark => { this._watermark = watermark; this.configForm.setValue({ ...this._watermark }); diff --git a/apps/red-ui/src/app/modules/dossier/components/document-info/document-info.component.ts b/apps/red-ui/src/app/modules/dossier/components/document-info/document-info.component.ts index 0331901d1..8bf1714fe 100644 --- a/apps/red-ui/src/app/modules/dossier/components/document-info/document-info.component.ts +++ b/apps/red-ui/src/app/modules/dossier/components/document-info/document-info.component.ts @@ -6,6 +6,7 @@ import { AutoUnsubscribe } from '@iqser/common-ui'; import { File } from '@models/file/file'; import { FileAttributesService } from '../../services/file-attributes.service'; import { DossiersService } from '../../services/dossiers.service'; +import { DossierTemplatesService } from '../../services/dossier-templates.service'; @Component({ selector: 'redaction-document-info', @@ -21,6 +22,7 @@ export class DocumentInfoComponent extends AutoUnsubscribe implements OnInit { constructor( private readonly _appStateService: AppStateService, private readonly _dossiersService: DossiersService, + private readonly _dossierTemplatesService: DossierTemplatesService, private readonly _fileAttributesService: FileAttributesService, private readonly _dialogService: DossiersDialogService ) { @@ -32,13 +34,13 @@ export class DocumentInfoComponent extends AutoUnsubscribe implements OnInit { } get dossierTemplateName(): string { - return this._appStateService.getDossierTemplateById(this.dossier.dossierTemplateId).name; + return this._dossierTemplatesService.find(this.dossier.dossierTemplateId).name; } ngOnInit(): void { this.fileAttributesConfig = this._fileAttributesService.getFileAttributeConfig(this.dossier.dossierTemplateId); - this.addSubscription = this._appStateService.dossierTemplateChanged$.subscribe(() => { + this.addSubscription = this._dossierTemplatesService.entityChanged$.subscribe(() => { this.fileAttributesConfig = this._fileAttributesService.getFileAttributeConfig(this.dossier.dossierTemplateId); }); } diff --git a/apps/red-ui/src/app/modules/dossier/dialogs/add-dossier-dialog/add-dossier-dialog.component.ts b/apps/red-ui/src/app/modules/dossier/dialogs/add-dossier-dialog/add-dossier-dialog.component.ts index eae7a0f44..7d4b42d17 100644 --- a/apps/red-ui/src/app/modules/dossier/dialogs/add-dossier-dialog/add-dossier-dialog.component.ts +++ b/apps/red-ui/src/app/modules/dossier/dialogs/add-dossier-dialog/add-dossier-dialog.component.ts @@ -8,11 +8,11 @@ import { ReportTemplateControllerService } from '@redaction/red-ui-http'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { AppStateService } from '@state/app-state.service'; import * as moment from 'moment'; import { downloadTypesTranslations } from '../../../../translations/download-types-translations'; import { IconButtonTypes } from '@iqser/common-ui'; import { DossiersService } from '../../services/dossiers.service'; +import { DossierTemplatesService } from '../../services/dossier-templates.service'; @Component({ templateUrl: './add-dossier-dialog.component.html', @@ -31,8 +31,8 @@ export class AddDossierDialogComponent { availableReportTypes = []; constructor( - private readonly _appStateService: AppStateService, private readonly _dossiersService: DossiersService, + private readonly _dossierTemplatesService: DossierTemplatesService, private readonly _formBuilder: FormBuilder, private readonly _reportTemplateController: ReportTemplateControllerService, readonly dialogRef: MatDialogRef @@ -110,7 +110,7 @@ export class AddDossierDialogComponent { } private _filterInvalidDossierTemplates() { - this.dossierTemplates = this._appStateService.dossierTemplates.filter(r => { + this.dossierTemplates = this._dossierTemplatesService.all.filter(r => { const notYetValid = !!r.validFrom && moment(r.validFrom).isAfter(moment()); const notValidAnymore = !!r.validTo && moment(r.validTo).add(1, 'd').isBefore(moment()); return !(notYetValid || notValidAnymore); diff --git a/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.ts b/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.ts index 03967596f..015072d6c 100644 --- a/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.ts +++ b/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.ts @@ -1,7 +1,6 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { DossierRequest, IDossierTemplate } from '@redaction/red-ui-http'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { AppStateService } from '@state/app-state.service'; import * as moment from 'moment'; import { Dossier } from '@state/model/dossier'; import { EditDossierSectionInterface } from '../edit-dossier-section.interface'; @@ -13,6 +12,7 @@ import { EditDossierDialogComponent } from '../edit-dossier-dialog.component'; import { ConfirmationDialogInput, IconButtonTypes, TitleColors, Toaster } from '@iqser/common-ui'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { DossiersService } from '../../../services/dossiers.service'; +import { DossierTemplatesService } from '../../../services/dossier-templates.service'; @Component({ selector: 'redaction-edit-dossier-general-info', @@ -31,7 +31,7 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti constructor( readonly permissionsService: PermissionsService, - private readonly _appStateService: AppStateService, + private readonly _dossierTemplatesService: DossierTemplatesService, private readonly _dossiersService: DossiersService, private readonly _formBuilder: FormBuilder, private readonly _dialogService: DossiersDialogService, @@ -133,7 +133,7 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti } private _filterInvalidDossierTemplates() { - this.dossierTemplates = this._appStateService.dossierTemplates.filter(r => { + this.dossierTemplates = this._dossierTemplatesService.all.filter(r => { if (this.dossier?.dossierTemplateId === r.dossierTemplateId) { return true; } diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/dossier-details-stats/dossier-details-stats.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/dossier-details-stats/dossier-details-stats.component.ts index 92fd0f559..2e294eda8 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/dossier-details-stats/dossier-details-stats.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/components/dossier-details-stats/dossier-details-stats.component.ts @@ -2,9 +2,10 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; import { DossierAttributeWithValue } from '@models/dossier-attributes.model'; import { AppStateService } from '@state/app-state.service'; import { Dossier } from '@state/model/dossier'; -import { IDossierTemplate } from '@redaction/red-ui-http'; import { DossiersDialogService } from '../../../../services/dossiers-dialog.service'; import { DossiersService } from '../../../../services/dossiers.service'; +import { DossierTemplatesService } from '../../../../services/dossier-templates.service'; +import { DossierTemplate } from '@models/file/dossier-template'; @Component({ selector: 'redaction-dossier-details-stats', @@ -18,12 +19,13 @@ export class DossierDetailsStatsComponent { constructor( private readonly _appStateService: AppStateService, + private readonly _dossierTemplatesService: DossierTemplatesService, private readonly _dialogService: DossiersDialogService, readonly dossiersService: DossiersService ) {} - dossierTemplate(dossier: Dossier): IDossierTemplate { - return this._appStateService.getDossierTemplateById(dossier.dossierTemplateId); + dossierTemplate(dossier: Dossier): DossierTemplate { + return this._dossierTemplatesService.find(dossier.dossierTemplateId); } openEditDossierAttributesDialog(dossier: Dossier) { diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.ts index 59c7df650..654534817 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview/screen/dossier-overview-screen.component.ts @@ -51,6 +51,7 @@ import { FileAttributesService } from '../../../services/file-attributes.service import { ConfigService as AppConfigService } from '@services/config.service'; import { ConfigService } from '../config.service'; import { DossiersService } from '../../../services/dossiers.service'; +import { DossierTemplatesService } from '../../../services/dossier-templates.service'; @Component({ templateUrl: './dossier-overview-screen.component.html', @@ -85,6 +86,7 @@ export class DossierOverviewScreenComponent extends ListingComponent imple private readonly _loadingService: LoadingService, private readonly _appStateService: AppStateService, private readonly _dossiersService: DossiersService, + private readonly _dossierTemplatesService: DossierTemplatesService, readonly routerHistoryService: RouterHistoryService, private readonly _appConfigService: AppConfigService, private readonly _translateService: TranslateService, @@ -153,7 +155,7 @@ export class DossierOverviewScreenComponent extends ListingComponent imple this.calculateData(); }); - this.addSubscription = this._appStateService.dossierTemplateChanged$.subscribe(() => { + this.addSubscription = this._dossierTemplatesService.entityChanged$.subscribe(() => { this.fileAttributeConfigs = this._fileAttributesService.getFileAttributeConfig( this.currentDossier.dossierTemplateId )?.fileAttributeConfigs; diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/components/dossiers-listing-dossier-name/dossiers-listing-dossier-name.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/components/dossiers-listing-dossier-name/dossiers-listing-dossier-name.component.ts index 2ba4cc448..c779b0287 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/components/dossiers-listing-dossier-name/dossiers-listing-dossier-name.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/components/dossiers-listing-dossier-name/dossiers-listing-dossier-name.component.ts @@ -1,18 +1,19 @@ -import { Component, Input } from '@angular/core'; +import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; import { Dossier } from '@state/model/dossier'; -import { AppStateService } from '@state/app-state.service'; +import { DossierTemplatesService } from '../../../../services/dossier-templates.service'; @Component({ selector: 'redaction-dossiers-listing-dossier-name', templateUrl: './dossiers-listing-dossier-name.component.html', - styleUrls: ['./dossiers-listing-dossier-name.component.scss'] + styleUrls: ['./dossiers-listing-dossier-name.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush }) export class DossiersListingDossierNameComponent { @Input() dossier: Dossier; - constructor(private readonly _appStateService: AppStateService) {} + constructor(private readonly _dossierTemplatesService: DossierTemplatesService) {} getDossierTemplateNameFor(dossierTemplateId: string): string { - return this._appStateService.getDossierTemplateById(dossierTemplateId).name; + return this._dossierTemplatesService.find(dossierTemplateId).name; } } diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/config.service.ts b/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/config.service.ts index 8dc080462..771578905 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/config.service.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossiers-listing/config.service.ts @@ -17,6 +17,7 @@ import { } from '@utils/index'; import { workloadTranslations } from '../../translations/workload-translations'; import { AppStateService } from '@state/app-state.service'; +import { DossierTemplatesService } from '../../services/dossier-templates.service'; @Injectable() export class ConfigService { @@ -24,7 +25,8 @@ export class ConfigService { private readonly _translateService: TranslateService, private readonly _userPreferenceService: UserPreferenceService, private readonly _userService: UserService, - private readonly _appStateService: AppStateService + private readonly _appStateService: AppStateService, + private readonly _dossierTemplatesService: DossierTemplatesService ) {} get tableConfig(): TableColumnConfig[] { @@ -171,7 +173,7 @@ export class ConfigService { id => new NestedFilter({ id: id, - label: this._appStateService.getDossierTemplateById(id).name + label: this._dossierTemplatesService.find(id).name }) ); diff --git a/apps/red-ui/src/app/modules/dossier/services/dossier-templates.service.ts b/apps/red-ui/src/app/modules/dossier/services/dossier-templates.service.ts index 8457a09d1..fec91b34d 100644 --- a/apps/red-ui/src/app/modules/dossier/services/dossier-templates.service.ts +++ b/apps/red-ui/src/app/modules/dossier/services/dossier-templates.service.ts @@ -3,19 +3,67 @@ import { DossierTemplate } from '@models/file/dossier-template'; import { IDossierTemplate } from '@redaction/red-ui-http'; import { Injectable, Injector } from '@angular/core'; import { TEMPORARY_INJECTOR } from './injector'; -import { Observable } from 'rxjs'; -import { map } from 'rxjs/operators'; +import { BehaviorSubject, Observable } from 'rxjs'; +import { FileAttributesService } from './file-attributes.service'; +import { ActivationEnd, Router } from '@angular/router'; +import { currentComponentRoute } from '@utils/functions'; @Injectable({ providedIn: 'root' }) export class DossierTemplatesService extends EntitiesService { - constructor(protected readonly _injector: Injector) { + readonly activeDossierTemplate$: Observable; + private readonly _activeDossierTemplate$ = new BehaviorSubject(undefined); + + constructor( + protected readonly _injector: Injector, + private readonly _fileAttributesService: FileAttributesService, + private readonly _router: Router + ) { super(TEMPORARY_INJECTOR(_injector), 'dossier-template'); + this.activeDossierTemplate$ = this._activeDossierTemplate$.asObservable(); + + _router.events.pipe(currentComponentRoute).subscribe((event: ActivationEnd) => { + const dossierTemplateId = event.snapshot.paramMap.get('dossierTemplateId'); + const sameIdAsCurrentActive = dossierTemplateId === this._activeDossierTemplate$.getValue()?.dossierTemplateId; + + if (sameIdAsCurrentActive) { + return; + } + + if (dossierTemplateId === null || dossierTemplateId === undefined) { + return this._activeDossierTemplate$.next(undefined); + } + + if (!this.has(dossierTemplateId)) { + this._activeDossierTemplate$.next(undefined); + return this._router.navigate(['/main/admin/dossier-templates']).then(); + } + + this._activeDossierTemplate$.next(this.find(dossierTemplateId)); + }); } - fetch() { - this.get().pipe(map(entities => entities.map(dossierTemplate => new DossierTemplate(dossierTemplate)))); + get activeDossierTemplate(): DossierTemplate | undefined { + return this._activeDossierTemplate$.value; + } + + get activeDossierTemplateId(): string | undefined { + return this._activeDossierTemplate$.value?.dossierTemplateId; + } + + async loadAll(): Promise { + const dossierTemplates = await this.get().toPromise(); + this.setEntities(dossierTemplates.map(dossierTemplate => new DossierTemplate(dossierTemplate))); + for (const dossierTemplate of this.all) { + await this._fileAttributesService.getFileAttributesConfig(dossierTemplate.dossierTemplateId).toPromise(); + } + } + + async loadAllIfEmpty(): Promise { + if (!this.all.length) { + await this.loadAll(); + } } /** diff --git a/apps/red-ui/src/app/modules/dossier/services/dossiers.service.ts b/apps/red-ui/src/app/modules/dossier/services/dossiers.service.ts index 90654ad04..b17d73bfc 100644 --- a/apps/red-ui/src/app/modules/dossier/services/dossiers.service.ts +++ b/apps/red-ui/src/app/modules/dossier/services/dossiers.service.ts @@ -2,21 +2,20 @@ import { Injectable, Injector } from '@angular/core'; import { DossierRequest, IDossier } from '@redaction/red-ui-http'; import { EntitiesService, List, QueryParam, RequiredParam, Toaster, Validate } from '@iqser/common-ui'; import { Dossier } from '@state/model/dossier'; -import { catchError, filter, map, tap } from 'rxjs/operators'; +import { catchError, map, tap } from 'rxjs/operators'; import { TEMPORARY_INJECTOR } from './injector'; -import { BehaviorSubject, Observable, of, Subject } from 'rxjs'; +import { BehaviorSubject, Observable, of } from 'rxjs'; import { ActivationEnd, Router } from '@angular/router'; -import { BaseScreenComponent } from '@components/base-screen/base-screen.component'; import { File } from '@models/file/file'; import { DictionaryService } from '@shared/services/dictionary.service'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; +import { currentComponentRoute } from '@utils/functions'; export interface IDossiersStats { totalPeople: number; totalAnalyzedPages: number; } -const getRelatedEvents = filter(event => event instanceof ActivationEnd && event.snapshot.component !== BaseScreenComponent); const DOSSIER_EXISTS_MSG = _('add-dossier-dialog.errors.dossier-already-exists'); const GENERIC_MGS = _('add-dossier-dialog.errors.generic'); @@ -26,7 +25,6 @@ const GENERIC_MGS = _('add-dossier-dialog.errors.generic'); export class DossiersService extends EntitiesService { readonly stats$ = this.all$.pipe(map(entities => this._computeStats(entities))); readonly activeDossier$: Observable; - readonly dossierChanged$ = new Subject(); private readonly _activeDossier$ = new BehaviorSubject(undefined); constructor( @@ -38,7 +36,7 @@ export class DossiersService extends EntitiesService { super(TEMPORARY_INJECTOR(_injector), 'dossier'); this.activeDossier$ = this._activeDossier$.asObservable(); - _router.events.pipe(getRelatedEvents).subscribe((event: ActivationEnd) => { + _router.events.pipe(currentComponentRoute).subscribe((event: ActivationEnd) => { const dossierId = event.snapshot.paramMap.get('dossierId'); const sameIdAsCurrentActive = dossierId === this._activeDossier$.getValue()?.dossierId; @@ -79,24 +77,17 @@ export class DossiersService extends EntitiesService { find(dossierId: string): Dossier | undefined; find(dossierId: string, fileId: string): File | undefined; find(dossierId: string, fileId?: string): Dossier | File | undefined { - const dossier = this.all.find(item => item.dossierId === dossierId); + const dossier = super.find(dossierId); return fileId ? dossier?.files.find(file => file.fileId === fileId) : dossier; } replace(newDossier: Dossier) { - const dossiers = this.all.filter(dossier => dossier.dossierId !== newDossier.dossierId); - dossiers.push(newDossier); - this.setEntities(dossiers); - this.dossierChanged$.next(newDossier); + super.replace(newDossier); if (newDossier.dossierId === this.activeDossierId) { this._activeDossier$.next(newDossier); } } - has(dossierId: string): boolean { - return this.all.some(dossier => dossier.dossierId === dossierId); - } - async updateDossierDictionary(dossierTemplateId: string, dossierId: string) { // dossier exists, load its dictionary const dossier = this.find(dossierId); @@ -131,7 +122,6 @@ export class DossiersService extends EntitiesService { delete(dossier: Dossier): Observable { const updateDossiers = () => { - console.log(this.all.filter(d => d.dossierId !== dossier.dossierId)); this.setEntities(this.all.filter(d => d.dossierId !== dossier.dossierId)); }; const showToast = () => { diff --git a/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.ts b/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.ts index 7c60c66a5..4dae7a6f7 100644 --- a/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.ts +++ b/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.ts @@ -107,7 +107,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD this._setup(); }); - this.addSubscription = this.dossiersService.dossierChanged$.subscribe(() => { + this.addSubscription = this.dossiersService.entityChanged$.subscribe(() => { this._setup(); }); } diff --git a/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.html b/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.html index 5b097423b..c7dcdb041 100644 --- a/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.html +++ b/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.html @@ -30,6 +30,14 @@ {{ 'dictionary-overview.compare.compare' | translate }} +
+ + {{ selectDossier.dossierName | translate }} + + {{ dossier.dossierName }} + + +
{{ selectDossier.dossierName | translate }} 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 270dd1efe..659227060 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 @@ -24,6 +24,7 @@ export class DictionaryManagerComponent implements OnChanges, OnInit { readonly iconButtonTypes = IconButtonTypes; @Input() withFloatingActions = true; + @Input() filterByDossierTemplate = false; @Input() initialEntries: List; @Input() canEdit = false; @Output() readonly saveDictionary = new EventEmitter(); diff --git a/apps/red-ui/src/app/modules/shared/services/controller-wrappers/dossier-attributes.service.ts b/apps/red-ui/src/app/modules/shared/services/controller-wrappers/dossier-attributes.service.ts index b6fa9b25e..1a89f56a0 100644 --- a/apps/red-ui/src/app/modules/shared/services/controller-wrappers/dossier-attributes.service.ts +++ b/apps/red-ui/src/app/modules/shared/services/controller-wrappers/dossier-attributes.service.ts @@ -2,9 +2,9 @@ import { Injectable } from '@angular/core'; import { DossierAttribute, DossierAttributes, DossierAttributesControllerService, IDossierAttributeConfig } from '@redaction/red-ui-http'; import { Dossier } from '@state/model/dossier'; import { DossierAttributeWithValue } from '@models/dossier-attributes.model'; -import { AppStateService } from '@state/app-state.service'; import { Observable } from 'rxjs'; import { DossierAttributeConfig } from '@state/model/dossier-attribute-config'; +import { DossierTemplatesService } from '../../../dossier/services/dossier-templates.service'; @Injectable({ providedIn: 'root' @@ -12,7 +12,7 @@ import { DossierAttributeConfig } from '@state/model/dossier-attribute-config'; export class DossierAttributesService { constructor( private readonly _dossierAttributesControllerService: DossierAttributesControllerService, - private readonly _appStateService: AppStateService + private readonly _dossierTemplatesService: DossierTemplatesService ) {} async getValues(dossier: Dossier): Promise { @@ -31,11 +31,11 @@ export class DossierAttributesService { return this._dossierAttributesControllerService.setDossierAttributes({ dossierAttributeList }, dossier.id).toPromise(); } - deleteConfigs(ids: string[], dossierTemplateId = this._appStateService.activeDossierTemplateId): Promise { + deleteConfigs(ids: string[], dossierTemplateId = this._dossierTemplatesService.activeDossierTemplateId): Promise { return this._dossierAttributesControllerService.deleteDossierAttributesConfig(ids, dossierTemplateId).toPromise(); } - async getConfig(dossierTemplateId = this._appStateService.activeDossierTemplateId): Promise { + async getConfig(dossierTemplateId = this._dossierTemplatesService.activeDossierTemplateId): Promise { const config$ = this._dossierAttributesControllerService.getDossierAttributesConfig(dossierTemplateId); const result = (await config$.toPromise())?.dossierAttributeConfigs || []; return result.map(item => new DossierAttributeConfig(item)); @@ -43,7 +43,7 @@ export class DossierAttributesService { addOrUpdateConfig( attribute: IDossierAttributeConfig, - dossierTemplateId = this._appStateService.activeDossierTemplateId + dossierTemplateId = this._dossierTemplatesService.activeDossierTemplateId ): Observable { return this._dossierAttributesControllerService.addOrUpdateDossierAttributesConfig(attribute, dossierTemplateId); } diff --git a/apps/red-ui/src/app/state/app-state.guard.ts b/apps/red-ui/src/app/state/app-state.guard.ts index 113c461c2..5f4ba7ee7 100644 --- a/apps/red-ui/src/app/state/app-state.guard.ts +++ b/apps/red-ui/src/app/state/app-state.guard.ts @@ -3,6 +3,7 @@ import { ActivatedRouteSnapshot, CanActivate, Router } from '@angular/router'; import { AppStateService } from './app-state.service'; import { UserService } from '@services/user.service'; import { DossiersService } from '../modules/dossier/services/dossiers.service'; +import { DossierTemplatesService } from '../modules/dossier/services/dossier-templates.service'; @Injectable({ providedIn: 'root' @@ -11,6 +12,7 @@ export class AppStateGuard implements CanActivate { constructor( private readonly _appStateService: AppStateService, private readonly _dossiersService: DossiersService, + private readonly _dossierTemplatesService: DossierTemplatesService, private readonly _userService: UserService, private readonly _router: Router ) {} @@ -22,7 +24,7 @@ export class AppStateGuard implements CanActivate { if (this._userService.currentUser.isUser || this._userService.currentUser.isAdmin) { await this._userService.loadUsersIfNecessary(); - await this._appStateService.loadDossierTemplatesIfNecessary(); + await this._dossierTemplatesService.loadAllIfEmpty(); await this._appStateService.loadDictionaryDataIfNecessary(); } @@ -42,7 +44,7 @@ export class AppStateGuard implements CanActivate { return false; } - if (dossierTemplateId && !this._appStateService.getDossierTemplateById(dossierTemplateId)) { + if (dossierTemplateId && !this._dossierTemplatesService.find(dossierTemplateId)) { await this._router.navigate(['main', 'admin', 'dossier-templates']); return false; } diff --git a/apps/red-ui/src/app/state/app-state.service.ts b/apps/red-ui/src/app/state/app-state.service.ts index 9d91b6165..0b61648c2 100644 --- a/apps/red-ui/src/app/state/app-state.service.ts +++ b/apps/red-ui/src/app/state/app-state.service.ts @@ -1,10 +1,10 @@ import { Injectable } from '@angular/core'; import { Colors, IFile, ReanalysisControllerService } from '@redaction/red-ui-http'; -import { ActivationEnd, Event, ResolveStart, Router } from '@angular/router'; +import { ActivationEnd, Router } from '@angular/router'; import { UserService } from '@services/user.service'; import { forkJoin, Observable, of, Subject } from 'rxjs'; import { catchError, filter, first, map, tap } from 'rxjs/operators'; -import { FALLBACK_COLOR, hexToRgb } from '@utils/functions'; +import { currentComponentRoute, FALLBACK_COLOR, hexToRgb } from '@utils/functions'; import { File } from '@models/file/file'; import { Dossier } from './model/dossier'; import { TypeValue } from '@models/file/type-value'; @@ -15,26 +15,20 @@ import { FilesService } from '../modules/dossier/services/files.service'; import { DictionaryService } from '@shared/services/dictionary.service'; import { DossierTemplatesService } from '../modules/dossier/services/dossier-templates.service'; import { FileAttributesService } from '../modules/dossier/services/file-attributes.service'; -import { BaseScreenComponent } from '@components/base-screen/base-screen.component'; export interface AppState { - dossierTemplates: DossierTemplate[]; activeFileId?: string; - activeDossierTemplateId?: string; activeDictionaryType?: string; } -const getRelatedEvents = filter(event => event instanceof ActivationEnd && event.snapshot.component !== BaseScreenComponent); - @Injectable({ providedIn: 'root' }) export class AppStateService { readonly fileChanged$ = new Subject(); readonly fileReanalysed$ = new Subject(); - readonly dossierTemplateChanged$ = new Subject(); - private _appState: AppState; + private _appState: AppState = {}; constructor( private readonly _router: Router, @@ -47,11 +41,7 @@ export class AppStateService { private readonly _fileAttributesService: FileAttributesService, private readonly _userPreferenceService: UserPreferenceService ) { - this._appState = { - dossierTemplates: [] - }; - - _router.events.pipe(getRelatedEvents).subscribe(async (event: ActivationEnd) => { + _router.events.pipe(currentComponentRoute).subscribe(async (event: ActivationEnd) => { const fileId = event.snapshot.paramMap.get('fileId'); const sameIdAsCurrentActive = fileId === this.activeFileId; @@ -80,16 +70,8 @@ export class AppStateService { return this._dictionaryData; } - get activeDossierTemplateId(): string | undefined { - return this._appState.activeDossierTemplateId; - } - - get activeDossierTemplate(): DossierTemplate | undefined { - return this.getDossierTemplateById(this.activeDossierTemplateId); - } - get dossierTemplates(): DossierTemplate[] { - return this._appState.dossierTemplates; + return this._dossierTemplatesService.all; } get activeDictionaryType(): string | undefined { @@ -97,11 +79,9 @@ export class AppStateService { } get activeDictionary(): TypeValue | undefined { - return this.activeDossierTemplateId && - this.activeDictionaryType && - this.dictionaryData && - this.dictionaryData[this.activeDossierTemplateId] - ? this.dictionaryData[this.activeDossierTemplateId][this.activeDictionaryType] + const activeDossierTemplateId = this._dossierTemplatesService.activeDossierTemplateId; + return activeDossierTemplateId && this.activeDictionaryType && this.dictionaryData && this.dictionaryData[activeDossierTemplateId] + ? this.dictionaryData[activeDossierTemplateId][this.activeDictionaryType] : undefined; } @@ -113,10 +93,6 @@ export class AppStateService { return this._appState.activeFileId; } - private static _isFileOverviewRoute(event: Event) { - return event instanceof ResolveStart && event.url.includes('/main/dossiers/') && event.url.includes('/file/'); - } - async reloadActiveDossierFilesIfNecessary() { if (this._dossiersService.activeDossier?.hasPendingOrProcessing) { await this.reloadActiveDossierFiles(); @@ -139,13 +115,6 @@ export class AppStateService { return color ?? this._dictionaryData[dossierTemplateId]['default'].hexColor; } - getDossierTemplateById(id?: string): DossierTemplate | undefined { - if (!id) { - return undefined; - } - return this.dossierTemplates.find(rs => rs.dossierTemplateId === id); - } - getDictionaryTypeValue(key: string, dossierTemplateId = this._dossiersService.activeDossier.dossierTemplateId): TypeValue | undefined { if (!dossierTemplateId) { dossierTemplateId = this.dossierTemplates.length > 0 ? this.dossierTemplates[0].dossierTemplateId : undefined; @@ -226,29 +195,18 @@ export class AppStateService { await this._updateLastActiveFileForDossier(dossierId, fileId); } - async activateDossierTemplate(dossierTemplateId: string) { - this._appState.activeDossierTemplateId = dossierTemplateId; - this._appState.activeDictionaryType = null; - if (!this.activeDossierTemplate) { - this._appState.activeDossierTemplateId = null; - await this._router.navigate(['/main/admin/dossier-templates']); - } - } - - async activateDictionary(dictionaryType: string, dossierTemplateId: string) { - await this.activateDossierTemplate(dossierTemplateId); - if (this.activeDossierTemplate) { + async activateDictionary(dictionaryType: string) { + if (this._dossierTemplatesService.activeDossierTemplate) { this._appState.activeDictionaryType = dictionaryType; if (!this.activeDictionary) { this._appState.activeDictionaryType = null; - await this._router.navigate(['/main/admin/dossier-templates/' + this.activeDossierTemplateId]); + await this._router.navigate([this._dossierTemplatesService.activeDossierTemplate.routerLink]); } } } reset() { this._appState.activeFileId = null; - this._appState.activeDossierTemplateId = null; this._appState.activeDictionaryType = null; } @@ -258,33 +216,15 @@ export class AppStateService { } } - async loadAllDossierTemplates() { - const dossierTemplates = await this._dossierTemplatesService.get().toPromise(); - this._appState.dossierTemplates = dossierTemplates.map(dossierTemplate => new DossierTemplate(dossierTemplate)); - for (const dossierTemplate of this._appState.dossierTemplates) { - await this._fileAttributesService.getFileAttributesConfig(dossierTemplate.dossierTemplateId).toPromise(); - } - } - async refreshDossierTemplate(dossierTemplateId: string) { const dossierTemplate = await this._dossierTemplatesService.get(dossierTemplateId).toPromise(); await this._fileAttributesService.getFileAttributesConfig(dossierTemplateId).toPromise(); - Object.assign( - this._appState.dossierTemplates.find(d => d.dossierTemplateId === dossierTemplateId), - new DossierTemplate(dossierTemplate) - ); + const newDossierTemplate = new DossierTemplate(dossierTemplate); + this._dossierTemplatesService.replace(newDossierTemplate); await this.refreshDossierTemplateDictionaryData(dossierTemplateId); - - this.dossierTemplateChanged$.next(this._appState.dossierTemplates.find(d => d.dossierTemplateId === dossierTemplateId)); - } - - async loadDossierTemplatesIfNecessary() { - if (!this._appState.dossierTemplates.length) { - await this.loadAllDossierTemplates(); - } } async loadAllDossiersIfNecessary() { diff --git a/apps/red-ui/src/app/utils/functions.ts b/apps/red-ui/src/app/utils/functions.ts index 28d8757e9..9410bf00c 100644 --- a/apps/red-ui/src/app/utils/functions.ts +++ b/apps/red-ui/src/app/utils/functions.ts @@ -1,5 +1,12 @@ import * as moment from 'moment'; import { List } from '@iqser/common-ui'; +import { filter } from 'rxjs/operators'; +import { ActivationEnd } from '@angular/router'; +import { BaseScreenComponent } from '@components/base-screen/base-screen.component'; + +export const currentComponentRoute = filter( + event => event instanceof ActivationEnd && !!event.snapshot.component && event.snapshot.component !== BaseScreenComponent +); export const FALLBACK_COLOR = '#CCCCCC';