Generic dossiers service

This commit is contained in:
Adina Țeudan 2022-02-22 14:25:01 +02:00
parent 0728047171
commit 12d655a7b7
58 changed files with 361 additions and 352 deletions

View File

@ -6,9 +6,9 @@ import { BaseScreenComponent } from '@components/base-screen/base-screen.compone
import { RouteReuseStrategy, RouterModule, Routes } from '@angular/router';
import { NgModule } from '@angular/core';
import { DownloadsListScreenComponent } from '@components/downloads-list-screen/downloads-list-screen.component';
import { DossiersGuard } from '@guards/dossiers.guard';
import { DossierTemplatesGuard } from '@guards/dossier-templates.guard';
import { ArchivedDossiersGuard } from '@guards/archived-dossiers.guard';
import { DossiersGuard } from '@guards/dossiers.guard';
import { ACTIVE_DOSSIERS_SERVICE, ARCHIVED_DOSSIERS_SERVICE } from './tokens';
const routes: Routes = [
{
@ -39,6 +39,7 @@ const routes: Routes = [
data: {
routeGuards: [AuthGuard, RedRoleGuard, DossierTemplatesGuard, DossiersGuard],
requiredRoles: ['RED_USER', 'RED_MANAGER'],
dossiersService: ACTIVE_DOSSIERS_SERVICE,
},
},
{
@ -47,8 +48,9 @@ const routes: Routes = [
loadChildren: () => import('./modules/archive/archive.module').then(m => m.ArchiveModule),
canActivate: [CompositeRouteGuard],
data: {
routeGuards: [AuthGuard, RedRoleGuard, DossierTemplatesGuard, ArchivedDossiersGuard],
routeGuards: [AuthGuard, RedRoleGuard, DossierTemplatesGuard, DossiersGuard],
requiredRoles: ['RED_USER', 'RED_MANAGER'],
dossiersService: ARCHIVED_DOSSIERS_SERVICE,
},
},
{

View File

@ -20,7 +20,7 @@ import { AppRoutingModule } from './app-routing.module';
import { SharedModule } from '@shared/shared.module';
import { FileUploadDownloadModule } from '@upload-download/file-upload-download.module';
import { PlatformLocation } from '@angular/common';
import { BASE_HREF } from './tokens';
import { ACTIVE_DOSSIERS_SERVICE, ARCHIVED_DOSSIERS_SERVICE, BASE_HREF } from './tokens';
import { MonacoEditorModule } from '@materia-ui/ngx-monaco-editor';
import { GlobalErrorHandler } from '@utils/global-error-handler.service';
import { REDMissingTranslationHandler } from '@utils/missing-translations-handler';
@ -44,6 +44,8 @@ import { GeneralSettingsService } from '@services/general-settings.service';
import { BreadcrumbsComponent } from '@components/breadcrumbs/breadcrumbs.component';
import { UserPreferenceService } from '@services/user-preference.service';
import { UserService } from '@services/user.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { ArchivedDossiersService } from '@services/entity-services/archived-dossiers.service';
export function httpLoaderFactory(httpClient: HttpClient, configService: ConfigService): PruningTranslationLoader {
return new PruningTranslationLoader(httpClient, '/assets/i18n/', `.json?version=${configService.values.FRONTEND_APP_VERSION}`);
@ -144,6 +146,14 @@ const components = [AppComponent, AuthErrorComponent, NotificationsComponent, Sp
useFactory: (configService: ConfigService) => configService.values.MAX_RETRIES_ON_SERVER_ERROR,
deps: [ConfigService],
},
{
provide: ACTIVE_DOSSIERS_SERVICE,
useExisting: ActiveDossiersService,
},
{
provide: ARCHIVED_DOSSIERS_SERVICE,
useExisting: ArchivedDossiersService,
},
DatePipe,
],
bootstrap: [AppComponent],

View File

@ -2,7 +2,7 @@ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { DatePipe } from '@shared/pipes/date.pipe';
import { UserService } from '@services/user.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { NotificationsService } from '@services/notifications.service';
import { Notification } from '@red/domain';
import { distinctUntilChanged, map, switchMap, tap } from 'rxjs/operators';
@ -33,7 +33,7 @@ export class NotificationsComponent extends AutoUnsubscribe implements OnInit {
private readonly _translateService: TranslateService,
private readonly _userService: UserService,
private readonly _notificationsService: NotificationsService,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
private readonly _datePipe: DatePipe,
) {
super();

View File

@ -1,14 +0,0 @@
import { Injectable } from '@angular/core';
import { CanActivate } from '@angular/router';
import { firstValueFrom } from 'rxjs';
import { ArchivedDossiersService } from '@services/entity-services/archived-dossiers.service';
@Injectable({ providedIn: 'root' })
export class ArchivedDossiersGuard implements CanActivate {
constructor(private readonly _archivedDossiersService: ArchivedDossiersService) {}
async canActivate(): Promise<boolean> {
await firstValueFrom(this._archivedDossiersService.loadAll());
return true;
}
}

View File

@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, Router } from '@angular/router';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { FilesMapService } from '@services/entity-services/files-map.service';
import { FilesService } from '@services/entity-services/files.service';
import { firstValueFrom } from 'rxjs';
@ -9,7 +9,7 @@ import { DOSSIER_ID } from '@utils/constants';
@Injectable({ providedIn: 'root' })
export class DossierFilesGuard implements CanActivate {
constructor(
private readonly _dossiersService: DossiersService,
private readonly _dossiersService: ActiveDossiersService,
private readonly _filesMapService: FilesMapService,
private readonly _filesService: FilesService,
private readonly _router: Router,

View File

@ -1,14 +1,16 @@
import { Injectable } from '@angular/core';
import { CanActivate } from '@angular/router';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { Injectable, Injector, ProviderToken } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate } from '@angular/router';
import { firstValueFrom } from 'rxjs';
import { DossiersService } from '@services/entity-services/dossiers.service';
@Injectable({ providedIn: 'root' })
export class DossiersGuard implements CanActivate {
constructor(private readonly _dossiersService: DossiersService) {}
constructor(private readonly _injector: Injector) {}
async canActivate(): Promise<boolean> {
await firstValueFrom(this._dossiersService.loadAll());
async canActivate(route: ActivatedRouteSnapshot): Promise<boolean> {
const token: ProviderToken<DossiersService> = route.data.dossiersService;
const dossiersService: DossiersService = this._injector.get<DossiersService>(token);
await firstValueFrom(dossiersService.loadAll());
return true;
}
}

View File

@ -1,14 +1,14 @@
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, Router } from '@angular/router';
import { FilesMapService } from '@services/entity-services/files-map.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { DOSSIER_ID, FILE_ID } from '@utils/constants';
@Injectable({ providedIn: 'root' })
export class FilePreviewGuard implements CanActivate {
constructor(
private readonly _filesMapService: FilesMapService,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
private readonly _router: Router,
) {}
@ -16,7 +16,7 @@ export class FilePreviewGuard implements CanActivate {
const dossierId = route.paramMap.get(DOSSIER_ID);
const fileId = route.paramMap.get(FILE_ID);
const dossier = this._dossiersService.find(dossierId);
const dossier = this._activeDossiersService.find(dossierId);
if (!this._filesMapService.get(dossierId, fileId)) {
await this._router.navigate([dossier.routerLink]);

View File

@ -1,5 +1,5 @@
import { ChangeDetectionStrategy, Component, Inject, Injector } from '@angular/core';
import { BaseDialogComponent } from '../../../../../../../../libs/common-ui/src';
import { BaseDialogComponent } from '@iqser/common-ui';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { IDossierState } from '@red/domain';

View File

@ -4,7 +4,7 @@ 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 '../../../../../../../../libs/common-ui/src';
import { BaseDialogComponent } from '@iqser/common-ui';
@Component({
selector: 'redaction-add-edit-file-attribute-dialog',

View File

@ -2,7 +2,7 @@ import { Component, Inject } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { List, LoadingService } from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { UserService } from '@services/user.service';
import { firstValueFrom } from 'rxjs';
@ -22,7 +22,7 @@ export class ConfirmDeleteUsersDialogComponent {
constructor(
private readonly _userService: UserService,
private readonly _loadingService: LoadingService,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
@Inject(MAT_DIALOG_DATA) readonly userIds: List<string>,
readonly dialogRef: MatDialogRef<ConfirmDeleteUsersDialogComponent>,
) {
@ -34,8 +34,9 @@ export class ConfirmDeleteUsersDialogComponent {
}
private get _dossierCount(): number {
return this._dossiersService.all.filter(dw => this.userIds.reduce((prev, userId) => prev || dw.memberIds.includes(userId), false))
.length;
return this._activeDossiersService.all.filter(dw =>
this.userIds.reduce((prev, userId) => prev || dw.memberIds.includes(userId), false),
).length;
}
async deleteUser() {

View File

@ -7,10 +7,10 @@ import {
LoadingService,
TableColumnConfig,
Toaster,
} from '../../../../../../../../libs/common-ui/src';
} from '@iqser/common-ui';
import { DossierState, IDossierState } from '@red/domain';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { DossierStateService } from '@services/entity-services/dossier-state.service';
import { firstValueFrom } from 'rxjs';
import { AdminDialogService } from '../../services/admin-dialog.service';
@ -44,7 +44,7 @@ export class DossierStatesListingScreenComponent extends ListingComponent<Dossie
constructor(
protected readonly _injector: Injector,
private readonly _loadingService: LoadingService,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
readonly dossierStateService: DossierStateService,
private readonly _dialogService: AdminDialogService,
private readonly _userService: UserService,
@ -106,7 +106,7 @@ export class DossierStatesListingScreenComponent extends ListingComponent<Dossie
async #loadData(): Promise<void> {
this._loadingService.start();
await firstValueFrom(this._dossiersService.loadAll());
await firstValueFrom(this._activeDossiersService.loadAll());
try {
const dossierStates = this.dossierStateService.all.filter(d => d.dossierTemplateId === this.#dossierTemplateId);
@ -121,6 +121,6 @@ export class DossierStatesListingScreenComponent extends ListingComponent<Dossie
}
#setStatesCount(dossierStates: DossierState[]): void {
dossierStates.forEach(state => (state.dossierCount = this._dossiersService.getCountWithState(state.dossierStatusId)));
dossierStates.forEach(state => (state.dossierCount = this._activeDossiersService.getCountWithState(state.dossierStatusId)));
}
}

View File

@ -12,7 +12,7 @@ import {
} from '@iqser/common-ui';
import { ConfigService } from '@services/config.service';
import * as moment from 'moment';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { AdminDialogService } from '../../services/admin-dialog.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { Observable } from 'rxjs';
@ -50,7 +50,7 @@ export class TrashScreenComponent extends ListingComponent<DossierListItem> impl
protected readonly _injector: Injector,
private readonly _loadingService: LoadingService,
private readonly _permissionsService: PermissionsService,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
readonly routerHistoryService: RouterHistoryService,
private readonly _configService: ConfigService,
private readonly _adminDialogService: AdminDialogService,
@ -108,7 +108,7 @@ export class TrashScreenComponent extends ListingComponent<DossierListItem> impl
}
private async _loadDossiersData(): Promise<void> {
this.entitiesService.setEntities(this._toListItems(await this._dossiersService.getDeleted()).filter(d => d.canRestore));
this.entitiesService.setEntities(this._toListItems(await this._activeDossiersService.getDeleted()).filter(d => d.canRestore));
}
private _canRestoreDossier(restoreDate: string): boolean {
@ -137,13 +137,13 @@ export class TrashScreenComponent extends ListingComponent<DossierListItem> impl
private async _restore(dossiers: DossierListItem[]): Promise<void> {
const dossierIds = dossiers.map(d => d.id);
await this._dossiersService.restore(dossierIds);
await this._activeDossiersService.restore(dossierIds);
this._removeFromList(dossierIds);
}
private async _hardDelete(dossiers: DossierListItem[]) {
const dossierIds = dossiers.map(d => d.id);
await this._dossiersService.hardDelete(dossierIds);
await this._activeDossiersService.hardDelete(dossierIds);
this._removeFromList(dossierIds);
}

View File

@ -5,7 +5,7 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import * as moment from 'moment';
import { downloadTypesTranslations } from '../../../../translations/download-types-translations';
import { BaseDialogComponent, IconButtonTypes, SaveOptions } from '@iqser/common-ui';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service';
import { ReportTemplateService } from '@services/report-template.service';
import { firstValueFrom } from 'rxjs';
@ -29,7 +29,7 @@ export class AddDossierDialogComponent extends BaseDialogComponent {
availableReportTypes = [];
constructor(
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
private readonly _dossierTemplatesService: DossierTemplatesService,
private readonly _formBuilder: FormBuilder,
private readonly _reportTemplateController: ReportTemplateService,
@ -61,7 +61,7 @@ export class AddDossierDialogComponent extends BaseDialogComponent {
reportTemplateValueMapper = (reportTemplate: IReportTemplate) => reportTemplate.templateId;
async save(options?: SaveOptions) {
const savedDossier = await firstValueFrom(this._dossiersService.createOrUpdate(this._formToObject()));
const savedDossier = await firstValueFrom(this._activeDossiersService.createOrUpdate(this._formToObject()));
if (savedDossier) {
this._dialogRef.close({ dossier: savedDossier, addMembers: options?.addMembers });
}

View File

@ -6,7 +6,7 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Dossier, File } from '@red/domain';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { FilesService } from '@services/entity-services/files.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { PermissionsService } from '@services/permissions.service';
import { firstValueFrom } from 'rxjs';
@ -30,14 +30,14 @@ export class AssignReviewerApproverDialogComponent {
readonly userService: UserService,
private readonly _toaster: Toaster,
private readonly _formBuilder: FormBuilder,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
private readonly _filesService: FilesService,
private readonly _loadingService: LoadingService,
readonly permissionsService: PermissionsService,
private readonly _dialogRef: MatDialogRef<AssignReviewerApproverDialogComponent, boolean>,
@Inject(MAT_DIALOG_DATA) readonly data: DialogData,
) {
this.dossier = this._dossiersService.find(this.data.files[0].dossierId);
this.dossier = this._activeDossiersService.find(this.data.files[0].dossierId);
this.form = this._getForm();
}

View File

@ -3,7 +3,7 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { PermissionsService } from '@services/permissions.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { JustificationsService } from '@services/entity-services/justifications.service';
import { Dossier } from '@red/domain';
import { BaseDialogComponent } from '@iqser/common-ui';
@ -24,7 +24,7 @@ export class ChangeLegalBasisDialogComponent extends BaseDialogComponent impleme
constructor(
private readonly _justificationsService: JustificationsService,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
private readonly _permissionsService: PermissionsService,
private readonly _formBuilder: FormBuilder,
protected readonly _injector: Injector,

View File

@ -4,7 +4,7 @@ import { LoadingService, Toaster } from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { firstValueFrom } from 'rxjs';
import { Dossier } from '@red/domain';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { ArchivedDossiersService } from '@services/entity-services/archived-dossiers.service';
@Component({
@ -17,7 +17,7 @@ export class ConfirmArchiveDossierDialogComponent {
constructor(
private readonly _loadingService: LoadingService,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
private readonly _archivedDossiersService: ArchivedDossiersService,
private readonly _toaster: Toaster,
@Inject(MAT_DIALOG_DATA) readonly dossier: Dossier,

View File

@ -3,7 +3,7 @@ import { FormBuilder, FormGroup } 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';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { FilesService } from '@services/entity-services/files.service';
import { BaseDialogComponent } from '@iqser/common-ui';
import { firstValueFrom } from 'rxjs';
@ -19,7 +19,7 @@ export class DocumentInfoDialogComponent extends BaseDialogComponent implements
private readonly _dossier: Dossier;
constructor(
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
private readonly _formBuilder: FormBuilder,
private readonly _fileAttributesService: FileAttributesService,
private readonly _filesService: FilesService,
@ -28,7 +28,7 @@ export class DocumentInfoDialogComponent extends BaseDialogComponent implements
@Inject(MAT_DIALOG_DATA) readonly data: File,
) {
super(_injector, _dialogRef);
this._dossier = this._dossiersService.find(this.data.dossierId);
this._dossier = this._activeDossiersService.find(this.data.dossierId);
}
async ngOnInit() {

View File

@ -5,7 +5,7 @@ import { PermissionsService } from '@services/permissions.service';
import { DictionaryManagerComponent } from '@shared/components/dictionary-manager/dictionary-manager.component';
import { DictionaryService } from '@shared/services/dictionary.service';
import { CircleButtonTypes, LoadingService, Toaster } from '@iqser/common-ui';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { FormBuilder, FormGroup } from '@angular/forms';
import { firstValueFrom } from 'rxjs';
@ -27,7 +27,7 @@ export class EditDossierDictionaryComponent implements EditDossierSectionInterfa
@ViewChild(DictionaryManagerComponent, { static: false }) private readonly _dictionaryManager: DictionaryManagerComponent;
constructor(
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
private readonly _dictionaryService: DictionaryService,
private readonly _permissionsService: PermissionsService,
private readonly _loadingService: LoadingService,

View File

@ -3,7 +3,7 @@ import { Dossier, DownloadFileType, IReportTemplate } from '@red/domain';
import { FormBuilder, FormGroup } from '@angular/forms';
import { EditDossierSaveResult, EditDossierSectionInterface } from '../edit-dossier-section.interface';
import { downloadTypesTranslations } from '../../../../../translations/download-types-translations';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { ReportTemplateService } from '@services/report-template.service';
import { PermissionsService } from '@services/permissions.service';
import { firstValueFrom } from 'rxjs';
@ -26,7 +26,7 @@ export class EditDossierDownloadPackageComponent implements OnInit, EditDossierS
@Input() dossier: Dossier;
constructor(
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
private readonly _reportTemplateController: ReportTemplateService,
private readonly _formBuilder: FormBuilder,
private readonly _permissionsService: PermissionsService,
@ -88,7 +88,7 @@ export class EditDossierDownloadPackageComponent implements OnInit, EditDossierS
reportTemplateIds: this.form.get('reportTemplateIds').value,
};
const updatedDossier = await firstValueFrom(this._dossiersService.createOrUpdate(dossier));
const updatedDossier = await firstValueFrom(this._activeDossiersService.createOrUpdate(dossier));
return { success: !!updatedDossier };
}

View File

@ -10,7 +10,7 @@ import { EditDossierAttributesComponent } from './attributes/edit-dossier-attrib
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { EditDossierDeletedDocumentsComponent } from './deleted-documents/edit-dossier-deleted-documents.component';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { EditDossierTeamComponent } from './edit-dossier-team/edit-dossier-team.component';
@ -40,7 +40,7 @@ export class EditDossierDialogComponent extends BaseDialogComponent implements A
constructor(
private readonly _toaster: Toaster,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
private readonly _changeRef: ChangeDetectorRef,
private readonly _loadingService: LoadingService,
private readonly _permissionsService: PermissionsService,
@ -85,16 +85,10 @@ export class EditDossierDialogComponent extends BaseDialogComponent implements A
},
];
this.dossier$ = this._dossiersService.getEntityChanged$(_data.dossierId).pipe(tap(dossier => (this._dossier = dossier)));
this.dossier$ = this._activeDossiersService.getEntityChanged$(_data.dossierId).pipe(tap(dossier => (this._dossier = dossier)));
this.activeNav = _data.section || 'dossierInfo';
}
ngAfterViewInit() {
if (!this._dossier.ownerId) {
this._toaster.error(_('edit-dossier-dialog.missing-owner'));
}
}
get activeNavItem(): { key: string; title?: string } {
return this.navItems.find(item => item.key === this.activeNav);
}
@ -137,6 +131,12 @@ export class EditDossierDialogComponent extends BaseDialogComponent implements A
return this.activeComponent?.disabled;
}
ngAfterViewInit() {
if (!this._dossier.ownerId) {
this._toaster.error(_('edit-dossier-dialog.missing-owner'));
}
}
async save(options?: SaveOptions) {
this._loadingService.start();
const result = await this.activeComponent.save();

View File

@ -1,7 +1,7 @@
import { ChangeDetectionStrategy, Component, Input, OnDestroy, OnInit } from '@angular/core';
import { UserService } from '@services/user.service';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { Dossier, IDossierRequest } from '@red/domain';
import { AutoUnsubscribe } from '@iqser/common-ui';
import { EditDossierSaveResult, EditDossierSectionInterface } from '../edit-dossier-section.interface';
@ -28,7 +28,7 @@ export class EditDossierTeamComponent extends AutoUnsubscribe implements EditDos
constructor(
readonly userService: UserService,
private readonly _formBuilder: FormBuilder,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
private readonly _permissionsService: PermissionsService,
) {
super();
@ -91,7 +91,7 @@ export class EditDossierTeamComponent extends AutoUnsubscribe implements EditDos
ownerId: this.selectedOwnerId,
} as IDossierRequest;
const updatedDossier = await firstValueFrom(this._dossiersService.createOrUpdate(dossier));
const updatedDossier = await firstValueFrom(this._activeDossiersService.createOrUpdate(dossier));
return { success: !!updatedDossier };
}

View File

@ -10,7 +10,7 @@ import { MatDialogRef } from '@angular/material/dialog';
import { EditDossierDialogComponent } from '../edit-dossier-dialog.component';
import { ConfirmationDialogInput, IconButtonTypes, TitleColors, Toaster } from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service';
import { DossierStatsService } from '@services/entity-services/dossier-stats.service';
import { firstValueFrom } from 'rxjs';
@ -38,7 +38,7 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
readonly permissionsService: PermissionsService,
private readonly _dossierStateService: DossierStateService,
private readonly _dossierTemplatesService: DossierTemplatesService,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
private readonly _dossierStatsService: DossierStatsService,
private readonly _formBuilder: FormBuilder,
private readonly _dialogService: DossiersDialogService,
@ -120,7 +120,7 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
dossierStatusId: this.form.get('dossierStatusId').value,
} as IDossierRequest;
const updatedDossier = await firstValueFrom(this._dossiersService.createOrUpdate(dossier));
const updatedDossier = await firstValueFrom(this._activeDossiersService.createOrUpdate(dossier));
return { success: !!updatedDossier };
}
@ -139,7 +139,7 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
},
});
this._dialogService.openDialog('confirm', null, data, async () => {
await firstValueFrom(this._dossiersService.delete(this.dossier));
await firstValueFrom(this._activeDossiersService.delete(this.dossier));
this._editDossierDialogRef.close();
this._router.navigate(['main', 'dossiers']).then(() => this.#notifyDossierDeleted());
});

View File

@ -6,7 +6,7 @@ import { TranslateService } from '@ngx-translate/core';
import { UserService } from '@services/user.service';
import { ManualAnnotationService } from '../../services/manual-annotation.service';
import { PermissionsService } from '@services/permissions.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { JustificationsService } from '@services/entity-services/justifications.service';
import { Dossier, ILegalBasisChangeRequest } from '@red/domain';
import { firstValueFrom } from 'rxjs';
@ -28,7 +28,7 @@ export class ForceAnnotationDialogComponent extends BaseDialogComponent implemen
legalOptions: LegalBasisOption[] = [];
constructor(
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
private readonly _userService: UserService,
private readonly _formBuilder: FormBuilder,
private readonly _notificationService: Toaster,

View File

@ -6,7 +6,7 @@ import { ManualAnnotationService } from '../../services/manual-annotation.servic
import { PermissionsService } from '@services/permissions.service';
import { JustificationsService } from '@services/entity-services/justifications.service';
import { Dictionary, Dossier, IAddRedactionRequest } from '@red/domain';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { DictionaryService } from '@shared/services/dictionary.service';
import { BaseDialogComponent } from '@iqser/common-ui';
import { firstValueFrom } from 'rxjs';
@ -36,14 +36,14 @@ export class ManualAnnotationDialogComponent extends BaseDialogComponent impleme
private readonly _justificationsService: JustificationsService,
private readonly _manualAnnotationService: ManualAnnotationService,
private readonly _permissionsService: PermissionsService,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
private readonly _dictionaryService: DictionaryService,
protected readonly _injector: Injector,
protected readonly _dialogRef: MatDialogRef<ManualAnnotationDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: { manualRedactionEntryWrapper: ManualRedactionEntryWrapper; dossierId: string },
) {
super(_injector, _dialogRef);
this._dossier = this._dossiersService.find(this.data.dossierId);
this._dossier = this._activeDossiersService.find(this.data.dossierId);
this.isDocumentAdmin = this._permissionsService.isApprover(this._dossier);
this.isFalsePositiveRequest = this.data.manualRedactionEntryWrapper.type === 'FALSE_POSITIVE';

View File

@ -6,7 +6,7 @@ import { FilterService, ProgressBarConfigModel, shareLast, Toaster } from '@iqse
import { workflowFileStatusTranslations } from '../../../../translations/file-status-translations';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { Dossier, DossierAttributeWithValue, DossierStats, IDossierRequest, StatusSorter, User } from '@red/domain';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { ActivatedRoute } from '@angular/router';
import { firstValueFrom, Observable } from 'rxjs';
import { DossierStatsService } from '@services/entity-services/dossier-stats.service';
@ -37,7 +37,7 @@ export class DossierDetailsComponent {
statusConfig$: Observable<ProgressBarConfigModel[]>;
constructor(
readonly dossiersService: DossiersService,
readonly activeDossiersService: ActiveDossiersService,
readonly translateChartService: TranslateChartService,
readonly filterService: FilterService,
private readonly _changeDetectorRef: ChangeDetectorRef,
@ -49,7 +49,7 @@ export class DossierDetailsComponent {
activatedRoute: ActivatedRoute,
) {
this.dossierId = activatedRoute.snapshot.paramMap.get(DOSSIER_ID);
this.dossier$ = this.dossiersService.getEntityChanged$(this.dossierId).pipe(shareLast());
this.dossier$ = this.activeDossiersService.getEntityChanged$(this.dossierId).pipe(shareLast());
this.dossierStats$ = this.dossier$.pipe(
pluck('dossierId'),
switchMap(dossierId => this._dossierStatsService.watch$(dossierId)),
@ -65,7 +65,7 @@ export class DossierDetailsComponent {
async assignOwner(user: User | string, dossier: Dossier) {
const owner = typeof user === 'string' ? this._userService.find(user) : user;
const dossierRequest: IDossierRequest = { ...dossier, ownerId: owner.id };
await firstValueFrom(this.dossiersService.createOrUpdate(dossierRequest));
await firstValueFrom(this.activeDossiersService.createOrUpdate(dossierRequest));
const ownerName = this._userService.getNameForId(owner.id);
const dossierName = dossier.dossierName;

View File

@ -1,6 +1,6 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { File } from '@red/domain';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { UserService } from '@services/user.service';
import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service';
@ -16,7 +16,7 @@ export class FileWorkloadComponent {
constructor(
readonly userService: UserService,
private readonly _dictionariesMapService: DictionariesMapService,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
) {}
get suggestionColor() {
@ -44,6 +44,9 @@ export class FileWorkloadComponent {
}
private _getDictionaryColor(type: string) {
return this._dictionariesMapService.getDictionaryColor(type, this._dossiersService.find(this.file.dossierId).dossierTemplateId);
return this._dictionariesMapService.getDictionaryColor(
type,
this._activeDossiersService.find(this.file.dossierId).dossierTemplateId,
);
}
}

View File

@ -38,7 +38,7 @@ import { PermissionsService } from '@services/permissions.service';
import { ActivatedRoute, Router } from '@angular/router';
import { FileAttributesService } from '@services/entity-services/file-attributes.service';
import { ConfigService } from '../config.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service';
import { LongPressEvent } from '@shared/directives/long-press.directive';
import { UserPreferenceService } from '@services/user-preference.service';
@ -78,7 +78,7 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
protected readonly _injector: Injector,
private readonly _router: Router,
private readonly _loadingService: LoadingService,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
private readonly _dossierTemplatesService: DossierTemplatesService,
private readonly _fileUploadService: FileUploadService,
private readonly _filesService: FilesService,
@ -95,10 +95,10 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
) {
super(_injector);
this.dossierId = activatedRoute.snapshot.paramMap.get(DOSSIER_ID);
this.dossier$ = this._dossiersService
this.dossier$ = this._activeDossiersService
.getEntityChanged$(this.dossierId)
.pipe(tap(dossier => (this.dossierTemplateId = dossier.dossierTemplateId)));
this.currentDossier = this._dossiersService.find(this.dossierId);
this.currentDossier = this._activeDossiersService.find(this.dossierId);
this._updateFileAttributes();
}
@ -133,7 +133,7 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
this._computeAllFilters();
});
this.addSubscription = this._dossiersService.dossierFileChanges$
this.addSubscription = this._activeDossiersService.dossierFileChanges$
.pipe(
filter(dossierId => dossierId === this.dossierId),
switchMap(dossierId => this._filesService.loadAll(dossierId)),
@ -176,7 +176,7 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
@HostListener('drop', ['$event'])
onDrop(event: DragEvent): void {
const currentDossier = this._dossiersService.find(this.dossierId);
const currentDossier = this._activeDossiersService.find(this.dossierId);
handleFileDrop(event, currentDossier, this._uploadFiles.bind(this));
}
@ -192,7 +192,7 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
}
private _setRemovableSubscriptions(): void {
this.addActiveScreenSubscription = this._dossiersService
this.addActiveScreenSubscription = this._activeDossiersService
.getEntityDeleted$(this.dossierId)
.pipe(tap(() => this._handleDeletedDossier()))
.subscribe();
@ -214,7 +214,7 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
}
private _loadEntitiesFromState() {
this.currentDossier = this._dossiersService.find(this.dossierId);
this.currentDossier = this._activeDossiersService.find(this.dossierId);
this._computeAllFilters();
}

View File

@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
import { Dossier, File } from '@red/domain';
import { DossiersDialogService } from '../../../services/dossiers-dialog.service';
import { ConfirmationDialogInput, LoadingService } from '@iqser/common-ui';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { FilesService } from '@services/entity-services/files.service';
import { FileAssignService } from '../../../shared/services/file-assign.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
@ -15,7 +15,7 @@ export class BulkActionsService {
constructor(
private readonly _dialogService: DossiersDialogService,
private readonly _loadingService: LoadingService,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
private readonly _filesService: FilesService,
private readonly _fileAssignService: FileAssignService,
private readonly _reanalysisService: ReanalysisService,
@ -152,7 +152,7 @@ export class BulkActionsService {
}
private _getDossier(files: File[]): Dossier {
return this._dossiersService.find(files[0].dossierId);
return this._activeDossiersService.find(files[0].dossierId);
}
private _assignFiles(files: File[], mode: 'reviewer' | 'approver', ignoreChanged = false, withUnassignedOption = false) {

View File

@ -1,6 +1,6 @@
import { ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/core';
import { DossierStats, StatusSorter } from '../../../../../../../../../../libs/red-domain/src';
import { List, StatusBarConfig } from '../../../../../../../../../../libs/common-ui/src';
import { List, StatusBarConfig } from '@iqser/common-ui';
@Component({
selector: 'redaction-dossier-documents-status',

View File

@ -8,7 +8,7 @@ import { LongPressEvent } from '@shared/directives/long-press.directive';
import { UserPreferenceService } from '@services/user-preference.service';
import { FilesMapService } from '@services/entity-services/files-map.service';
import { ReanalysisService } from '@services/reanalysis.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { firstValueFrom } from 'rxjs';
@Component({
@ -32,13 +32,17 @@ export class DossiersListingActionsComponent implements OnChanges {
constructor(
private readonly _reanalysisService: ReanalysisService,
private readonly _userService: UserService,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
readonly permissionsService: PermissionsService,
readonly filesMapService: FilesMapService,
private readonly _dialogService: DossiersDialogService,
private readonly _userPreferenceService: UserPreferenceService,
) {}
get scrollableParentView(): ScrollableParentView {
return ScrollableParentViews.VIRTUAL_SCROLL;
}
ngOnChanges() {
this.files = this.filesMapService.get(this.dossier.dossierId);
this.displayReanalyseBtn = this.permissionsService.displayReanalyseBtn(this.dossier) && this.analysisForced;
@ -56,8 +60,4 @@ export class DossiersListingActionsComponent implements OnChanges {
$event.stopPropagation();
await firstValueFrom(this._reanalysisService.reanalyzeDossier(id));
}
get scrollableParentView(): ScrollableParentView {
return ScrollableParentViews.VIRTUAL_SCROLL;
}
}

View File

@ -7,7 +7,7 @@
[subtitle]="'dossier-listing.stats.charts.dossiers' | translate: { count: config[0].value }"
></redaction-simple-doughnut-chart>
<div *ngIf="dossiersService.generalStats$ | async as stats" class="dossier-stats-container">
<div *ngIf="activeDossiersService.generalStats$ | async as stats" class="dossier-stats-container">
<div class="dossier-stats-item">
<mat-icon svgIcon="red:needs-work"></mat-icon>
<div>

View File

@ -1,7 +1,7 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { DoughnutChartConfig } from '@shared/components/simple-doughnut-chart/simple-doughnut-chart.component';
import { FilterService, mapEach } from '@iqser/common-ui';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { combineLatest, Observable } from 'rxjs';
import { DossierStats, FileCountPerWorkflowStatus, StatusSorter } from '@red/domain';
import { workflowFileStatusTranslations } from '../../../../translations/file-status-translations';
@ -23,25 +23,25 @@ export class DossiersListingDetailsComponent {
constructor(
readonly filterService: FilterService,
readonly dossiersService: DossiersService,
readonly activeDossiersService: ActiveDossiersService,
private readonly _dossierStatsMap: DossierStatsService,
private readonly _translateChartService: TranslateChartService,
private readonly _dossierStateService: DossierStateService,
private readonly _translateService: TranslateService,
) {
this.documentsChartData$ = this.dossiersService.all$.pipe(
this.documentsChartData$ = this.activeDossiersService.all$.pipe(
mapEach(dossier => _dossierStatsMap.watch$(dossier.dossierId)),
switchMap(stats$ => combineLatest(stats$)),
filter(stats => !stats.some(s => s === undefined)),
map(stats => this._toChartData(stats)),
);
this.dossiersChartData$ = this.dossiersService.all$.pipe(switchMap(dossiers => this._toDossierChartData()));
this.dossiersChartData$ = this.activeDossiersService.all$.pipe(switchMap(dossiers => this._toDossierChartData()));
}
private async _toDossierChartData(): Promise<DoughnutChartConfig[]> {
this._dossierStateService.all.forEach(
state => (state.dossierCount = this.dossiersService.getCountWithState(state.dossierStatusId)),
state => (state.dossierCount = this.activeDossiersService.getCountWithState(state.dossierStatusId)),
);
const configArray: DoughnutChartConfig[] = [
...this._dossierStateService.all
@ -54,7 +54,7 @@ export class DossiersListingDetailsComponent {
.values(),
];
const notAssignedLength = this.dossiersService.all.length - configArray.map(v => v.value).reduce((acc, val) => acc + val, 0);
const notAssignedLength = this.activeDossiersService.all.length - configArray.map(v => v.value).reduce((acc, val) => acc + val, 0);
configArray.push({
value: notAssignedLength,
label: this._translateService.instant('edit-dossier-dialog.general-info.form.dossier-status.placeholder'),

View File

@ -8,7 +8,7 @@ import { DossiersDialogService } from '../../../services/dossiers-dialog.service
import { DefaultListingServicesTmp, EntitiesService, ListingComponent, OnAttach, TableComponent } from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { ConfigService } from '../config.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { FilesService } from '@services/entity-services/files.service';
import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service';
import { tap } from 'rxjs/operators';
@ -18,7 +18,7 @@ import { tap } from 'rxjs/operators';
styleUrls: ['./dossiers-listing-screen.component.scss'],
providers: [
...DefaultListingServicesTmp,
{ provide: EntitiesService, useExisting: DossiersService },
{ provide: EntitiesService, useExisting: ActiveDossiersService },
{ provide: ListingComponent, useExisting: forwardRef(() => DossiersListingScreenComponent) },
],
changeDetection: ChangeDetectionStrategy.OnPush,
@ -40,7 +40,7 @@ export class DossiersListingScreenComponent extends ListingComponent<Dossier> im
protected readonly _injector: Injector,
private readonly _userService: UserService,
readonly permissionsService: PermissionsService,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
private readonly _dialogService: DossiersDialogService,
private readonly _translateChartService: TranslateChartService,
private readonly _configService: ConfigService,
@ -55,7 +55,7 @@ export class DossiersListingScreenComponent extends ListingComponent<Dossier> im
}
ngOnInit(): void {
this.addSubscription = this._dossiersService.all$.pipe(tap(() => this._computeAllFilters())).subscribe();
this.addSubscription = this._activeDossiersService.all$.pipe(tap(() => this._computeAllFilters())).subscribe();
}
ngOnAttach(): void {

View File

@ -8,7 +8,7 @@ import { UserService } from '@services/user.service';
import { AnnotationReferencesService } from '../../services/annotation-references.service';
import { MultiSelectService } from '../../services/multi-select.service';
import { FilePreviewStateService } from '../../services/file-preview-state.service';
import { HelpModeService, ScrollableParentView, ScrollableParentViews } from '../../../../../../../../../../libs/common-ui/src';
import { HelpModeService, ScrollableParentView, ScrollableParentViews } from '@iqser/common-ui';
export const AnnotationButtonTypes = {
dark: 'dark',
@ -72,6 +72,10 @@ export class AnnotationActionsComponent implements OnChanges {
return this.annotations?.length === 1 && this.annotations?.[0].resizing;
}
get scrollableParentView(): ScrollableParentView {
return ScrollableParentViews.ANNOTATIONS_LIST;
}
async ngOnChanges(): Promise<void> {
await this._setPermissions();
}
@ -115,10 +119,6 @@ export class AnnotationActionsComponent implements OnChanges {
this.annotationActionsService.cancelResize($event, this.viewer, this.annotations[0], this.annotationsChanged);
}
get scrollableParentView(): ScrollableParentView {
return ScrollableParentViews.ANNOTATIONS_LIST;
}
private async _setPermissions() {
const dossier = await this._state.dossier;
this.annotationPermissions = AnnotationPermissions.forUser(

View File

@ -3,7 +3,7 @@ import { DossiersDialogService } from '../../../../services/dossiers-dialog.serv
import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service';
import { DocumentInfoService } from '../../services/document-info.service';
import { combineLatest, Observable, switchMap } from 'rxjs';
import { PermissionsService } from '../../../../../../services/permissions.service';
import { PermissionsService } from '@services/permissions.service';
import { FilePreviewStateService } from '../../services/file-preview-state.service';
import { map } from 'rxjs/operators';
import { File } from '@red/domain';

View File

@ -11,7 +11,7 @@ import { TranslateService } from '@ngx-translate/core';
import { BehaviorSubject, combineLatest, firstValueFrom, Observable, switchMap } from 'rxjs';
import { FilePreviewStateService } from '../../services/file-preview-state.service';
import { distinctUntilChanged, map } from 'rxjs/operators';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
@Component({
selector: 'redaction-user-management',
@ -42,9 +42,9 @@ export class UserManagementComponent {
readonly loadingService: LoadingService,
readonly translateService: TranslateService,
readonly stateService: FilePreviewStateService,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
) {
this._dossier$ = this.stateService.file$.pipe(switchMap(file => this._dossiersService.getEntityChanged$(file.dossierId)));
this._dossier$ = this.stateService.file$.pipe(switchMap(file => this._activeDossiersService.getEntityChanged$(file.dossierId)));
this.statusBarConfig$ = this.stateService.file$.pipe(map(file => [{ length: 1, color: file.workflowStatus }]));
this.assignTooltip$ = this.stateService.file$.pipe(
map(file =>

View File

@ -3,7 +3,7 @@ import { FormBuilder, FormGroup, 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';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { BaseDialogComponent } from '@iqser/common-ui';
import { DictionaryService } from '@shared/services/dictionary.service';
import { ManualAnnotationService } from '../../../../services/manual-annotation.service';
@ -33,14 +33,14 @@ export class AcceptRecommendationDialogComponent extends BaseDialogComponent imp
private readonly _formBuilder: FormBuilder,
private readonly _manualAnnotationService: ManualAnnotationService,
private readonly _permissionsService: PermissionsService,
private readonly _dossiersService: DossiersService,
private readonly _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._dossiersService.find(this.data.dossierId);
this._dossier = this._activeDossiersService.find(this.data.dossierId);
this.isDocumentAdmin = this._permissionsService.isApprover(this._dossier);
this.form = this._getForm();
this.initialFormValue = this.form.getRawValue();

View File

@ -9,7 +9,7 @@ import { AnnotationActionsService } from './services/annotation-actions.service'
import { FilePreviewStateService } from './services/file-preview-state.service';
import { PdfViewerDataService } from '../../services/pdf-viewer-data.service';
import { AnnotationReferencesService } from './services/annotation-references.service';
import { FilterService } from '../../../../../../../../libs/common-ui/src';
import { FilterService } from '@iqser/common-ui';
export const filePreviewScreenProviders = [
FilterService,

View File

@ -34,7 +34,7 @@ import { clearStamps, stampPDFPage } from '@utils/page-stamper';
import { TranslateService } from '@ngx-translate/core';
import { handleFilterDelta } from '@utils/filter-utils';
import { FilesService } from '@services/entity-services/files.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { FileManagementService } from '@services/entity-services/file-management.service';
import { catchError, map, switchMap, tap } from 'rxjs/operators';
import { FilesMapService } from '@services/entity-services/files-map.service';
@ -104,7 +104,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
private readonly _filterService: FilterService,
private readonly _translateService: TranslateService,
private readonly _filesMapService: FilesMapService,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
private readonly _reanalysisService: ReanalysisService,
private readonly _errorService: ErrorService,
private readonly _skippedService: SkippedService,
@ -200,7 +200,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
async ngOnAttach(previousRoute: ActivatedRouteSnapshot): Promise<boolean> {
const file = await this.stateService.file;
if (!file.canBeOpened) {
return this._router.navigate([this._dossiersService.find(this.dossierId)?.routerLink]);
return this._router.navigate([this._activeDossiersService.find(this.dossierId)?.routerLink]);
}
this.viewModeService.compareMode = false;
this.viewModeService.switchToStandard();
@ -487,7 +487,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
await clearStamps(pdfDoc, pdfNet, allPages);
if (this.viewModeService.isRedacted) {
const dossier = this._dossiersService.find(this.dossierId);
const dossier = this._activeDossiersService.find(this.dossierId);
if (dossier.watermarkPreviewEnabled) {
await this._stampPreview(pdfDoc, dossier.dossierTemplateId);
}
@ -541,7 +541,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
.pipe(switchMap(() => this._filesService.reload(this.dossierId, this.fileId)))
.subscribe();
this.addActiveScreenSubscription = this._dossiersService
this.addActiveScreenSubscription = this._activeDossiersService
.getEntityDeleted$(this.dossierId)
.pipe(tap(() => this._handleDeletedDossier()))
.subscribe();
@ -570,7 +570,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
private async _loadFileData(file: File): Promise<void | boolean> {
if (!file || file.isError) {
return this._router.navigate([this._dossiersService.find(this.dossierId).routerLink]);
return this._router.navigate([this._activeDossiersService.find(this.dossierId).routerLink]);
}
if (file.isUnprocessed) {

View File

@ -14,7 +14,7 @@ import { Dossier, IAddRedactionRequest, ILegalBasisChangeRequest, IRectangle, IR
import { toPosition } from '../../../utils/pdf-calculation.utils';
import { AnnotationDrawService } from './annotation-draw.service';
import { translateQuads } from '@utils/pdf-coordinates';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import {
AcceptRecommendationData,
AcceptRecommendationDialogComponent,
@ -38,12 +38,12 @@ export class AnnotationActionsService {
private readonly _dialogService: DossiersDialogService,
private readonly _dialog: MatDialog,
private readonly _annotationDrawService: AnnotationDrawService,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
private readonly _screenStateService: FilePreviewStateService,
) {}
private get _dossier(): Dossier {
return this._dossiersService.find(this._screenStateService.dossierId);
return this._activeDossiersService.find(this._screenStateService.dossierId);
}
acceptSuggestion($event: MouseEvent, annotations: AnnotationWrapper[], annotationsChanged: EventEmitter<AnnotationWrapper>) {

View File

@ -3,7 +3,7 @@ import { Core, WebViewerInstance } from '@pdftron/webviewer';
import { hexToRgb } from '@utils/functions';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { UserPreferenceService } from '@services/user-preference.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { RedactionLogService } from '../../../services/redaction-log.service';
import { environment } from '@environments/environment';
@ -21,7 +21,7 @@ export class AnnotationDrawService {
constructor(
private readonly _dictionariesMapService: DictionariesMapService,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
private readonly _redactionLogService: RedactionLogService,
private readonly _userPreferenceService: UserPreferenceService,
private readonly _skippedService: SkippedService,
@ -128,7 +128,7 @@ export class AnnotationDrawService {
}
private _computeSection(activeViewer: WebViewerInstance, pageNumber: number, sectionRectangle: ISectionRectangle, dossierId: string) {
const dossierTemplateId = this._dossiersService.find(dossierId).dossierTemplateId;
const dossierTemplateId = this._activeDossiersService.find(dossierId).dossierTemplateId;
const rectangleAnnot = new activeViewer.Core.Annotations.RectangleAnnotation();
const pageHeight = activeViewer.Core.documentViewer.getPageHeight(pageNumber);
const rectangle: IRectangle = {
@ -156,7 +156,7 @@ export class AnnotationDrawService {
compareMode: boolean,
) {
const pageNumber = compareMode ? annotationWrapper.pageNumber * 2 - 1 : annotationWrapper.pageNumber;
const dossierTemplateId = this._dossiersService.find(dossierId).dossierTemplateId;
const dossierTemplateId = this._activeDossiersService.find(dossierId).dossierTemplateId;
let annotation: Core.Annotations.RectangleAnnotation | Core.Annotations.TextHighlightAnnotation;
if (annotationWrapper.rectangle || annotationWrapper.isImage) {

View File

@ -2,10 +2,10 @@ import { Injectable } from '@angular/core';
import { BehaviorSubject, firstValueFrom, Observable, pairwise, switchMap } from 'rxjs';
import { FileDataModel } from '@models/file/file-data.model';
import { Dossier, File } from '@red/domain';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { ActivatedRoute } from '@angular/router';
import { FilesMapService } from '@services/entity-services/files-map.service';
import { PermissionsService } from '../../../../../services/permissions.service';
import { PermissionsService } from '@services/permissions.service';
import { boolFactory, shareLast } from '@iqser/common-ui';
import { filter, startWith } from 'rxjs/operators';
import { FileManagementService } from '@services/entity-services/file-management.service';
@ -27,7 +27,7 @@ export class FilePreviewStateService {
readonly #fileData$ = new BehaviorSubject<FileDataModel | undefined>(undefined);
constructor(
dossiersService: DossiersService,
activeDossiersService: ActiveDossiersService,
filesMapService: FilesMapService,
permissionsService: PermissionsService,
activatedRoute: ActivatedRoute,
@ -35,9 +35,9 @@ export class FilePreviewStateService {
) {
this.fileId = activatedRoute.snapshot.paramMap.get(FILE_ID);
this.dossierId = activatedRoute.snapshot.paramMap.get(DOSSIER_ID);
this.dossierTemplateId = dossiersService.find(this.dossierId).dossierTemplateId;
this.dossierTemplateId = activeDossiersService.find(this.dossierId).dossierTemplateId;
this.dossier$ = dossiersService.getEntityChanged$(this.dossierId);
this.dossier$ = activeDossiersService.getEntityChanged$(this.dossierId);
this.file$ = filesMapService.watch$(this.dossierId, this.fileId);
[this.isReadonly$, this.isWritable$] = boolFactory(this.file$, file => !permissionsService.canPerformAnnotationActions(file));

View File

@ -17,7 +17,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { workflowFileStatusTranslations } from '../../translations/file-status-translations';
import { TranslateService } from '@ngx-translate/core';
import { RouterHistoryService } from '@services/router-history.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { Dossier, IMatchedDocument, ISearchListItem, ISearchResponse } from '@red/domain';
import { FilesMapService } from '@services/entity-services/files-map.service';
import { PlatformSearchService } from '@services/entity-services/platform-search.service';
@ -56,7 +56,7 @@ export class SearchScreenComponent extends ListingComponent<ISearchListItem> imp
protected readonly _injector: Injector,
private readonly _activatedRoute: ActivatedRoute,
private readonly _loadingService: LoadingService,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
readonly routerHistoryService: RouterHistoryService,
private readonly _translateService: TranslateService,
private readonly _filesMapService: FilesMapService,
@ -76,7 +76,7 @@ export class SearchScreenComponent extends ListingComponent<ISearchListItem> imp
label: this._translateService.instant('search-screen.filters.by-dossier'),
filterceptionPlaceholder: this._translateService.instant('search-screen.filters.search-placeholder'),
icon: 'red:folder',
filters: this._dossiersService.all.map(dossierToFilter),
filters: this._activeDossiersService.all.map(dossierToFilter),
checker: keyChecker('dossierId'),
};
this.filterService.addFilterGroups([dossierNameFilter]);
@ -137,7 +137,7 @@ export class SearchScreenComponent extends ListingComponent<ISearchListItem> imp
status: file.workflowStatus,
assignee: file.assignee,
numberOfPages: file.numberOfPages,
dossierName: this._dossiersService.find(dossierId).dossierName,
dossierName: this._activeDossiersService.find(dossierId).dossierName,
filename: file.filename,
searchKey: score.toString(),
routerLink: `/main/dossiers/${dossierId}/file/${fileId}`,

View File

@ -17,7 +17,7 @@ import { AnnotationActionMode } from '../models/annotation-action-mode.model';
import { annotationActionsTranslations } from '../translations/annotation-actions-translations';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { HttpErrorResponse, HttpStatusCode } from '@angular/common/http';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { Observable } from 'rxjs';
import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service';
@ -31,7 +31,7 @@ export class ManualAnnotationService extends GenericService<IManualAddResponse>
private readonly _dictionariesMapService: DictionariesMapService,
private readonly _toaster: Toaster,
private readonly _permissionsService: PermissionsService,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
protected readonly _injector: Injector,
) {
super(_injector, 'manualRedaction');
@ -371,7 +371,7 @@ export class ManualAnnotationService extends GenericService<IManualAddResponse>
}
private _dossier(dossierId: string): Dossier {
return this._dossiersService.find(dossierId);
return this._activeDossiersService.find(dossierId);
}
private _getMessage(mode: AnnotationActionMode, modifyDictionary?: boolean, error = false, isConflict = false) {

View File

@ -28,7 +28,7 @@ import { UserService } from '@services/user.service';
import { UserPreferenceService } from '@services/user-preference.service';
import { LongPressEvent } from '@shared/directives/long-press.directive';
import { FileAssignService } from '../../services/file-assign.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { FileManagementService } from '@services/entity-services/file-management.service';
import { FilesService } from '@services/entity-services/files.service';
import { ReanalysisService, ReanalyzeQueryParams } from '@services/reanalysis.service';
@ -93,7 +93,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
@Optional() private readonly _excludedPagesService: ExcludedPagesService,
@Optional() private readonly _documentInfoService: DocumentInfoService,
private readonly _permissionsService: PermissionsService,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
private readonly _dialogService: DossiersDialogService,
private readonly _fileAssignService: FileAssignService,
private readonly _loadingService: LoadingService,
@ -255,7 +255,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
}
ngOnInit() {
this.addSubscription = this._dossiersService
this.addSubscription = this._activeDossiersService
.getEntityChanged$(this.file.dossierId)
.pipe(tap(() => this._setup()))
.subscribe();
@ -285,11 +285,6 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
);
}
private _triggerImportRedactions($event: MouseEvent) {
$event.stopPropagation();
this.importRedactionsInput.nativeElement.click();
}
async importRedactions(files: FileList) {
const fileToImport = files[0];
@ -311,6 +306,11 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
this._setup();
}
private _triggerImportRedactions($event: MouseEvent) {
$event.stopPropagation();
this.importRedactionsInput.nativeElement.click();
}
private _openDeleteFileDialog($event: MouseEvent) {
this._dialogService.openDialog(
'confirm',
@ -322,7 +322,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
async () => {
this._loadingService.start();
try {
const dossier = this._dossiersService.find(this.file.dossierId);
const dossier = this._activeDossiersService.find(this.file.dossierId);
await firstValueFrom(this._fileManagementService.delete([this.file.fileId], this.file.dossierId));
await this._router.navigate([dossier.routerLink]);
} catch (error) {

View File

@ -5,7 +5,7 @@ import { DossiersDialogService } from '../../services/dossiers-dialog.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { FilesService } from '@services/entity-services/files.service';
import { ConfirmationDialogInput, LoadingService, Toaster } from '@iqser/common-ui';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { firstValueFrom, Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
@ -15,7 +15,7 @@ export class FileAssignService {
private readonly _dialogService: DossiersDialogService,
private readonly _userService: UserService,
private readonly _filesService: FilesService,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
private readonly _loadingService: LoadingService,
private readonly _toaster: Toaster,
) {}
@ -53,7 +53,7 @@ export class FileAssignService {
$event?.stopPropagation();
const currentUserId = this._userService.currentUser.id;
const currentDossier = this._dossiersService.find(file.dossierId);
const currentDossier = this._activeDossiersService.find(file.dossierId);
const eligibleUsersIds = this._getUserIds(mode, currentDossier);
if (file.isNew) {

View File

@ -51,7 +51,7 @@
</div>
</ng-container>
<div *ngIf="!filterByDossierTemplate && dossiersService.all$ | async as dossiers" class="iqser-input-group w-200 mt-0">
<div *ngIf="!filterByDossierTemplate && activeDossiersService.all$ | async as dossiers" class="iqser-input-group w-200 mt-0">
<mat-select [(ngModel)]="dossier" [disabled]="!compare">
<mat-option [value]="selectDossier">{{ selectDossier.dossierName | translate }}</mat-option>
<mat-option *ngFor="let dossier of dossiers" [value]="dossier">

View File

@ -5,7 +5,7 @@ import { catchError, map, take, tap } from 'rxjs/operators';
import { Dictionary, Dossier, DossierTemplate } from '@red/domain';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { DictionaryService } from '@shared/services/dictionary.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service';
import { EditorComponent } from '@shared/components/editor/editor.component';
import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service';
@ -47,7 +47,7 @@ export class DictionaryManagerComponent implements OnChanges {
constructor(
private readonly _dictionaryService: DictionaryService,
private readonly _dictionariesMapService: DictionariesMapService,
readonly dossiersService: DossiersService,
readonly activeDossiersService: ActiveDossiersService,
readonly dossierTemplatesService: DossierTemplatesService,
) {}

View File

@ -1,7 +1,7 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { Dossier, DossierStats } from '@red/domain';
import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import * as moment from 'moment';
const DUE_DATE_WARN_DAYS = 14;
@ -16,7 +16,10 @@ export class DossiersListingDossierNameComponent {
@Input() dossier: Dossier;
@Input() dossierStats: DossierStats;
constructor(private readonly _dossierTemplatesService: DossierTemplatesService, private readonly _dossiersService: DossiersService) {}
constructor(
private readonly _dossierTemplatesService: DossierTemplatesService,
private readonly _activeDossiersService: ActiveDossiersService,
) {}
get approachingDueDate(): boolean {
return this._dueDateDaysDiff >= 0 && this._dueDateDaysDiff <= DUE_DATE_WARN_DAYS;

View File

@ -2,7 +2,7 @@ import { ChangeDetectorRef, Component, HostListener, Inject } from '@angular/cor
import { FileUploadService } from '../services/file-upload.service';
import { OverlayRef } from '@angular/cdk/overlay';
import { StatusOverlayService } from '../services/status-overlay.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
import { handleFileDrop } from '@utils/file-drop-utils';
import { FileUploadModel } from '@upload-download/model/file-upload.model';
import { DOSSIER_ID } from '../../../tokens';
@ -15,7 +15,7 @@ export class FileDropComponent {
constructor(
private readonly _dialogRef: OverlayRef,
private readonly _fileUploadService: FileUploadService,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
private readonly _changeDetectorRef: ChangeDetectorRef,
private readonly _statusOverlayService: StatusOverlayService,
@Inject(DOSSIER_ID) private readonly _dossierId: string,
@ -34,7 +34,7 @@ export class FileDropComponent {
@HostListener('drop', ['$event'])
onDrop(event: DragEvent) {
const dossier = this._dossiersService.find(this._dossierId);
const dossier = this._activeDossiersService.find(this._dossierId);
handleFileDrop(event, dossier, this.uploadFiles.bind(this));
}

View File

@ -4,7 +4,7 @@ import { ActivatedRouteSnapshot, IsActiveMatchOptions, NavigationEnd, Router } f
import { BehaviorSubject, Observable, of } from 'rxjs';
import { filter, pluck } from 'rxjs/operators';
import { FilesMapService } from '@services/entity-services/files-map.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from './entity-services/active-dossiers.service';
import { TranslateService } from '@ngx-translate/core';
import { BreadcrumbTypes } from '@red/domain';
import { DOSSIER_ID, FILE_ID } from '@utils/constants';
@ -37,7 +37,7 @@ export class BreadcrumbsService {
private readonly _router: Router,
private readonly _translateService: TranslateService,
private readonly _filesMapService: FilesMapService,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
) {
this.breadcrumbs$ = this._store$.asObservable();
@ -137,7 +137,7 @@ export class BreadcrumbsService {
private _addDossierBreadcrumb(route: ActivatedRouteSnapshot): void {
const dossierId = route.paramMap.get(DOSSIER_ID);
this._append({
name$: this._dossiersService.getEntityChanged$(dossierId).pipe(pluck('dossierName')),
name$: this._activeDossiersService.getEntityChanged$(dossierId).pipe(pluck('dossierName')),
type: 'text' as BreadcrumbDisplayType,
options: {
routerLink: ['/main', 'dossiers', dossierId],

View File

@ -0,0 +1,133 @@
import { Injectable, Injector } from '@angular/core';
import { List, QueryParam, RequiredParam, Toaster, Validate } from '@iqser/common-ui';
import { Dossier, DossierStats, IDossier, IDossierRequest } from '@red/domain';
import { catchError, filter, map, mapTo, pluck, switchMap, tap } from 'rxjs/operators';
import { firstValueFrom, forkJoin, Observable, of, Subject, throwError, timer } from 'rxjs';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { HttpErrorResponse, HttpStatusCode } from '@angular/common/http';
import { CHANGED_CHECK_INTERVAL } from '@utils/constants';
import { DossiersService } from '@services/entity-services/dossiers.service';
export interface IDossiersStats {
totalPeople: number;
totalAnalyzedPages: number;
}
interface DossierChange {
readonly dossierChanges: boolean;
readonly dossierId: string;
readonly fileChanges: boolean;
}
type DossierChanges = readonly DossierChange[];
interface ChangesDetails {
readonly dossierChanges: DossierChanges;
}
const DOSSIER_EXISTS_MSG = _('add-dossier-dialog.errors.dossier-already-exists');
const GENERIC_MSG = _('add-dossier-dialog.errors.generic');
@Injectable({
providedIn: 'root',
})
export class ActiveDossiersService extends DossiersService {
readonly dossierFileChanges$ = new Subject<string>();
constructor(private readonly _toaster: Toaster, protected readonly _injector: Injector) {
super(_injector, 'dossier');
timer(CHANGED_CHECK_INTERVAL, CHANGED_CHECK_INTERVAL)
.pipe(
switchMap(() => this.loadOnlyChanged()),
tap(changes => this.#emitFileChanges(changes)),
)
.subscribe();
}
loadOnlyChanged(): Observable<DossierChanges> {
const removeIfNotFound = (id: string) =>
catchError((error: HttpErrorResponse) => {
if (error.status === HttpStatusCode.NotFound) {
this.remove(id);
return of([]);
}
return throwError(() => error);
});
const load = (changes: DossierChanges) =>
changes.map(change => this._load(change.dossierId).pipe(removeIfNotFound(change.dossierId)));
return this.hasChangesDetails$().pipe(
pluck('dossierChanges'),
switchMap(dossierChanges => forkJoin(load(dossierChanges)).pipe(mapTo(dossierChanges))),
tap(() => this._updateLastChanged()),
);
}
hasChangesDetails$(): Observable<ChangesDetails> {
const body = { value: this._lastCheckedForChanges.get('root') ?? '0' };
return this._post<ChangesDetails>(body, `${this._defaultModelPath}/changes/details`).pipe(
filter(changes => changes.dossierChanges.length > 0),
);
}
@Validate()
createOrUpdate(@RequiredParam() dossier: IDossierRequest): Observable<Dossier | undefined> {
const showToast = (error: HttpErrorResponse) => {
this._toaster.error(error.status === HttpStatusCode.Conflict ? DOSSIER_EXISTS_MSG : GENERIC_MSG);
return of(undefined);
};
return this._post(dossier).pipe(
switchMap(newDossier => this.loadAll().pipe(map(() => this.find(newDossier.dossierId)))),
catchError(showToast),
);
}
getDeleted(): Promise<IDossier[]> {
return firstValueFrom(this.getAll('deleted-dossiers'));
}
delete(dossier: Dossier): Observable<unknown> {
const showToast = () => {
this._toaster.error(_('dossier-listing.delete.delete-failed'), { params: dossier });
return of({});
};
return super.delete(dossier.dossierId).pipe(
tap(() => this.#removeDossiers([dossier])),
catchError(showToast),
);
}
@Validate()
restore(@RequiredParam() dossierIds: List): Promise<unknown> {
return firstValueFrom(this._post(dossierIds, 'deleted-dossiers/restore').pipe(switchMap(() => this.loadAll())));
}
@Validate()
hardDelete(@RequiredParam() dossierIds: List): Promise<unknown> {
const body = dossierIds.map<QueryParam>(id => ({ key: 'dossierId', value: id }));
return firstValueFrom(super.delete(body, 'deleted-dossiers/hard-delete', body));
}
getCountWithState(dossierStatusId: string): number {
return this.all.filter(dossier => dossier.dossierStatusId === dossierStatusId).length;
}
#removeDossiers(dossiers: Dossier[]): void {
this.setEntities(this.all.filter(dossier => !dossiers.find(d => dossier.id === d.id)));
}
private _load(id: string, queryParams?: List<QueryParam>): Observable<DossierStats[]> {
return super._getOne([id], this._defaultModelPath, queryParams).pipe(
map(entity => new Dossier(entity)),
tap(dossier => this.replace(dossier)),
switchMap(dossier => this._dossierStatsService.getFor([dossier.dossierId])),
);
}
#emitFileChanges(dossierChanges: DossierChanges): void {
dossierChanges.filter(change => change.fileChanges).forEach(change => this.dossierFileChanges$.next(change.dossierId));
}
}

View File

@ -1,36 +1,20 @@
import { Injectable, Injector } from '@angular/core';
import { EntitiesService, mapEach, Toaster } from '@iqser/common-ui';
import { Dossier, IDossier } from '@red/domain';
import { catchError, mapTo, switchMap, tap } from 'rxjs/operators';
import { Toaster } from '@iqser/common-ui';
import { Dossier } from '@red/domain';
import { catchError, tap } from 'rxjs/operators';
import { Observable, of } from 'rxjs';
import { DossierStateService } from '@services/entity-services/dossier-state.service';
import { DossierStatsService } from '@services/entity-services/dossier-stats.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { ActiveDossiersService } from './active-dossiers.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
@Injectable({
providedIn: 'root',
})
export class ArchivedDossiersService extends EntitiesService<Dossier, IDossier> {
@Injectable({ providedIn: 'root' })
export class ArchivedDossiersService extends DossiersService {
constructor(
protected readonly _injector: Injector,
private readonly _toaster: Toaster,
private readonly _dossierStateService: DossierStateService,
private readonly _dossierStatsService: DossierStatsService,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
) {
super(_injector, Dossier, 'archived-dossiers');
}
loadAll(): Observable<Dossier[]> {
const dossierIds = (dossiers: Dossier[]) => dossiers.map(d => d.id);
return this.getAll().pipe(
mapEach(entity => new Dossier(entity)),
/* Load stats before updating entities */
switchMap(dossiers => this._dossierStatsService.getFor(dossierIds(dossiers)).pipe(mapTo(dossiers))),
switchMap(dossiers => this._dossierStateService.loadAllForAllTemplates().pipe(mapTo(dossiers))),
tap(dossiers => this.setEntities(dossiers)),
);
super(_injector, 'archived-dossiers');
}
archive(dossiers: Dossier[]): Observable<unknown> {
@ -48,6 +32,8 @@ export class ArchivedDossiersService extends EntitiesService<Dossier, IDossier>
}
#removeDossiers(dossiers: Dossier[]): void {
this._dossiersService.setEntities(this._dossiersService.all.filter(dossier => !dossiers.find(d => dossier.id === d.id)));
this._activeDossiersService.setEntities(
this._activeDossiersService.all.filter(dossier => !dossiers.find(d => dossier.id === d.id)),
);
}
}

View File

@ -1,55 +1,19 @@
import { Injectable, Injector } from '@angular/core';
import { EntitiesService, List, mapEach, QueryParam, RequiredParam, shareLast, Toaster, Validate } from '@iqser/common-ui';
import { Dossier, DossierStats, IDossier, IDossierRequest } from '@red/domain';
import { catchError, filter, map, mapTo, pluck, switchMap, tap } from 'rxjs/operators';
import { combineLatest, firstValueFrom, forkJoin, Observable, of, Subject, throwError, timer } from 'rxjs';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { HttpErrorResponse, HttpStatusCode } from '@angular/common/http';
import { DossierStatsService } from '@services/entity-services/dossier-stats.service';
import { CHANGED_CHECK_INTERVAL } from '@utils/constants';
import { DossierStateService } from '@services/entity-services/dossier-state.service';
import { EntitiesService, List, mapEach, shareLast } from '@iqser/common-ui';
import { Dossier, IDossier } from '@red/domain';
import { combineLatest, Observable } from 'rxjs';
import { filter, map, mapTo, switchMap, tap } from 'rxjs/operators';
import { Injector } from '@angular/core';
import { DossierStateService } from './dossier-state.service';
import { DossierStatsService } from './dossier-stats.service';
import { IDossiersStats } from '@services/entity-services/active-dossiers.service';
export interface IDossiersStats {
totalPeople: number;
totalAnalyzedPages: number;
}
interface DossierChange {
readonly dossierChanges: boolean;
readonly dossierId: string;
readonly fileChanges: boolean;
}
type DossierChanges = readonly DossierChange[];
interface ChangesDetails {
readonly dossierChanges: DossierChanges;
}
const DOSSIER_EXISTS_MSG = _('add-dossier-dialog.errors.dossier-already-exists');
const GENERIC_MSG = _('add-dossier-dialog.errors.generic');
@Injectable({
providedIn: 'root',
})
export class DossiersService extends EntitiesService<Dossier, IDossier> {
export abstract class DossiersService extends EntitiesService<Dossier, IDossier> {
readonly generalStats$ = this.all$.pipe(switchMap(entities => this.#generalStats$(entities)));
readonly dossierFileChanges$ = new Subject<string>();
protected readonly _dossierStatsService = this._injector.get(DossierStatsService);
protected readonly _dossierStateService = this._injector.get(DossierStateService);
constructor(
private readonly _toaster: Toaster,
protected readonly _injector: Injector,
private readonly _dossierStatsService: DossierStatsService,
private readonly _dossierStateService: DossierStateService,
) {
super(_injector, Dossier, 'dossier');
timer(CHANGED_CHECK_INTERVAL, CHANGED_CHECK_INTERVAL)
.pipe(
switchMap(() => this.loadOnlyChanged()),
tap(changes => this.#emitFileChanges(changes)),
)
.subscribe();
protected constructor(protected readonly _injector: Injector, protected readonly _path: string) {
super(_injector, Dossier, _path);
}
loadAll(): Observable<Dossier[]> {
@ -63,92 +27,6 @@ export class DossiersService extends EntitiesService<Dossier, IDossier> {
);
}
loadOnlyChanged(): Observable<DossierChanges> {
const removeIfNotFound = (id: string) =>
catchError((error: HttpErrorResponse) => {
if (error.status === HttpStatusCode.NotFound) {
this.remove(id);
return of([]);
}
return throwError(() => error);
});
const load = (changes: DossierChanges) =>
changes.map(change => this._load(change.dossierId).pipe(removeIfNotFound(change.dossierId)));
return this.hasChangesDetails$().pipe(
pluck('dossierChanges'),
switchMap(dossierChanges => forkJoin(load(dossierChanges)).pipe(mapTo(dossierChanges))),
tap(() => this._updateLastChanged()),
);
}
hasChangesDetails$(): Observable<ChangesDetails> {
const body = { value: this._lastCheckedForChanges.get('root') ?? '0' };
return this._post<ChangesDetails>(body, `${this._defaultModelPath}/changes/details`).pipe(
filter(changes => changes.dossierChanges.length > 0),
);
}
@Validate()
createOrUpdate(@RequiredParam() dossier: IDossierRequest): Observable<Dossier | undefined> {
const showToast = (error: HttpErrorResponse) => {
this._toaster.error(error.status === HttpStatusCode.Conflict ? DOSSIER_EXISTS_MSG : GENERIC_MSG);
return of(undefined);
};
return this._post(dossier).pipe(
switchMap(newDossier => this.loadAll().pipe(map(() => this.find(newDossier.dossierId)))),
catchError(showToast),
);
}
getDeleted(): Promise<IDossier[]> {
return firstValueFrom(this.getAll('deleted-dossiers'));
}
delete(dossier: Dossier): Observable<unknown> {
const showToast = () => {
this._toaster.error(_('dossier-listing.delete.delete-failed'), { params: dossier });
return of({});
};
return super.delete(dossier.dossierId).pipe(
tap(() => this.#removeDossiers([dossier])),
catchError(showToast),
);
}
@Validate()
restore(@RequiredParam() dossierIds: List): Promise<unknown> {
return firstValueFrom(this._post(dossierIds, 'deleted-dossiers/restore').pipe(switchMap(() => this.loadAll())));
}
@Validate()
hardDelete(@RequiredParam() dossierIds: List): Promise<unknown> {
const body = dossierIds.map<QueryParam>(id => ({ key: 'dossierId', value: id }));
return firstValueFrom(super.delete(body, 'deleted-dossiers/hard-delete', body));
}
getCountWithState(dossierStatusId: string): number {
return this.all.filter(dossier => dossier.dossierStatusId === dossierStatusId).length;
}
#removeDossiers(dossiers: Dossier[]): void {
this.setEntities(this.all.filter(dossier => !dossiers.find(d => dossier.id === d.id)));
}
private _load(id: string, queryParams?: List<QueryParam>): Observable<DossierStats[]> {
return super._getOne([id], this._defaultModelPath, queryParams).pipe(
map(entity => new Dossier(entity)),
tap(dossier => this.replace(dossier)),
switchMap(dossier => this._dossierStatsService.getFor([dossier.dossierId])),
);
}
#emitFileChanges(dossierChanges: DossierChanges): void {
dossierChanges.filter(change => change.fileChanges).forEach(change => this.dossierFileChanges$.next(change.dossierId));
}
#computeStats(entities: List<Dossier>): IDossiersStats {
let totalAnalyzedPages = 0;
const totalPeople = new Set<string>();

View File

@ -3,7 +3,7 @@ import { GenericService } from '@iqser/common-ui';
import { IMatchedDocument, ISearchInput, ISearchRequest, ISearchResponse } from '@red/domain';
import { Observable, of, zip } from 'rxjs';
import { mapTo, switchMap } from 'rxjs/operators';
import { DossiersService } from './dossiers.service';
import { ActiveDossiersService } from './active-dossiers.service';
import { FilesMapService } from './files-map.service';
import { FilesService } from './files.service';
@ -12,7 +12,7 @@ export class PlatformSearchService extends GenericService<ISearchResponse> {
constructor(
protected readonly _injector: Injector,
private readonly _filesService: FilesService,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
private readonly _filesMapService: FilesMapService,
) {
super(_injector, 'search-v2');
@ -38,7 +38,9 @@ export class PlatformSearchService extends GenericService<ISearchResponse> {
}
private _loadMissingFiles$(searchResponse: ISearchResponse): Observable<ISearchResponse> {
const documentsOfActiveDossiers = searchResponse.matchedDocuments.filter(document => this._dossiersService.has(document.dossierId));
const documentsOfActiveDossiers = searchResponse.matchedDocuments.filter(document =>
this._activeDossiersService.has(document.dossierId),
);
const fileNotLoaded = ({ dossierId, fileId }: IMatchedDocument) => !this._filesMapService.get(dossierId, fileId);
const dossiersWithNotLoadedFiles = documentsOfActiveDossiers.filter(fileNotLoaded).map(document => document.dossierId);

View File

@ -7,7 +7,7 @@ import { INotification, Notification, NotificationTypes } from '@red/domain';
import { map, switchMap } from 'rxjs/operators';
import { notificationsTranslations } from '../translations/notifications-translations';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { ActiveDossiersService } from './entity-services/active-dossiers.service';
import { UserService } from '@services/user.service';
import { FilesMapService } from '@services/entity-services/files-map.service';
@ -18,7 +18,7 @@ export class NotificationsService extends GenericService<Notification> {
constructor(
protected readonly _injector: Injector,
private readonly _translateService: TranslateService,
private readonly _dossiersService: DossiersService,
private readonly _activeDossiersService: ActiveDossiersService,
private readonly _userService: UserService,
private readonly _filesMapService: FilesMapService,
) {
@ -67,7 +67,7 @@ export class NotificationsService extends GenericService<Notification> {
private _translate(notification: INotification, translation: string): string {
const fileId = notification.target.fileId;
const dossierId = notification.target.dossierId;
const dossier = this._dossiersService.find(dossierId);
const dossier = this._activeDossiersService.find(dossierId);
const files = this._filesMapService.get(dossierId);
const file = files?.find(f => f.fileId === fileId);

View File

@ -1,13 +1,13 @@
import { Injectable } from '@angular/core';
import { UserService } from './user.service';
import { Dossier, File, IComment, IDossier } from '@red/domain';
import { DossiersService } from './entity-services/dossiers.service';
import { ActiveDossiersService } from './entity-services/active-dossiers.service';
@Injectable({
providedIn: 'root',
})
export class PermissionsService {
constructor(private readonly _userService: UserService, private readonly _dossiersService: DossiersService) {}
constructor(private readonly _userService: UserService, private readonly _activeDossiersService: ActiveDossiersService) {}
isReviewerOrApprover(file: File): boolean {
const dossier = this._getDossier(file);
@ -228,6 +228,6 @@ export class PermissionsService {
}
private _getDossier(file: File): Dossier {
return this._dossiersService.find(file.dossierId);
return this._activeDossiersService.find(file.dossierId);
}
}

View File

@ -2,3 +2,6 @@ import { InjectionToken } from '@angular/core';
export const BASE_HREF: InjectionToken<string> = new InjectionToken<string>('BASE_HREF');
export const DOSSIER_ID: InjectionToken<string> = new InjectionToken<string>('DOSSIER_ID');
export const ACTIVE_DOSSIERS_SERVICE = new InjectionToken<string>('Active dossiers service');
export const ARCHIVED_DOSSIERS_SERVICE = new InjectionToken<string>('Archived dossiers service');