RED-3800: remove some constructor dependencies

This commit is contained in:
Dan Percic 2022-07-11 21:43:37 +03:00
parent 0334f24b21
commit 006d14547f
103 changed files with 684 additions and 986 deletions

View File

@ -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<DownloadStatus> {
readonly circleButtonTypes = CircleButtonTypes;
@ -38,12 +26,11 @@ export class DownloadsListScreenComponent extends ListingComponent<DownloadStatu
];
constructor(
protected readonly _injector: Injector,
private readonly _loadingService: LoadingService,
readonly fileDownloadService: FileDownloadService,
readonly routerHistoryService: RouterHistoryService,
) {
super(_injector);
super();
this._loadingService.loadWhile(this._loadData());
setInterval(() => this._loadData(), 5000);
}

View File

@ -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<INotificationPreferences> {
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<INotification
}
update(notificationPreferences: INotificationPreferences): Observable<Notification[]> {
return super._post(notificationPreferences).pipe(switchMap(() => this._notificationsService.loadAll()));
return super._post(notificationPreferences).pipe(switchMap(() => this.#notificationsService.loadAll()));
}
}

View File

@ -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<string[]>;
readonly canDeleteEntity$: Observable<boolean>;
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(

View File

@ -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<void> {
@ -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);
}
}

View File

@ -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<AddEditDossierAttributeDialogComponent>,
@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();
}

View File

@ -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<AddEditDossierStateDialogComponent>,
@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();
}

View File

@ -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<AddEditCloneDossierTemplateDialogComponent>,
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;
}
}

View File

@ -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<AddEditFileAttributeDialogComponent>,
@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);

View File

@ -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<AddEditUserDialogComponent>,
@Inject(MAT_DIALOG_DATA) readonly user: User,
) {
super(_injector, _dialogRef, !!user);
constructor(protected readonly _dialogRef: MatDialogRef<AddEditUserDialogComponent>, @Inject(MAT_DIALOG_DATA) readonly user: User) {
super(_dialogRef, !!user);
}
get changed(): boolean {

View File

@ -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<AddEntityDialogComponent>,
@Inject(MAT_DIALOG_DATA) private readonly _data: DialogData,
) {
super(_injector, _dialogRef, false);
super(_dialogRef, false);
}
get valid(): boolean {

View File

@ -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<ConfigureCertificateDialogComponent>,
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<void> {
try {
await this.activeComponent.save();

View File

@ -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<EditColorDialogComponent>,
@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 } });

View File

@ -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<FileAttributesConfigurationsDialogComponent>,
@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();
}

View File

@ -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<IField> implements OnChanges {
readonly circleButtonTypes = CircleButtonTypes;
@ -44,10 +44,6 @@ export class ActiveFieldsListingComponent extends ListingComponent<IField> imple
@Output() readonly setHoveredColumn = new EventEmitter<string>();
@Output() readonly toggleFieldActive = new EventEmitter<IField>();
constructor(protected readonly _injector: Injector) {
super(_injector);
}
ngOnChanges(changes: SimpleChanges): void {
if (changes.entities) {
this.entitiesService.setEntities(this.entities);

View File

@ -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<IField> {
@ -38,13 +38,12 @@ export class FileAttributesCsvImportDialogComponent extends ListingComponent<IFi
constructor(
private readonly _toaster: Toaster,
protected readonly _injector: Injector,
private readonly _formBuilder: UntypedFormBuilder,
readonly dialogRef: MatDialogRef<FileAttributesCsvImportDialogComponent>,
private readonly _fileAttributesService: FileAttributesService,
@Inject(MAT_DIALOG_DATA) readonly data: IFileAttributesCSVImportData,
) {
super(_injector);
super();
this.form = this._getForm();
this.readFile();
}

View File

@ -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<SmtpAuthDialogComponent>,
@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],
});
}
}

View File

