diff --git a/apps/red-ui/src/app/components/downloads-list-screen/downloads-list-screen.component.ts b/apps/red-ui/src/app/components/downloads-list-screen/downloads-list-screen.component.ts index a24666a62..b6a0fc9a1 100644 --- a/apps/red-ui/src/app/components/downloads-list-screen/downloads-list-screen.component.ts +++ b/apps/red-ui/src/app/components/downloads-list-screen/downloads-list-screen.component.ts @@ -1,31 +1,19 @@ -import { Component, forwardRef, Injector } from '@angular/core'; +import { Component } from '@angular/core'; import { FileDownloadService } from '@upload-download/services/file-download.service'; import { DownloadStatus } from '@red/domain'; -import { - CircleButtonTypes, - DefaultListingServicesTmp, - EntitiesService, - ListingComponent, - LoadingService, - TableColumnConfig, -} from '@iqser/common-ui'; +import { CircleButtonTypes, ListingComponent, listingProvidersFactory, LoadingService, TableColumnConfig } from '@iqser/common-ui'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { RouterHistoryService } from '@services/router-history.service'; -import { firstValueFrom, interval } from 'rxjs'; -import { switchMap } from 'rxjs/operators'; +import { firstValueFrom } from 'rxjs'; @Component({ selector: 'redaction-downloads-list-screen', templateUrl: './downloads-list-screen.component.html', styleUrls: ['./downloads-list-screen.component.scss'], - providers: [ - ...DefaultListingServicesTmp, - { provide: EntitiesService, useExisting: FileDownloadService }, - { - provide: ListingComponent, - useExisting: forwardRef(() => DownloadsListScreenComponent), - }, - ], + providers: listingProvidersFactory({ + entitiesService: FileDownloadService, + component: DownloadsListScreenComponent, + }), }) export class DownloadsListScreenComponent extends ListingComponent { readonly circleButtonTypes = CircleButtonTypes; @@ -38,12 +26,11 @@ export class DownloadsListScreenComponent extends ListingComponent this._loadData(), 5000); } diff --git a/apps/red-ui/src/app/modules/account/services/notification-preferences.service.ts b/apps/red-ui/src/app/modules/account/services/notification-preferences.service.ts index c2248de92..243d4837f 100644 --- a/apps/red-ui/src/app/modules/account/services/notification-preferences.service.ts +++ b/apps/red-ui/src/app/modules/account/services/notification-preferences.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Injector } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { GenericService } from '@iqser/common-ui'; import { Observable, of, switchMap } from 'rxjs'; import { UserService } from '@services/user.service'; @@ -8,13 +8,9 @@ import { NotificationsService } from '@services/notifications.service'; @Injectable() export class NotificationPreferencesService extends GenericService { - constructor( - protected readonly _injector: Injector, - private readonly _userService: UserService, - private readonly _notificationsService: NotificationsService, - ) { - super(_injector, 'notification-preferences'); - } + protected readonly _defaultModelPath = 'notification-preferences'; + + readonly #notificationsService = inject(NotificationsService); private get _defaultPreferences(): INotificationPreferences { return { @@ -31,6 +27,6 @@ export class NotificationPreferencesService extends GenericService { - return super._post(notificationPreferences).pipe(switchMap(() => this._notificationsService.loadAll())); + return super._post(notificationPreferences).pipe(switchMap(() => this.#notificationsService.loadAll())); } } diff --git a/apps/red-ui/src/app/modules/admin/base-entity-screen/base-entity-screen.component.ts b/apps/red-ui/src/app/modules/admin/base-entity-screen/base-entity-screen.component.ts index 654906fa3..23db68ea2 100644 --- a/apps/red-ui/src/app/modules/admin/base-entity-screen/base-entity-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/base-entity-screen/base-entity-screen.component.ts @@ -1,10 +1,10 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; -import { DOSSIER_TEMPLATE_ID, ENTITY_TYPE } from '@red/domain'; -import { ActivatedRoute, Router } from '@angular/router'; +import { DOSSIER_TEMPLATE_ID, DossierTemplate, ENTITY_TYPE } from '@red/domain'; +import { Router } from '@angular/router'; import { firstValueFrom, Observable } from 'rxjs'; import { AdminDialogService } from '../services/admin-dialog.service'; import { DictionaryService } from '@services/entity-services/dictionary.service'; -import { LoadingService } from '@iqser/common-ui'; +import { getParam, LoadingService } from '@iqser/common-ui'; import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service'; import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service'; import { map } from 'rxjs/operators'; @@ -17,11 +17,10 @@ import { PermissionsService } from '@services/permissions.service'; export class BaseEntityScreenComponent { readonly disabledItems$: Observable; readonly canDeleteEntity$: Observable; - readonly #dossierTemplateId: string; - readonly #entityType: string; + readonly #dossierTemplateId: string = getParam(DOSSIER_TEMPLATE_ID); + readonly #entityType: string = getParam(ENTITY_TYPE); constructor( - route: ActivatedRoute, private readonly _router: Router, dictionaryMapService: DictionariesMapService, private readonly _loadingService: LoadingService, @@ -30,8 +29,6 @@ export class BaseEntityScreenComponent { private readonly _permissionsService: PermissionsService, private readonly _dossierTemplatesService: DossierTemplatesService, ) { - this.#dossierTemplateId = route.snapshot.paramMap.get(DOSSIER_TEMPLATE_ID); - this.#entityType = route.snapshot.paramMap.get(ENTITY_TYPE); const entity$ = dictionaryMapService.watch$(this.#dossierTemplateId, this.#entityType); this.canDeleteEntity$ = entity$.pipe(map(entity => this._permissionsService.canDeleteEntities(entity))); this.disabledItems$ = entity$.pipe( diff --git a/apps/red-ui/src/app/modules/admin/base-watermark-screen/base-watermark-screen.component.ts b/apps/red-ui/src/app/modules/admin/base-watermark-screen/base-watermark-screen.component.ts index c812d7357..5a7dd87db 100644 --- a/apps/red-ui/src/app/modules/admin/base-watermark-screen/base-watermark-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/base-watermark-screen/base-watermark-screen.component.ts @@ -1,10 +1,10 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import { firstValueFrom } from 'rxjs'; import { AdminDialogService } from '../services/admin-dialog.service'; -import { ConfirmationDialogInput, LoadingService, Toaster } from '@iqser/common-ui'; +import { ConfirmationDialogInput, getParam, LoadingService, Toaster } from '@iqser/common-ui'; import { WatermarkService } from '../../../services/entity-services/watermark.service'; import { DOSSIER_TEMPLATE_ID, WATERMARK_ID } from '@red/domain'; -import { ActivatedRoute, Router } from '@angular/router'; +import { Router } from '@angular/router'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; @Component({ @@ -12,19 +12,19 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class BaseWatermarkScreenComponent { - readonly #dossierTemplateId: string; - readonly #watermarkId: string; + readonly #dossierTemplateId: string = getParam(DOSSIER_TEMPLATE_ID); + readonly #watermarkId: string = getParam(WATERMARK_ID); constructor( private readonly _dialogService: AdminDialogService, private readonly _loadingService: LoadingService, private readonly _watermarkService: WatermarkService, private readonly _toaster: Toaster, - private readonly _route: ActivatedRoute, private readonly _router: Router, - ) { - this.#dossierTemplateId = _route.snapshot.paramMap.get(DOSSIER_TEMPLATE_ID); - this.#watermarkId = _route.snapshot.paramMap.get(WATERMARK_ID); + ) {} + + get editMode(): boolean { + return !!Number(this.#watermarkId); } async openDeleteWatermarkDialog($event: MouseEvent): Promise { @@ -50,8 +50,4 @@ export class BaseWatermarkScreenComponent { await this._router.navigate([`/main/admin/dossier-templates/${this.#dossierTemplateId}/watermarks`]); this._loadingService.stop(); } - - get editMode(): boolean { - return !!Number(this.#watermarkId); - } } diff --git a/apps/red-ui/src/app/modules/admin/dialogs/add-edit-dossier-attribute-dialog/add-edit-dossier-attribute-dialog.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/add-edit-dossier-attribute-dialog/add-edit-dossier-attribute-dialog.component.ts index 2a6cb505f..f4b5fd83f 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/add-edit-dossier-attribute-dialog/add-edit-dossier-attribute-dialog.component.ts +++ b/apps/red-ui/src/app/modules/admin/dialogs/add-edit-dossier-attribute-dialog/add-edit-dossier-attribute-dialog.component.ts @@ -1,8 +1,8 @@ -import { Component, HostListener, Inject, Injector, OnDestroy } from '@angular/core'; -import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { Component, HostListener, Inject, OnDestroy } from '@angular/core'; +import { UntypedFormGroup, Validators } from '@angular/forms'; import { DossierAttributeConfigTypes, FileAttributeConfigTypes, IDossierAttributeConfig } from '@red/domain'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { BaseDialogComponent, IqserEventTarget, LoadingService, Toaster } from '@iqser/common-ui'; +import { BaseDialogComponent, IqserEventTarget } from '@iqser/common-ui'; import { HttpErrorResponse } from '@angular/common/http'; import { DossierAttributesService } from '@services/entity-services/dossier-attributes.service'; import { dossierAttributeTypesTranslations } from '@translations/dossier-attribute-types-translations'; @@ -18,16 +18,12 @@ export class AddEditDossierAttributeDialogComponent extends BaseDialogComponent readonly typeOptions = Object.keys(DossierAttributeConfigTypes); constructor( - private readonly _formBuilder: UntypedFormBuilder, - private readonly _loadingService: LoadingService, private readonly _dossierAttributesService: DossierAttributesService, - private readonly _toaster: Toaster, - protected readonly _injector: Injector, protected readonly _dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) readonly data: { readonly dossierAttribute: IDossierAttributeConfig; dossierTemplateId: string }, ) { - super(_injector, _dialogRef, !!data.dossierAttribute); + super(_dialogRef, !!data.dossierAttribute); this.form = this._getForm(this.dossierAttribute); this.initialFormValue = this.form.getRawValue(); } diff --git a/apps/red-ui/src/app/modules/admin/dialogs/add-edit-dossier-state-dialog/add-edit-dossier-state-dialog.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/add-edit-dossier-state-dialog/add-edit-dossier-state-dialog.component.ts index da0c91ecb..f7c58e3d7 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/add-edit-dossier-state-dialog/add-edit-dossier-state-dialog.component.ts +++ b/apps/red-ui/src/app/modules/admin/dialogs/add-edit-dossier-state-dialog/add-edit-dossier-state-dialog.component.ts @@ -1,6 +1,6 @@ -import { ChangeDetectionStrategy, Component, Inject, Injector } from '@angular/core'; -import { BaseDialogComponent, LoadingService, Toaster } from '@iqser/common-ui'; -import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { ChangeDetectionStrategy, Component, Inject } from '@angular/core'; +import { BaseDialogComponent } from '@iqser/common-ui'; +import { UntypedFormGroup, Validators } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { IDossierState } from '@red/domain'; import { firstValueFrom } from 'rxjs'; @@ -20,15 +20,11 @@ interface DialogData { }) export class AddEditDossierStateDialogComponent extends BaseDialogComponent { constructor( - private readonly _formBuilder: UntypedFormBuilder, - private readonly _loadingService: LoadingService, - private readonly _toaster: Toaster, private readonly _dossierStatesService: DossierStatesService, - protected readonly _injector: Injector, protected readonly _dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) readonly data: DialogData, ) { - super(_injector, _dialogRef, !!data.dossierState); + super(_dialogRef, !!data.dossierState); this.form = this.#getForm(); this.initialFormValue = this.form.getRawValue(); } diff --git a/apps/red-ui/src/app/modules/admin/dialogs/add-edit-dossier-template-dialog/add-edit-clone-dossier-template-dialog.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/add-edit-dossier-template-dialog/add-edit-clone-dossier-template-dialog.component.ts index 55b53c75e..0dd833c18 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/add-edit-dossier-template-dialog/add-edit-clone-dossier-template-dialog.component.ts +++ b/apps/red-ui/src/app/modules/admin/dialogs/add-edit-dossier-template-dialog/add-edit-clone-dossier-template-dialog.component.ts @@ -1,14 +1,13 @@ -import { Component, Inject, Injector } from '@angular/core'; -import { AbstractControl, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { Component, Inject } from '@angular/core'; +import { AbstractControl, UntypedFormGroup, Validators } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { applyIntervalConstraints } from '@utils/date-inputs-utils'; import { downloadTypesTranslations } from '@translations/download-types-translations'; import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service'; -import { BaseDialogComponent, LoadingService, Toaster } from '@iqser/common-ui'; +import { BaseDialogComponent } from '@iqser/common-ui'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { DossierTemplate, DownloadFileType, IDossierTemplate } from '@red/domain'; import { HttpStatusCode } from '@angular/common/http'; -import { DictionaryService } from '@services/entity-services/dictionary.service'; import { firstValueFrom } from 'rxjs'; import dayjs, { Dayjs } from 'dayjs'; @@ -36,16 +35,11 @@ export class AddEditCloneDossierTemplateDialogComponent extends BaseDialogCompon private _lastValidTo: Dayjs; constructor( - private readonly _toaster: Toaster, private readonly _dossierTemplatesService: DossierTemplatesService, - private readonly _dictionaryService: DictionaryService, - private readonly _formBuilder: UntypedFormBuilder, - protected readonly _injector: Injector, protected readonly _dialogRef: MatDialogRef, - private readonly _loadingService: LoadingService, @Inject(MAT_DIALOG_DATA) readonly data: EditCloneTemplateData, ) { - super(_injector, _dialogRef, !!data && !data.clone); + super(_dialogRef, !!data && !data.clone); this.dossierTemplate = this._dossierTemplatesService.find(this.data?.dossierTemplateId); this.form = this._getForm(); this.initialFormValue = this.form.getRawValue(); @@ -56,6 +50,13 @@ export class AddEditCloneDossierTemplateDialogComponent extends BaseDialogCompon this._previousValidTo = this._lastValidTo = this.form.get('validTo').value; } + get disabled(): boolean { + if (!this.data?.clone) { + return super.disabled; + } + return !this.valid; + } + toggleHasValid(extremity: string) { if (extremity === 'from') { this.hasValidFrom = !this.hasValidFrom; @@ -92,6 +93,16 @@ export class AddEditCloneDossierTemplateDialogComponent extends BaseDialogCompon this._loadingService.stop(); } + applyValidityIntervalConstraints(): void { + const formValue = this.form.value; + applyIntervalConstraints(formValue, this._previousValidFrom, this._previousValidTo, this.form, 'validFrom', 'validTo'); + + this._previousValidFrom = this.form.get('validFrom').value; + this._previousValidTo = this.form.get('validTo').value; + this._lastValidFrom = this._previousValidFrom || this._lastValidFrom; + this._lastValidTo = this._previousValidTo || this._lastValidTo; + } + private _getForm(): UntypedFormGroup { return this._formBuilder.group({ name: [this._getCloneName(), Validators.required], @@ -134,16 +145,6 @@ export class AddEditCloneDossierTemplateDialogComponent extends BaseDialogCompon return this.dossierTemplate?.name; } - applyValidityIntervalConstraints(): void { - const formValue = this.form.value; - applyIntervalConstraints(formValue, this._previousValidFrom, this._previousValidTo, this.form, 'validFrom', 'validTo'); - - this._previousValidFrom = this.form.get('validFrom').value; - this._previousValidTo = this.form.get('validTo').value; - this._lastValidFrom = this._previousValidFrom || this._lastValidFrom; - this._lastValidTo = this._previousValidTo || this._lastValidTo; - } - private _requiredIfValidator(predicate) { return (formControl: AbstractControl) => { if (!formControl.parent) { @@ -155,11 +156,4 @@ export class AddEditCloneDossierTemplateDialogComponent extends BaseDialogCompon return null; }; } - - get disabled(): boolean { - if (!this.data?.clone) { - return super.disabled; - } - return !this.valid; - } } diff --git a/apps/red-ui/src/app/modules/admin/dialogs/add-edit-file-attribute-dialog/add-edit-file-attribute-dialog.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/add-edit-file-attribute-dialog/add-edit-file-attribute-dialog.component.ts index f721f3399..0400e67c0 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/add-edit-file-attribute-dialog/add-edit-file-attribute-dialog.component.ts +++ b/apps/red-ui/src/app/modules/admin/dialogs/add-edit-file-attribute-dialog/add-edit-file-attribute-dialog.component.ts @@ -1,9 +1,8 @@ -import { ChangeDetectionStrategy, Component, Inject, Injector } from '@angular/core'; -import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { ChangeDetectionStrategy, Component, Inject } from '@angular/core'; +import { UntypedFormGroup, Validators } from '@angular/forms'; import { FileAttributeConfigTypes, IFileAttributeConfig } from '@red/domain'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { fileAttributeTypesTranslations } from '@translations/file-attribute-types-translations'; -import { FileAttributesService } from '@services/entity-services/file-attributes.service'; import { BaseDialogComponent } from '@iqser/common-ui'; @Component({ @@ -13,28 +12,25 @@ import { BaseDialogComponent } from '@iqser/common-ui'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class AddEditFileAttributeDialogComponent extends BaseDialogComponent { - DISPLAYED_FILTERABLE_LIMIT = 3; - translations = fileAttributeTypesTranslations; + readonly DISPLAYED_FILTERABLE_LIMIT = 3; + readonly translations = fileAttributeTypesTranslations; fileAttribute: IFileAttributeConfig = this.data.fileAttribute; - dossierTemplateId: string = this.data.dossierTemplateId; + readonly dossierTemplateId: string = this.data.dossierTemplateId; readonly typeOptions = Object.keys(FileAttributeConfigTypes); readonly canSetDisplayed!: boolean; readonly canSetFilterable!: boolean; constructor( - private readonly _formBuilder: UntypedFormBuilder, - private readonly _fileAttributesService: FileAttributesService, - protected readonly _injector: Injector, protected readonly _dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) - public data: { + readonly data: { fileAttribute: IFileAttributeConfig; dossierTemplateId: string; numberOfDisplayedAttrs: number; numberOfFilterableAttrs: number; }, ) { - super(_injector, _dialogRef, !!data.fileAttribute); + super(_dialogRef, !!data.fileAttribute); this.canSetDisplayed = data.numberOfDisplayedAttrs < this.DISPLAYED_FILTERABLE_LIMIT || data.fileAttribute?.displayedInFileList; this.canSetFilterable = data.numberOfFilterableAttrs < this.DISPLAYED_FILTERABLE_LIMIT || data.fileAttribute?.filterable; this.form = this._getForm(this.fileAttribute); diff --git a/apps/red-ui/src/app/modules/admin/dialogs/add-edit-user-dialog/add-edit-user-dialog.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/add-edit-user-dialog/add-edit-user-dialog.component.ts index a215c215d..491ae77d3 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/add-edit-user-dialog/add-edit-user-dialog.component.ts +++ b/apps/red-ui/src/app/modules/admin/dialogs/add-edit-user-dialog/add-edit-user-dialog.component.ts @@ -1,4 +1,4 @@ -import { Component, Inject, Injector, ViewChild } from '@angular/core'; +import { Component, Inject, ViewChild } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { User } from '@red/domain'; import { UserDetailsComponent } from './user-details/user-details.component'; @@ -13,12 +13,8 @@ export class AddEditUserDialogComponent extends BaseDialogComponent { resettingPassword = false; @ViewChild(UserDetailsComponent) private readonly _userDetailsComponent: UserDetailsComponent; - constructor( - protected readonly _injector: Injector, - protected readonly _dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) readonly user: User, - ) { - super(_injector, _dialogRef, !!user); + constructor(protected readonly _dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) readonly user: User) { + super(_dialogRef, !!user); } get changed(): boolean { diff --git a/apps/red-ui/src/app/modules/admin/dialogs/add-entity-dialog/add-entity-dialog.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/add-entity-dialog/add-entity-dialog.component.ts index d51cea4dd..0390822ea 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/add-entity-dialog/add-entity-dialog.component.ts +++ b/apps/red-ui/src/app/modules/admin/dialogs/add-entity-dialog/add-entity-dialog.component.ts @@ -1,7 +1,6 @@ -import { ChangeDetectionStrategy, Component, Inject, Injector, ViewChild } from '@angular/core'; +import { ChangeDetectionStrategy, Component, inject, Inject, ViewChild } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { TranslateService } from '@ngx-translate/core'; -import { UserService } from '@services/user.service'; import { AddEditEntityComponent } from '../../../shared/components/add-edit-entity/add-edit-entity.component'; import { BaseDialogComponent } from '@iqser/common-ui'; @@ -15,19 +14,16 @@ interface DialogData { changeDetection: ChangeDetectionStrategy.OnPush, }) export class AddEntityDialogComponent extends BaseDialogComponent { - readonly dialogHeader = this._translateService.instant('add-entity.title'); + readonly dialogHeader = inject(TranslateService).instant('add-entity.title'); readonly dossierTemplateId = this._data.dossierTemplateId; @ViewChild(AddEditEntityComponent, { static: true }) private readonly _addEditEntityComponent: AddEditEntityComponent; constructor( - readonly userService: UserService, - private readonly _translateService: TranslateService, - protected readonly _injector: Injector, protected readonly _dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) private readonly _data: DialogData, ) { - super(_injector, _dialogRef, false); + super(_dialogRef, false); } get valid(): boolean { diff --git a/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/configure-certificate-dialog.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/configure-certificate-dialog.component.ts index 4ae9ad1b6..428970caf 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/configure-certificate-dialog.component.ts +++ b/apps/red-ui/src/app/modules/admin/dialogs/configure-digital-signature-dialog/configure-certificate-dialog.component.ts @@ -1,13 +1,12 @@ -import { ChangeDetectorRef, Component, Injector, ViewChild } from '@angular/core'; +import { ChangeDetectorRef, Component, ViewChild } from '@angular/core'; import { digitalSignatureDialogTranslations } from '../../translations/digital-signature-dialog-translations'; -import { BaseDialogComponent, DetailsRadioOption, LoadingService, Toaster } from '@iqser/common-ui'; +import { BaseDialogComponent, DetailsRadioOption } from '@iqser/common-ui'; import { MatDialogRef } from '@angular/material/dialog'; import { PkcsSignatureConfigurationComponent } from './form/pkcs-signature-configuration/pkcs-signature-configuration.component'; import { KmsSignatureConfigurationComponent } from './form/kms-signature-configuration/kms-signature-configuration.component'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { HttpStatusCode } from '@angular/common/http'; import { DigitalSignatureOption, DigitalSignatureOptions } from '@red/domain'; -import { UntypedFormBuilder, FormGroup, Validators } from '@angular/forms'; const DEFAULT_DIALOG_WIDTH = '662px'; const KMS_SIGNATURE_DIALOG_WIDTH = '810px'; @@ -38,30 +37,16 @@ export class ConfigureCertificateDialogComponent extends BaseDialogComponent { isInConfiguration = false; constructor( - protected readonly _injector: Injector, protected readonly _dialogRef: MatDialogRef, - private readonly _formBuilder: UntypedFormBuilder, - private readonly _loadingService: LoadingService, - private readonly _toaster: Toaster, private readonly _changeDetectorRef: ChangeDetectorRef, ) { - super(_injector, _dialogRef); + super(_dialogRef); this.form = this._formBuilder.group({ option: [this.options[0]], }); } - toggleIsInConfiguration() { - this.isInConfiguration = !this.isInConfiguration; - if (this.isInConfiguration && this.selectedOption === DigitalSignatureOptions.KMS) { - this._dialogRef.updateSize(KMS_SIGNATURE_DIALOG_WIDTH); - } else { - this._dialogRef.updateSize(DEFAULT_DIALOG_WIDTH); - } - this._changeDetectorRef.detectChanges(); - } - get disabled(): boolean { return this.activeComponent?.disabled; } @@ -76,6 +61,16 @@ export class ConfigureCertificateDialogComponent extends BaseDialogComponent { return this.form.get('option').value.value; } + toggleIsInConfiguration() { + this.isInConfiguration = !this.isInConfiguration; + if (this.isInConfiguration && this.selectedOption === DigitalSignatureOptions.KMS) { + this._dialogRef.updateSize(KMS_SIGNATURE_DIALOG_WIDTH); + } else { + this._dialogRef.updateSize(DEFAULT_DIALOG_WIDTH); + } + this._changeDetectorRef.detectChanges(); + } + async save(): Promise { try { await this.activeComponent.save(); 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 329819e65..e73585a07 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 @@ -1,8 +1,8 @@ -import { Component, Inject, Injector } from '@angular/core'; +import { Component, Inject } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { DefaultColorType, IColors } from '@red/domain'; -import { BaseDialogComponent, Toaster } from '@iqser/common-ui'; -import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { BaseDialogComponent } from '@iqser/common-ui'; +import { UntypedFormGroup, Validators } from '@angular/forms'; import { TranslateService } from '@ngx-translate/core'; import { defaultColorsTranslations } from '@translations/default-colors-translations'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; @@ -20,21 +20,15 @@ interface IEditColorData { styleUrls: ['./edit-color-dialog.component.scss'], }) export class EditColorDialogComponent extends BaseDialogComponent { - translations = defaultColorsTranslations; - private readonly _dossierTemplateId: string; + readonly translations = defaultColorsTranslations; constructor( - private readonly _formBuilder: UntypedFormBuilder, private readonly _dictionaryService: DictionaryService, - private readonly _toaster: Toaster, private readonly _translateService: TranslateService, - protected readonly _injector: Injector, protected readonly _dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) - readonly data: IEditColorData, + @Inject(MAT_DIALOG_DATA) readonly data: IEditColorData, ) { - super(_injector, _dialogRef, true); - this._dossierTemplateId = data.dossierTemplateId; + super(_dialogRef, true); this.form = this._getForm(); this.initialFormValue = this.form.getRawValue(); @@ -47,7 +41,7 @@ export class EditColorDialogComponent extends BaseDialogComponent { }; try { - await firstValueFrom(this._dictionaryService.setColors(colors, this._dossierTemplateId)); + await firstValueFrom(this._dictionaryService.setColors(colors, this.data.dossierTemplateId)); this._dialogRef.close(true); const color = this._translateService.instant(defaultColorsTranslations[this.data.colorKey]); this._toaster.info(_('edit-color-dialog.success'), { params: { color: color } }); diff --git a/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-configurations-dialog/file-attributes-configurations-dialog.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-configurations-dialog/file-attributes-configurations-dialog.component.ts index 8760eed8b..a758fcfec 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-configurations-dialog/file-attributes-configurations-dialog.component.ts +++ b/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-configurations-dialog/file-attributes-configurations-dialog.component.ts @@ -1,11 +1,9 @@ -import { ChangeDetectionStrategy, Component, Inject, Injector, OnInit } from '@angular/core'; +import { ChangeDetectionStrategy, Component, Inject, OnInit } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { UntypedFormGroup, Validators } from '@angular/forms'; import { FileAttributeEncodingTypes, IFileAttributesConfig } from '@red/domain'; import { fileAttributeEncodingTypesTranslations } from '@translations/file-attribute-encoding-types-translations'; -import { BaseDialogComponent, Toaster } from '@iqser/common-ui'; -import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service'; -import { FileAttributesService } from '@services/entity-services/file-attributes.service'; +import { BaseDialogComponent } from '@iqser/common-ui'; @Component({ templateUrl: './file-attributes-configurations-dialog.component.html', @@ -18,15 +16,10 @@ export class FileAttributesConfigurationsDialogComponent extends BaseDialogCompo readonly #configuration = this._data.config; constructor( - private readonly _formBuilder: UntypedFormBuilder, - private readonly _dossierTemplatesService: DossierTemplatesService, - private readonly _fileAttributesService: FileAttributesService, - private readonly _toaster: Toaster, - protected readonly _injector: Injector, protected readonly _dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) private readonly _data: { config: IFileAttributesConfig; dossierTemplateId: string }, ) { - super(_injector, _dialogRef, true); + super(_dialogRef, true); this.form = this.#getForm(); this.initialFormValue = this.form.getRawValue(); } diff --git a/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/active-fields-listing/active-fields-listing.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/active-fields-listing/active-fields-listing.component.ts index 47303f061..8794a0719 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/active-fields-listing/active-fields-listing.component.ts +++ b/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/active-fields-listing/active-fields-listing.component.ts @@ -1,5 +1,5 @@ -import { Component, EventEmitter, forwardRef, Injector, Input, OnChanges, Output, SimpleChanges } from '@angular/core'; -import { CircleButtonTypes, DefaultListingServices, ListingComponent, TableColumnConfig } from '@iqser/common-ui'; +import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core'; +import { CircleButtonTypes, ListingComponent, listingProvidersFactory, TableColumnConfig } from '@iqser/common-ui'; import { fileAttributeTypesTranslations } from '@translations/file-attribute-types-translations'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { FileAttributeConfigTypes, IField } from '@red/domain'; @@ -8,7 +8,7 @@ import { FileAttributeConfigTypes, IField } from '@red/domain'; selector: 'redaction-active-fields-listing', templateUrl: './active-fields-listing.component.html', styleUrls: ['./active-fields-listing.component.scss'], - providers: [...DefaultListingServices, { provide: ListingComponent, useExisting: forwardRef(() => ActiveFieldsListingComponent) }], + providers: listingProvidersFactory(ActiveFieldsListingComponent), }) export class ActiveFieldsListingComponent extends ListingComponent implements OnChanges { readonly circleButtonTypes = CircleButtonTypes; @@ -44,10 +44,6 @@ export class ActiveFieldsListingComponent extends ListingComponent imple @Output() readonly setHoveredColumn = new EventEmitter(); @Output() readonly toggleFieldActive = new EventEmitter(); - constructor(protected readonly _injector: Injector) { - super(_injector); - } - ngOnChanges(changes: SimpleChanges): void { if (changes.entities) { this.entitiesService.setEntities(this.entities); diff --git a/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/file-attributes-csv-import-dialog.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/file-attributes-csv-import-dialog.component.ts index 96d892ca4..a6a696453 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/file-attributes-csv-import-dialog.component.ts +++ b/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/file-attributes-csv-import-dialog.component.ts @@ -1,10 +1,10 @@ -import { ChangeDetectionStrategy, Component, Inject, Injector } from '@angular/core'; +import { ChangeDetectionStrategy, Component, Inject } from '@angular/core'; import { AbstractControl, UntypedFormBuilder, UntypedFormGroup, ValidatorFn, Validators } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import * as Papa from 'papaparse'; import { firstValueFrom, Observable } from 'rxjs'; import { map, startWith } from 'rxjs/operators'; -import { DefaultListingServices, ListingComponent, TableColumnConfig, Toaster, trackByFactory } from '@iqser/common-ui'; +import { ListingComponent, listingProvidersFactory, TableColumnConfig, Toaster, trackByFactory } from '@iqser/common-ui'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { FileAttributeConfig, FileAttributeConfigTypes, IField, IFileAttributesConfig } from '@red/domain'; import { FileAttributesService } from '@services/entity-services/file-attributes.service'; @@ -18,7 +18,7 @@ interface IFileAttributesCSVImportData { @Component({ templateUrl: './file-attributes-csv-import-dialog.component.html', styleUrls: ['./file-attributes-csv-import-dialog.component.scss'], - providers: [...DefaultListingServices], + providers: listingProvidersFactory(), changeDetection: ChangeDetectionStrategy.OnPush, }) export class FileAttributesCsvImportDialogComponent extends ListingComponent { @@ -38,13 +38,12 @@ export class FileAttributesCsvImportDialogComponent extends ListingComponent, private readonly _fileAttributesService: FileAttributesService, @Inject(MAT_DIALOG_DATA) readonly data: IFileAttributesCSVImportData, ) { - super(_injector); + super(); this.form = this._getForm(); this.readFile(); } diff --git a/apps/red-ui/src/app/modules/admin/dialogs/smtp-auth-dialog/smtp-auth-dialog.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/smtp-auth-dialog/smtp-auth-dialog.component.ts index bfde86b33..df3d28727 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/smtp-auth-dialog/smtp-auth-dialog.component.ts +++ b/apps/red-ui/src/app/modules/admin/dialogs/smtp-auth-dialog/smtp-auth-dialog.component.ts @@ -1,7 +1,7 @@ -import { Component, Inject, Injector } from '@angular/core'; -import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { Component, Inject } from '@angular/core'; +import { UntypedFormGroup, Validators } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { UserService } from '@services/user.service'; +import { getCurrentUser } from '@services/user.service'; import { ISmtpConfiguration } from '@red/domain'; import { BaseDialogComponent } from '@iqser/common-ui'; @@ -11,26 +11,25 @@ import { BaseDialogComponent } from '@iqser/common-ui'; styleUrls: ['./smtp-auth-dialog.component.scss'], }) export class SmtpAuthDialogComponent extends BaseDialogComponent { + readonly #currentUser = getCurrentUser(); + constructor( - private readonly _formBuilder: UntypedFormBuilder, - private readonly _userService: UserService, - protected readonly _injector: Injector, protected readonly _dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) public data: ISmtpConfiguration, + @Inject(MAT_DIALOG_DATA) readonly data: ISmtpConfiguration, ) { - super(_injector, _dialogRef); + super(_dialogRef); this.form = this._getForm(); this.initialFormValue = this.form.getRawValue(); } - private _getForm(): UntypedFormGroup { - return this._formBuilder.group({ - user: [this.data?.user || this._userService.currentUser.email, [Validators.required]], - password: [this.data?.password, Validators.required], - }); - } - save() { this._dialogRef.close(this.form.getRawValue()); } + + private _getForm(): UntypedFormGroup { + return this._formBuilder.group({ + user: [this.data?.user || this.#currentUser.email, [Validators.required]], + password: [this.data?.password, Validators.required], + }); + } } diff --git a/apps/red-ui/src/app/modules/admin/screens/audit/audit-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/audit/audit-screen.component.ts index e9311f451..c0b26c416 100644 --- a/apps/red-ui/src/app/modules/admin/screens/audit/audit-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/audit/audit-screen.component.ts @@ -1,7 +1,7 @@ -import { Component, forwardRef, inject, Injector, OnDestroy, OnInit } from '@angular/core'; +import { Component, inject, OnDestroy, OnInit } from '@angular/core'; import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; import { applyIntervalConstraints } from '@utils/date-inputs-utils'; -import { DefaultListingServices, ListingComponent, LoadingService, TableColumnConfig } from '@iqser/common-ui'; +import { ListingComponent, listingProvidersFactory, LoadingService, TableColumnConfig } from '@iqser/common-ui'; import { auditCategoriesTranslations } from '@translations/audit-categories-translations'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { UserService } from '@services/user.service'; @@ -17,13 +17,13 @@ const PAGE_SIZE = 50; selector: 'redaction-audit-screen', templateUrl: './audit-screen.component.html', styleUrls: ['./audit-screen.component.scss'], - providers: [...DefaultListingServices, { provide: ListingComponent, useExisting: forwardRef(() => AuditScreenComponent) }], + providers: listingProvidersFactory(AuditScreenComponent), }) export class AuditScreenComponent extends ListingComponent implements OnInit, OnDestroy { readonly ALL_CATEGORIES = 'allCategories'; readonly ALL_USERS = _('audit-screen.all-users'); readonly translations = auditCategoriesTranslations; - readonly currentUser = this._userService.currentUser; + readonly currentUser = inject(UserService).currentUser; readonly form: UntypedFormGroup = this._getForm(); readonly routerHistoryService = inject(RouterHistoryService); categories: string[] = []; @@ -40,13 +40,11 @@ export class AuditScreenComponent extends ListingComponent implements OnI private _previousTo: Dayjs; constructor( - private readonly _userService: UserService, - protected readonly _injector: Injector, private readonly _formBuilder: UntypedFormBuilder, private readonly _loadingService: LoadingService, private readonly _auditService: AuditService, ) { - super(_injector); + super(); } get totalPages(): number { 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 ce8d058d5..e77e55af3 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 @@ -1,20 +1,20 @@ -import { ChangeDetectionStrategy, Component, forwardRef, Injector, OnInit } from '@angular/core'; -import { DefaultColorType, DOSSIER_TEMPLATE_ID, IColors, User } from '@red/domain'; +import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; +import { DefaultColorType, DOSSIER_TEMPLATE_ID, IColors } from '@red/domain'; import { AdminDialogService } from '../../services/admin-dialog.service'; import { CircleButtonTypes, - DefaultListingServices, + getParam, IListable, ListingComponent, + listingProvidersFactory, LoadingService, TableColumnConfig, } from '@iqser/common-ui'; import { defaultColorsTranslations } from '@translations/default-colors-translations'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; -import { UserService } from '@services/user.service'; +import { getCurrentUser } from '@services/user.service'; import { DictionaryService } from '@services/entity-services/dictionary.service'; import { firstValueFrom } from 'rxjs'; -import { ActivatedRoute } from '@angular/router'; interface ListItem extends IListable { readonly key: string; @@ -25,11 +25,11 @@ interface ListItem extends IListable { templateUrl: './default-colors-screen.component.html', styleUrls: ['./default-colors-screen.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, - providers: [...DefaultListingServices, { provide: ListingComponent, useExisting: forwardRef(() => DefaultColorsScreenComponent) }], + providers: listingProvidersFactory(DefaultColorsScreenComponent), }) export class DefaultColorsScreenComponent extends ListingComponent implements OnInit { readonly circleButtonTypes = CircleButtonTypes; - readonly currentUser: User; + readonly currentUser = getCurrentUser(); readonly translations = defaultColorsTranslations; readonly tableHeaderLabel = _('default-colors-screen.table-header.title'); readonly tableColumnConfigs: TableColumnConfig[] = [ @@ -38,19 +38,14 @@ export class DefaultColorsScreenComponent extends ListingComponent imp ]; #colorsObj: IColors; - readonly #dossierTemplateId: string; + readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID); constructor( - route: ActivatedRoute, - userService: UserService, - protected readonly _injector: Injector, private readonly _loadingService: LoadingService, private readonly _dialogService: AdminDialogService, private readonly _dictionaryService: DictionaryService, ) { - super(_injector); - this.currentUser = userService.currentUser; - this.#dossierTemplateId = route.snapshot.paramMap.get(DOSSIER_TEMPLATE_ID); + super(); } openEditColorDialog($event: MouseEvent, color: { key: DefaultColorType | string; value: string }) { 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 9c7080f7d..f7eee164c 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 @@ -1,10 +1,10 @@ -import { Component, forwardRef, Injector, OnInit, TemplateRef, ViewChild } from '@angular/core'; +import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core'; import { CircleButtonTypes, - DefaultListingServicesTmp, - EntitiesService, + getParam, IconButtonTypes, ListingComponent, + listingProvidersFactory, LoadingService, TableColumnConfig, } from '@iqser/common-ui'; @@ -12,25 +12,22 @@ import { AdminDialogService } from '../../services/admin-dialog.service'; import { DossierAttributesService } from '@services/entity-services/dossier-attributes.service'; import { dossierAttributeTypesTranslations } from '@translations/dossier-attribute-types-translations'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; -import { UserService } from '@services/user.service'; +import { getCurrentUser } from '@services/user.service'; import { DOSSIER_TEMPLATE_ID, DossierAttributeConfig, IDossierAttributeConfig } from '@red/domain'; import { firstValueFrom } from 'rxjs'; -import { ReportTemplateService } from '../../../../services/report-template.service'; -import { ActivatedRoute } from '@angular/router'; @Component({ templateUrl: './dossier-attributes-listing-screen.component.html', styleUrls: ['./dossier-attributes-listing-screen.component.scss'], - providers: [ - ...DefaultListingServicesTmp, - { provide: EntitiesService, useExisting: DossierAttributesService }, - { provide: ListingComponent, useExisting: forwardRef(() => DossierAttributesListingScreenComponent) }, - ], + providers: listingProvidersFactory({ + entitiesService: DossierAttributesService, + component: DossierAttributesListingScreenComponent, + }), }) export class DossierAttributesListingScreenComponent extends ListingComponent implements OnInit { readonly iconButtonTypes = IconButtonTypes; readonly circleButtonTypes = CircleButtonTypes; - readonly currentUser = this._userService.currentUser; + readonly currentUser = getCurrentUser(); readonly translations = dossierAttributeTypesTranslations; readonly tableHeaderLabel = _('dossier-attributes-listing.table-header.title'); readonly tableColumnConfigs: TableColumnConfig[] = [ @@ -39,19 +36,14 @@ export class DossierAttributesListingScreenComponent extends ListingComponent; - readonly #dossierTemplateId: string; + readonly #dossierTemplateId: string = getParam(DOSSIER_TEMPLATE_ID); constructor( - protected readonly _injector: Injector, - private readonly _dialogService: AdminDialogService, private readonly _loadingService: LoadingService, + private readonly _dialogService: AdminDialogService, private readonly _dossierAttributesService: DossierAttributesService, - private readonly _userService: UserService, - private readonly _reportTemplateService: ReportTemplateService, - private readonly _route: ActivatedRoute, ) { - super(_injector); - this.#dossierTemplateId = _route.snapshot.paramMap.get(DOSSIER_TEMPLATE_ID); + super(); } async ngOnInit(): Promise { diff --git a/apps/red-ui/src/app/modules/admin/screens/dossier-states-listing/dossier-states-listing-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/dossier-states-listing/dossier-states-listing-screen.component.ts index 7e7a5f349..4f042e556 100644 --- a/apps/red-ui/src/app/modules/admin/screens/dossier-states-listing/dossier-states-listing-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/dossier-states-listing/dossier-states-listing-screen.component.ts @@ -1,9 +1,10 @@ -import { ChangeDetectionStrategy, Component, forwardRef, Injector, OnDestroy, OnInit } from '@angular/core'; +import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core'; import { CircleButtonTypes, - DefaultListingServices, + getParam, IconButtonTypes, ListingComponent, + listingProvidersFactory, SortingOrders, TableColumnConfig, } from '@iqser/common-ui'; @@ -11,7 +12,6 @@ import { DonutChartConfig, DossierState, IDossierState } from '@red/domain'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { firstValueFrom, Observable } from 'rxjs'; import { AdminDialogService } from '../../services/admin-dialog.service'; -import { ActivatedRoute } from '@angular/router'; import { DossierStatesMapService } from '@services/entity-services/dossier-states-map.service'; import { map, tap } from 'rxjs/operators'; import { PermissionsService } from '@services/permissions.service'; @@ -21,10 +21,7 @@ import { DossierStatesService } from '@services/entity-services/dossier-states.s templateUrl: './dossier-states-listing-screen.component.html', styleUrls: ['./dossier-states-listing-screen.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, - providers: [ - ...DefaultListingServices, - { provide: ListingComponent, useExisting: forwardRef(() => DossierStatesListingScreenComponent) }, - ], + providers: listingProvidersFactory(DossierStatesListingScreenComponent), }) export class DossierStatesListingScreenComponent extends ListingComponent implements OnInit, OnDestroy { readonly iconButtonTypes = IconButtonTypes; @@ -36,18 +33,15 @@ export class DossierStatesListingScreenComponent extends ListingComponent; - readonly #dossierTemplateId: string; + readonly #dossierTemplateId = getParam('dossierTemplateId'); constructor( - protected readonly _injector: Injector, private readonly _dialogService: AdminDialogService, - private readonly _route: ActivatedRoute, private readonly _dossierStatesMapService: DossierStatesMapService, private readonly _dossierStatesService: DossierStatesService, readonly permissionsService: PermissionsService, ) { - super(_injector); - this.#dossierTemplateId = _route.snapshot.paramMap.get('dossierTemplateId'); + super(); this.chartConfig$ = this._dossierStatesMapService.get$(this.#dossierTemplateId).pipe( tap(states => this.entitiesService.setEntities(states)), map(states => this.#chartConfig(states)), diff --git a/apps/red-ui/src/app/modules/admin/screens/dossier-templates-listing/dossier-templates-listing-screen/dossier-templates-listing-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/dossier-templates-listing/dossier-templates-listing-screen/dossier-templates-listing-screen.component.ts index c662f9f2c..8018da695 100644 --- a/apps/red-ui/src/app/modules/admin/screens/dossier-templates-listing/dossier-templates-listing-screen/dossier-templates-listing-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/dossier-templates-listing/dossier-templates-listing-screen/dossier-templates-listing-screen.component.ts @@ -1,13 +1,12 @@ -import { ChangeDetectionStrategy, Component, forwardRef, Injector } from '@angular/core'; +import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; import { UserPreferenceService } from '@services/user-preference.service'; import { AdminDialogService } from '../../../services/admin-dialog.service'; import { DossierTemplate } from '@red/domain'; import { CircleButtonTypes, - DefaultListingServicesTmp, - EntitiesService, IconButtonTypes, ListingComponent, + listingProvidersFactory, LoadingService, TableColumnConfig, } from '@iqser/common-ui'; @@ -21,16 +20,15 @@ import { firstValueFrom } from 'rxjs'; templateUrl: './dossier-templates-listing-screen.component.html', styleUrls: ['./dossier-templates-listing-screen.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, - providers: [ - ...DefaultListingServicesTmp, - { provide: EntitiesService, useExisting: DossierTemplatesService }, - { provide: ListingComponent, useExisting: forwardRef(() => DossierTemplatesListingScreenComponent) }, - ], + providers: listingProvidersFactory({ + entitiesService: DossierTemplatesService, + component: DossierTemplatesListingScreenComponent, + }), }) export class DossierTemplatesListingScreenComponent extends ListingComponent { readonly iconButtonTypes = IconButtonTypes; readonly circleButtonTypes = CircleButtonTypes; - readonly currentUser = this._userService.currentUser; + readonly currentUser = inject(UserService).currentUser; readonly tableHeaderLabel = _('dossier-templates-listing.table-header.title'); readonly tableColumnConfigs: TableColumnConfig[] = [ { label: _('dossier-templates-listing.table-col-names.name'), sortByKey: 'searchKey', width: '3fr' }, @@ -43,15 +41,13 @@ export class DossierTemplatesListingScreenComponent extends ListingComponent EntitiesListingScreenComponent) }], + providers: listingProvidersFactory(EntitiesListingScreenComponent), }) export class EntitiesListingScreenComponent extends ListingComponent { readonly iconButtonTypes = IconButtonTypes; @@ -34,20 +34,17 @@ export class EntitiesListingScreenComponent extends ListingComponent { label: _('entities-listing.table-col-names.dictionary-entries') }, ]; readonly templateStats$: Observable; - readonly #dossierTemplateId: string; + readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID); constructor( - protected readonly _injector: Injector, private readonly _loadingService: LoadingService, private readonly _dictionariesMapService: DictionariesMapService, private readonly _dialogService: AdminDialogService, private readonly _dictionaryService: DictionaryService, private readonly _dossierTemplateStatsService: DossierTemplateStatsService, - private readonly _route: ActivatedRoute, readonly permissionsService: PermissionsService, ) { - super(_injector); - this.#dossierTemplateId = _route.snapshot.paramMap.get(DOSSIER_TEMPLATE_ID); + super(); this.templateStats$ = this._dossierTemplateStatsService.watch$(this.#dossierTemplateId).pipe(tap(() => this._loadDictionaryData())); } diff --git a/apps/red-ui/src/app/modules/admin/screens/entities/screens/info/info.component.ts b/apps/red-ui/src/app/modules/admin/screens/entities/screens/info/info.component.ts index 0397da7a3..96fc46421 100644 --- a/apps/red-ui/src/app/modules/admin/screens/entities/screens/info/info.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/entities/screens/info/info.component.ts @@ -1,8 +1,8 @@ import { ChangeDetectionStrategy, Component, HostListener, ViewChild } from '@angular/core'; -import { Dictionary, DOSSIER_TEMPLATE_ID, ENTITY_TYPE, User } from '@red/domain'; +import { Dictionary, DOSSIER_TEMPLATE_ID, ENTITY_TYPE } from '@red/domain'; import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service'; import { ActivatedRoute } from '@angular/router'; -import { UserService } from '@services/user.service'; +import { getCurrentUser } from '@services/user.service'; import { PermissionsService } from '@services/permissions.service'; import { AddEditEntityComponent } from '@shared/components/add-edit-entity/add-edit-entity.component'; import { IqserEventTarget } from '@iqser/common-ui'; @@ -15,18 +15,12 @@ import { Observable } from 'rxjs'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class InfoComponent { - readonly currentUser: User; + readonly currentUser = getCurrentUser(); readonly entity$: Observable; readonly dossierTemplateId: string; @ViewChild(AddEditEntityComponent) private readonly _addEditEntityComponent: AddEditEntityComponent; - constructor( - route: ActivatedRoute, - userService: UserService, - dictionariesMapService: DictionariesMapService, - readonly permissionsService: PermissionsService, - ) { - this.currentUser = userService.currentUser; + constructor(route: ActivatedRoute, dictionariesMapService: DictionariesMapService, readonly permissionsService: PermissionsService) { this.dossierTemplateId = route.parent.snapshot.paramMap.get(DOSSIER_TEMPLATE_ID); const entityType = route.parent.snapshot.paramMap.get(ENTITY_TYPE); this.entity$ = dictionariesMapService.watch$(this.dossierTemplateId, entityType); diff --git a/apps/red-ui/src/app/modules/admin/screens/file-attributes-listing/file-attributes-listing-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/file-attributes-listing/file-attributes-listing-screen.component.ts index c3c19130b..6ccfd1e3b 100644 --- a/apps/red-ui/src/app/modules/admin/screens/file-attributes-listing/file-attributes-listing-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/file-attributes-listing/file-attributes-listing-screen.component.ts @@ -1,47 +1,34 @@ -import { - ChangeDetectionStrategy, - Component, - ElementRef, - forwardRef, - Injector, - OnDestroy, - OnInit, - TemplateRef, - ViewChild, -} from '@angular/core'; +import { ChangeDetectionStrategy, Component, ElementRef, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core'; import { AdminDialogService } from '../../services/admin-dialog.service'; import { CircleButtonTypes, - DefaultListingServices, + getParam, IconButtonTypes, ListingComponent, + listingProvidersFactory, LoadingService, TableColumnConfig, Toaster, } from '@iqser/common-ui'; import { fileAttributeTypesTranslations } from '@translations/file-attribute-types-translations'; -import { UserService } from '@services/user.service'; +import { getCurrentUser } from '@services/user.service'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; -import { DOSSIER_TEMPLATE_ID, FileAttributeConfig, IFileAttributeConfig, IFileAttributesConfig, User } from '@red/domain'; +import { DOSSIER_TEMPLATE_ID, FileAttributeConfig, IFileAttributeConfig, IFileAttributesConfig } from '@red/domain'; import { FileAttributesService } from '@services/entity-services/file-attributes.service'; import { HttpStatusCode } from '@angular/common/http'; import { firstValueFrom } from 'rxjs'; -import { ActivatedRoute } from '@angular/router'; import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service'; @Component({ templateUrl: './file-attributes-listing-screen.component.html', styleUrls: ['./file-attributes-listing-screen.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, - providers: [ - ...DefaultListingServices, - { provide: ListingComponent, useExisting: forwardRef(() => FileAttributesListingScreenComponent) }, - ], + providers: listingProvidersFactory(FileAttributesListingScreenComponent), }) export class FileAttributesListingScreenComponent extends ListingComponent implements OnInit, OnDestroy { readonly iconButtonTypes = IconButtonTypes; readonly circleButtonTypes = CircleButtonTypes; - readonly currentUser: User; + readonly currentUser = getCurrentUser(); readonly translations = fileAttributeTypesTranslations; readonly tableHeaderLabel = _('file-attributes-listing.table-header.title'); readonly tableColumnConfigs: TableColumnConfig[] = [ @@ -61,21 +48,16 @@ export class FileAttributesListingScreenComponent extends ListingComponent; #existingConfiguration: IFileAttributesConfig; @ViewChild('fileInput') private _fileInput: ElementRef; - readonly #dossierTemplateId: string; + readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID); constructor( - route: ActivatedRoute, - userService: UserService, private readonly _toaster: Toaster, - protected readonly _injector: Injector, private readonly _loadingService: LoadingService, private readonly _dialogService: AdminDialogService, private readonly _fileAttributesService: FileAttributesService, private readonly _dossierTemplatesService: DossierTemplatesService, ) { - super(_injector); - this.currentUser = userService.currentUser; - this.#dossierTemplateId = route.snapshot.paramMap.get(DOSSIER_TEMPLATE_ID); + super(); } private get _numberOfDisplayedAttrs(): number { diff --git a/apps/red-ui/src/app/modules/admin/screens/info/info-screen/dossier-template-info-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/info/info-screen/dossier-template-info-screen.component.ts index aca6f0d22..2b826e788 100644 --- a/apps/red-ui/src/app/modules/admin/screens/info/info-screen/dossier-template-info-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/info/info-screen/dossier-template-info-screen.component.ts @@ -1,12 +1,12 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service'; -import { ActivatedRoute } from '@angular/router'; import { Observable } from 'rxjs'; import { DOSSIER_TEMPLATE_ID, DossierTemplate, DossierTemplateStats } from '@red/domain'; import { DossierTemplateStatsService } from '@services/entity-services/dossier-template-stats.service'; import { AdminDialogService } from '../../../services/admin-dialog.service'; import { PermissionsService } from '@services/permissions.service'; import { dossierTemplateStatusTranslations } from '@translations/dossier-template-status-translations'; +import { getParam } from '@iqser/common-ui'; @Component({ templateUrl: './dossier-template-info-screen.component.html', @@ -19,13 +19,12 @@ export class DossierTemplateInfoScreenComponent { readonly translations = dossierTemplateStatusTranslations; constructor( - route: ActivatedRoute, readonly permissionsService: PermissionsService, dossierTemplatesService: DossierTemplatesService, private readonly _dialogService: AdminDialogService, dossierTemplateStatsService: DossierTemplateStatsService, ) { - const dossierTemplateId = route.snapshot.paramMap.get(DOSSIER_TEMPLATE_ID); + const dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID); this.dossierTemplate$ = dossierTemplatesService.getEntityChanged$(dossierTemplateId); this.dossierTemplateStats$ = dossierTemplateStatsService.watch$(dossierTemplateId); } diff --git a/apps/red-ui/src/app/modules/admin/screens/justifications/add-edit-justification-dialog/add-edit-justification-dialog.component.ts b/apps/red-ui/src/app/modules/admin/screens/justifications/add-edit-justification-dialog/add-edit-justification-dialog.component.ts index d546237ba..29458959c 100644 --- a/apps/red-ui/src/app/modules/admin/screens/justifications/add-edit-justification-dialog/add-edit-justification-dialog.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/justifications/add-edit-justification-dialog/add-edit-justification-dialog.component.ts @@ -1,29 +1,23 @@ -import { ChangeDetectionStrategy, Component, Inject, Injector } from '@angular/core'; -import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { ChangeDetectionStrategy, Component, Inject } from '@angular/core'; +import { UntypedFormGroup, Validators } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { Justification } from '@red/domain'; import { JustificationsService } from '@services/entity-services/justifications.service'; -import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service'; -import { BaseDialogComponent, LoadingService } from '@iqser/common-ui'; +import { BaseDialogComponent } from '@iqser/common-ui'; import { firstValueFrom } from 'rxjs'; @Component({ - selector: 'redaction-add-edit-justification-dialog', templateUrl: './add-edit-justification-dialog.component.html', styleUrls: ['./add-edit-justification-dialog.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, }) export class AddEditJustificationDialogComponent extends BaseDialogComponent { constructor( - private readonly _formBuilder: UntypedFormBuilder, private readonly _justificationService: JustificationsService, - private readonly _dossierTemplatesService: DossierTemplatesService, - private readonly _loadingService: LoadingService, - protected readonly _injector: Injector, protected readonly _dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) public data: { justification?: Justification; dossierTemplateId: string }, + @Inject(MAT_DIALOG_DATA) readonly data: { justification?: Justification; dossierTemplateId: string }, ) { - super(_injector, _dialogRef, !!data.justification); + super(_dialogRef, !!data.justification); this.form = this._getForm(); this.initialFormValue = this.form.getRawValue(); diff --git a/apps/red-ui/src/app/modules/admin/screens/justifications/justifications-screen/justifications-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/justifications/justifications-screen/justifications-screen.component.ts index 518c1a533..adaf556fd 100644 --- a/apps/red-ui/src/app/modules/admin/screens/justifications/justifications-screen/justifications-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/justifications/justifications-screen/justifications-screen.component.ts @@ -1,60 +1,54 @@ -import { ChangeDetectionStrategy, Component, forwardRef, Injector, OnInit } from '@angular/core'; +import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { CircleButtonTypes, - DefaultListingServicesTmp, - EntitiesService, + getParam, IconButtonTypes, ListingComponent, + listingProvidersFactory, LoadingService, TableColumnConfig, } from '@iqser/common-ui'; import { DOSSIER_TEMPLATE_ID, Justification } from '@red/domain'; import { JustificationsService } from '@services/entity-services/justifications.service'; import { JustificationsDialogService } from '../justifications-dialog.service'; -import { UserService } from '@services/user.service'; +import { getCurrentUser } from '@services/user.service'; import { UserPreferenceService } from '@services/user-preference.service'; import { firstValueFrom } from 'rxjs'; -import { ActivatedRoute } from '@angular/router'; @Component({ selector: 'redaction-justifications-screen', templateUrl: './justifications-screen.component.html', styleUrls: ['./justifications-screen.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, - providers: [ - ...DefaultListingServicesTmp, - { provide: EntitiesService, useExisting: JustificationsService }, - { provide: ListingComponent, useExisting: forwardRef(() => JustificationsScreenComponent) }, - ], + providers: listingProvidersFactory({ + entitiesService: JustificationsService, + component: JustificationsScreenComponent, + }), }) export class JustificationsScreenComponent extends ListingComponent implements OnInit { readonly iconButtonTypes = IconButtonTypes; readonly circleButtonTypes = CircleButtonTypes; - readonly tableHeaderLabel = _('justifications-listing.table-header'); readonly tableColumnConfigs: TableColumnConfig[] = [ { label: _('justifications-listing.table-col-names.name'), width: '2fr' }, { label: _('justifications-listing.table-col-names.reason') }, { label: _('justifications-listing.table-col-names.description'), width: '2fr' }, ]; - readonly #dossierTemplateId: string; + readonly #currentUser = getCurrentUser(); + readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID); constructor( - protected readonly _injector: Injector, private readonly _justificationService: JustificationsService, private readonly _loadingService: LoadingService, private readonly _dialogService: JustificationsDialogService, readonly userPreferenceService: UserPreferenceService, - readonly userService: UserService, - private readonly _route: ActivatedRoute, ) { - super(_injector); - this.#dossierTemplateId = _route.snapshot.paramMap.get(DOSSIER_TEMPLATE_ID); + super(); } get canUpdateJustifications(): boolean { - return this.userPreferenceService.areDevFeaturesEnabled && this.userService.currentUser.isAdmin; + return this.userPreferenceService.areDevFeaturesEnabled && this.#currentUser.isAdmin; } async ngOnInit(): Promise { diff --git a/apps/red-ui/src/app/modules/admin/screens/justifications/table-item/table-item.component.ts b/apps/red-ui/src/app/modules/admin/screens/justifications/table-item/table-item.component.ts index 2b715e2ab..9c3ceaca2 100644 --- a/apps/red-ui/src/app/modules/admin/screens/justifications/table-item/table-item.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/justifications/table-item/table-item.component.ts @@ -1,11 +1,9 @@ -import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; -import { DOSSIER_TEMPLATE_ID, Justification, User } from '@red/domain'; -import { CircleButtonTypes } from '@iqser/common-ui'; +import { ChangeDetectionStrategy, Component, inject, Input } from '@angular/core'; +import { DOSSIER_TEMPLATE_ID, Justification } from '@red/domain'; +import { CircleButtonTypes, getParam } from '@iqser/common-ui'; import { JustificationsDialogService } from '../justifications-dialog.service'; import { UserService } from '@services/user.service'; import { UserPreferenceService } from '@services/user-preference.service'; -import { ActivatedRoute } from '@angular/router'; -import { Observable } from 'rxjs'; @Component({ selector: 'redaction-table-item', @@ -16,18 +14,10 @@ import { Observable } from 'rxjs'; export class TableItemComponent { readonly circleButtonTypes = CircleButtonTypes; @Input() justification: Justification; - readonly currentUser$: Observable; - readonly #dossierTemplateId: string; + readonly currentUser$ = inject(UserService).currentUser$; + readonly #dossierTemplateId: string = getParam(DOSSIER_TEMPLATE_ID); - constructor( - route: ActivatedRoute, - userService: UserService, - readonly userPreferenceService: UserPreferenceService, - private readonly _dialogService: JustificationsDialogService, - ) { - this.currentUser$ = userService.currentUser$; - this.#dossierTemplateId = route.snapshot.paramMap.get(DOSSIER_TEMPLATE_ID); - } + constructor(readonly userPreferenceService: UserPreferenceService, private readonly _dialogService: JustificationsDialogService) {} openEditJustificationDialog() { this._dialogService.openDialog('addEditJustification', null, { diff --git a/apps/red-ui/src/app/modules/admin/screens/permissions/permissions-screen/permissions-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/permissions/permissions-screen/permissions-screen.component.ts index 23e29aa0f..72a8bf515 100644 --- a/apps/red-ui/src/app/modules/admin/screens/permissions/permissions-screen/permissions-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/permissions/permissions-screen/permissions-screen.component.ts @@ -1,5 +1,5 @@ -import { ChangeDetectionStrategy, Component, forwardRef, Injector } from '@angular/core'; -import { DefaultListingServices, ListingComponent, LoadingService, SortingOrders, TableColumnConfig } from '@iqser/common-ui'; +import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { ListingComponent, listingProvidersFactory, LoadingService, SortingOrders, TableColumnConfig } from '@iqser/common-ui'; import { PermissionsMapping } from '@red/domain'; import { ConfigService } from '../config.service'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; @@ -18,11 +18,11 @@ import { RouterHistoryService } from '@services/router-history.service'; @Component({ templateUrl: './permissions-screen.component.html', styleUrls: ['./permissions-screen.component.scss'], - providers: [...DefaultListingServices, { provide: ListingComponent, useExisting: forwardRef(() => PermissionsScreenComponent) }], + providers: listingProvidersFactory(PermissionsScreenComponent), changeDetection: ChangeDetectionStrategy.OnPush, }) export class PermissionsScreenComponent extends ListingComponent { - readonly currentUser = this._userService.currentUser; + readonly currentUser = inject(UserService).currentUser; readonly translations = permissionsTranslations; readonly tableColumnConfigs: TableColumnConfig[]; readonly tableHeaderLabel = _('permissions-screen.table-header.title'); @@ -30,20 +30,18 @@ export class PermissionsScreenComponent extends ListingComponent([]); availableTemplates$ = new BehaviorSubject([]); - readonly #dossierTemplateId: string; + readonly #dossierTemplateId: string = getParam(DOSSIER_TEMPLATE_ID); @ViewChild('fileInput') private _fileInput: ElementRef; constructor( - private readonly _dossierTemplatesService: DossierTemplatesService, private readonly _reportTemplateService: ReportTemplateService, private readonly _dialogService: AdminDialogService, private readonly _toaster: Toaster, private readonly _loadingService: LoadingService, - private readonly _route: ActivatedRoute, readonly permissionsService: PermissionsService, - ) { - this.#dossierTemplateId = _route.snapshot.paramMap.get(DOSSIER_TEMPLATE_ID); - } + ) {} async ngOnInit() { this._loadingService.start(); diff --git a/apps/red-ui/src/app/modules/admin/screens/rules/rules-screen/rules-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/rules/rules-screen/rules-screen.component.ts index 5e810dc17..1edf3f628 100644 --- a/apps/red-ui/src/app/modules/admin/screens/rules/rules-screen/rules-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/rules/rules-screen/rules-screen.component.ts @@ -1,11 +1,10 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, OnInit, ViewChild } from '@angular/core'; import { PermissionsService } from '@services/permissions.service'; -import { Debounce, IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui'; +import { Debounce, getParam, IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui'; import { saveAs } from 'file-saver'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { RulesService } from '../../../services/rules.service'; import { firstValueFrom } from 'rxjs'; -import { ActivatedRoute } from '@angular/router'; import { DOSSIER_TEMPLATE_ID } from '@red/domain'; import { EditorThemeService } from '@services/editor-theme.service'; import ICodeEditor = monaco.editor.ICodeEditor; @@ -37,7 +36,7 @@ export class RulesScreenComponent implements OnInit { private _codeEditor: ICodeEditor; private _decorations: string[] = []; - readonly #dossierTemplateId: string; + readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID); constructor( readonly permissionsService: PermissionsService, @@ -46,10 +45,7 @@ export class RulesScreenComponent implements OnInit { private readonly _toaster: Toaster, private readonly _loadingService: LoadingService, private readonly _editorThemeService: EditorThemeService, - route: ActivatedRoute, - ) { - this.#dossierTemplateId = route.snapshot.paramMap.get(DOSSIER_TEMPLATE_ID); - } + ) {} set isLeavingPage(isLeaving: boolean) { this.isLeaving = isLeaving; diff --git a/apps/red-ui/src/app/modules/admin/screens/user-listing/user-listing-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/user-listing/user-listing-screen.component.ts index b86b0887c..52eb056be 100644 --- a/apps/red-ui/src/app/modules/admin/screens/user-listing/user-listing-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/user-listing/user-listing-screen.component.ts @@ -1,4 +1,4 @@ -import { Component, forwardRef, inject, Injector, OnInit } from '@angular/core'; +import { Component, inject, OnInit } from '@angular/core'; import { UserService } from '@services/user.service'; import { AdminDialogService } from '../../services/admin-dialog.service'; import { TranslateService } from '@ngx-translate/core'; @@ -7,10 +7,9 @@ import { TranslateChartService } from '@services/translate-chart.service'; import { ButtonConfig, CircleButtonTypes, - DefaultListingServicesTmp, - EntitiesService, IconButtonTypes, ListingComponent, + listingProvidersFactory, LoadingService, NestedFilter, SearchPositions, @@ -33,14 +32,10 @@ function configToFilter({ key, label }: DonutChartConfig) { @Component({ templateUrl: './user-listing-screen.component.html', styleUrls: ['./user-listing-screen.component.scss'], - providers: [ - ...DefaultListingServicesTmp, - { provide: EntitiesService, useExisting: UserService }, - { - provide: ListingComponent, - useExisting: forwardRef(() => UserListingScreenComponent), - }, - ], + providers: listingProvidersFactory({ + entitiesService: UserService, + component: UserListingScreenComponent, + }), }) export class UserListingScreenComponent extends ListingComponent implements OnInit { readonly routerHistoryService = inject(RouterHistoryService); @@ -71,13 +66,12 @@ export class UserListingScreenComponent extends ListingComponent implement constructor( readonly userService: UserService, - protected readonly _injector: Injector, private readonly _loadingService: LoadingService, private readonly _dialogService: AdminDialogService, private readonly _translateService: TranslateService, private readonly _translateChartService: TranslateChartService, ) { - super(_injector); + super(); } get #canDeleteSelected$(): Observable { diff --git a/apps/red-ui/src/app/modules/admin/screens/watermark/watermark-screen/watermark-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/watermark/watermark-screen/watermark-screen.component.ts index 1f9b1ec78..95aa6abf5 100644 --- a/apps/red-ui/src/app/modules/admin/screens/watermark/watermark-screen/watermark-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/watermark/watermark-screen/watermark-screen.component.ts @@ -3,7 +3,7 @@ import { PermissionsService } from '@services/permissions.service'; import WebViewer, { WebViewerInstance } from '@pdftron/webviewer'; import { HttpClient } from '@angular/common/http'; import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; -import { Debounce, IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui'; +import { Debounce, getParam, IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui'; import { DOSSIER_TEMPLATE_ID, IWatermark, WATERMARK_ID, WatermarkOrientation, WatermarkOrientations } from '@red/domain'; import { BASE_HREF_FN, BaseHrefFn } from '../../../../../tokens'; import { stampPDFPage } from '@utils/page-stamper'; @@ -13,7 +13,7 @@ import { firstValueFrom, Observable, of } from 'rxjs'; import { catchError, tap } from 'rxjs/operators'; import { LicenseService } from '@services/license.service'; import { UserPreferenceService } from '@services/user-preference.service'; -import { ActivatedRoute, Router } from '@angular/router'; +import { Router } from '@angular/router'; export const DEFAULT_WATERMARK: IWatermark = { id: null, @@ -39,15 +39,14 @@ export const DEFAULT_WATERMARK: IWatermark = { export class WatermarkScreenComponent implements OnInit { readonly iconButtonTypes = IconButtonTypes; readonly form: UntypedFormGroup = this._getForm(); - readonly #dossierTemplateId: string; - readonly #watermarkId: string; + readonly #dossierTemplateId: string = getParam(DOSSIER_TEMPLATE_ID); + readonly #watermarkId = getParam(WATERMARK_ID); private _instance: WebViewerInstance; private _watermark: IWatermark = {} as IWatermark; @ViewChild('viewer', { static: true }) private _viewer: ElementRef; constructor( - route: ActivatedRoute, private readonly _http: HttpClient, private readonly _toaster: Toaster, private readonly _formBuilder: UntypedFormBuilder, @@ -61,8 +60,6 @@ export class WatermarkScreenComponent implements OnInit { private readonly _router: Router, ) { this._loadingService.start(); - this.#dossierTemplateId = route.snapshot.paramMap.get(DOSSIER_TEMPLATE_ID); - this.#watermarkId = route.snapshot.paramMap.get(WATERMARK_ID); } get changed(): boolean { diff --git a/apps/red-ui/src/app/modules/admin/screens/watermarks-listing/watermarks-listing-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/watermarks-listing/watermarks-listing-screen.component.ts index bed1458e0..b49e4ca68 100644 --- a/apps/red-ui/src/app/modules/admin/screens/watermarks-listing/watermarks-listing-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/watermarks-listing/watermarks-listing-screen.component.ts @@ -1,35 +1,32 @@ -import { ChangeDetectionStrategy, Component, forwardRef, Injector, OnInit } from '@angular/core'; +import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; import { CircleButtonTypes, ConfirmationDialogInput, - DefaultListingServices, + getParam, IconButtonTypes, ListingComponent, + listingProvidersFactory, LoadingService, TableColumnConfig, Toaster, } from '@iqser/common-ui'; -import { DOSSIER_TEMPLATE_ID, User, Watermark } from '@red/domain'; -import { UserService } from '../../../../services/user.service'; +import { DOSSIER_TEMPLATE_ID, Watermark } from '@red/domain'; +import { getCurrentUser } from '@services/user.service'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { firstValueFrom } from 'rxjs'; -import { WatermarkService } from '../../../../services/entity-services/watermark.service'; -import { ActivatedRoute } from '@angular/router'; +import { WatermarkService } from '@services/entity-services/watermark.service'; import { AdminDialogService } from '../../services/admin-dialog.service'; @Component({ templateUrl: './watermarks-listing-screen.component.html', styleUrls: ['./watermarks-listing-screen.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, - providers: [...DefaultListingServices, { provide: ListingComponent, useExisting: forwardRef(() => WatermarksListingScreenComponent) }], + providers: listingProvidersFactory(WatermarksListingScreenComponent), }) export class WatermarksListingScreenComponent extends ListingComponent implements OnInit { - private readonly _dossierTemplateId: string; - readonly iconButtonTypes = IconButtonTypes; readonly circleButtonTypes = CircleButtonTypes; - readonly currentUser: User; - + readonly currentUser = getCurrentUser(); readonly tableColumnConfigs: TableColumnConfig[] = [ { label: _('watermarks-listing.table-col-names.name'), sortByKey: 'searchKey', width: '2fr' }, { label: _('watermarks-listing.table-col-names.status'), sortByKey: 'enabled', class: 'flex-center' }, @@ -38,37 +35,21 @@ export class WatermarksListingScreenComponent extends ListingComponent { await this._loadData(); } - private async _loadData(): Promise { - this._loadingService.start(); - - try { - const response = await firstValueFrom(this._watermarkService.getWatermarks(this._dossierTemplateId)); - const watermarkConfig = response?.map(item => new Watermark(item)) || []; - this.entitiesService.setEntities(watermarkConfig); - } catch (e) {} - - this._loadingService.stop(); - } - async openConfirmDeleteWatermarkDialog($event: MouseEvent, watermark: Watermark): Promise { const isUsed = await firstValueFrom(this._watermarkService.isWatermarkUsed(watermark.id)); @@ -85,14 +66,6 @@ export class WatermarksListingScreenComponent extends ListingComponent { - this._loadingService.start(); - await firstValueFrom(this._watermarkService.deleteWatermark(watermark.id)); - this._toaster.success(_('watermarks-listing.action.delete-success')); - await this._loadData(); - this._loadingService.stop(); - } - async toggleStatus(watermark?: Watermark): Promise { watermark.enabled = !watermark.enabled; this._loadingService.start(); @@ -101,6 +74,28 @@ export class WatermarksListingScreenComponent extends ListingComponent { + this._loadingService.start(); + + try { + const response = await firstValueFrom(this._watermarkService.getWatermarks(this.#dossierTemplateId)); + const watermarkConfig = response?.map(item => new Watermark(item)) || []; + this.entitiesService.setEntities(watermarkConfig); + } catch (e) { + console.log(e); + } + + this._loadingService.stop(); + } + + private async _deleteWatermark(watermark: Watermark): Promise { + this._loadingService.start(); + await firstValueFrom(this._watermarkService.deleteWatermark(watermark.id)); + this._toaster.success(_('watermarks-listing.action.delete-success')); + await this._loadData(); + this._loadingService.stop(); } } diff --git a/apps/red-ui/src/app/modules/admin/services/audit.service.ts b/apps/red-ui/src/app/modules/admin/services/audit.service.ts index 6cf421b2d..d64f462b4 100644 --- a/apps/red-ui/src/app/modules/admin/services/audit.service.ts +++ b/apps/red-ui/src/app/modules/admin/services/audit.service.ts @@ -5,9 +5,7 @@ import { Observable } from 'rxjs'; @Injectable() export class AuditService extends GenericService { - constructor(protected readonly _injector: Injector) { - super(_injector, 'audit'); - } + protected readonly _defaultModelPath = 'audit'; getCategories(): Observable { return super.getAll(`${this._defaultModelPath}/categories`); diff --git a/apps/red-ui/src/app/modules/admin/services/digital-signature.service.ts b/apps/red-ui/src/app/modules/admin/services/digital-signature.service.ts index b9c8fcda0..a6722bf66 100644 --- a/apps/red-ui/src/app/modules/admin/services/digital-signature.service.ts +++ b/apps/red-ui/src/app/modules/admin/services/digital-signature.service.ts @@ -12,9 +12,7 @@ import { catchError, map } from 'rxjs/operators'; @Injectable() export class DigitalSignatureService extends GenericService { - constructor(protected readonly _injector: Injector) { - super(_injector, 'digital-signature'); - } + protected readonly _defaultModelPath = 'digital-signature'; @Validate() updateSignature(@RequiredParam() body: IPkcsDigitalSignatureRequest): Observable { diff --git a/apps/red-ui/src/app/modules/admin/services/rules.service.ts b/apps/red-ui/src/app/modules/admin/services/rules.service.ts index 368058d8e..b6e560e89 100644 --- a/apps/red-ui/src/app/modules/admin/services/rules.service.ts +++ b/apps/red-ui/src/app/modules/admin/services/rules.service.ts @@ -4,9 +4,7 @@ import { IRules } from '@red/domain'; @Injectable() export class RulesService extends GenericService { - constructor(protected readonly _injector: Injector) { - super(_injector, 'rules'); - } + protected readonly _defaultModelPath = 'rules'; @Validate() download(@RequiredParam() dossierTemplateId: string) { diff --git a/apps/red-ui/src/app/modules/admin/services/smtp-config.service.ts b/apps/red-ui/src/app/modules/admin/services/smtp-config.service.ts index 7d9f0faea..c7485cab8 100644 --- a/apps/red-ui/src/app/modules/admin/services/smtp-config.service.ts +++ b/apps/red-ui/src/app/modules/admin/services/smtp-config.service.ts @@ -4,9 +4,7 @@ import { ISmtpConfiguration } from '@red/domain'; @Injectable() export class SmtpConfigService extends GenericService { - constructor(protected readonly _injector: Injector) { - super(_injector, 'configuration'); - } + protected readonly _defaultModelPath = 'configuration'; @Validate() updateSMTPConfiguration(@RequiredParam() body: ISmtpConfiguration) { diff --git a/apps/red-ui/src/app/modules/admin/shared/components/dossier-template-actions/dossier-template-actions.component.ts b/apps/red-ui/src/app/modules/admin/shared/components/dossier-template-actions/dossier-template-actions.component.ts index 12cfc1706..2bb96e463 100644 --- a/apps/red-ui/src/app/modules/admin/shared/components/dossier-template-actions/dossier-template-actions.component.ts +++ b/apps/red-ui/src/app/modules/admin/shared/components/dossier-template-actions/dossier-template-actions.component.ts @@ -2,7 +2,7 @@ import { Component, Input, OnInit } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { AdminDialogService } from '../../../services/admin-dialog.service'; import { CircleButtonTypes, LoadingService } from '@iqser/common-ui'; -import { UserService } from '@services/user.service'; +import { getCurrentUser } from '@services/user.service'; import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service'; import { firstValueFrom } from 'rxjs'; import { DOSSIER_TEMPLATE_ID } from '@red/domain'; @@ -14,14 +14,13 @@ import { DOSSIER_TEMPLATE_ID } from '@red/domain'; }) export class DossierTemplateActionsComponent implements OnInit { readonly circleButtonTypes = CircleButtonTypes; - readonly currentUser = this._userService.currentUser; + readonly currentUser = getCurrentUser(); @Input() dossierTemplateId: string; constructor( private readonly _router: Router, private readonly _route: ActivatedRoute, - private readonly _userService: UserService, private readonly _loadingService: LoadingService, private readonly _dialogService: AdminDialogService, private readonly _dossierTemplatesService: DossierTemplatesService, diff --git a/apps/red-ui/src/app/modules/archive/screens/archived-dossiers-screen/archived-dossiers-screen.component.ts b/apps/red-ui/src/app/modules/archive/screens/archived-dossiers-screen/archived-dossiers-screen.component.ts index 6ce7fac56..94d8d530a 100644 --- a/apps/red-ui/src/app/modules/archive/screens/archived-dossiers-screen/archived-dossiers-screen.component.ts +++ b/apps/red-ui/src/app/modules/archive/screens/archived-dossiers-screen/archived-dossiers-screen.component.ts @@ -1,6 +1,6 @@ -import { ChangeDetectionStrategy, Component, forwardRef, Injector, OnInit } from '@angular/core'; +import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; -import { DefaultListingServices, ListingComponent } from '@iqser/common-ui'; +import { ListingComponent, listingProvidersFactory } from '@iqser/common-ui'; import { Dossier, DOSSIER_TEMPLATE_ID } from '@red/domain'; import { ConfigService } from '../../services/config.service'; import { tap } from 'rxjs/operators'; @@ -11,29 +11,28 @@ import { Router } from '@angular/router'; selector: 'redaction-archived-dossiers-screen', templateUrl: './archived-dossiers-screen.component.html', styleUrls: ['./archived-dossiers-screen.component.scss'], - providers: [...DefaultListingServices, { provide: ListingComponent, useExisting: forwardRef(() => ArchivedDossiersScreenComponent) }], + providers: listingProvidersFactory(ArchivedDossiersScreenComponent), changeDetection: ChangeDetectionStrategy.OnPush, }) export class ArchivedDossiersScreenComponent extends ListingComponent implements OnInit { readonly tableColumnConfigs = this._configService.tableConfig; readonly tableHeaderLabel = _('archived-dossiers-listing.table-header.title'); - private readonly _dossierTemplateId: string; readonly computeFilters$ = this.entitiesService.all$.pipe(tap(() => this._computeAllFilters())); + readonly #dossierTemplateId: string; constructor( - protected readonly _injector: Injector, private readonly _configService: ConfigService, private readonly _archivedDossiersService: ArchivedDossiersService, - private readonly _router: Router, + router: Router, ) { - super(_injector); - this._dossierTemplateId = this._router.routerState.snapshot.root.firstChild.firstChild.paramMap.get(DOSSIER_TEMPLATE_ID); - this.entitiesService.setEntities(this._archivedDossiersService.all.filter(d => d.dossierTemplateId === this._dossierTemplateId)); + super(); + this.#dossierTemplateId = router.routerState.snapshot.root.firstChild.firstChild.paramMap.get(DOSSIER_TEMPLATE_ID); + this.entitiesService.setEntities(this._archivedDossiersService.all.filter(d => d.dossierTemplateId === this.#dossierTemplateId)); } ngOnInit(): void { this.addSubscription = this._archivedDossiersService.all$ - .pipe(tap(dossiers => this.entitiesService.setEntities(dossiers.filter(d => d.dossierTemplateId === this._dossierTemplateId)))) + .pipe(tap(dossiers => this.entitiesService.setEntities(dossiers.filter(d => d.dossierTemplateId === this.#dossierTemplateId)))) .subscribe(); } diff --git a/apps/red-ui/src/app/modules/dossier-overview/components/dossier-details/dossier-details.component.ts b/apps/red-ui/src/app/modules/dossier-overview/components/dossier-details/dossier-details.component.ts index 3539b3133..9ee3d253a 100644 --- a/apps/red-ui/src/app/modules/dossier-overview/components/dossier-details/dossier-details.component.ts +++ b/apps/red-ui/src/app/modules/dossier-overview/components/dossier-details/dossier-details.component.ts @@ -12,10 +12,9 @@ import { } from '@red/domain'; import { TranslateChartService } from '@services/translate-chart.service'; import { UserService } from '@services/user.service'; -import { FilterService, ProgressBarConfigModel, shareLast, Toaster } from '@iqser/common-ui'; +import { FilterService, getParam, ProgressBarConfigModel, shareLast, Toaster } from '@iqser/common-ui'; import { workflowFileStatusTranslations } from '@translations/file-status-translations'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; -import { ActivatedRoute } from '@angular/router'; import { firstValueFrom, Observable } from 'rxjs'; import { DossierStatsService } from '@services/dossiers/dossier-stats.service'; import { map } from 'rxjs/operators'; @@ -43,7 +42,6 @@ export class DossierDetailsComponent { readonly statusConfig$: Observable; constructor( - activatedRoute: ActivatedRoute, private readonly _toaster: Toaster, readonly filterService: FilterService, dossierStatsService: DossierStatsService, @@ -51,7 +49,7 @@ export class DossierDetailsComponent { private readonly _dossiersService: DossiersService, readonly translateChartService: TranslateChartService, ) { - const dossierId = activatedRoute.snapshot.paramMap.get(DOSSIER_ID); + const dossierId = getParam(DOSSIER_ID); this.dossier$ = _dossiersService.getEntityChanged$(dossierId).pipe(shareLast()); this.dossierStats$ = dossierStatsService.watch$(dossierId).pipe(shareLast()); this.chartConfig$ = this.dossierStats$.pipe(map(stats => this.#calculateChartConfig(stats))); diff --git a/apps/red-ui/src/app/modules/dossier-overview/screen/dossier-overview-screen.component.ts b/apps/red-ui/src/app/modules/dossier-overview/screen/dossier-overview-screen.component.ts index 330bb820c..0d69ec13e 100644 --- a/apps/red-ui/src/app/modules/dossier-overview/screen/dossier-overview-screen.component.ts +++ b/apps/red-ui/src/app/modules/dossier-overview/screen/dossier-overview-screen.component.ts @@ -1,4 +1,4 @@ -import { Component, ElementRef, forwardRef, HostListener, Injector, OnInit, TemplateRef, ViewChild } from '@angular/core'; +import { Component, ElementRef, HostListener, OnInit, TemplateRef, ViewChild } from '@angular/core'; import { Dossier, DOSSIER_ID, DossierAttributeWithValue, File, IFileAttributeConfig, WorkflowFileStatus } from '@red/domain'; import { FileDropOverlayService } from '@upload-download/services/file-drop-overlay.service'; import { FileUploadModel } from '@upload-download/model/file-upload.model'; @@ -10,10 +10,11 @@ import { convertFiles, Files, handleFileDrop } from '@utils/index'; import { CircleButtonTypes, CustomError, - DefaultListingServices, ErrorService, + getParam, ListingComponent, ListingModes, + listingProvidersFactory, LoadingService, NestedFilter, OnAttach, @@ -25,7 +26,7 @@ import { import { DossierAttributesService } from '@services/entity-services/dossier-attributes.service'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { PermissionsService } from '@services/permissions.service'; -import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; +import { NavigationEnd, Router } from '@angular/router'; import { FileAttributesService } from '@services/entity-services/file-attributes.service'; import { ConfigService } from '../config.service'; import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service'; @@ -40,13 +41,7 @@ import { NGXLogger } from 'ngx-logger'; @Component({ templateUrl: './dossier-overview-screen.component.html', styleUrls: ['./dossier-overview-screen.component.scss'], - providers: [ - ...DefaultListingServices, - ConfigService, - BulkActionsService, - { provide: ListingComponent, useExisting: forwardRef(() => DossierOverviewScreenComponent) }, - dossiersServiceProvider, - ], + providers: [...listingProvidersFactory(DossierOverviewScreenComponent), ConfigService, BulkActionsService, dossiersServiceProvider], }) export class DossierOverviewScreenComponent extends ListingComponent implements OnInit, OnAttach { readonly listingModes = ListingModes; @@ -64,7 +59,7 @@ export class DossierOverviewScreenComponent extends ListingComponent imple ); readonly dossier$: Observable; readonly files$: Observable; - readonly dossierId: string; + readonly dossierId = getParam(DOSSIER_ID); readonly dossierTemplateId: string; readonly workflowConfig: WorkflowConfig; #currentDossier: Dossier; @@ -75,11 +70,9 @@ export class DossierOverviewScreenComponent extends ListingComponent imple private _fileAttributeConfigs: IFileAttributeConfig[]; constructor( - route: ActivatedRoute, private readonly _router: Router, private readonly _logger: NGXLogger, readonly configService: ConfigService, - protected readonly _injector: Injector, private readonly _errorService: ErrorService, private readonly _filesService: FilesService, readonly permissionsService: PermissionsService, @@ -94,8 +87,7 @@ export class DossierOverviewScreenComponent extends ListingComponent imple private readonly _dossierTemplatesService: DossierTemplatesService, private readonly _dossierAttributesService: DossierAttributesService, ) { - super(_injector); - this.dossierId = route.snapshot.paramMap.get(DOSSIER_ID); + super(); this.dossier$ = _dossiersService.getEntityChanged$(this.dossierId).pipe(tap(dossier => (this.#currentDossier = dossier))); this.#currentDossier = _dossiersService.find(this.dossierId); this.workflowConfig = configService.workflowConfig(this.#currentDossier); diff --git a/apps/red-ui/src/app/modules/dossiers-listing/components/dossiers-listing-details/dossiers-listing-details.component.ts b/apps/red-ui/src/app/modules/dossiers-listing/components/dossiers-listing-details/dossiers-listing-details.component.ts index f8620c3d1..283137f18 100644 --- a/apps/red-ui/src/app/modules/dossiers-listing/components/dossiers-listing-details/dossiers-listing-details.component.ts +++ b/apps/red-ui/src/app/modules/dossiers-listing/components/dossiers-listing-details/dossiers-listing-details.component.ts @@ -4,7 +4,7 @@ import { Observable } from 'rxjs'; import { TranslateChartService } from '@services/translate-chart.service'; import { map } from 'rxjs/operators'; import { DashboardStatsService } from '@services/dossier-templates/dashboard-stats.service'; -import { ActivatedRoute } from '@angular/router'; +import { getParam } from '@iqser/common-ui'; @Component({ selector: 'redaction-dossiers-listing-details', @@ -17,12 +17,8 @@ export class DossiersListingDetailsComponent { readonly documentsChartConfig$: Observable; readonly dossiersChartConfig$: Observable; - constructor( - route: ActivatedRoute, - dashboardStatsService: DashboardStatsService, - private readonly _translateChartService: TranslateChartService, - ) { - const dossierTemplateId = route.snapshot.paramMap.get(DOSSIER_TEMPLATE_ID); + constructor(dashboardStatsService: DashboardStatsService, private readonly _translateChartService: TranslateChartService) { + const dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID); this.stats$ = dashboardStatsService.getEntityChanged$(dossierTemplateId); this.dossiersChartConfig$ = this.stats$.pipe( diff --git a/apps/red-ui/src/app/modules/dossiers-listing/screen/dossiers-listing-screen.component.ts b/apps/red-ui/src/app/modules/dossiers-listing/screen/dossiers-listing-screen.component.ts index 74f629c6b..989dd30be 100644 --- a/apps/red-ui/src/app/modules/dossiers-listing/screen/dossiers-listing-screen.component.ts +++ b/apps/red-ui/src/app/modules/dossiers-listing/screen/dossiers-listing-screen.component.ts @@ -1,7 +1,7 @@ -import { ChangeDetectionStrategy, Component, forwardRef, Injector, OnInit, TemplateRef, ViewChild } from '@angular/core'; +import { ChangeDetectionStrategy, Component, OnInit, TemplateRef, ViewChild } from '@angular/core'; import { Dossier, DOSSIER_TEMPLATE_ID, DossierTemplate } from '@red/domain'; import { PermissionsService } from '@services/permissions.service'; -import { ButtonConfig, DefaultListingServices, ListingComponent, OnAttach, TableComponent } from '@iqser/common-ui'; +import { ButtonConfig, ListingComponent, listingProvidersFactory, OnAttach, TableComponent } from '@iqser/common-ui'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { ConfigService } from '../config.service'; import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service'; @@ -9,12 +9,12 @@ import { tap } from 'rxjs/operators'; import { Router } from '@angular/router'; import { UserPreferenceService } from '@services/user-preference.service'; import { SharedDialogService } from '@shared/services/dialog.service'; -import { DossierTemplatesService } from '../../../services/dossier-templates/dossier-templates.service'; +import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service'; @Component({ templateUrl: './dossiers-listing-screen.component.html', styleUrls: ['./dossiers-listing-screen.component.scss'], - providers: [...DefaultListingServices, { provide: ListingComponent, useExisting: forwardRef(() => DossiersListingScreenComponent) }], + providers: listingProvidersFactory(DossiersListingScreenComponent), changeDetection: ChangeDetectionStrategy.OnPush, }) export class DossiersListingScreenComponent extends ListingComponent implements OnInit, OnAttach { @@ -32,17 +32,16 @@ export class DossiersListingScreenComponent extends ListingComponent im constructor( router: Router, - protected readonly _injector: Injector, private readonly _configService: ConfigService, readonly permissionsService: PermissionsService, private readonly _dialogService: SharedDialogService, private readonly _activeDossiersService: ActiveDossiersService, private readonly _userPreferenceService: UserPreferenceService, - private readonly _dossierTemplatesService: DossierTemplatesService, + dossierTemplatesService: DossierTemplatesService, ) { - super(_injector); + super(); const dossierTemplateId = router.routerState.snapshot.root.firstChild.firstChild.paramMap.get(DOSSIER_TEMPLATE_ID); - this.dossierTemplate = this._dossierTemplatesService.find(dossierTemplateId); + this.dossierTemplate = dossierTemplatesService.find(dossierTemplateId); this.buttonConfigs = this._configService.buttonsConfig(this.dossierTemplate); this.entitiesService.setEntities(this._activeDossiersService.all.filter(d => d.dossierTemplateId === this.dossierTemplate.id)); } diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/accept-recommendation-dialog/accept-recommendation-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/accept-recommendation-dialog/accept-recommendation-dialog.component.ts index dc5181c5b..a553580cf 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/accept-recommendation-dialog/accept-recommendation-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/accept-recommendation-dialog/accept-recommendation-dialog.component.ts @@ -1,5 +1,5 @@ -import { Component, Inject, Injector, OnInit } from '@angular/core'; -import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { Component, Inject, OnInit } from '@angular/core'; +import { UntypedFormGroup, Validators } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { PermissionsService } from '@services/permissions.service'; import { Dictionary, Dossier } from '@red/domain'; @@ -29,17 +29,15 @@ export class AcceptRecommendationDialogComponent extends BaseDialogComponent imp private readonly _dossier: Dossier; constructor( - private readonly _formBuilder: UntypedFormBuilder, - private readonly _permissionsService: PermissionsService, - private readonly _activeDossiersService: ActiveDossiersService, + permissionsService: PermissionsService, + activeDossiersService: ActiveDossiersService, private readonly _dictionaryService: DictionaryService, - protected readonly _injector: Injector, protected readonly _dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) readonly data: AcceptRecommendationData, ) { - super(_injector, _dialogRef); - this._dossier = this._activeDossiersService.find(this.data.dossierId); - this.isDocumentAdmin = this._permissionsService.isApprover(this._dossier); + super(_dialogRef); + this._dossier = activeDossiersService.find(this.data.dossierId); + this.isDocumentAdmin = permissionsService.isApprover(this._dossier); this.form = this._getForm(); this.initialFormValue = this.form.getRawValue(); } diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/change-legal-basis-dialog/change-legal-basis-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/change-legal-basis-dialog/change-legal-basis-dialog.component.ts index 54fc1f05c..c0ee5badc 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/change-legal-basis-dialog/change-legal-basis-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/change-legal-basis-dialog/change-legal-basis-dialog.component.ts @@ -1,9 +1,7 @@ -import { Component, Inject, Injector, OnInit } from '@angular/core'; +import { Component, Inject, OnInit } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { AnnotationWrapper } from '@models/file/annotation.wrapper'; -import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; -import { PermissionsService } from '@services/permissions.service'; -import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service'; +import { UntypedFormGroup, Validators } from '@angular/forms'; import { JustificationsService } from '@services/entity-services/justifications.service'; import { Dossier } from '@red/domain'; import { BaseDialogComponent } from '@iqser/common-ui'; @@ -23,14 +21,10 @@ export class ChangeLegalBasisDialogComponent extends BaseDialogComponent impleme constructor( private readonly _justificationsService: JustificationsService, - private readonly _activeDossiersService: ActiveDossiersService, - private readonly _permissionsService: PermissionsService, - private readonly _formBuilder: UntypedFormBuilder, - protected readonly _injector: Injector, protected readonly _dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) private readonly _data: { annotations: AnnotationWrapper[]; dossier: Dossier }, ) { - super(_injector, _dialogRef, true); + super(_dialogRef, true); this.form = this._getForm(); } diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/document-info-dialog/document-info-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/document-info-dialog/document-info-dialog.component.ts index f596e3e94..c8e3fdf98 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/document-info-dialog/document-info-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/document-info-dialog/document-info-dialog.component.ts @@ -1,5 +1,5 @@ -import { Component, Inject, Injector, OnInit } from '@angular/core'; -import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { Component, Inject, OnInit } from '@angular/core'; +import { UntypedFormGroup } from '@angular/forms'; import { Dossier, File, IFileAttributeConfig } from '@red/domain'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { FileAttributesService } from '@services/entity-services/file-attributes.service'; @@ -19,16 +19,14 @@ export class DocumentInfoDialogComponent extends BaseDialogComponent implements private readonly _dossier: Dossier; constructor( - private readonly _activeDossiersService: ActiveDossiersService, - private readonly _formBuilder: UntypedFormBuilder, + activeDossiersService: ActiveDossiersService, private readonly _fileAttributesService: FileAttributesService, private readonly _filesService: FilesService, - protected readonly _injector: Injector, protected readonly _dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) readonly file: File, ) { - super(_injector, _dialogRef); - this._dossier = this._activeDossiersService.find(this.file.dossierId); + super(_dialogRef); + this._dossier = activeDossiersService.find(this.file.dossierId); } async ngOnInit() { diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.ts index 20db963ee..0fa81e0de 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/force-redaction-dialog/force-annotation-dialog.component.ts @@ -1,5 +1,5 @@ -import { Component, Inject, Injector, OnInit } from '@angular/core'; -import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { Component, Inject, OnInit } from '@angular/core'; +import { UntypedFormGroup, Validators } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { BaseDialogComponent } from '@iqser/common-ui'; import { JustificationsService } from '@services/entity-services/justifications.service'; @@ -22,14 +22,12 @@ export class ForceAnnotationDialogComponent extends BaseDialogComponent implemen legalOptions: LegalBasisOption[] = []; constructor( - private readonly _formBuilder: UntypedFormBuilder, private readonly _justificationsService: JustificationsService, - protected readonly _injector: Injector, protected readonly _dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) private readonly _data: { readonly dossier: Dossier; readonly hint: boolean; annotations: AnnotationWrapper[] }, ) { - super(_injector, _dialogRef); + super(_dialogRef); this.form = this._getForm(); } diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/highlight-action-dialog/highlight-action-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/highlight-action-dialog/highlight-action-dialog.component.ts index 7f477626e..2e2b631eb 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/highlight-action-dialog/highlight-action-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/highlight-action-dialog/highlight-action-dialog.component.ts @@ -1,8 +1,8 @@ -import { Component, Inject, Injector } from '@angular/core'; -import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { Component, Inject } from '@angular/core'; +import { UntypedFormGroup, Validators } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { TextHighlightOperation, TextHighlightOperationPages } from '@red/domain'; -import { BaseDialogComponent, DetailsRadioOption, LoadingService } from '@iqser/common-ui'; +import { BaseDialogComponent, DetailsRadioOption } from '@iqser/common-ui'; import { TextHighlightService } from '@services/files/text-highlight.service'; import { firstValueFrom } from 'rxjs'; import { AnnotationWrapper } from '@models/file/annotation.wrapper'; @@ -39,14 +39,11 @@ export class HighlightActionDialogComponent extends BaseDialogComponent { ]; constructor( - private readonly _formBuilder: UntypedFormBuilder, - protected readonly _injector: Injector, protected readonly _dialogRef: MatDialogRef, private readonly _textHighlightService: TextHighlightService, - private readonly _loadingService: LoadingService, @Inject(MAT_DIALOG_DATA) readonly data: HighlightActionData, ) { - super(_injector, _dialogRef); + super(_dialogRef); this.form = this._getForm(); this.initialFormValue = this.form.getRawValue(); } @@ -76,10 +73,9 @@ export class HighlightActionDialogComponent extends BaseDialogComponent { color: [{ value: this.data.color, disabled: true }, Validators.required], option: [this.options[0], Validators.required], }); - } else { - return this._formBuilder.group({ - confirmation: [false, Validators.requiredTrue], - }); } + return this._formBuilder.group({ + confirmation: [false, Validators.requiredTrue], + }); } } diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/import-redactions-dialog/import-redactions-dialog.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/import-redactions-dialog/import-redactions-dialog.ts index a2807682b..ec90b2ce7 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/import-redactions-dialog/import-redactions-dialog.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/import-redactions-dialog/import-redactions-dialog.ts @@ -1,5 +1,5 @@ -import { Component, ElementRef, Inject, Injector, ViewChild } from '@angular/core'; -import { BaseDialogComponent, LoadingService, Toaster } from '@iqser/common-ui'; +import { Component, ElementRef, Inject, ViewChild } from '@angular/core'; +import { BaseDialogComponent } from '@iqser/common-ui'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { firstValueFrom } from 'rxjs'; import { RedactionImportService } from '@services/files/redaction-import.service'; @@ -22,15 +22,11 @@ export class ImportRedactionsDialogComponent extends BaseDialogComponent { onlyForSpecificPages = false; constructor( - protected readonly _injector: Injector, protected readonly _dialogRef: MatDialogRef, - private readonly _loadingService: LoadingService, private readonly _redactionImportService: RedactionImportService, - private readonly _toaster: Toaster, - @Inject(MAT_DIALOG_DATA) - readonly data: ImportData, + @Inject(MAT_DIALOG_DATA) readonly data: ImportData, ) { - super(_injector, _dialogRef); + super(_dialogRef); } fileChanged(file: File | null) { diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.ts index ea15d50ce..b3acd6846 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/manual-redaction-dialog/manual-annotation-dialog.component.ts @@ -1,12 +1,12 @@ -import { Component, Inject, Injector, OnInit } from '@angular/core'; -import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { Component, Inject, OnInit } from '@angular/core'; +import { UntypedFormGroup, Validators } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper'; import { JustificationsService } from '@services/entity-services/justifications.service'; import { Dictionary, Dossier, File, IAddRedactionRequest } from '@red/domain'; import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service'; import { DictionaryService } from '@services/entity-services/dictionary.service'; -import { BaseDialogComponent, CircleButtonTypes, Toaster } from '@iqser/common-ui'; +import { BaseDialogComponent, CircleButtonTypes } from '@iqser/common-ui'; import { firstValueFrom } from 'rxjs'; import { ManualRedactionService } from '../../services/manual-redaction.service'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; @@ -34,18 +34,15 @@ export class ManualAnnotationDialogComponent extends BaseDialogComponent impleme private readonly _dossier: Dossier; constructor( - private readonly _formBuilder: UntypedFormBuilder, private readonly _justificationsService: JustificationsService, private readonly _manualRedactionService: ManualRedactionService, - private readonly _activeDossiersService: ActiveDossiersService, + activeDossiersService: ActiveDossiersService, private readonly _dictionaryService: DictionaryService, - protected readonly _injector: Injector, - protected readonly _toaster: Toaster, protected readonly _dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) readonly data: { manualRedactionEntryWrapper: ManualRedactionEntryWrapper; dossierId: string; file: File }, ) { - super(_injector, _dialogRef); - this._dossier = this._activeDossiersService.find(this.data.dossierId); + super(_dialogRef); + this._dossier = activeDossiersService.find(this.data.dossierId); this.isFalsePositiveRequest = this.data.manualRedactionEntryWrapper.type === 'FALSE_POSITIVE'; this.isDictionaryRequest = this.data.manualRedactionEntryWrapper.type === 'DICTIONARY' || this.isFalsePositiveRequest; diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/recategorize-image-dialog/recategorize-image-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/recategorize-image-dialog/recategorize-image-dialog.component.ts index 6d3661ade..1589d4fb0 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/recategorize-image-dialog/recategorize-image-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/recategorize-image-dialog/recategorize-image-dialog.component.ts @@ -1,5 +1,5 @@ -import { Component, Inject, Injector, OnInit } from '@angular/core'; -import { UntypedFormBuilder, Validators } from '@angular/forms'; +import { Component, Inject, OnInit } from '@angular/core'; +import { Validators } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { AnnotationWrapper } from '@models/file/annotation.wrapper'; import { imageCategoriesTranslations } from '@translations/image-categories-translations'; @@ -10,16 +10,14 @@ import { BaseDialogComponent } from '@iqser/common-ui'; templateUrl: './recategorize-image-dialog.component.html', }) export class RecategorizeImageDialogComponent extends BaseDialogComponent implements OnInit { - typeOptions: ImageCategory[] = ['signature', 'logo', 'formula', 'image']; - translations = imageCategoriesTranslations; + readonly typeOptions: ImageCategory[] = ['signature', 'logo', 'formula', 'image']; + readonly translations = imageCategoriesTranslations; constructor( - private readonly _formBuilder: UntypedFormBuilder, - protected readonly _injector: Injector, protected readonly _dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) public data: { annotations: AnnotationWrapper[]; dossier: Dossier }, + @Inject(MAT_DIALOG_DATA) readonly data: { annotations: AnnotationWrapper[]; dossier: Dossier }, ) { - super(_injector, _dialogRef); + super(_dialogRef); } get changed(): boolean { diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-annotations-dialog/remove-annotations-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-annotations-dialog/remove-annotations-dialog.component.ts index 7163c6d33..18431093d 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/remove-annotations-dialog/remove-annotations-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/remove-annotations-dialog/remove-annotations-dialog.component.ts @@ -1,8 +1,7 @@ -import { Component, Inject, Injector } from '@angular/core'; +import { Component, Inject } from '@angular/core'; import { AnnotationWrapper } from '@models/file/annotation.wrapper'; import { TranslateService } from '@ngx-translate/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { UntypedFormBuilder } from '@angular/forms'; import { BaseDialogComponent, humanize } from '@iqser/common-ui'; import { Dossier } from '@red/domain'; @@ -20,12 +19,10 @@ export interface RemoveAnnotationsDialogInput { export class RemoveAnnotationsDialogComponent extends BaseDialogComponent { constructor( private readonly _translateService: TranslateService, - private readonly _formBuilder: UntypedFormBuilder, - protected readonly _injector: Injector, protected readonly _dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) public data: RemoveAnnotationsDialogInput, + @Inject(MAT_DIALOG_DATA) readonly data: RemoveAnnotationsDialogInput, ) { - super(_injector, _dialogRef); + super(_dialogRef); this.form = this._formBuilder.group({ comment: [null], }); @@ -45,8 +42,7 @@ export class RemoveAnnotationsDialogComponent extends BaseDialogComponent { return this._translateService.instant('remove-annotations-dialog.image-type', { typeLabel: humanize(annotation.type), }); - } else { - return annotation.value; } + return annotation.value; } } diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/resize-annotation-dialog/resize-annotation-dialog.component.ts b/apps/red-ui/src/app/modules/file-preview/dialogs/resize-annotation-dialog/resize-annotation-dialog.component.ts index de19825dd..0ad30acaf 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/resize-annotation-dialog/resize-annotation-dialog.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/resize-annotation-dialog/resize-annotation-dialog.component.ts @@ -1,6 +1,5 @@ -import { Component, Inject, Injector, OnInit } from '@angular/core'; +import { Component, Inject, OnInit } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { UntypedFormBuilder } from '@angular/forms'; import { BaseDialogComponent } from '@iqser/common-ui'; import { AnnotationWrapper } from '@models/file/annotation.wrapper'; @@ -9,12 +8,10 @@ import { AnnotationWrapper } from '@models/file/annotation.wrapper'; }) export class ResizeAnnotationDialogComponent extends BaseDialogComponent implements OnInit { constructor( - private readonly _formBuilder: UntypedFormBuilder, - protected readonly _injector: Injector, protected readonly _dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) private readonly _data: { annotation: AnnotationWrapper; text?: string }, ) { - super(_injector, _dialogRef); + super(_dialogRef); } get disabled(): boolean { diff --git a/apps/red-ui/src/app/modules/file-preview/services/file-data.service.ts b/apps/red-ui/src/app/modules/file-preview/services/file-data.service.ts index 936f3c390..fbb2cd2d7 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/file-data.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/file-data.service.ts @@ -2,7 +2,7 @@ import { ChangeType, File, IRedactionLog, IRedactionLogEntry, IViewedPage, ViewM import { AnnotationWrapper } from '@models/file/annotation.wrapper'; import { BehaviorSubject, firstValueFrom, iif, Observable, Subject } from 'rxjs'; import { RedactionLogEntry } from '@models/file/redaction-log.entry'; -import { Injectable, Injector } from '@angular/core'; +import { Injectable } from '@angular/core'; import { FilePreviewStateService } from './file-preview-state.service'; import { ViewedPagesService } from '@services/files/viewed-pages.service'; import { UserPreferenceService } from '@services/user-preference.service'; @@ -25,10 +25,9 @@ const DELTA_VIEW_TIME = 10 * 60 * 1000; // 10 minutes; export class FileDataService extends EntitiesService { viewedPages: IViewedPage[] = []; missingTypes = new Set(); - readonly hasChangeLog$ = new BehaviorSubject(false); readonly annotations$: Observable; - readonly hiddenAnnotations = new Set(); + protected readonly _entityClass = AnnotationWrapper; readonly #redactionLog$ = new Subject(); readonly #textHighlights$ = new BehaviorSubject([]); @@ -45,9 +44,8 @@ export class FileDataService extends EntitiesService { private readonly _filesService: FilesService, private readonly _toaster: Toaster, private readonly _logger: NGXLogger, - protected readonly _injector: Injector, ) { - super(_injector, AnnotationWrapper); + super(); this.annotations$ = this.#annotations$; this._viewModeService.viewMode$ .pipe( diff --git a/apps/red-ui/src/app/modules/file-preview/services/file-preview-state.service.ts b/apps/red-ui/src/app/modules/file-preview/services/file-preview-state.service.ts index 98a393daa..6f92e097d 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/file-preview-state.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/file-preview-state.service.ts @@ -1,10 +1,10 @@ import { Injectable, Injector } from '@angular/core'; import { combineLatest, firstValueFrom, from, merge, Observable, of, pairwise, Subject, switchMap } from 'rxjs'; import { Dictionary, Dossier, DOSSIER_ID, File, FILE_ID } from '@red/domain'; -import { ActivatedRoute, Router } from '@angular/router'; +import { Router } from '@angular/router'; import { FilesMapService } from '@services/files/files-map.service'; import { PermissionsService } from '@services/permissions.service'; -import { boolFactory, LoadingService } from '@iqser/common-ui'; +import { boolFactory, getParam, LoadingService } from '@iqser/common-ui'; import { filter, map, startWith, tap, withLatestFrom } from 'rxjs/operators'; import { FileManagementService } from '@services/files/file-management.service'; import { dossiersServiceResolver } from '@services/entity-services/dossiers.service.provider'; @@ -38,9 +38,9 @@ export class FilePreviewStateService { readonly isReadonly$: Observable; readonly isWritable$: Observable; - readonly dossierId: string; + readonly dossierId: string = getParam(DOSSIER_ID); readonly dossierTemplateId: string; - readonly fileId: string; + readonly fileId: string = getParam(FILE_ID); dossier: Dossier; file: File; #dossierDictionary: Dictionary; @@ -48,7 +48,6 @@ export class FilePreviewStateService { constructor( router: Router, - route: ActivatedRoute, filesMapService: FilesMapService, private readonly _injector: Injector, permissionsService: PermissionsService, @@ -62,8 +61,6 @@ export class FilePreviewStateService { ) { const dossiersService = dossiersServiceResolver(_injector, router); - this.fileId = route.snapshot.paramMap.get(FILE_ID); - this.dossierId = route.snapshot.paramMap.get(DOSSIER_ID); this.dossierTemplateId = dossiersService.find(this.dossierId).dossierTemplateId; this.dossier$ = dossiersService.getEntityChanged$(this.dossierId).pipe(tap(dossier => (this.dossier = dossier))); diff --git a/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts b/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts index fbdb5aed6..6272f62f2 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts @@ -36,17 +36,17 @@ function getMessage(action: ManualRedactionActions, isDictionary = false, error @Injectable() export class ManualRedactionService extends GenericService { - readonly bulkRequest = `${this._defaultModelPath}/bulk/request`; - readonly bulkRedaction = `${this._defaultModelPath}/bulk/redaction`; + protected readonly _defaultModelPath = 'manualRedaction'; + readonly #bulkRequest = `${this._defaultModelPath}/bulk/request`; + readonly #bulkRedaction = `${this._defaultModelPath}/bulk/redaction`; constructor( private readonly _toaster: Toaster, private readonly _logger: NGXLogger, - protected readonly _injector: Injector, private readonly _permissionsService: PermissionsService, private readonly _activeDossiersService: ActiveDossiersService, ) { - super(_injector, 'manualRedaction'); + super(); } @Validate() @@ -159,7 +159,7 @@ export class ManualRedactionService extends GenericService { @Validate() add(@RequiredParam() body: List, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) { - return this._post(body, `${this.bulkRedaction}/add/${dossierId}/${fileId}`).pipe(this.#log('Add', body)); + return this._post(body, `${this.#bulkRedaction}/add/${dossierId}/${fileId}`).pipe(this.#log('Add', body)); } @Validate() @@ -168,7 +168,7 @@ export class ManualRedactionService extends GenericService { @RequiredParam() dossierId: string, @RequiredParam() fileId: string, ) { - return this._post(body, `${this.bulkRedaction}/recategorize/${dossierId}/${fileId}`).pipe(this.#log('Recategorize', body)); + return this._post(body, `${this.#bulkRedaction}/recategorize/${dossierId}/${fileId}`).pipe(this.#log('Recategorize', body)); } @Validate() @@ -177,7 +177,7 @@ export class ManualRedactionService extends GenericService { @RequiredParam() dossierId: string, @RequiredParam() fileId: string, ) { - return this._post(body, `${this.bulkRequest}/recategorize/${dossierId}/${fileId}`).pipe(this.#log('Request recategorize', body)); + return this._post(body, `${this.#bulkRequest}/recategorize/${dossierId}/${fileId}`).pipe(this.#log('Request recategorize', body)); } @Validate() @@ -186,7 +186,7 @@ export class ManualRedactionService extends GenericService { @RequiredParam() dossierId: string, @RequiredParam() fileId: string, ) { - return this._post(body, `${this.bulkRedaction}/legalBasisChange/${dossierId}/${fileId}`).pipe( + return this._post(body, `${this.#bulkRedaction}/legalBasisChange/${dossierId}/${fileId}`).pipe( this.#log('Legal basis change', body), ); } @@ -197,7 +197,7 @@ export class ManualRedactionService extends GenericService { @RequiredParam() dossierId: string, @RequiredParam() fileId: string, ) { - return this._post(body, `${this.bulkRequest}/legalBasis/${dossierId}/${fileId}`).pipe( + return this._post(body, `${this.#bulkRequest}/legalBasis/${dossierId}/${fileId}`).pipe( this.#log('Request legal basis change', body), ); } @@ -208,7 +208,7 @@ export class ManualRedactionService extends GenericService { @RequiredParam() dossierId: string, @RequiredParam() fileId: string, ) { - return this._post(body, `${this.bulkRequest}/remove/${dossierId}/${fileId}`).pipe(this.#log('Request remove', body)); + return this._post(body, `${this.#bulkRequest}/remove/${dossierId}/${fileId}`).pipe(this.#log('Request remove', body)); } @Validate() @@ -234,12 +234,12 @@ export class ManualRedactionService extends GenericService { @Validate() remove(@RequiredParam() body: List, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) { - return this._post(body, `${this.bulkRedaction}/remove/${dossierId}/${fileId}`).pipe(this.#log('Remove', body)); + return this._post(body, `${this.#bulkRedaction}/remove/${dossierId}/${fileId}`).pipe(this.#log('Remove', body)); } @Validate() requestAdd(@RequiredParam() body: List, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) { - return this._post(body, `${this.bulkRequest}/add/${dossierId}/${fileId}`).pipe(this.#log('Request add', body)); + return this._post(body, `${this.#bulkRequest}/add/${dossierId}/${fileId}`).pipe(this.#log('Request add', body)); } @Validate() @@ -248,7 +248,7 @@ export class ManualRedactionService extends GenericService { @RequiredParam() dossierId: string, @RequiredParam() fileId: string, ) { - return this._post(body, `${this.bulkRedaction}/force/${dossierId}/${fileId}`).pipe(this.#log('Force redaction', body)); + return this._post(body, `${this.#bulkRedaction}/force/${dossierId}/${fileId}`).pipe(this.#log('Force redaction', body)); } @Validate() @@ -257,17 +257,17 @@ export class ManualRedactionService extends GenericService { @RequiredParam() dossierId: string, @RequiredParam() fileId: string, ) { - return this._post(body, `${this.bulkRequest}/force/${dossierId}/${fileId}`).pipe(this.#log('Request force redaction', body)); + return this._post(body, `${this.#bulkRequest}/force/${dossierId}/${fileId}`).pipe(this.#log('Request force redaction', body)); } @Validate() resize(@RequiredParam() body: List, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) { - return this._post(body, `${this.bulkRedaction}/resize/${dossierId}/${fileId}`).pipe(this.#log('Resize', body)); + return this._post(body, `${this.#bulkRedaction}/resize/${dossierId}/${fileId}`).pipe(this.#log('Resize', body)); } @Validate() requestResize(@RequiredParam() body: List, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) { - return this._post(body, `${this.bulkRequest}/resize/${dossierId}/${fileId}`).pipe(this.#log('Request resize', body)); + return this._post(body, `${this.#bulkRequest}/resize/${dossierId}/${fileId}`).pipe(this.#log('Request resize', body)); } #log(action: string, body: unknown) { diff --git a/apps/red-ui/src/app/modules/search/search-screen/search-screen.component.ts b/apps/red-ui/src/app/modules/search/search-screen/search-screen.component.ts index 22caab14b..7f0b56dc4 100644 --- a/apps/red-ui/src/app/modules/search/search-screen/search-screen.component.ts +++ b/apps/red-ui/src/app/modules/search/search-screen/search-screen.component.ts @@ -1,16 +1,16 @@ -import { ChangeDetectionStrategy, Component, forwardRef, Injector, OnDestroy, OnInit } from '@angular/core'; +import { ChangeDetectionStrategy, Component, OnDestroy } from '@angular/core'; import { - DefaultListingServices, IFilterGroup, keyChecker, ListingComponent, + listingProvidersFactory, LoadingService, NestedFilter, SearchPositions, SortingOrders, TableColumnConfig, } from '@iqser/common-ui'; -import { combineLatest, firstValueFrom, Observable, of } from 'rxjs'; +import { combineLatest, Observable, of } from 'rxjs'; import { debounceTime, map, startWith, switchMap, tap } from 'rxjs/operators'; import { ActivatedRoute, Router } from '@angular/router'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; @@ -30,14 +30,14 @@ import { import { FilesMapService } from '@services/files/files-map.service'; import { PlatformSearchService } from '@services/entity-services/platform-search.service'; import { FeaturesService } from '@services/features.service'; -import { DossiersCacheService } from '../../../services/dossiers/dossiers-cache.service'; -import { DossierTemplatesService } from '../../../services/dossier-templates/dossier-templates.service'; -import { UserService } from '../../../services/user.service'; +import { DossiersCacheService } from '@services/dossiers/dossiers-cache.service'; +import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service'; +import { UserService } from '@services/user.service'; @Component({ templateUrl: './search-screen.component.html', styleUrls: ['./search-screen.component.scss'], - providers: [...DefaultListingServices, { provide: ListingComponent, useExisting: forwardRef(() => SearchScreenComponent) }], + providers: listingProvidersFactory(SearchScreenComponent), changeDetection: ChangeDetectionStrategy.OnPush, }) export class SearchScreenComponent extends ListingComponent implements OnDestroy { @@ -79,7 +79,6 @@ export class SearchScreenComponent extends ListingComponent imp constructor( private readonly _router: Router, - protected readonly _injector: Injector, private readonly _activatedRoute: ActivatedRoute, private readonly _loadingService: LoadingService, private readonly _dossiersCacheService: DossiersCacheService, @@ -91,12 +90,76 @@ export class SearchScreenComponent extends ListingComponent imp private readonly _dossierTemplateService: DossierTemplatesService, private readonly _userService: UserService, ) { - super(_injector); + super(); this.searchService.skip = true; this.sortingService.setSortingOption({ column: 'searchKey', order: SortingOrders.desc }); this._initFilters(); } + private get _routeDossierIds(): string[] { + return this._activatedRoute.snapshot.queryParamMap.get('dossierIds').split(','); + } + + private get _routeDossierTemplateIds(): string[] { + return this._activatedRoute.snapshot.queryParamMap.get('dossierTemplateIds')?.split(','); + } + + private get _routeStatus(): WorkflowFileStatus { + return this._activatedRoute.snapshot.queryParamMap.get('status') as WorkflowFileStatus; + } + + private get _routeAssignee(): string { + return this._activatedRoute.snapshot.queryParamMap.get('assignee'); + } + + private get _routeOnlyActive(): boolean { + return this._activatedRoute.snapshot.queryParamMap.get('onlyActive') === 'true'; + } + + private get _routeQuery(): string { + return this._activatedRoute.snapshot.queryParamMap.get('query'); + } + + private get _queryChanged(): Observable { + return this.searchService.valueChanges$.pipe( + startWith(this._routeQuery), + tap(query => (this.searchService.searchValue = query)), + debounceTime(300), + ); + } + + get #enabledArchive(): boolean { + return this._featuresService.isEnabled(DOSSIERS_ARCHIVE); + } + + private get _filtersChanged$(): Observable<[string[], WorkflowFileStatus, string, string[], boolean]> { + const onlyActiveDossiers$ = this.#enabledArchive + ? this.filterService.getSingleFilter('onlyActiveDossiers').pipe(map(f => !!f.checked)) + : of(true); + const filterGroups$ = this.filterService.filterGroups$; + return combineLatest([filterGroups$, onlyActiveDossiers$]).pipe( + map(([groups, onlyActive]) => { + const dossierIds: string[] = groups[0].filters.filter(v => v.checked).map(v => v.id); + const workflowStatus: WorkflowFileStatus = groups[1].filters.filter(v => v.checked).map(v => v.id)[0] as WorkflowFileStatus; + const assignee: string = groups[2].filters.filter(v => v.checked).map(v => v.id)[0]; + const dossierTemplateIds: string[] = groups[3]?.filters.filter(v => v.checked).map(v => v.id); + return [dossierIds, workflowStatus, assignee, dossierTemplateIds, onlyActive]; + }), + startWith<[string[], WorkflowFileStatus, string, string[], boolean]>([ + this._routeDossierIds, + this._routeStatus, + this._routeAssignee, + this._routeDossierTemplateIds, + this._routeOnlyActive, + ]), + ); + } + + mustContain(value: string) { + const newQuery = this.searchService.searchValue.replace(value, `"${value}"`); + this.searchService.searchValue = newQuery ?? ''; + } + private _initFilters() { const dossierIds = this._routeDossierIds; const dossierToFilter = ({ dossierName, id }: Dossier) => { @@ -175,70 +238,6 @@ export class SearchScreenComponent extends ListingComponent imp this.filterService.addFilterGroups([templateNameFilter]); } - private get _routeDossierIds(): string[] { - return this._activatedRoute.snapshot.queryParamMap.get('dossierIds').split(','); - } - - private get _routeDossierTemplateIds(): string[] { - return this._activatedRoute.snapshot.queryParamMap.get('dossierTemplateIds')?.split(','); - } - - private get _routeStatus(): WorkflowFileStatus { - return this._activatedRoute.snapshot.queryParamMap.get('status') as WorkflowFileStatus; - } - - private get _routeAssignee(): string { - return this._activatedRoute.snapshot.queryParamMap.get('assignee'); - } - - private get _routeOnlyActive(): boolean { - return this._activatedRoute.snapshot.queryParamMap.get('onlyActive') === 'true'; - } - - private get _routeQuery(): string { - return this._activatedRoute.snapshot.queryParamMap.get('query'); - } - - private get _queryChanged(): Observable { - return this.searchService.valueChanges$.pipe( - startWith(this._routeQuery), - tap(query => (this.searchService.searchValue = query)), - debounceTime(300), - ); - } - - get #enabledArchive(): boolean { - return this._featuresService.isEnabled(DOSSIERS_ARCHIVE); - } - - private get _filtersChanged$(): Observable<[string[], WorkflowFileStatus, string, string[], boolean]> { - const onlyActiveDossiers$ = this.#enabledArchive - ? this.filterService.getSingleFilter('onlyActiveDossiers').pipe(map(f => !!f.checked)) - : of(true); - const filterGroups$ = this.filterService.filterGroups$; - return combineLatest([filterGroups$, onlyActiveDossiers$]).pipe( - map(([groups, onlyActive]) => { - const dossierIds: string[] = groups[0].filters.filter(v => v.checked).map(v => v.id); - const workflowStatus: WorkflowFileStatus = groups[1].filters.filter(v => v.checked).map(v => v.id)[0] as WorkflowFileStatus; - const assignee: string = groups[2].filters.filter(v => v.checked).map(v => v.id)[0]; - const dossierTemplateIds: string[] = groups[3]?.filters.filter(v => v.checked).map(v => v.id); - return [dossierIds, workflowStatus, assignee, dossierTemplateIds, onlyActive]; - }), - startWith<[string[], WorkflowFileStatus, string, string[], boolean]>([ - this._routeDossierIds, - this._routeStatus, - this._routeAssignee, - this._routeDossierTemplateIds, - this._routeOnlyActive, - ]), - ); - } - - mustContain(value: string) { - const newQuery = this.searchService.searchValue.replace(value, `"${value}"`); - this.searchService.searchValue = newQuery ?? ''; - } - private _updateNavigation( query?: string, dossierIds?: string[], diff --git a/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/dictionary/dictionary-details-dialog/dictionary-details-dialog.component.ts b/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/dictionary/dictionary-details-dialog/dictionary-details-dialog.component.ts index 8fa41f1bd..13df4ee7b 100644 --- a/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/dictionary/dictionary-details-dialog/dictionary-details-dialog.component.ts +++ b/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/dictionary/dictionary-details-dialog/dictionary-details-dialog.component.ts @@ -1,4 +1,4 @@ -import { Component, Inject, Injector, ViewChild } from '@angular/core'; +import { Component, Inject, ViewChild } from '@angular/core'; import { BaseDialogComponent } from '@iqser/common-ui'; import { dossiersServiceProvider } from '@services/entity-services/dossiers.service.provider'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; @@ -16,10 +16,9 @@ export class DictionaryDetailsDialogComponent extends BaseDialogComponent { constructor( @Inject(MAT_DIALOG_DATA) readonly data: { dictionary: Dictionary; dossierId: string; readOnly: boolean }, - protected readonly _injector: Injector, protected readonly _dialogRef: MatDialogRef, ) { - super(_injector, _dialogRef, true); + super(_dialogRef, true); } get valid(): boolean { diff --git a/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/edit-dossier-dialog.component.ts b/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/edit-dossier-dialog.component.ts index ed5407b64..e3252b14f 100644 --- a/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/edit-dossier-dialog.component.ts +++ b/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/edit-dossier-dialog.component.ts @@ -1,10 +1,10 @@ -import { AfterViewInit, Component, Inject, Injector, ViewChild } from '@angular/core'; +import { AfterViewInit, Component, Inject, ViewChild } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { Dossier } from '@red/domain'; import { EditDossierGeneralInfoComponent } from './general-info/edit-dossier-general-info.component'; import { EditDossierDownloadPackageComponent } from './download-package/edit-dossier-download-package.component'; import { EditDossierSectionInterface } from './edit-dossier-section.interface'; -import { BaseDialogComponent, ConfirmOptions, IconButtonTypes, LoadingService, SaveOptions, Toaster } from '@iqser/common-ui'; +import { BaseDialogComponent, ConfirmOptions, IconButtonTypes, SaveOptions } from '@iqser/common-ui'; import { EditDossierDictionaryComponent } from './dictionary/edit-dossier-dictionary.component'; import { EditDossierAttributesComponent } from './attributes/edit-dossier-attributes.component'; @@ -13,7 +13,7 @@ import { Observable } from 'rxjs'; import { tap } from 'rxjs/operators'; import { EditDossierTeamComponent } from './edit-dossier-team/edit-dossier-team.component'; import { PermissionsService } from '@services/permissions.service'; -import { UserService } from '@services/user.service'; +import { getCurrentUser } from '@services/user.service'; import { DossiersService } from '@services/dossiers/dossiers.service'; import { dossiersServiceProvider } from '@services/entity-services/dossiers.service.provider'; @@ -37,22 +37,17 @@ export class EditDossierDialogComponent extends BaseDialogComponent implements A readonly iconButtonTypes = IconButtonTypes; activeNav: Section; readonly dossier$: Observable; - @ViewChild(EditDossierGeneralInfoComponent) generalInfoComponent: EditDossierGeneralInfoComponent; @ViewChild(EditDossierDownloadPackageComponent) downloadPackageComponent: EditDossierDownloadPackageComponent; @ViewChild(EditDossierDictionaryComponent) dictionaryComponent: EditDossierDictionaryComponent; @ViewChild(EditDossierTeamComponent) membersComponent: EditDossierTeamComponent; @ViewChild(EditDossierAttributesComponent) attributesComponent: EditDossierAttributesComponent; - + readonly #currentUser = getCurrentUser(); private _dossier: Dossier; constructor( - private readonly _toaster: Toaster, private readonly _dossiersService: DossiersService, - private readonly _loadingService: LoadingService, private readonly _permissionsService: PermissionsService, - private readonly _userService: UserService, - protected readonly _injector: Injector, protected readonly _dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) private readonly _data: { @@ -60,7 +55,7 @@ export class EditDossierDialogComponent extends BaseDialogComponent implements A section?: Section; }, ) { - super(_injector, _dialogRef, true); + super(_dialogRef, true); this.dossier$ = this._dossiersService.getEntityChanged$(_data.dossierId).pipe( tap(dossier => { this._dossier = dossier; @@ -94,8 +89,7 @@ export class EditDossierDialogComponent extends BaseDialogComponent implements A get showActionButtons(): boolean { return ( - (['members'].includes(this.activeNav) && this._userService.currentUser.isManager) || - this._permissionsService.canEditDossier(this._dossier) + (['members'].includes(this.activeNav) && this.#currentUser.isManager) || this._permissionsService.canEditDossier(this._dossier) ); } diff --git a/apps/red-ui/src/app/modules/shared/components/add-edit-entity/add-edit-entity.component.ts b/apps/red-ui/src/app/modules/shared/components/add-edit-entity/add-edit-entity.component.ts index 769080ed8..57535c4da 100644 --- a/apps/red-ui/src/app/modules/shared/components/add-edit-entity/add-edit-entity.component.ts +++ b/apps/red-ui/src/app/modules/shared/components/add-edit-entity/add-edit-entity.component.ts @@ -211,7 +211,7 @@ export class AddEditEntityComponent extends BaseFormComponent implements OnInit } private _formToObject(): IDictionary { - // Fields that aren't set for hints, need additional check + // Fields which aren't set for hints, need additional check const addToDictionaryAction = !!this.form.get('addToDictionaryAction')?.value; const hasDictionary = !!this.form.get('hasDictionary')?.value; @@ -225,7 +225,7 @@ export class AddEditEntityComponent extends BaseFormComponent implements OnInit addToDictionaryAction, }; - if (this.entity.type !== 'dossier_redaction') { + if (this.entity?.type !== 'dossier_redaction') { entity = { ...entity, type: this.form.get('type').value, diff --git a/apps/red-ui/src/app/modules/shared/components/dossiers-type-switch/dossiers-type-switch.component.ts b/apps/red-ui/src/app/modules/shared/components/dossiers-type-switch/dossiers-type-switch.component.ts index 558b12b3c..b3fd3e003 100644 --- a/apps/red-ui/src/app/modules/shared/components/dossiers-type-switch/dossiers-type-switch.component.ts +++ b/apps/red-ui/src/app/modules/shared/components/dossiers-type-switch/dossiers-type-switch.component.ts @@ -1,8 +1,7 @@ -import { ChangeDetectionStrategy, Component } from '@angular/core'; -import { ARCHIVE_ROUTE, DashboardStats, DOSSIER_TEMPLATE_ID, DOSSIERS_ROUTE } from '@red/domain'; +import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { ARCHIVE_ROUTE, DOSSIER_TEMPLATE_ID, DOSSIERS_ROUTE } from '@red/domain'; import { DashboardStatsService } from '@services/dossier-templates/dashboard-stats.service'; -import { ActivatedRoute } from '@angular/router'; -import { Observable } from 'rxjs'; +import { getParam } from '@iqser/common-ui'; @Component({ selector: 'redaction-dossiers-type-switch', @@ -13,11 +12,5 @@ import { Observable } from 'rxjs'; export class DossiersTypeSwitchComponent { readonly DOSSIERS_ROUTE = DOSSIERS_ROUTE; readonly ARCHIVE_ROUTE = ARCHIVE_ROUTE; - - readonly dossierTemplate$: Observable; - - constructor(private readonly _dashboardStatsService: DashboardStatsService, private readonly _route: ActivatedRoute) { - const dossierTemplateId = _route.snapshot.paramMap.get(DOSSIER_TEMPLATE_ID); - this.dossierTemplate$ = _dashboardStatsService.getEntityChanged$(dossierTemplateId); - } + readonly dossierTemplate$ = inject(DashboardStatsService).getEntityChanged$(getParam(DOSSIER_TEMPLATE_ID)); } diff --git a/apps/red-ui/src/app/modules/shared/dialogs/add-dossier-dialog/add-dossier-dialog.component.ts b/apps/red-ui/src/app/modules/shared/dialogs/add-dossier-dialog/add-dossier-dialog.component.ts index ea1b16778..3ae34e23b 100644 --- a/apps/red-ui/src/app/modules/shared/dialogs/add-dossier-dialog/add-dossier-dialog.component.ts +++ b/apps/red-ui/src/app/modules/shared/dialogs/add-dossier-dialog/add-dossier-dialog.component.ts @@ -1,9 +1,9 @@ -import { Component, Inject, Injector, OnInit } from '@angular/core'; +import { Component, Inject, OnInit } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { DOSSIER_TEMPLATE_ID, DownloadFileType, IDossierRequest, IDossierTemplate, IReportTemplate } from '@red/domain'; -import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { UntypedFormGroup, Validators } from '@angular/forms'; import { downloadTypesTranslations } from '@translations/download-types-translations'; -import { BaseDialogComponent, IconButtonTypes, LoadingService, SaveOptions } from '@iqser/common-ui'; +import { BaseDialogComponent, IconButtonTypes, SaveOptions } from '@iqser/common-ui'; import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service'; import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service'; import { ReportTemplateService } from '@services/report-template.service'; @@ -38,16 +38,13 @@ export class AddDossierDialogComponent extends BaseDialogComponent implements On constructor( private readonly _activeDossiersService: ActiveDossiersService, private readonly _dossierTemplatesService: DossierTemplatesService, - private readonly _formBuilder: UntypedFormBuilder, private readonly _reportTemplateController: ReportTemplateService, private readonly _router: Router, private readonly _dialogService: DossiersDialogService, - private readonly _loadingService: LoadingService, - protected readonly _injector: Injector, protected readonly _dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) readonly data: DialogData, ) { - super(_injector, _dialogRef); + super(_dialogRef); this._getDossierTemplates(); this.form = this._getForm(); this.initialFormValue = this.form.getRawValue(); diff --git a/apps/red-ui/src/app/modules/trash/trash-screen/trash-screen.component.ts b/apps/red-ui/src/app/modules/trash/trash-screen/trash-screen.component.ts index c221547a8..db8594f9d 100644 --- a/apps/red-ui/src/app/modules/trash/trash-screen/trash-screen.component.ts +++ b/apps/red-ui/src/app/modules/trash/trash-screen/trash-screen.component.ts @@ -1,9 +1,8 @@ -import { ChangeDetectionStrategy, Component, forwardRef, Injector } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { CircleButtonTypes, - DefaultListingServicesTmp, - EntitiesService, ListingComponent, + listingProvidersFactory, LoadingService, SortingOrders, TableColumnConfig, @@ -14,22 +13,16 @@ import { distinctUntilChanged, map } from 'rxjs/operators'; import { RouterHistoryService } from '@services/router-history.service'; import { TrashItem } from '@red/domain'; import { TrashService } from '@services/entity-services/trash.service'; -import { FilesService } from '@services/files/files.service'; -import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service'; import { TrashDialogService } from '../services/trash-dialog.service'; @Component({ templateUrl: './trash-screen.component.html', styleUrls: ['./trash-screen.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, - providers: [ - ...DefaultListingServicesTmp, - { provide: EntitiesService, useExisting: TrashService }, - { - provide: ListingComponent, - useExisting: forwardRef(() => TrashScreenComponent), - }, - ], + providers: listingProvidersFactory({ + entitiesService: TrashService, + component: TrashScreenComponent, + }), }) export class TrashScreenComponent extends ListingComponent { readonly circleButtonTypes = CircleButtonTypes; @@ -45,15 +38,12 @@ export class TrashScreenComponent extends ListingComponent { ]; constructor( - protected readonly _injector: Injector, private readonly _loadingService: LoadingService, private readonly _trashService: TrashService, - private readonly _activeDossiersService: ActiveDossiersService, - private readonly _filesService: FilesService, readonly routerHistoryService: RouterHistoryService, private readonly _dialogService: TrashDialogService, ) { - super(_injector); + super(); this.sortingService.setSortingOption({ column: 'type', diff --git a/apps/red-ui/src/app/modules/upload-download/services/file-download.service.ts b/apps/red-ui/src/app/modules/upload-download/services/file-download.service.ts index 7176cfea2..926a3e0e9 100644 --- a/apps/red-ui/src/app/modules/upload-download/services/file-download.service.ts +++ b/apps/red-ui/src/app/modules/upload-download/services/file-download.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Injector } from '@angular/core'; +import { Injectable } from '@angular/core'; import { DownloadStatus, IDownloadResponse, @@ -16,15 +16,17 @@ import { EntitiesService, List, mapEach, RequiredParam, Validate } from '@iqser/ import { NGXLogger } from 'ngx-logger'; @Injectable() -export class FileDownloadService extends EntitiesService { +export class FileDownloadService extends EntitiesService { + protected readonly _defaultModelPath = 'async/download'; + protected readonly _entityClass = DownloadStatus; + constructor( private readonly _userService: UserService, private readonly _keycloakService: KeycloakService, private readonly _configService: ConfigService, - protected readonly _injector: Injector, private readonly _logger: NGXLogger, ) { - super(_injector, DownloadStatus, 'async/download'); + super(); } downloadFiles(fileIds: List, dossierId: string): Observable { diff --git a/apps/red-ui/src/app/modules/upload-download/services/file-upload.service.ts b/apps/red-ui/src/app/modules/upload-download/services/file-upload.service.ts index a7a2222f0..4101beb15 100644 --- a/apps/red-ui/src/app/modules/upload-download/services/file-upload.service.ts +++ b/apps/red-ui/src/app/modules/upload-download/services/file-upload.service.ts @@ -21,14 +21,15 @@ export interface ActiveUpload { @Injectable() export class FileUploadService extends GenericService implements OnDestroy { static readonly MAX_PARALLEL_UPLOADS = 5; + protected readonly _defaultModelPath = 'upload'; files: FileUploadModel[] = []; groupedFiles: { [key: string]: FileUploadModel[] } = {}; activeUploads = 0; - private _pendingUploads: FileUploadModel[] = []; - private _activeUploads: ActiveUpload[] = []; + #pendingUploads: FileUploadModel[] = []; + #activeUploads: ActiveUpload[] = []; - private readonly _fetchFiles$ = new Subject(); - private readonly _subscriptions = new Subscription(); + readonly #fetchFiles$ = new Subject(); + readonly #subscriptions = new Subscription(); constructor( private readonly _filesService: FilesService, @@ -38,17 +39,15 @@ export class FileUploadService extends GenericService impleme private readonly _configService: ConfigService, private readonly _dialogService: UploadDownloadDialogService, private readonly _errorMessageService: ErrorMessageService, - private readonly _activeDossiersService: ActiveDossiersService, - protected readonly _injector: Injector, ) { - super(_injector, 'upload'); - const fileFetch$ = this._fetchFiles$.pipe( + super(); + const fileFetch$ = this.#fetchFiles$.pipe( throttleTime(250), switchMap(dossierId => this._filesService.loadAll(dossierId)), ); - this._subscriptions.add(fileFetch$.subscribe()); + this.#subscriptions.add(fileFetch$.subscribe()); const interval$ = interval(2500).pipe(tap(() => this._handleUploads())); - this._subscriptions.add(interval$.subscribe()); + this.#subscriptions.add(interval$.subscribe()); } get activeDossierKeys() { @@ -56,7 +55,7 @@ export class FileUploadService extends GenericService impleme } ngOnDestroy() { - this._subscriptions.unsubscribe(); + this.#subscriptions.unsubscribe(); } scheduleUpload(item: FileUploadModel) { @@ -64,7 +63,7 @@ export class FileUploadService extends GenericService impleme item.progress = 0; item.completed = false; item.error = null; - this._pendingUploads.push(item); + this.#pendingUploads.push(item); } } @@ -159,7 +158,7 @@ export class FileUploadService extends GenericService impleme const index = this.files.indexOf(item); if (index > -1) { this._removeFileFromGroup(item); - this._fetchFiles$.next(item.dossierId); + this.#fetchFiles$.next(item.dossierId); this.files.splice(index, 1); } } @@ -196,19 +195,19 @@ export class FileUploadService extends GenericService impleme } private _handleUploads() { - if (this._activeUploads.length < FileUploadService.MAX_PARALLEL_UPLOADS && this._pendingUploads.length > 0) { - let cnt = FileUploadService.MAX_PARALLEL_UPLOADS - this._activeUploads.length; - while (cnt > 0 && this._pendingUploads.length > 0) { + if (this.#activeUploads.length < FileUploadService.MAX_PARALLEL_UPLOADS && this.#pendingUploads.length > 0) { + let cnt = FileUploadService.MAX_PARALLEL_UPLOADS - this.#activeUploads.length; + while (cnt > 0 && this.#pendingUploads.length > 0) { // Only schedule CSVs when no other file types in queue. // CSVs are sorted at the end of `_pendingUploads`. - if (isCsv(this._pendingUploads[0]) && this._activeUploads.filter(upload => !isCsv(upload.fileUploadModel)).length > 0) { + if (isCsv(this.#pendingUploads[0]) && this.#activeUploads.filter(upload => !isCsv(upload.fileUploadModel)).length > 0) { return; } cnt--; - const poppedFileUploadModel = this._pendingUploads.shift(); + const poppedFileUploadModel = this.#pendingUploads.shift(); const subscription = this._createSubscription(poppedFileUploadModel); - this._activeUploads.push({ + this.#activeUploads.push({ subscription: subscription, fileUploadModel: poppedFileUploadModel, }); @@ -254,9 +253,9 @@ export class FileUploadService extends GenericService impleme } private _removeUpload(fileUploadModel: FileUploadModel) { - const index = this._activeUploads.findIndex(au => au.fileUploadModel === fileUploadModel); + const index = this.#activeUploads.findIndex(au => au.fileUploadModel === fileUploadModel); if (index > -1) { - const subscription = this._activeUploads[index].subscription; + const subscription = this.#activeUploads[index].subscription; if (subscription) { try { subscription.unsubscribe(); @@ -265,7 +264,7 @@ export class FileUploadService extends GenericService impleme } } - this._activeUploads.splice(index, 1); + this.#activeUploads.splice(index, 1); this.activeUploads--; } } diff --git a/apps/red-ui/src/app/services/dossier-templates/dashboard-stats.service.ts b/apps/red-ui/src/app/services/dossier-templates/dashboard-stats.service.ts index e5b57103a..3fab25c8c 100644 --- a/apps/red-ui/src/app/services/dossier-templates/dashboard-stats.service.ts +++ b/apps/red-ui/src/app/services/dossier-templates/dashboard-stats.service.ts @@ -1,7 +1,6 @@ import { EntitiesService, mapEach } from '@iqser/common-ui'; import { DashboardStats, IDashboardStats } from '@red/domain'; -import { Injectable, Injector } from '@angular/core'; -import { NGXLogger } from 'ngx-logger'; +import { inject, Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { map, switchMap, tap } from 'rxjs/operators'; import { DossierStatesService } from '../entity-services/dossier-states.service'; @@ -18,19 +17,16 @@ const templatesSorter = (a: DashboardStats, b: DashboardStats) => { @Injectable({ providedIn: 'root', }) -export class DashboardStatsService extends EntitiesService { - constructor( - protected readonly _injector: Injector, - private readonly _dossierStatesService: DossierStatesService, - private readonly _logger: NGXLogger, - ) { - super(_injector, DashboardStats, 'dossier-template/stats'); - } +export class DashboardStatsService extends EntitiesService { + protected readonly _defaultModelPath = 'dossier-template/stats'; + protected readonly _entityClass = DashboardStats; + + readonly #dossierStatesService = inject(DossierStatesService); loadAll(): Observable { return this.getAll(this._defaultModelPath).pipe( mapEach(entity => new DashboardStats(entity)), - switchMap(entities => this._dossierStatesService.loadAllForAllTemplates().pipe(map(() => entities))), + switchMap(entities => this.#dossierStatesService.loadAllForAllTemplates().pipe(map(() => entities))), tap(entities => entities.sort(templatesSorter)), tap(entities => this.setEntities(entities)), ); diff --git a/apps/red-ui/src/app/services/dossier-templates/dossier-templates.service.ts b/apps/red-ui/src/app/services/dossier-templates/dossier-templates.service.ts index 098b375b0..50ae0e7ab 100644 --- a/apps/red-ui/src/app/services/dossier-templates/dossier-templates.service.ts +++ b/apps/red-ui/src/app/services/dossier-templates/dossier-templates.service.ts @@ -1,6 +1,6 @@ import { EntitiesService, List, mapEach, RequiredParam, Toaster, Validate } from '@iqser/common-ui'; import { DossierTemplate, IDossierTemplate } from '@red/domain'; -import { Injectable, Injector } from '@angular/core'; +import { Injectable } from '@angular/core'; import { forkJoin, Observable, of } from 'rxjs'; import { FileAttributesService } from '../entity-services/file-attributes.service'; import { catchError, mapTo, switchMap, tap } from 'rxjs/operators'; @@ -15,15 +15,17 @@ const GENERIC_MSG = _('dossier-templates-listing.error.generic'); @Injectable({ providedIn: 'root', }) -export class DossierTemplatesService extends EntitiesService { +export class DossierTemplatesService extends EntitiesService { + protected readonly _defaultModelPath = 'dossier-template'; + protected readonly _entityClass = DossierTemplate; + constructor( - protected readonly _injector: Injector, private readonly _toaster: Toaster, private readonly _fileAttributesService: FileAttributesService, private readonly _dossierTemplateStatsService: DossierTemplateStatsService, private readonly _dictionaryService: DictionaryService, ) { - super(_injector, DossierTemplate, 'dossier-template'); + super(); } loadAll(): Observable { @@ -41,9 +43,8 @@ export class DossierTemplatesService extends EntitiesService this.setEntities(templates)), ); diff --git a/apps/red-ui/src/app/services/dossiers/active-dossiers.service.ts b/apps/red-ui/src/app/services/dossiers/active-dossiers.service.ts index b3cc9ab59..f443a73f9 100644 --- a/apps/red-ui/src/app/services/dossiers/active-dossiers.service.ts +++ b/apps/red-ui/src/app/services/dossiers/active-dossiers.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Injector } from '@angular/core'; +import { Injectable } from '@angular/core'; import { DossiersService } from './dossiers.service'; import { DOSSIERS_ROUTE } from '@red/domain'; @@ -6,7 +6,6 @@ import { DOSSIERS_ROUTE } from '@red/domain'; providedIn: 'root', }) export class ActiveDossiersService extends DossiersService { - constructor(protected readonly _injector: Injector) { - super(_injector, 'dossier', DOSSIERS_ROUTE); - } + protected readonly _defaultModelPath = 'dossier'; + readonly routerPath = DOSSIERS_ROUTE; } diff --git a/apps/red-ui/src/app/services/dossiers/archived-dossiers.service.ts b/apps/red-ui/src/app/services/dossiers/archived-dossiers.service.ts index 733f47d70..ed9a379d9 100644 --- a/apps/red-ui/src/app/services/dossiers/archived-dossiers.service.ts +++ b/apps/red-ui/src/app/services/dossiers/archived-dossiers.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Injector } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { ARCHIVE_ROUTE, Dossier, DOSSIERS_ARCHIVE, DOSSIERS_ROUTE } from '@red/domain'; import { catchError, switchMap, tap } from 'rxjs/operators'; import { Observable, of } from 'rxjs'; @@ -7,21 +7,17 @@ import { ActiveDossiersService } from './active-dossiers.service'; import { DossiersService } from './dossiers.service'; import { FilesMapService } from '../files/files-map.service'; import { FeaturesService } from '../features.service'; -import { DashboardStatsService } from '@services/dossier-templates/dashboard-stats.service'; import { Router } from '@angular/router'; @Injectable({ providedIn: 'root' }) export class ArchivedDossiersService extends DossiersService { - constructor( - protected readonly _injector: Injector, - private readonly _activeDossiersService: ActiveDossiersService, - private readonly _filesMapService: FilesMapService, - private readonly _featuresService: FeaturesService, - private readonly _dashboardStats: DashboardStatsService, - private readonly _router: Router, - ) { - super(_injector, 'archived-dossiers', ARCHIVE_ROUTE); - } + protected readonly _defaultModelPath = 'archived-dossiers'; + readonly routerPath = ARCHIVE_ROUTE; + + readonly #activeDossiersService = inject(ActiveDossiersService); + readonly #filesMapService = inject(FilesMapService); + readonly #featuresService = inject(FeaturesService); + readonly #router = inject(Router); archive(dossiers: Dossier[]): Observable { const showArchiveFailedToast = () => { @@ -33,26 +29,26 @@ export class ArchivedDossiersService extends DossiersService { const dossierTemplateId = dossiers[0].dossierTemplateId; return this._post(archivedDossiersIds, `${this._defaultModelPath}/archive`).pipe( - switchMap(() => this._dashboardStats.loadAll()), + switchMap(() => this._dashboardStatsService.loadAll()), tap(() => this.#removeFromActiveDossiers(archivedDossiersIds)), switchMap(async () => { let route = dossiers[0].dossiersListRouterLink; - if (!this._activeDossiersService.all.find(d => d.dossierTemplateId === dossierTemplateId)) { + if (!this.#activeDossiersService.all.find(d => d.dossierTemplateId === dossierTemplateId)) { route = route.replace(DOSSIERS_ROUTE, ARCHIVE_ROUTE); } - await this._router.navigate([route]); + await this.#router.navigate([route]); }), catchError(showArchiveFailedToast), ); } loadAll(): Observable { - return this._featuresService.isEnabled(DOSSIERS_ARCHIVE) ? super.loadAll() : of([]); + return this.#featuresService.isEnabled(DOSSIERS_ARCHIVE) ? super.loadAll() : of([]); } #removeFromActiveDossiers(archivedDossiersIds: string[]): void { - const remainingEntities = this._activeDossiersService.all.filter(d => !archivedDossiersIds.includes(d.dossierId)); - this._activeDossiersService.setEntities(remainingEntities); - this._filesMapService.delete(archivedDossiersIds); + const remainingEntities = this.#activeDossiersService.all.filter(d => !archivedDossiersIds.includes(d.dossierId)); + this.#activeDossiersService.setEntities(remainingEntities); + this.#filesMapService.delete(archivedDossiersIds); } } diff --git a/apps/red-ui/src/app/services/dossiers/dossier-changes.service.ts b/apps/red-ui/src/app/services/dossiers/dossier-changes.service.ts index bdaab839d..aeea7d7aa 100644 --- a/apps/red-ui/src/app/services/dossiers/dossier-changes.service.ts +++ b/apps/red-ui/src/app/services/dossiers/dossier-changes.service.ts @@ -6,33 +6,27 @@ import { HttpErrorResponse, HttpStatusCode } from '@angular/common/http'; import { NGXLogger } from 'ngx-logger'; import { ActiveDossiersService } from './active-dossiers.service'; import { ArchivedDossiersService } from './archived-dossiers.service'; -import { Injectable, Injector } from '@angular/core'; +import { inject, Injectable, Injector } from '@angular/core'; import { DossierStatsService } from './dossier-stats.service'; import { DashboardStatsService } from '../dossier-templates/dashboard-stats.service'; import { CHANGED_CHECK_INTERVAL } from '@utils/constants'; @Injectable({ providedIn: 'root' }) export class DossiersChangesService extends GenericService { - private _initializedRefresh = false; + protected readonly _defaultModelPath = 'dossier'; + #initializedRefresh = false; - private readonly _activeDossiersService: ActiveDossiersService = this._injector.get(ActiveDossiersService); - private readonly _archivedDossiersService: ArchivedDossiersService = this._injector.get(ArchivedDossiersService); - - protected constructor( - protected readonly _injector: Injector, - private readonly _dossierStatsService: DossierStatsService, - private readonly _dashboardStatsService: DashboardStatsService, - private readonly _logger: NGXLogger, - ) { - super(_injector, 'dossier'); - } + readonly #activeDossiersService = inject(ActiveDossiersService); + readonly #archivedDossiersService = inject(ArchivedDossiersService); + readonly #dashboardStatsService = inject(DashboardStatsService); + readonly #logger = inject(NGXLogger); loadOnlyChanged(): Observable { const removeIfNotFound = (id: string) => catchError((error: HttpErrorResponse) => { if (error.status === HttpStatusCode.NotFound) { - this._activeDossiersService.remove(id); - this._archivedDossiersService.remove(id); + this.#activeDossiersService.remove(id); + this.#archivedDossiersService.remove(id); return of([]); } return throwError(() => error); @@ -42,9 +36,9 @@ export class DossiersChangesService extends GenericService { changes.map(change => this._load(change.dossierId).pipe(removeIfNotFound(change.dossierId))); return this.hasChangesDetails$().pipe( - tap(changes => this._logger.info('[CHANGES] ', changes)), + tap(changes => this.#logger.info('[CHANGES] ', changes)), switchMap(dossierChanges => - forkJoin([...load(dossierChanges), this._dashboardStatsService.loadAll().pipe(take(1))]).pipe(map(() => dossierChanges)), + forkJoin([...load(dossierChanges), this.#dashboardStatsService.loadAll().pipe(take(1))]).pipe(map(() => dossierChanges)), ), tap(() => this._updateLastChanged()), ); @@ -56,16 +50,16 @@ export class DossiersChangesService extends GenericService { } initializeRefresh() { - if (this._initializedRefresh) { + if (this.#initializedRefresh) { return; } - this._initializedRefresh = true; + this.#initializedRefresh = true; timer(CHANGED_CHECK_INTERVAL, CHANGED_CHECK_INTERVAL) .pipe( switchMap(() => this.loadOnlyChanged()), tap(changes => { - this._activeDossiersService.emitFileChanges(changes); - this._archivedDossiersService.emitFileChanges(changes); + this.#activeDossiersService.emitFileChanges(changes); + this.#archivedDossiersService.emitFileChanges(changes); }), ) .subscribe(); @@ -77,11 +71,11 @@ export class DossiersChangesService extends GenericService { map(entity => new Dossier(entity)), switchMap((dossier: Dossier) => { if (dossier.isArchived) { - this._activeDossiersService.remove(dossier.id); - return this._archivedDossiersService.updateDossier(dossier); + this.#activeDossiersService.remove(dossier.id); + return this.#archivedDossiersService.updateDossier(dossier); } - this._archivedDossiersService.remove(dossier.id); - return this._activeDossiersService.updateDossier(dossier); + this.#archivedDossiersService.remove(dossier.id); + return this.#activeDossiersService.updateDossier(dossier); }), ); } diff --git a/apps/red-ui/src/app/services/dossiers/dossier-stats.service.ts b/apps/red-ui/src/app/services/dossiers/dossier-stats.service.ts index 38ee3cc36..da47af88e 100644 --- a/apps/red-ui/src/app/services/dossiers/dossier-stats.service.ts +++ b/apps/red-ui/src/app/services/dossiers/dossier-stats.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Injector } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { StatsService } from '@iqser/common-ui'; import { DOSSIER_ID, DossierStats, IDossierStats } from '@red/domain'; import { Observable, of } from 'rxjs'; @@ -10,16 +10,18 @@ import { tap } from 'rxjs/operators'; providedIn: 'root', }) export class DossierStatsService extends StatsService { - constructor(protected readonly _injector: Injector, private readonly _userService: UserService, private readonly _logger: NGXLogger) { - super(_injector, DOSSIER_ID, DossierStats, 'dossier-stats'); - } + protected readonly _primaryKey = DOSSIER_ID; + protected readonly _entityClass = DossierStats; + protected readonly _defaultModelPath = 'dossier-stats'; + readonly #userService = inject(UserService); + readonly #logger = inject(NGXLogger); getFor(ids: string[]): Observable { - const isUserAdminOnly = this._userService.currentUser.roles.length === 1 && this._userService.currentUser.isUserAdmin; + const isUserAdminOnly = this.#userService.currentUser.roles.length === 1 && this.#userService.currentUser.isUserAdmin; if (isUserAdminOnly) { return of([]); } - return super.getFor(ids).pipe(tap(stats => this._logger.info('[STATS] Loaded', stats))); + return super.getFor(ids).pipe(tap(stats => this.#logger.info('[STATS] Loaded', stats))); } } diff --git a/apps/red-ui/src/app/services/dossiers/dossiers.service.ts b/apps/red-ui/src/app/services/dossiers/dossiers.service.ts index 5bb5fcbf6..9b27970db 100644 --- a/apps/red-ui/src/app/services/dossiers/dossiers.service.ts +++ b/apps/red-ui/src/app/services/dossiers/dossiers.service.ts @@ -2,7 +2,7 @@ import { EntitiesService, mapEach, RequiredParam, Toaster, Validate } from '@iqs import { Dossier, DossierStats, IDossier, IDossierChanges, IDossierRequest } from '@red/domain'; import { Observable, of, Subject } from 'rxjs'; import { catchError, map, switchMap, tap } from 'rxjs/operators'; -import { Injector } from '@angular/core'; +import { inject } from '@angular/core'; import { DossierStatsService } from './dossier-stats.service'; import { HttpErrorResponse, HttpStatusCode } from '@angular/common/http'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; @@ -12,16 +12,15 @@ import { DashboardStatsService } from '../dossier-templates/dashboard-stats.serv const CONFLICT_MSG = _('add-dossier-dialog.errors.dossier-already-exists'); const GENERIC_MSG = _('add-dossier-dialog.errors.generic'); -export abstract class DossiersService extends EntitiesService { +export abstract class DossiersService extends EntitiesService { readonly dossierFileChanges$ = new Subject(); - protected readonly _dossierStatsService = this._injector.get(DossierStatsService); - protected readonly _dashboardStatsService = this._injector.get(DashboardStatsService); - protected readonly _toaster = this._injector.get(Toaster); - protected readonly _logger = this._injector.get(NGXLogger); - - protected constructor(protected readonly _injector: Injector, protected readonly _path: string, readonly routerPath: string) { - super(_injector, Dossier, _path); - } + abstract readonly routerPath: string; + protected readonly _dossierStatsService = inject(DossierStatsService); + protected readonly _dashboardStatsService = inject(DashboardStatsService); + protected readonly _toaster = inject(Toaster); + protected readonly _logger = inject(NGXLogger); + protected abstract readonly _defaultModelPath: string; + protected readonly _entityClass = Dossier; @Validate() createOrUpdate(@RequiredParam() dossier: IDossierRequest): Observable { diff --git a/apps/red-ui/src/app/services/entity-permissions/entity-permissions.service.ts b/apps/red-ui/src/app/services/entity-permissions/entity-permissions.service.ts index a4fc8d08d..a9b4a4fbc 100644 --- a/apps/red-ui/src/app/services/entity-permissions/entity-permissions.service.ts +++ b/apps/red-ui/src/app/services/entity-permissions/entity-permissions.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Injector } from '@angular/core'; +import { inject, Injectable, Injector } from '@angular/core'; import { GenericService, mapEach } from '@iqser/common-ui'; import { IPermissionsMapping, PermissionsMapping } from '@red/domain'; import { Observable } from 'rxjs'; @@ -10,18 +10,15 @@ import { PermissionsMapService } from './permissions-map.service'; providedIn: 'root', }) export class EntityPermissionsService extends GenericService { - constructor( - protected readonly _injector: Injector, - private readonly _permissionsConfigurationMapService: PermissionsConfigurationMapService, - private readonly _permissionsMapService: PermissionsMapService, - ) { - super(_injector, 'permissions'); - } + protected readonly _defaultModelPath = 'permissions'; + + readonly #permissionsConfigurationMapService = inject(PermissionsConfigurationMapService); + readonly #permissionsMapService = inject(PermissionsMapService); loadConfigFor(targetObject: string): Observable { return this._http.get(`/${this._defaultModelPath}/${targetObject}/mapping`).pipe( mapEach(mapping => new PermissionsMapping(mapping, targetObject)), - tap(mappings => this._permissionsConfigurationMapService.set(targetObject, mappings)), + tap(mappings => this.#permissionsConfigurationMapService.set(targetObject, mappings)), ); } @@ -30,16 +27,16 @@ export class EntityPermissionsService extends GenericService new PermissionsMapping(mapping, targetObject)), tap(mappings => { this.#addMissingPermissions(mappings, targetObject); - this._permissionsMapService.set(targetObject, mappings); + this.#permissionsMapService.set(targetObject, mappings); }), ); } togglePermission(targetObject: string, targetPermission: string, changedPermission: string): Observable { - const config = this._permissionsConfigurationMapService.get(targetObject); + const config = this.#permissionsConfigurationMapService.get(targetObject); const targetPermissionConfig = config.find(p => p.searchKey === targetPermission); - const permissions = this._permissionsMapService.get(targetObject); - const currentTargetPermissionValues = this._permissionsMapService.get(targetObject, targetPermission); + const permissions = this.#permissionsMapService.get(targetObject); + const currentTargetPermissionValues = this.#permissionsMapService.get(targetObject, targetPermission); const index = currentTargetPermissionValues.mappedPermissions.findIndex(p => p.name === changedPermission); if (index !== -1) { currentTargetPermissionValues.mappedPermissions.splice(index, 1); @@ -51,7 +48,7 @@ export class EntityPermissionsService extends GenericService p.targetPermission.name === targetPermission)) { diff --git a/apps/red-ui/src/app/services/entity-permissions/permissions-configuration-map.service.ts b/apps/red-ui/src/app/services/entity-permissions/permissions-configuration-map.service.ts index 7000d1056..a79e5ba75 100644 --- a/apps/red-ui/src/app/services/entity-permissions/permissions-configuration-map.service.ts +++ b/apps/red-ui/src/app/services/entity-permissions/permissions-configuration-map.service.ts @@ -4,9 +4,7 @@ import { EntitiesMapService } from '@iqser/common-ui'; @Injectable({ providedIn: 'root' }) export class PermissionsConfigurationMapService extends EntitiesMapService { - constructor() { - super('name'); - } + protected readonly _primaryKey = 'name'; getMappedPermissions(targetObject: string): string[] { return Array.from( diff --git a/apps/red-ui/src/app/services/entity-permissions/permissions-map.service.ts b/apps/red-ui/src/app/services/entity-permissions/permissions-map.service.ts index b2f63f9ed..fb3093067 100644 --- a/apps/red-ui/src/app/services/entity-permissions/permissions-map.service.ts +++ b/apps/red-ui/src/app/services/entity-permissions/permissions-map.service.ts @@ -4,7 +4,5 @@ import { EntitiesMapService } from '@iqser/common-ui'; @Injectable({ providedIn: 'root' }) export class PermissionsMapService extends EntitiesMapService { - constructor() { - super('name'); - } + protected readonly _primaryKey = 'name'; } diff --git a/apps/red-ui/src/app/services/entity-services/dictionaries-map.service.ts b/apps/red-ui/src/app/services/entity-services/dictionaries-map.service.ts index a7f3aa9dc..9b7c4e390 100644 --- a/apps/red-ui/src/app/services/entity-services/dictionaries-map.service.ts +++ b/apps/red-ui/src/app/services/entity-services/dictionaries-map.service.ts @@ -4,9 +4,7 @@ import { EntitiesMapService } from '@iqser/common-ui'; @Injectable({ providedIn: 'root' }) export class DictionariesMapService extends EntitiesMapService { - constructor() { - super(DOSSIER_TEMPLATE_ID); - } + protected readonly _primaryKey = DOSSIER_TEMPLATE_ID; /** If the type is not found, it returns the 'default' type. */ getDictionary(type: string, dossierTemplateId: string): Dictionary | undefined { diff --git a/apps/red-ui/src/app/services/entity-services/dictionary.service.ts b/apps/red-ui/src/app/services/entity-services/dictionary.service.ts index 04429b8ac..72101acb6 100644 --- a/apps/red-ui/src/app/services/entity-services/dictionary.service.ts +++ b/apps/red-ui/src/app/services/entity-services/dictionary.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Injector } from '@angular/core'; +import { Injectable } from '@angular/core'; import { firstValueFrom, forkJoin, Observable, of, throwError } from 'rxjs'; import { EntitiesService, List, QueryParam, RequiredParam, Toaster, Validate } from '@iqser/common-ui'; import { Dictionary, DictionaryEntryType, DictionaryEntryTypes, IColors, IDictionary, IUpdateDictionary } from '@red/domain'; @@ -8,7 +8,6 @@ import { DossierTemplateStatsService } from './dossier-template-stats.service'; import { DictionariesMapService } from './dictionaries-map.service'; import { FALLBACK_COLOR } from '@utils/constants'; import { hexToRgb } from '@utils/functions'; -import { FileAttributesService } from './file-attributes.service'; import { HttpErrorResponse, HttpStatusCode } from '@angular/common/http'; import { SuperTypes } from '@models/file/super-types'; @@ -17,15 +16,16 @@ const MIN_WORD_LENGTH = 2; @Injectable({ providedIn: 'root', }) -export class DictionaryService extends EntitiesService { +export class DictionaryService extends EntitiesService { + protected readonly _defaultModelPath = 'dictionary'; + protected readonly _entityClass = Dictionary; + constructor( private readonly _toaster: Toaster, - protected readonly _injector: Injector, - private readonly _fileAttributesService: FileAttributesService, private readonly _dossierTemplateStatsService: DossierTemplateStatsService, private readonly _dictionariesMapService: DictionariesMapService, ) { - super(_injector, Dictionary, 'dictionary'); + super(); } /** @@ -155,25 +155,25 @@ export class DictionaryService extends EntitiesService return obs.pipe( switchMap(dictionary => this._dossierTemplateStatsService.getFor([dossierTemplateId]).pipe(map(() => dictionary))), - tap( - () => { + tap({ + next: () => { if (showToast) { this._toaster.success(_('dictionary-overview.success.generic')); } }, - error => { + error: error => { if (error.status === 400) { this._toaster.error(_('dictionary-overview.error.400')); } else { this._toaster.error(_('dictionary-overview.error.generic')); } }, - ), + }), ); } this._toaster.error(_('dictionary-overview.error.entries-too-short')); - return throwError('Entries too short'); + return throwError(() => 'Entries too short'); } async getDictionariesOptions(dossierTemplateId: string, dossierId: string): Promise { diff --git a/apps/red-ui/src/app/services/entity-services/dossier-attributes.service.ts b/apps/red-ui/src/app/services/entity-services/dossier-attributes.service.ts index f41357caa..ade9d9771 100644 --- a/apps/red-ui/src/app/services/entity-services/dossier-attributes.service.ts +++ b/apps/red-ui/src/app/services/entity-services/dossier-attributes.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Injector } from '@angular/core'; +import { Injectable } from '@angular/core'; import { Dossier, DossierAttributeConfig, DossierAttributeWithValue, IDossierAttribute, IDossierAttributeConfig } from '@red/domain'; import { firstValueFrom, Observable } from 'rxjs'; import { EntitiesService, List, mapEach, RequiredParam, Validate } from '@iqser/common-ui'; @@ -7,10 +7,9 @@ import { map, tap } from 'rxjs/operators'; @Injectable({ providedIn: 'root', }) -export class DossierAttributesService extends EntitiesService { - constructor(protected readonly _injector: Injector) { - super(_injector, DossierAttributeConfig, 'dossier-attributes'); - } +export class DossierAttributesService extends EntitiesService { + protected readonly _defaultModelPath = 'dossier-attributes'; + protected readonly _entityClass = DossierAttributeConfig; async getWithValues(dossier: Dossier): Promise { const attributes = await firstValueFrom(this.getAttributes(dossier.id)); diff --git a/apps/red-ui/src/app/services/entity-services/dossier-states-map.service.ts b/apps/red-ui/src/app/services/entity-services/dossier-states-map.service.ts index 1c6083cae..9fd47259d 100644 --- a/apps/red-ui/src/app/services/entity-services/dossier-states-map.service.ts +++ b/apps/red-ui/src/app/services/entity-services/dossier-states-map.service.ts @@ -5,9 +5,7 @@ import { flatMap } from 'lodash-es'; @Injectable({ providedIn: 'root' }) export class DossierStatesMapService extends EntitiesMapService { - constructor() { - super(DOSSIER_TEMPLATE_ID); - } + protected readonly _primaryKey = DOSSIER_TEMPLATE_ID; get stats(): DonutChartConfig[] { const allStates = flatMap(Array.from(this._map.values()).map(obs => obs.value)); diff --git a/apps/red-ui/src/app/services/entity-services/dossier-states.service.ts b/apps/red-ui/src/app/services/entity-services/dossier-states.service.ts index 7b8cfd323..55c6636ba 100644 --- a/apps/red-ui/src/app/services/entity-services/dossier-states.service.ts +++ b/apps/red-ui/src/app/services/entity-services/dossier-states.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Injector } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { EntitiesService, mapEach, RequiredParam, Toaster, Validate } from '@iqser/common-ui'; import { DossierState, IDossierState } from '@red/domain'; import { EMPTY, forkJoin, Observable, switchMap } from 'rxjs'; @@ -14,20 +14,18 @@ const GENERIC_MSG = _('dossier-states-listing.error.generic'); @Injectable({ providedIn: 'root', }) -export class DossierStatesService extends EntitiesService { - constructor( - protected readonly _injector: Injector, - private readonly _toaster: Toaster, - private readonly _dossierTemplatesService: DossierTemplatesService, - private readonly _dossierStatesMapService: DossierStatesMapService, - ) { - super(_injector, DossierState, 'dossier-status'); - } +export class DossierStatesService extends EntitiesService { + protected readonly _defaultModelPath = 'dossier-status'; + protected readonly _entityClass = DossierState; + + readonly #toaster = inject(Toaster); + readonly #dossierTemplatesService = inject(DossierTemplatesService); + readonly #dossierStatesMapService = inject(DossierStatesMapService); @Validate() createOrUpdate(@RequiredParam() state: IDossierState): Observable { const showToast = (error: HttpErrorResponse) => { - this._toaster.error(error.status === HttpStatusCode.Conflict ? CONFLICT_MSG : GENERIC_MSG); + this.#toaster.error(error.status === HttpStatusCode.Conflict ? CONFLICT_MSG : GENERIC_MSG); return EMPTY; }; return this._post(state, this._defaultModelPath).pipe( @@ -39,12 +37,12 @@ export class DossierStatesService extends EntitiesService this._dossierStatesMapService.set(templateId, states)), + tap(states => this.#dossierStatesMapService.set(templateId, states)), ); } loadAllForAllTemplates(): Observable { - return this._dossierTemplatesService.all$.pipe( + return this.#dossierTemplatesService.all$.pipe( mapEach(template => template.dossierTemplateId), mapEach(id => this.loadAllForTemplate(id)), switchMap(all => forkJoin(all).pipe(defaultIfEmpty([] as DossierState[][]))), diff --git a/apps/red-ui/src/app/services/entity-services/dossier-template-stats.service.ts b/apps/red-ui/src/app/services/entity-services/dossier-template-stats.service.ts index b323ea579..d66399c2b 100644 --- a/apps/red-ui/src/app/services/entity-services/dossier-template-stats.service.ts +++ b/apps/red-ui/src/app/services/entity-services/dossier-template-stats.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Injector } from '@angular/core'; +import { Injectable } from '@angular/core'; import { StatsService } from '@iqser/common-ui'; import { DOSSIER_TEMPLATE_ID, DossierTemplateStats, IDossierTemplateStats } from '@red/domain'; @@ -6,7 +6,7 @@ import { DOSSIER_TEMPLATE_ID, DossierTemplateStats, IDossierTemplateStats } from providedIn: 'root', }) export class DossierTemplateStatsService extends StatsService { - constructor(protected readonly _injector: Injector) { - super(_injector, DOSSIER_TEMPLATE_ID, DossierTemplateStats, 'dossier-template-stats'); - } + protected readonly _primaryKey = DOSSIER_TEMPLATE_ID; + protected readonly _entityClass = DossierTemplateStats; + protected readonly _defaultModelPath = 'dossier-template-stats'; } diff --git a/apps/red-ui/src/app/services/entity-services/file-attributes.service.ts b/apps/red-ui/src/app/services/entity-services/file-attributes.service.ts index bc1046d9a..7a7c068f3 100644 --- a/apps/red-ui/src/app/services/entity-services/file-attributes.service.ts +++ b/apps/red-ui/src/app/services/entity-services/file-attributes.service.ts @@ -1,5 +1,5 @@ import { EntitiesService, List, RequiredParam, Validate } from '@iqser/common-ui'; -import { Injectable, Injector } from '@angular/core'; +import { Injectable } from '@angular/core'; import { BehaviorSubject, Observable, of } from 'rxjs'; import { catchError, tap } from 'rxjs/operators'; import { FileAttributeConfig, FileAttributes, IFileAttributeConfig, IFileAttributesConfig } from '@red/domain'; @@ -9,12 +9,10 @@ type FileAttributesConfigMap = Readonly>; @Injectable({ providedIn: 'root', }) -export class FileAttributesService extends EntitiesService { - private readonly _fileAttributesConfig$ = new BehaviorSubject({}); - - constructor(protected readonly _injector: Injector) { - super(_injector, FileAttributeConfig, 'fileAttributes'); - } +export class FileAttributesService extends EntitiesService { + protected readonly _defaultModelPath = 'fileAttributes'; + protected readonly _entityClass = FileAttributeConfig; + readonly #fileAttributesConfig$ = new BehaviorSubject({}); /** * Get the file attributes that can be used at importing csv. @@ -25,8 +23,8 @@ export class FileAttributesService extends EntitiesService entities.fileAttributeConfigs.sort((c1, c2) => c1.placeholder.localeCompare(c2.placeholder))), tap(entities => - this._fileAttributesConfig$.next({ - ...this._fileAttributesConfig$.value, + this.#fileAttributesConfig$.next({ + ...this.#fileAttributesConfig$.value, [dossierTemplateId]: entities, }), ), @@ -35,7 +33,7 @@ export class FileAttributesService extends EntitiesService { - constructor(protected readonly _injector: Injector) { - super(_injector, Justification, 'legalBasis'); - } +export class JustificationsService extends EntitiesService { + protected readonly _defaultModelPath = 'legalBasis'; + protected readonly _entityClass = Justification; @Validate() createOrUpdate(@RequiredParam() justification: Justification, @RequiredParam() dossierTemplateId: string) { diff --git a/apps/red-ui/src/app/services/entity-services/platform-search.service.ts b/apps/red-ui/src/app/services/entity-services/platform-search.service.ts index 6e8398581..075db0c72 100644 --- a/apps/red-ui/src/app/services/entity-services/platform-search.service.ts +++ b/apps/red-ui/src/app/services/entity-services/platform-search.service.ts @@ -9,13 +9,14 @@ import { DossiersCacheService } from '../dossiers/dossiers-cache.service'; @Injectable({ providedIn: 'root' }) export class PlatformSearchService extends GenericService { + protected readonly _defaultModelPath = 'search-v2'; + constructor( - protected readonly _injector: Injector, private readonly _filesService: FilesService, private readonly _dossiersCacheService: DossiersCacheService, private readonly _filesMapService: FilesMapService, ) { - super(_injector, 'search-v2'); + super(); } search({ diff --git a/apps/red-ui/src/app/services/entity-services/trash.service.ts b/apps/red-ui/src/app/services/entity-services/trash.service.ts index 94931ee73..d43d40bf5 100644 --- a/apps/red-ui/src/app/services/entity-services/trash.service.ts +++ b/apps/red-ui/src/app/services/entity-services/trash.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Injector } from '@angular/core'; +import { Injectable } from '@angular/core'; import { EntitiesService, List, mapEach, QueryParam, RequiredParam, Toaster, Validate } from '@iqser/common-ui'; import { Dossier, File, IDossier, IFile, TrashDossier, TrashFile, TrashItem } from '@red/domain'; import { catchError, switchMap, take, tap } from 'rxjs/operators'; @@ -18,7 +18,6 @@ import { ArchivedDossiersService } from '@services/dossiers/archived-dossiers.se }) export class TrashService extends EntitiesService { constructor( - protected readonly _injector: Injector, private readonly _toaster: Toaster, private readonly _systemPreferencesService: SystemPreferencesService, private readonly _permissionsService: PermissionsService, @@ -28,7 +27,7 @@ export class TrashService extends EntitiesService { private readonly _dossierStatsService: DossierStatsService, private readonly _filesService: FilesService, ) { - super(_injector, null, ''); + super(); } deleteDossier(dossier: Dossier): Observable { diff --git a/apps/red-ui/src/app/services/entity-services/watermark.service.ts b/apps/red-ui/src/app/services/entity-services/watermark.service.ts index 6294e4537..d32246f71 100644 --- a/apps/red-ui/src/app/services/entity-services/watermark.service.ts +++ b/apps/red-ui/src/app/services/entity-services/watermark.service.ts @@ -12,9 +12,7 @@ interface IsUsedResponse { providedIn: 'root', }) export class WatermarkService extends GenericService { - constructor(protected readonly _injector: Injector) { - super(_injector, 'watermark'); - } + protected readonly _defaultModelPath = 'watermark'; @Validate() saveWatermark(@RequiredParam() body: IWatermark) { diff --git a/apps/red-ui/src/app/services/files/file-management.service.ts b/apps/red-ui/src/app/services/files/file-management.service.ts index 1797710bf..377ba7362 100644 --- a/apps/red-ui/src/app/services/files/file-management.service.ts +++ b/apps/red-ui/src/app/services/files/file-management.service.ts @@ -1,5 +1,5 @@ import { GenericService, HeadersConfiguration, List, QueryParam, RequiredParam, Validate } from '@iqser/common-ui'; -import { Injectable, Injector } from '@angular/core'; +import { inject, Injectable, Injector } from '@angular/core'; import { HttpEvent, HttpHeaders, HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs'; import { switchMap } from 'rxjs/operators'; @@ -10,14 +10,13 @@ import { File, IPageRotationRequest } from '@red/domain'; providedIn: 'root', }) export class FileManagementService extends GenericService { - constructor(protected readonly _injector: Injector, private readonly _filesService: FilesService) { - super(_injector, ''); - } + readonly #filesService = inject(FilesService); + protected readonly _defaultModelPath = ''; @Validate() delete(@RequiredParam() files: List, @RequiredParam() dossierId: string) { const fileIds = files.map(f => f.id); - return super._post(fileIds, `delete/${dossierId}`).pipe(switchMap(() => this._filesService.loadAll(dossierId))); + return super._post(fileIds, `delete/${dossierId}`).pipe(switchMap(() => this.#filesService.loadAll(dossierId))); } @Validate() diff --git a/apps/red-ui/src/app/services/files/files-map.service.ts b/apps/red-ui/src/app/services/files/files-map.service.ts index ef789cf37..237c66dae 100644 --- a/apps/red-ui/src/app/services/files/files-map.service.ts +++ b/apps/red-ui/src/app/services/files/files-map.service.ts @@ -1,17 +1,22 @@ import { Injectable } from '@angular/core'; import { DOSSIER_ID, File, IFile } from '@red/domain'; -import { EntitiesMapService } from '@iqser/common-ui'; +import { EntitiesMapService, NonFunctionKeys } from '@iqser/common-ui'; @Injectable({ providedIn: 'root' }) export class FilesMapService extends EntitiesMapService { - constructor() { - super(DOSSIER_ID); - } + protected readonly _primaryKey = DOSSIER_ID; - replaceFiles(files: File[], property: keyof IFile, generateValue: Function) { + replaceFiles, T2 extends File[T]>(files: File[], property: T, generateValue: (value: T2) => T2) { const newFiles = files.map( file => - new File({ ...file, [property]: generateValue(file[property]), lastUpdated: new Date().toISOString() }, file.reviewerName), + new File( + { + ...file, + [property]: generateValue(file[property] as T2), + lastUpdated: new Date().toISOString(), + }, + file.reviewerName, + ), ); this.replace(newFiles); } diff --git a/apps/red-ui/src/app/services/files/files.service.ts b/apps/red-ui/src/app/services/files/files.service.ts index ca141e999..e00ab4c92 100644 --- a/apps/red-ui/src/app/services/files/files.service.ts +++ b/apps/red-ui/src/app/services/files/files.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Injector } from '@angular/core'; +import { Injectable } from '@angular/core'; import { EntitiesService, List, mapEach, RequiredParam, Validate } from '@iqser/common-ui'; import { File, IFile } from '@red/domain'; import { Observable } from 'rxjs'; @@ -11,15 +11,17 @@ import { NGXLogger } from 'ngx-logger'; @Injectable({ providedIn: 'root', }) -export class FilesService extends EntitiesService { +export class FilesService extends EntitiesService { + protected readonly _defaultModelPath = 'status'; + protected readonly _entityClass = File; + constructor( - protected readonly _injector: Injector, protected readonly _logger: NGXLogger, private readonly _userService: UserService, private readonly _filesMapService: FilesMapService, private readonly _dossierStatsService: DossierStatsService, ) { - super(_injector, File, 'status'); + super(); } /** Reload dossier files + stats. */ diff --git a/apps/red-ui/src/app/services/files/redaction-import.service.ts b/apps/red-ui/src/app/services/files/redaction-import.service.ts index 6cfa06d2d..2cda6ea57 100644 --- a/apps/red-ui/src/app/services/files/redaction-import.service.ts +++ b/apps/red-ui/src/app/services/files/redaction-import.service.ts @@ -3,9 +3,7 @@ import { GenericService, HeadersConfiguration, RequiredParam, Validate } from '@ @Injectable({ providedIn: 'root' }) export class RedactionImportService extends GenericService { - constructor(protected readonly _injector: Injector) { - super(_injector, 'import-redactions'); - } + protected readonly _defaultModelPath = 'import-redactions'; @Validate() importRedactions(@RequiredParam() dossierId: string, @RequiredParam() fileId: string, file?: Blob) { diff --git a/apps/red-ui/src/app/services/files/redaction-log.service.ts b/apps/red-ui/src/app/services/files/redaction-log.service.ts index 0eba00b09..4256806ee 100644 --- a/apps/red-ui/src/app/services/files/redaction-log.service.ts +++ b/apps/red-ui/src/app/services/files/redaction-log.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Injector } from '@angular/core'; +import { Injectable } from '@angular/core'; import { GenericService, QueryParam, RequiredParam, Validate } from '@iqser/common-ui'; import { IRedactionLog, ISectionGrid } from '@red/domain'; import { catchError, tap } from 'rxjs/operators'; @@ -8,9 +8,7 @@ import { of } from 'rxjs'; providedIn: 'root', }) export class RedactionLogService extends GenericService { - constructor(protected readonly _injector: Injector) { - super(_injector, ''); - } + protected readonly _defaultModelPath = ''; @Validate() getRedactionLog(@RequiredParam() dossierId: string, @RequiredParam() fileId: string, withManualRedactions?: boolean) { diff --git a/apps/red-ui/src/app/services/files/text-highlight.service.ts b/apps/red-ui/src/app/services/files/text-highlight.service.ts index b921265d9..eb9037980 100644 --- a/apps/red-ui/src/app/services/files/text-highlight.service.ts +++ b/apps/red-ui/src/app/services/files/text-highlight.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Injector } from '@angular/core'; +import { inject, Injectable, Injector } from '@angular/core'; import { GenericService, RequiredParam, Toaster, Validate } from '@iqser/common-ui'; import { Highlight, TextHighlightOperation, TextHighlightResponse } from '@red/domain'; import { catchError, map, tap } from 'rxjs/operators'; @@ -10,9 +10,8 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; providedIn: 'root', }) export class TextHighlightService extends GenericService { - constructor(protected readonly _injector: Injector, private readonly _toaster: Toaster) { - super(_injector, ''); - } + protected readonly _defaultModelPath = ''; + readonly #toaster = inject(Toaster); @Validate() getTextHighlights(@RequiredParam() dossierId: string, @RequiredParam() fileId: string): Observable { @@ -32,7 +31,7 @@ export class TextHighlightService extends GenericService @RequiredParam() operation: TextHighlightOperation, ) { return this._post({ ids }, `${this.#getPath(dossierId, fileId)}/${operation}`).pipe( - tap(() => this._toaster.success(_('highlight-action-dialog.success'), { params: { operation } })), + tap(() => this.#toaster.success(_('highlight-action-dialog.success'), { params: { operation } })), ); } diff --git a/apps/red-ui/src/app/services/files/viewed-pages.service.ts b/apps/red-ui/src/app/services/files/viewed-pages.service.ts index 9d8462112..1c8c8b2c3 100644 --- a/apps/red-ui/src/app/services/files/viewed-pages.service.ts +++ b/apps/red-ui/src/app/services/files/viewed-pages.service.ts @@ -8,9 +8,7 @@ import { of } from 'rxjs'; providedIn: 'root', }) export class ViewedPagesService extends GenericService { - constructor(protected readonly _injector: Injector) { - super(_injector, 'viewedPages'); - } + protected readonly _defaultModelPath = 'viewedPages'; @Validate() addPage(@RequiredParam() body: IViewedPagesRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) { diff --git a/apps/red-ui/src/app/services/general-settings.service.ts b/apps/red-ui/src/app/services/general-settings.service.ts index 2f5b18de8..11a75a8e7 100644 --- a/apps/red-ui/src/app/services/general-settings.service.ts +++ b/apps/red-ui/src/app/services/general-settings.service.ts @@ -7,9 +7,7 @@ import { Observable } from 'rxjs'; providedIn: 'root', }) export class GeneralSettingsService extends GenericService { - constructor(protected readonly _injector: Injector) { - super(_injector, 'configuration'); - } + protected readonly _defaultModelPath = 'configuration'; getGeneralConfigurations(): Observable { return this._getOne(['general']); diff --git a/apps/red-ui/src/app/services/license.service.ts b/apps/red-ui/src/app/services/license.service.ts index 931ad9cec..6a3132eb4 100644 --- a/apps/red-ui/src/app/services/license.service.ts +++ b/apps/red-ui/src/app/services/license.service.ts @@ -1,8 +1,7 @@ -import { Injectable, Injector } from '@angular/core'; +import { Injectable } from '@angular/core'; import { GenericService, QueryParam, RequiredParam, Validate } from '@iqser/common-ui'; import { ILicense, ILicenseReport, ILicenseReportRequest, ILicenses } from '@red/domain'; import { BehaviorSubject, firstValueFrom, Observable, of } from 'rxjs'; -import { ConfigService } from './config.service'; import { catchError, filter, tap } from 'rxjs/operators'; import { LICENSE_STORAGE_KEY } from '../modules/admin/screens/license/utils/constants'; @@ -48,11 +47,12 @@ export class LicenseService extends GenericService { readonly licenseData$: Observable; readonly selectedLicense$: Observable; activeLicenseId: string; + protected readonly _defaultModelPath = 'report'; readonly #licenseData$ = new BehaviorSubject(undefined); readonly #selectedLicense$ = new BehaviorSubject(undefined); - constructor(protected readonly _injector: Injector, private readonly _configService: ConfigService) { - super(_injector, 'report'); + constructor() { + super(); this.selectedLicense$ = this.#selectedLicense$.pipe(filter(license => !!license)); this.licenseData$ = this.#licenseData$.pipe( filter(licenses => !!licenses), diff --git a/apps/red-ui/src/app/services/notifications.service.ts b/apps/red-ui/src/app/services/notifications.service.ts index 08b1524f7..a193257ff 100644 --- a/apps/red-ui/src/app/services/notifications.service.ts +++ b/apps/red-ui/src/app/services/notifications.service.ts @@ -1,4 +1,4 @@ -import { Inject, Injectable, Injector } from '@angular/core'; +import { Inject, Injectable } from '@angular/core'; import { EntitiesService, List, mapEach, QueryParam, RequiredParam, Validate } from '@iqser/common-ui'; import { TranslateService } from '@ngx-translate/core'; import { EMPTY, iif, Observable, of, timer } from 'rxjs'; @@ -17,15 +17,17 @@ const INCLUDE_SEEN = false; @Injectable({ providedIn: 'root', }) -export class NotificationsService extends EntitiesService { +export class NotificationsService extends EntitiesService { + protected readonly _defaultModelPath = 'notification'; + protected readonly _entityClass = Notification; + constructor( @Inject(BASE_HREF) private readonly _baseHref: string, - protected readonly _injector: Injector, private readonly _translateService: TranslateService, private readonly _userService: UserService, private readonly _dossiersCacheService: DossiersCacheService, ) { - super(_injector, Notification, 'notification'); + super(); timer(0, CHANGED_CHECK_INTERVAL) .pipe( diff --git a/apps/red-ui/src/app/services/reanalysis.service.ts b/apps/red-ui/src/app/services/reanalysis.service.ts index 4c5382c55..91a0e3610 100644 --- a/apps/red-ui/src/app/services/reanalysis.service.ts +++ b/apps/red-ui/src/app/services/reanalysis.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Injector } from '@angular/core'; +import { Injectable } from '@angular/core'; import { GenericService, List, QueryParam, RequiredParam, Toaster, Validate } from '@iqser/common-ui'; import { Dossier, File, IPageExclusionRequest } from '@red/domain'; import { catchError, switchMap, tap } from 'rxjs/operators'; @@ -16,13 +16,14 @@ export interface ReanalyzeQueryParams { providedIn: 'root', }) export class ReanalysisService extends GenericService { + protected readonly _defaultModelPath = ''; + constructor( - protected readonly _injector: Injector, private readonly _toaster: Toaster, private readonly _filesService: FilesService, private readonly _filesMapService: FilesMapService, ) { - super(_injector, ''); + super(); } @Validate() diff --git a/apps/red-ui/src/app/services/report-template.service.ts b/apps/red-ui/src/app/services/report-template.service.ts index 585f4c36a..22e2b0738 100644 --- a/apps/red-ui/src/app/services/report-template.service.ts +++ b/apps/red-ui/src/app/services/report-template.service.ts @@ -8,9 +8,7 @@ import { HttpResponse } from '@angular/common/http'; providedIn: 'root', }) export class ReportTemplateService extends GenericService { - constructor(protected readonly _injector: Injector) { - super(_injector, 'templateUpload'); - } + protected readonly _defaultModelPath = 'templateUpload'; @Validate() uploadTemplateForm(@RequiredParam() dossierTemplateId: string, multiFileReport?: boolean, file?: Blob) { diff --git a/apps/red-ui/src/app/services/system-preferences.service.ts b/apps/red-ui/src/app/services/system-preferences.service.ts index b48c18ca8..776945a4e 100644 --- a/apps/red-ui/src/app/services/system-preferences.service.ts +++ b/apps/red-ui/src/app/services/system-preferences.service.ts @@ -8,12 +8,9 @@ import { tap } from 'rxjs/operators'; providedIn: 'root', }) export class SystemPreferencesService extends GenericService { + protected readonly _defaultModelPath = 'app-config'; values: SystemPreferences; - constructor(protected readonly _injector: Injector) { - super(_injector, 'app-config'); - } - loadPreferences(): Observable { return this.get().pipe( tap((config: SystemPreferences) => { diff --git a/apps/red-ui/src/app/services/user-preference.service.ts b/apps/red-ui/src/app/services/user-preference.service.ts index d426b3349..1498ca789 100644 --- a/apps/red-ui/src/app/services/user-preference.service.ts +++ b/apps/red-ui/src/app/services/user-preference.service.ts @@ -16,14 +16,11 @@ const KEYS = { providedIn: 'root', }) export class UserPreferenceService extends GenericService { - constructor(protected readonly _injector: Injector) { - super(_injector, 'attributes'); - } - - private _userAttributes: UserAttributes = {}; + protected readonly _defaultModelPath = 'attributes'; + #userAttributes: UserAttributes = {}; get userAttributes(): UserAttributes { - return this._userAttributes; + return this.#userAttributes; } get areDevFeaturesEnabled(): boolean { @@ -80,7 +77,7 @@ export class UserPreferenceService extends GenericService { async reload(): Promise { const attributes = await firstValueFrom(this.getAll()); - this._userAttributes = attributes ?? {}; + this.#userAttributes = attributes ?? {}; } @Validate() diff --git a/apps/red-ui/src/app/services/user.service.ts b/apps/red-ui/src/app/services/user.service.ts index 60ea8d6dd..33f6265f5 100644 --- a/apps/red-ui/src/app/services/user.service.ts +++ b/apps/red-ui/src/app/services/user.service.ts @@ -1,4 +1,4 @@ -import { Inject, Injectable, Injector } from '@angular/core'; +import { inject, Inject, Injectable } from '@angular/core'; import { KeycloakService } from 'keycloak-angular'; import jwt_decode from 'jwt-decode'; import { ICreateUserRequest, IMyProfileUpdateRequest, IProfileUpdateRequest, IResetPasswordRequest, IUser, User } from '@red/domain'; @@ -11,21 +11,19 @@ import { tap } from 'rxjs/operators'; @Injectable({ providedIn: 'root', }) -export class UserService extends EntitiesService { +export class UserService extends EntitiesService { readonly currentUser$: Observable; - private readonly _currentUser$ = new BehaviorSubject(null); + protected readonly _defaultModelPath = 'user'; + protected readonly _entityClass = User; + readonly #currentUser$ = new BehaviorSubject(null); - constructor( - protected readonly _injector: Injector, - @Inject(BASE_HREF) private readonly _baseHref: string, - private readonly _keycloakService: KeycloakService, - ) { - super(_injector, User, 'user'); - this.currentUser$ = this._currentUser$.asObservable(); + constructor(@Inject(BASE_HREF) private readonly _baseHref: string, private readonly _keycloakService: KeycloakService) { + super(); + this.currentUser$ = this.#currentUser$.asObservable(); } get currentUser(): User { - return this._currentUser$.value; + return this.#currentUser$.value; } get managerUsers(): User[] { @@ -70,7 +68,7 @@ export class UserService extends EntitiesService { const user = new User(await this._keycloakService.loadUserProfile(true), roles, userId); this.replace(user); - this._currentUser$.next(this.find(userId)); + this.#currentUser$.next(this.find(userId)); return user; } @@ -132,3 +130,7 @@ export class UserService extends EntitiesService { return super.find(id) || new User({ username: 'Deleted User' }, [], 'deleted'); } } + +export function getCurrentUser() { + return inject(UserService).currentUser; +} diff --git a/libs/common-ui b/libs/common-ui index f2f7283c9..c39a69df3 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit f2f7283c9c97e30752fdd4cf56ca3b41999e6962 +Subproject commit c39a69df3e04c1cce01587aba182e176951735f9