@ -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<Audit> 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<Audit> 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 {

View File

@ -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<ListItem> 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<ListItem>[] = [
@ -38,19 +38,14 @@ export class DefaultColorsScreenComponent extends ListingComponent<ListItem> 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 }) {

View File

@ -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<DossierAttributeConfig> 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<DossierAttributeConfig>[] = [
@ -39,19 +36,14 @@ export class DossierAttributesListingScreenComponent extends ListingComponent<Do
{ label: _('dossier-attributes-listing.table-col-names.type'), sortByKey: 'type' },
];
@ViewChild('impactedTemplates') impactedTemplatesRef: TemplateRef<unknown>;
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<void> {

View File

@ -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<DossierState> implements OnInit, OnDestroy {
readonly iconButtonTypes = IconButtonTypes;
@ -36,18 +33,15 @@ export class DossierStatesListingScreenComponent extends ListingComponent<Dossie
{ label: _('dossier-states-listing.table-col-names.dossiers-count') },
];
chartConfig$: Observable<DonutChartConfig[]>;
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)),

View File

@ -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<DossierTemplate> {
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<DossierTemplate>[] = [
{ label: _('dossier-templates-listing.table-col-names.name'), sortByKey: 'searchKey', width: '3fr' },
@ -43,15 +41,13 @@ export class DossierTemplatesListingScreenComponent extends ListingComponent<Dos
];
constructor(
protected readonly _injector: Injector,
private readonly _userService: UserService,
private readonly _loadingService: LoadingService,
private readonly _dialogService: AdminDialogService,
readonly routerHistoryService: RouterHistoryService,
readonly userPreferenceService: UserPreferenceService,
private readonly _dossierTemplatesService: DossierTemplatesService,
) {
super(_injector);
super();
}
openBulkDeleteTemplatesDialog($event?: MouseEvent) {

View File

@ -1,9 +1,10 @@
import { Component, forwardRef, Injector } from '@angular/core';
import { Component } from '@angular/core';
import {
CircleButtonTypes,
DefaultListingServices,
getParam,
IconButtonTypes,
ListingComponent,
listingProvidersFactory,
LoadingService,
TableColumnConfig,
} from '@iqser/common-ui';
@ -13,7 +14,6 @@ import { DictionaryService } from '@services/entity-services/dictionary.service'
import { Dictionary, DOSSIER_TEMPLATE_ID, DossierTemplateStats } from '@red/domain';
import { firstValueFrom, Observable } from 'rxjs';
import { DossierTemplateStatsService } from '@services/entity-services/dossier-template-stats.service';
import { ActivatedRoute } from '@angular/router';
import { tap } from 'rxjs/operators';
import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service';
import { PermissionsService } from '@services/permissions.service';
@ -21,7 +21,7 @@ import { PermissionsService } from '@services/permissions.service';
@Component({
templateUrl: './entities-listing-screen.component.html',
styleUrls: ['./entities-listing-screen.component.scss'],
providers: [...DefaultListingServices, { provide: ListingComponent, useExisting: forwardRef(() => EntitiesListingScreenComponent) }],
providers: listingProvidersFactory(EntitiesListingScreenComponent),
})
export class EntitiesListingScreenComponent extends ListingComponent<Dictionary> {
readonly iconButtonTypes = IconButtonTypes;
@ -34,20 +34,17 @@ export class EntitiesListingScreenComponent extends ListingComponent<Dictionary>
{ label: _('entities-listing.table-col-names.dictionary-entries') },
];
readonly templateStats$: Observable<DossierTemplateStats>;
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()));
}

View File

@ -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<Dictionary>;
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);

View File

@ -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<FileAttributeConfig> 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<FileAttributeConfig>[] = [
@ -61,21 +48,16 @@ export class FileAttributesListingScreenComponent extends ListingComponent<FileA
@ViewChild('impactedTemplates') private readonly _impactedTemplatesRef: TemplateRef<unknown>;
#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 {

View File

@ -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);
}

View File

@ -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<AddEditJustificationDialogComponent>,
@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();

View File

@ -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<Justification> implements OnInit {
readonly iconButtonTypes = IconButtonTypes;
readonly circleButtonTypes = CircleButtonTypes;
readonly tableHeaderLabel = _('justifications-listing.table-header');
readonly tableColumnConfigs: TableColumnConfig<Justification>[] = [
{ 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<void> {

View File

@ -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<User>;
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, {

View File

@ -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<PermissionsMapping> {
readonly currentUser = this._userService.currentUser;
readonly currentUser = inject(UserService).currentUser;
readonly translations = permissionsTranslations;
readonly tableColumnConfigs: TableColumnConfig<PermissionsMapping>[];
readonly tableHeaderLabel = _('permissions-screen.table-header.title');
@ -30,20 +30,18 @@ export class PermissionsScreenComponent extends ListingComponent<PermissionsMapp
readonly mappedPermissions: string[];
constructor(
protected readonly _injector: Injector,
private readonly _configService: ConfigService,
private readonly _userService: UserService,
route: ActivatedRoute,
configService: ConfigService,
private readonly _loadingService: LoadingService,
private readonly _entityPermissionsService: EntityPermissionsService,
private readonly _permissionsMapService: PermissionsMapService,
private readonly _permissionsConfigurationMapService: PermissionsConfigurationMapService,
private readonly _route: ActivatedRoute,
readonly routerHistoryService: RouterHistoryService,
private readonly _permissionsMapService: PermissionsMapService,
private readonly _entityPermissionsService: EntityPermissionsService,
permissionsConfigurationMapService: PermissionsConfigurationMapService,
) {
super(_injector);
this.targetObject = _route.snapshot.data.permissionsObject;
this.tableColumnConfigs = this._configService.tableConfig(this.targetObject);
this.mappedPermissions = this._permissionsConfigurationMapService.getMappedPermissions(this.targetObject);
super();
this.targetObject = route.snapshot.data.permissionsObject;
this.tableColumnConfigs = configService.tableConfig(this.targetObject);
this.mappedPermissions = permissionsConfigurationMapService.getMappedPermissions(this.targetObject);
this.entitiesService.setEntities(this._permissionsMapService.get(this.targetObject));
this.sortingService.setSortingOption({
column: 'sort',

View File

@ -1,7 +1,7 @@
import { ChangeDetectionStrategy, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { DOSSIER_TEMPLATE_ID, IPlaceholdersResponse, IReportTemplate } from '@red/domain';
import { download } from '@utils/file-download-utils';
import { ConfirmationDialogInput, LoadingService, Toaster } from '@iqser/common-ui';
import { ConfirmationDialogInput, getParam, LoadingService, Toaster } from '@iqser/common-ui';
import { PermissionsService } from '@services/permissions.service';
import {
generalPlaceholdersDescriptionsTranslations,
@ -10,10 +10,8 @@ import {
import { removeBraces } from '@utils/functions';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { AdminDialogService } from '../../../services/admin-dialog.service';
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
import { ReportTemplateService } from '@services/report-template.service';
import { BehaviorSubject, firstValueFrom } from 'rxjs';
import { ActivatedRoute } from '@angular/router';
interface Placeholder {
placeholder: string;
@ -33,21 +31,17 @@ const placeholderTypes: PlaceholderType[] = ['generalPlaceholders', 'fileAttribu
export class ReportsScreenComponent implements OnInit {
placeholders$ = new BehaviorSubject<Placeholder[]>([]);
availableTemplates$ = new BehaviorSubject<IReportTemplate[]>([]);
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();

View File

@ -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;

View File

@ -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<User> implements OnInit {
readonly routerHistoryService = inject(RouterHistoryService);
@ -71,13 +66,12 @@ export class UserListingScreenComponent extends ListingComponent<User> 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<boolean> {

View File

@ -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 {

View File

@ -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<Watermark> implements OnInit {
private readonly _dossierTemplateId: string;
readonly iconButtonTypes = IconButtonTypes;
readonly circleButtonTypes = CircleButtonTypes;
readonly currentUser: User;
readonly currentUser = getCurrentUser();
readonly tableColumnConfigs: TableColumnConfig<Watermark>[] = [
{ 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<Watermark
{ label: _('watermarks-listing.table-col-names.modified-on'), sortByKey: 'dateModified' },
];
readonly tableHeaderLabel: string = _('watermarks-listing.table-header.title');
readonly #dossierTemplateId: string = getParam(DOSSIER_TEMPLATE_ID);
constructor(
protected readonly _injector: Injector,
private readonly _route: ActivatedRoute,
private readonly _userService: UserService,
private readonly _loadingService: LoadingService,
private readonly _watermarkService: WatermarkService,
private readonly _dialogService: AdminDialogService,
private readonly _toaster: Toaster,
) {
super(_injector);
this.currentUser = _userService.currentUser;
this._dossierTemplateId = _route.snapshot.paramMap.get(DOSSIER_TEMPLATE_ID);
super();
}
async ngOnInit(): Promise<void> {
await this._loadData();
}
private async _loadData(): Promise<void> {
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<void> {
const isUsed = await firstValueFrom(this._watermarkService.isWatermarkUsed(watermark.id));
@ -85,14 +66,6 @@ export class WatermarksListingScreenComponent extends ListingComponent<Watermark
});
}
private async _deleteWatermark(watermark: Watermark): Promise<void> {
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<void> {
watermark.enabled = !watermark.enabled;
this._loadingService.start();
@ -101,6 +74,28 @@ export class WatermarksListingScreenComponent extends ListingComponent<Watermark
}
getRouterLink(watermark: Watermark = null): string {
return `/main/admin/dossier-templates/${this._dossierTemplateId}/watermarks/${watermark ? watermark.id : 0}`;
return `/main/admin/dossier-templates/${this.#dossierTemplateId}/watermarks/${watermark ? watermark.id : 0}`;
}
private async _loadData(): Promise<void> {
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<void> {
this._loadingService.start();
await firstValueFrom(this._watermarkService.deleteWatermark(watermark.id));
this._toaster.success(_('watermarks-listing.action.delete-success'));
await this._loadData();
this._loadingService.stop();
}
}

View File

@ -5,9 +5,7 @@ import { Observable } from 'rxjs';
@Injectable()
export class AuditService extends GenericService<IAudit> {
constructor(protected readonly _injector: Injector) {
super(_injector, 'audit');
}
protected readonly _defaultModelPath = 'audit';
getCategories(): Observable<ICategory[]> {
return super.getAll<ICategory[]>(`${this._defaultModelPath}/categories`);

View File

@ -12,9 +12,7 @@ import { catchError, map } from 'rxjs/operators';
@Injectable()
export class DigitalSignatureService extends GenericService<IDigitalSignatureRequest> {
constructor(protected readonly _injector: Injector) {
super(_injector, 'digital-signature');
}
protected readonly _defaultModelPath = 'digital-signature';
@Validate()
updateSignature(@RequiredParam() body: IPkcsDigitalSignatureRequest): Observable<unknown> {

View File

@ -4,9 +4,7 @@ import { IRules } from '@red/domain';
@Injectable()
export class RulesService extends GenericService<IRules> {
constructor(protected readonly _injector: Injector) {
super(_injector, 'rules');
}
protected readonly _defaultModelPath = 'rules';
@Validate()
download(@RequiredParam() dossierTemplateId: string) {

View File

@ -4,9 +4,7 @@ import { ISmtpConfiguration } from '@red/domain';
@Injectable()
export class SmtpConfigService extends GenericService<unknown> {
constructor(protected readonly _injector: Injector) {
super(_injector, 'configuration');
}
protected readonly _defaultModelPath = 'configuration';
@Validate()
updateSMTPConfiguration(@RequiredParam() body: ISmtpConfiguration) {

View File

@ -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,

View File

@ -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<Dossier> 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();
}

View File

@ -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<ProgressBarConfigModel[]>;
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)));

View File

@ -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<File> implements OnInit, OnAttach {
readonly listingModes = ListingModes;
@ -64,7 +59,7 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
);
readonly dossier$: Observable<Dossier>;
readonly files$: Observable<File[]>;
readonly dossierId: string;
readonly dossierId = getParam(DOSSIER_ID);
readonly dossierTemplateId: string;
readonly workflowConfig: WorkflowConfig<File, WorkflowFileStatus>;
#currentDossier: Dossier;
@ -75,11 +70,9 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> 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<File> 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);

View File

@ -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<DonutChartConfig[]>;
readonly dossiersChartConfig$: Observable<DonutChartConfig[]>;
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(

View File

@ -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<Dossier> implements OnInit, OnAttach {
@ -32,17 +32,16 @@ export class DossiersListingScreenComponent extends ListingComponent<Dossier> 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));
}

View File

@ -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<AcceptRecommendationDialogComponent, AcceptRecommendationReturnType>,
@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();
}

View File

@ -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<ChangeLegalBasisDialogComponent>,
@Inject(MAT_DIALOG_DATA) private readonly _data: { annotations: AnnotationWrapper[]; dossier: Dossier },
) {
super(_injector, _dialogRef, true);
super(_dialogRef, true);
this.form = this._getForm();
}

View File

@ -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<DocumentInfoDialogComponent>,
@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() {

View File

@ -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<ForceAnnotationDialogComponent>,
@Inject(MAT_DIALOG_DATA)
private readonly _data: { readonly dossier: Dossier; readonly hint: boolean; annotations: AnnotationWrapper[] },
) {
super(_injector, _dialogRef);
super(_dialogRef);
this.form = this._getForm();
}

View File

@ -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<HighlightActionDialogComponent>,
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],
});
}
}

View File

@ -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<ImportRedactionsDialogComponent>,
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) {

View File

@ -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<ManualAnnotationDialogComponent>,
@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;

View File

@ -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<RecategorizeImageDialogComponent>,
@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 {

View File

@ -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<RemoveAnnotationsDialogComponent>,
@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;
}
}

View File

@ -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<ResizeAnnotationDialogComponent>,
@Inject(MAT_DIALOG_DATA) private readonly _data: { annotation: AnnotationWrapper; text?: string },
) {
super(_injector, _dialogRef);
super(_dialogRef);
}
get disabled(): boolean {

View File

@ -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<AnnotationWrapper> {
viewedPages: IViewedPage[] = [];
missingTypes = new Set<string>();
readonly hasChangeLog$ = new BehaviorSubject<boolean>(false);
readonly annotations$: Observable<AnnotationWrapper[]>;
readonly hiddenAnnotations = new Set<string>();
protected readonly _entityClass = AnnotationWrapper;
readonly #redactionLog$ = new Subject<IRedactionLog>();
readonly #textHighlights$ = new BehaviorSubject<AnnotationWrapper[]>([]);
@ -45,9 +44,8 @@ export class FileDataService extends EntitiesService<AnnotationWrapper> {
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(

View File

@ -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<boolean>;
readonly isWritable$: Observable<boolean>;
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)));

View File

@ -36,17 +36,17 @@ function getMessage(action: ManualRedactionActions, isDictionary = false, error
@Injectable()
export class ManualRedactionService extends GenericService<IManualAddResponse> {
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<IManualAddResponse> {
@Validate()
add(@RequiredParam() body: List<IAddRedactionRequest>, @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<IManualAddResponse> {
@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<IManualAddResponse> {
@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<IManualAddResponse> {
@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<IManualAddResponse> {
@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<IManualAddResponse> {
@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<IManualAddResponse> {
@Validate()
remove(@RequiredParam() body: List<IRemoveRedactionRequest>, @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<IAddRedactionRequest>, @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<IManualAddResponse> {
@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<IManualAddResponse> {
@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<IResizeRequest>, @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<IResizeRequest>, @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) {

View File

@ -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<ISearchListItem> implements OnDestroy {
@ -79,7 +79,6 @@ export class SearchScreenComponent extends ListingComponent<ISearchListItem> 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<ISearchListItem> 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<string> {
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<ISearchListItem> 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<string> {
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[],

View File

@ -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<DictionaryDetailsDialogComponent>,
) {
super(_injector, _dialogRef, true);
super(_dialogRef, true);
}
get valid(): boolean {

View File

@ -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<Dossier>;
@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<EditDossierDialogComponent>,
@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)
);
}

View File

@ -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,

View File

@ -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<DashboardStats>;
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));
}

View File

@ -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<AddDossierDialogComponent>,
@Inject(MAT_DIALOG_DATA) readonly data: DialogData,
) {
super(_injector, _dialogRef);
super(_dialogRef);
this._getDossierTemplates();
this.form = this._getForm();
this.initialFormValue = this.form.getRawValue();

View File

@ -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<TrashItem> {
readonly circleButtonTypes = CircleButtonTypes;
@ -45,15 +38,12 @@ export class TrashScreenComponent extends ListingComponent<TrashItem> {
];
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',

View File

@ -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<DownloadStatus, IDownloadStatus> {
export class FileDownloadService extends EntitiesService<IDownloadStatus, DownloadStatus> {
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<DownloadStatus[]> {

View File

@ -21,14 +21,15 @@ export interface ActiveUpload {
@Injectable()
export class FileUploadService extends GenericService<IFileUploadResult> 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<string>();
private readonly _subscriptions = new Subscription();
readonly #fetchFiles$ = new Subject<string>();
readonly #subscriptions = new Subscription();
constructor(
private readonly _filesService: FilesService,
@ -38,17 +39,15 @@ export class FileUploadService extends GenericService<IFileUploadResult> 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<IFileUploadResult> impleme
}
ngOnDestroy() {
this._subscriptions.unsubscribe();
this.#subscriptions.unsubscribe();
}
scheduleUpload(item: FileUploadModel) {
@ -64,7 +63,7 @@ export class FileUploadService extends GenericService<IFileUploadResult> 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<IFileUploadResult> 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<IFileUploadResult> 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<IFileUploadResult> 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<IFileUploadResult> impleme
}
}
this._activeUploads.splice(index, 1);
this.#activeUploads.splice(index, 1);
this.activeUploads--;
}
}

View File

@ -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<DashboardStats, IDashboardStats> {
constructor(
protected readonly _injector: Injector,
private readonly _dossierStatesService: DossierStatesService,
private readonly _logger: NGXLogger,
) {
super(_injector, DashboardStats, 'dossier-template/stats');
}
export class DashboardStatsService extends EntitiesService<IDashboardStats, DashboardStats> {
protected readonly _defaultModelPath = 'dossier-template/stats';
protected readonly _entityClass = DashboardStats;
readonly #dossierStatesService = inject(DossierStatesService);
loadAll(): Observable<DashboardStats[]> {
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)),
);

View File

@ -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<DossierTemplate, IDossierTemplate> {
export class DossierTemplatesService extends EntitiesService<IDossierTemplate, DossierTemplate> {
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<DossierTemplate[]> {
@ -41,9 +43,8 @@ export class DossierTemplatesService extends EntitiesService<DossierTemplate, ID
...getAttributes(templates),
this._dictionaryService.loadDictionaryData(dossierTemplateIds(templates)),
]).pipe(mapTo(templates));
} else {
return of(templates);
}
return of(templates);
}),
tap(templates => this.setEntities(templates)),
);

View File

@ -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;
}

View File

@ -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<unknown> {
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<Dossier[]> {
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);
}
}

View File

@ -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<Dossier> {
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<IDossierChanges> {
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<Dossier> {
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<Dossier> {
}
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<Dossier> {
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);
}),
);
}

View File

@ -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<DossierStats, IDossierStats> {
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<DossierStats[]> {
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)));
}
}

View File

@ -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<Dossier, IDossier> {
export abstract class DossiersService extends EntitiesService<IDossier, Dossier> {
readonly dossierFileChanges$ = new Subject<string>();
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<Dossier> {

View File

@ -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<IPermissionsMapping> {
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<PermissionsMapping[]> {
return this._http.get<IPermissionsMapping[]>(`/${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<IPermissionsMapping
mapEach(mapping => 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<PermissionsMapping[]> {
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<IPermissionsMapping
}
#addMissingPermissions(mappings: PermissionsMapping[], targetObject: string): void {
const configuration = this._permissionsConfigurationMapService.get(targetObject);
const configuration = this.#permissionsConfigurationMapService.get(targetObject);
for (const mapping of configuration) {
const targetPermission: string = mapping.targetPermission.name;
if (!mappings.some(p => p.targetPermission.name === targetPermission)) {

View File

@ -4,9 +4,7 @@ import { EntitiesMapService } from '@iqser/common-ui';
@Injectable({ providedIn: 'root' })
export class PermissionsConfigurationMapService extends EntitiesMapService<PermissionsMapping, IPermissionsMapping> {
constructor() {
super('name');
}
protected readonly _primaryKey = 'name';
getMappedPermissions(targetObject: string): string[] {
return Array.from(

View File

@ -4,7 +4,5 @@ import { EntitiesMapService } from '@iqser/common-ui';
@Injectable({ providedIn: 'root' })
export class PermissionsMapService extends EntitiesMapService<PermissionsMapping, IPermissionsMapping> {
constructor() {
super('name');
}
protected readonly _primaryKey = 'name';
}

View File

@ -4,9 +4,7 @@ import { EntitiesMapService } from '@iqser/common-ui';
@Injectable({ providedIn: 'root' })
export class DictionariesMapService extends EntitiesMapService<Dictionary, IDictionary> {
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 {

View File

@ -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<Dictionary, IDictionary> {
export class DictionaryService extends EntitiesService<IDictionary, Dictionary> {
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<Dictionary, IDictionary>
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<Dictionary[]> {

View File

@ -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<DossierAttributeConfig, IDossierAttributeConfig> {
constructor(protected readonly _injector: Injector) {
super(_injector, DossierAttributeConfig, 'dossier-attributes');
}
export class DossierAttributesService extends EntitiesService<IDossierAttributeConfig, DossierAttributeConfig> {
protected readonly _defaultModelPath = 'dossier-attributes';
protected readonly _entityClass = DossierAttributeConfig;
async getWithValues(dossier: Dossier): Promise<DossierAttributeWithValue[]> {
const attributes = await firstValueFrom(this.getAttributes(dossier.id));

View File

@ -5,9 +5,7 @@ import { flatMap } from 'lodash-es';
@Injectable({ providedIn: 'root' })
export class DossierStatesMapService extends EntitiesMapService<DossierState, IDossierState> {
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));

View File

@ -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<DossierState, IDossierState> {
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<IDossierState, DossierState> {
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<DossierState[]> {
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<unknown>(state, this._defaultModelPath).pipe(
@ -39,12 +37,12 @@ export class DossierStatesService extends EntitiesService<DossierState, IDossier
@Validate()
loadAllForTemplate(@RequiredParam() templateId: string) {
return this.loadAll(`${this._defaultModelPath}/dossier-template/${templateId}`).pipe(
tap(states => this._dossierStatesMapService.set(templateId, states)),
tap(states => this.#dossierStatesMapService.set(templateId, states)),
);
}
loadAllForAllTemplates(): Observable<DossierState[][]> {
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[][]))),

View File

@ -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<DossierTemplateStats, IDossierTemplateStats> {
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';
}

View File

@ -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<Record<string, IFileAttributesConfig>>;
@Injectable({
providedIn: 'root',
})
export class FileAttributesService extends EntitiesService<FileAttributeConfig, IFileAttributeConfig> {
private readonly _fileAttributesConfig$ = new BehaviorSubject<FileAttributesConfigMap>({});
constructor(protected readonly _injector: Injector) {
super(_injector, FileAttributeConfig, 'fileAttributes');
}
export class FileAttributesService extends EntitiesService<IFileAttributeConfig, FileAttributeConfig> {
protected readonly _defaultModelPath = 'fileAttributes';
protected readonly _entityClass = FileAttributeConfig;
readonly #fileAttributesConfig$ = new BehaviorSubject<FileAttributesConfigMap>({});
/**
* Get the file attributes that can be used at importing csv.
@ -25,8 +23,8 @@ export class FileAttributesService extends EntitiesService<FileAttributeConfig,
return request$.pipe(
tap(entities => 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<FileAttributeConfig,
}
getFileAttributeConfig(dossierTemplateId: string): IFileAttributesConfig | undefined {
return this._fileAttributesConfig$.value[dossierTemplateId];
return this.#fileAttributesConfig$.value[dossierTemplateId];
}
/**

View File

@ -1,4 +1,4 @@
import { Injectable, Injector } from '@angular/core';
import { Injectable } from '@angular/core';
import { EntitiesService, RequiredParam, Validate } from '@iqser/common-ui';
import { ILegalBasis, Justification } from '@red/domain';
import { Observable } from 'rxjs';
@ -7,10 +7,9 @@ import { map } from 'rxjs/operators';
@Injectable({
providedIn: 'root',
})
export class JustificationsService extends EntitiesService<Justification, ILegalBasis> {
constructor(protected readonly _injector: Injector) {
super(_injector, Justification, 'legalBasis');
}
export class JustificationsService extends EntitiesService<ILegalBasis, Justification> {
protected readonly _defaultModelPath = 'legalBasis';
protected readonly _entityClass = Justification;
@Validate()
createOrUpdate(@RequiredParam() justification: Justification, @RequiredParam() dossierTemplateId: string) {

View File

@ -9,13 +9,14 @@ import { DossiersCacheService } from '../dossiers/dossiers-cache.service';
@Injectable({ providedIn: 'root' })
export class PlatformSearchService extends GenericService<ISearchResponse> {
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({

View File

@ -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<TrashItem> {
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<TrashItem> {
private readonly _dossierStatsService: DossierStatsService,
private readonly _filesService: FilesService,
) {
super(_injector, null, '');
super();
}
deleteDossier(dossier: Dossier): Observable<unknown> {

View File

@ -12,9 +12,7 @@ interface IsUsedResponse {
providedIn: 'root',
})
export class WatermarkService extends GenericService<IWatermark> {
constructor(protected readonly _injector: Injector) {
super(_injector, 'watermark');
}
protected readonly _defaultModelPath = 'watermark';
@Validate()
saveWatermark(@RequiredParam() body: IWatermark) {

View File

@ -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<unknown> {
constructor(protected readonly _injector: Injector, private readonly _filesService: FilesService) {
super(_injector, '');
}
readonly #filesService = inject(FilesService);
protected readonly _defaultModelPath = '';
@Validate()
delete(@RequiredParam() files: List<File>, @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()

View File

@ -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<File, IFile> {
constructor() {
super(DOSSIER_ID);
}
protected readonly _primaryKey = DOSSIER_ID;
replaceFiles(files: File[], property: keyof IFile, generateValue: Function) {
replaceFiles<T extends NonFunctionKeys<File>, 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);
}

View File

@ -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<File, IFile> {
export class FilesService extends EntitiesService<IFile, File> {
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. */

View File

@ -3,9 +3,7 @@ import { GenericService, HeadersConfiguration, RequiredParam, Validate } from '@
@Injectable({ providedIn: 'root' })
export class RedactionImportService extends GenericService<void> {
constructor(protected readonly _injector: Injector) {
super(_injector, 'import-redactions');
}
protected readonly _defaultModelPath = 'import-redactions';
@Validate()
importRedactions(@RequiredParam() dossierId: string, @RequiredParam() fileId: string, file?: Blob) {

View File

@ -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<unknown> {
constructor(protected readonly _injector: Injector) {
super(_injector, '');
}
protected readonly _defaultModelPath = '';
@Validate()
getRedactionLog(@RequiredParam() dossierId: string, @RequiredParam() fileId: string, withManualRedactions?: boolean) {

View File

@ -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<TextHighlightResponse> {
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<AnnotationWrapper[]> {
@ -32,7 +31,7 @@ export class TextHighlightService extends GenericService<TextHighlightResponse>
@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 } })),
);
}

View File

@ -8,9 +8,7 @@ import { of } from 'rxjs';
providedIn: 'root',
})
export class ViewedPagesService extends GenericService<unknown> {
constructor(protected readonly _injector: Injector) {
super(_injector, 'viewedPages');
}
protected readonly _defaultModelPath = 'viewedPages';
@Validate()
addPage(@RequiredParam() body: IViewedPagesRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {

View File

@ -7,9 +7,7 @@ import { Observable } from 'rxjs';
providedIn: 'root',
})
export class GeneralSettingsService extends GenericService<IGeneralConfiguration> {
constructor(protected readonly _injector: Injector) {
super(_injector, 'configuration');
}
protected readonly _defaultModelPath = 'configuration';
getGeneralConfigurations(): Observable<IGeneralConfiguration> {
return this._getOne(['general']);

View File

@ -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<ILicenseReport> {
readonly licenseData$: Observable<ILicenses>;
readonly selectedLicense$: Observable<ILicense>;
activeLicenseId: string;
protected readonly _defaultModelPath = 'report';
readonly #licenseData$ = new BehaviorSubject<ILicenses | undefined>(undefined);
readonly #selectedLicense$ = new BehaviorSubject<ILicense | undefined>(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),

View File

@ -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<Notification, INotification> {
export class NotificationsService extends EntitiesService<INotification, Notification> {
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(

View File

@ -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<unknown> {
protected readonly _defaultModelPath = '';
constructor(
protected readonly _injector: Injector,
private readonly _toaster: Toaster,
private readonly _filesService: FilesService,
private readonly _filesMapService: FilesMapService,
) {
super(_injector, '');
super();
}
@Validate()

View File

@ -8,9 +8,7 @@ import { HttpResponse } from '@angular/common/http';
providedIn: 'root',
})
export class ReportTemplateService extends GenericService<unknown> {
constructor(protected readonly _injector: Injector) {
super(_injector, 'templateUpload');
}
protected readonly _defaultModelPath = 'templateUpload';
@Validate()
uploadTemplateForm(@RequiredParam() dossierTemplateId: string, multiFileReport?: boolean, file?: Blob) {

View File

@ -8,12 +8,9 @@ import { tap } from 'rxjs/operators';
providedIn: 'root',
})
export class SystemPreferencesService extends GenericService<SystemPreferences> {
protected readonly _defaultModelPath = 'app-config';
values: SystemPreferences;
constructor(protected readonly _injector: Injector) {
super(_injector, 'app-config');
}
loadPreferences(): Observable<SystemPreferences> {
return this.get<SystemPreferences>().pipe(
tap((config: SystemPreferences) => {

Some files were not shown because too many files have changed in this diff Show More