From 06c9b2bbc78c373f1fa2824061ab4a8dc13d3d2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Tue, 3 May 2022 23:02:13 +0300 Subject: [PATCH] RED-3796: Removed routerPath --- apps/red-ui/src/app/app-routing.module.ts | 50 +++++++++++-------- .../base-screen/base-screen.component.ts | 7 ++- .../src/app/guards/dossier-files-guard.ts | 7 +-- .../guards/dossier-template-exists.guard.ts | 2 +- ...clone-dossier-template-dialog.component.ts | 30 +++++------ .../src/app/modules/auth/red-role.guard.ts | 12 ++--- .../dossier-details-stats.component.ts | 2 +- ...sier-overview-screen-header.component.html | 2 +- .../dossier-overview-screen.component.ts | 4 +- .../edit-dossier-general-info.component.ts | 4 +- .../services/file-preview-state.service.ts | 2 +- .../dossiers-type-switch.component.html | 4 +- .../dossiers-type-switch.component.ts | 6 ++- .../services/file-upload.service.ts | 2 +- .../src/app/services/breadcrumbs.service.ts | 9 ++-- .../dossiers/active-dossiers.service.ts | 4 +- .../dossiers/archived-dossiers.service.ts | 4 +- .../app/services/dossiers/dossiers.service.ts | 4 +- .../file-management.service.ts | 9 ++-- .../entity-services/files-map.service.ts | 6 +-- .../services/entity-services/files.service.ts | 42 ++++++---------- .../platform-search.service.ts | 2 +- .../services/entity-services/trash.service.ts | 4 +- .../src/app/services/reanalysis.service.ts | 27 ++++------ apps/red-ui/src/app/utils/constants.ts | 3 ++ apps/red-ui/src/assets/config/config.json | 4 +- libs/common-ui | 2 +- .../src/lib/dossiers/dossier.model.ts | 14 ++++-- libs/red-domain/src/lib/files/file.model.ts | 14 ++++-- libs/red-domain/src/lib/files/file.ts | 4 ++ 30 files changed, 144 insertions(+), 142 deletions(-) diff --git a/apps/red-ui/src/app/app-routing.module.ts b/apps/red-ui/src/app/app-routing.module.ts index 92a08b043..fde2d9f9c 100644 --- a/apps/red-ui/src/app/app-routing.module.ts +++ b/apps/red-ui/src/app/app-routing.module.ts @@ -9,7 +9,7 @@ import { DownloadsListScreenComponent } from '@components/downloads-list-screen/ import { DossiersGuard } from '@guards/dossiers.guard'; import { ACTIVE_DOSSIERS_SERVICE, ARCHIVED_DOSSIERS_SERVICE } from './tokens'; import { FeaturesGuard } from '@guards/features-guard.service'; -import { DOSSIER_TEMPLATE_ID, DOSSIERS_ARCHIVE } from '@utils/constants'; +import { ARCHIVE_ROUTE, DOSSIER_TEMPLATE_ID, DOSSIERS_ARCHIVE, DOSSIERS_ROUTE } from '@utils/constants'; import { DossierTemplatesGuard } from '@guards/dossier-templates.guard'; import { DossierTemplateExistsGuard } from '@guards/dossier-template-exists.guard'; @@ -46,24 +46,37 @@ const routes: Routes = [ }, }, { - path: `:${DOSSIER_TEMPLATE_ID}/dossiers`, - loadChildren: () => import('./modules/dossier/dossiers.module').then(m => m.DossiersModule), + path: `:${DOSSIER_TEMPLATE_ID}`, + children: [ + { + path: `${DOSSIERS_ROUTE}`, + loadChildren: () => import('./modules/dossier/dossiers.module').then(m => m.DossiersModule), + canActivate: [CompositeRouteGuard], + data: { + routeGuards: [DossiersGuard], + dossiersService: ACTIVE_DOSSIERS_SERVICE, + }, + }, + { + path: `${ARCHIVE_ROUTE}`, + loadChildren: () => import('./modules/archive/archive.module').then(m => m.ArchiveModule), + canActivate: [CompositeRouteGuard], + data: { + routeGuards: [FeaturesGuard, DossiersGuard], + dossiersService: ARCHIVED_DOSSIERS_SERVICE, + features: [DOSSIERS_ARCHIVE], + }, + }, + { + path: '**', + redirectTo: `${DOSSIERS_ROUTE}`, + pathMatch: 'full', + }, + ], canActivate: [CompositeRouteGuard], data: { - routeGuards: [AuthGuard, RedRoleGuard, DossierTemplatesGuard, DossierTemplateExistsGuard, DossiersGuard], + routeGuards: [AuthGuard, RedRoleGuard, DossierTemplatesGuard, DossierTemplateExistsGuard], requiredRoles: ['RED_USER', 'RED_MANAGER'], - dossiersService: ACTIVE_DOSSIERS_SERVICE, - }, - }, - { - path: `:${DOSSIER_TEMPLATE_ID}/archive`, - loadChildren: () => import('./modules/archive/archive.module').then(m => m.ArchiveModule), - canActivate: [CompositeRouteGuard], - data: { - routeGuards: [FeaturesGuard, AuthGuard, RedRoleGuard, DossierTemplatesGuard, DossierTemplateExistsGuard, DossiersGuard], - requiredRoles: ['RED_USER', 'RED_MANAGER'], - dossiersService: ARCHIVED_DOSSIERS_SERVICE, - features: [DOSSIERS_ARCHIVE], }, }, { @@ -83,11 +96,6 @@ const routes: Routes = [ requiredRoles: ['RED_USER', 'RED_MANAGER'], }, }, - { - path: `:${DOSSIER_TEMPLATE_ID}`, - redirectTo: `:${DOSSIER_TEMPLATE_ID}/dossiers`, - pathMatch: 'full', - }, ], }, { diff --git a/apps/red-ui/src/app/components/base-screen/base-screen.component.ts b/apps/red-ui/src/app/components/base-screen/base-screen.component.ts index 12e8a0df5..943d9e36c 100644 --- a/apps/red-ui/src/app/components/base-screen/base-screen.component.ts +++ b/apps/red-ui/src/app/components/base-screen/base-screen.component.ts @@ -7,10 +7,10 @@ import { TranslateService } from '@ngx-translate/core'; import { SpotlightSearchAction } from '@components/spotlight-search/spotlight-search-action'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { filter, map, startWith } from 'rxjs/operators'; -import { HelpModeService, shareDistinctLast } from '@iqser/common-ui'; +import { shareDistinctLast } from '@iqser/common-ui'; import { BreadcrumbsService } from '@services/breadcrumbs.service'; import { FeaturesService } from '@services/features.service'; -import { DOSSIERS_ARCHIVE } from '@utils/constants'; +import { ARCHIVE_ROUTE, DOSSIERS_ARCHIVE, DOSSIERS_ROUTE } from '@utils/constants'; interface MenuItem { readonly id: string; @@ -91,7 +91,6 @@ export class BaseScreenComponent { readonly userPreferenceService: UserPreferenceService, readonly titleService: Title, readonly breadcrumbsService: BreadcrumbsService, - readonly helpModeService: HelpModeService, ) {} private get _hideSearchThisDossier() { @@ -100,7 +99,7 @@ export class BaseScreenComponent { return true; } - const isDossierOverview = (routerLink.includes('dossiers') || routerLink.includes('archive')) && routerLink.length === 3; + const isDossierOverview = (routerLink.includes(DOSSIERS_ROUTE) || routerLink.includes(ARCHIVE_ROUTE)) && routerLink.length === 3; return !isDossierOverview; } diff --git a/apps/red-ui/src/app/guards/dossier-files-guard.ts b/apps/red-ui/src/app/guards/dossier-files-guard.ts index b6229360b..9aab2878a 100644 --- a/apps/red-ui/src/app/guards/dossier-files-guard.ts +++ b/apps/red-ui/src/app/guards/dossier-files-guard.ts @@ -3,7 +3,7 @@ import { ActivatedRouteSnapshot, CanActivate, Router } from '@angular/router'; import { FilesMapService } from '@services/entity-services/files-map.service'; import { FilesService } from '@services/entity-services/files.service'; import { firstValueFrom } from 'rxjs'; -import { DOSSIER_ID } from '@utils/constants'; +import { DOSSIER_ID, DOSSIER_TEMPLATE_ID } from '@utils/constants'; import { DossiersService } from '@services/dossiers/dossiers.service'; @Injectable({ providedIn: 'root' }) @@ -17,16 +17,17 @@ export class DossierFilesGuard implements CanActivate { async canActivate(route: ActivatedRouteSnapshot): Promise { const dossierId = route.paramMap.get(DOSSIER_ID); + const dossierTemplateId = route.paramMap.get(DOSSIER_TEMPLATE_ID); const token: ProviderToken = route.data.dossiersService; const dossiersService: DossiersService = this._injector.get(token); if (!dossiersService.has(dossierId)) { - await this._router.navigate(['/main', dossiersService.routerPath]); + await this._router.navigate(['/main', dossierTemplateId]); return false; } if (!this._filesMapService.has(dossierId)) { - await firstValueFrom(this._filesService.loadAll(dossierId, dossiersService.routerPath)); + await firstValueFrom(this._filesService.loadAll(dossierId)); } return true; } diff --git a/apps/red-ui/src/app/guards/dossier-template-exists.guard.ts b/apps/red-ui/src/app/guards/dossier-template-exists.guard.ts index aa0bf8ec1..655a56dfe 100644 --- a/apps/red-ui/src/app/guards/dossier-template-exists.guard.ts +++ b/apps/red-ui/src/app/guards/dossier-template-exists.guard.ts @@ -10,7 +10,7 @@ export class DossierTemplateExistsGuard implements CanActivate { async canActivate(route: ActivatedRouteSnapshot): Promise { const dossierTemplateId: string = route.paramMap.get(DOSSIER_TEMPLATE_ID); if (!this._dossierTemplatesService.find(dossierTemplateId)) { - const adminView = !(route.routeConfig.path.includes('dossiers') || route.routeConfig.path.includes('archive')); + const adminView = !!route.pathFromRoot.find(r => r.routeConfig?.path === 'admin'); const routerPath = adminView ? ['main', 'admin', 'dossier-templates'] : ['']; await this._router.navigate(routerPath); return false; diff --git a/apps/red-ui/src/app/modules/admin/dialogs/clone-dossier-template-dialog/clone-dossier-template-dialog.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/clone-dossier-template-dialog/clone-dossier-template-dialog.component.ts index 51437e070..3ae953481 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/clone-dossier-template-dialog/clone-dossier-template-dialog.component.ts +++ b/apps/red-ui/src/app/modules/admin/dialogs/clone-dossier-template-dialog/clone-dossier-template-dialog.component.ts @@ -1,8 +1,8 @@ import { Component, Inject } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { DossierTemplatesService } from '../../../../services/entity-services/dossier-templates.service'; -import { DossierTemplate, IDossierTemplate } from '../../../../../../../../libs/red-domain/src'; -import { LoadingService, Toaster } from '../../../../../../../../libs/common-ui/src'; +import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service'; +import { DossierTemplate } from '@red/domain'; +import { LoadingService, Toaster } from '@iqser/common-ui'; import { firstValueFrom } from 'rxjs'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; @@ -11,8 +11,8 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; styleUrls: ['./clone-dossier-template-dialog.component.scss'], }) export class CloneDossierTemplateDialogComponent { - private readonly _dossierTemplate: DossierTemplate; nameOfClonedDossierTemplate: string; + private readonly _dossierTemplate: DossierTemplate; constructor( private readonly _toaster: Toaster, @@ -25,6 +25,17 @@ export class CloneDossierTemplateDialogComponent { this.nameOfClonedDossierTemplate = this._getCloneName(); } + async save() { + this._loadingService.start(); + try { + await firstValueFrom(this._dossierTemplatesService.clone(this.dossierTemplateId, this.nameOfClonedDossierTemplate)); + this._dialogRef.close(true); + } catch (error: any) { + this._toaster.error(_('clone-dossier-template.error.generic'), { error }); + } + this._loadingService.stop(); + } + private _getCloneName(): string | null { const templateName = this._dossierTemplate.name.trim(); @@ -47,15 +58,4 @@ export class CloneDossierTemplateDialogComponent { } return `Clone of ${nameOfClonedTemplate}`; } - - async save() { - this._loadingService.start(); - try { - await firstValueFrom(this._dossierTemplatesService.clone(this.dossierTemplateId, this.nameOfClonedDossierTemplate)); - this._dialogRef.close(true); - } catch (error: any) { - this._toaster.error(_('clone-dossier-template.error.generic'), { error }); - } - this._loadingService.stop(); - } } diff --git a/apps/red-ui/src/app/modules/auth/red-role.guard.ts b/apps/red-ui/src/app/modules/auth/red-role.guard.ts index f9d43d465..e9f33c587 100644 --- a/apps/red-ui/src/app/modules/auth/red-role.guard.ts +++ b/apps/red-ui/src/app/modules/auth/red-role.guard.ts @@ -49,18 +49,16 @@ export class RedRoleGuard implements CanActivate { return; } - if (!this._userService.currentUser.isUser && state.url.startsWith('/main/dossiers')) { - this._router.navigate(['/main/admin']); - obs.next(false); - obs.complete(); - return; - } if (route.data.requiredRoles) { if (this._userService.hasAnyRole(route.data.requiredRoles)) { obs.next(true); obs.complete(); } else { - this._router.navigate(['/main/dossiers']); + if (!this._userService.currentUser.isUser) { + this._router.navigate(['/main/admin']); + } else { + this._router.navigate(['/']); + } obs.next(false); obs.complete(); } diff --git a/apps/red-ui/src/app/modules/dossier-overview/components/dossier-details-stats/dossier-details-stats.component.ts b/apps/red-ui/src/app/modules/dossier-overview/components/dossier-details-stats/dossier-details-stats.component.ts index 171927d46..eb0f1d0ce 100644 --- a/apps/red-ui/src/app/modules/dossier-overview/components/dossier-details-stats/dossier-details-stats.component.ts +++ b/apps/red-ui/src/app/modules/dossier-overview/components/dossier-details-stats/dossier-details-stats.component.ts @@ -35,7 +35,7 @@ export class DossierDetailsStatsComponent implements OnInit { openEditDossierDialog(section: string): void { const data = { dossierId: this.dossier.dossierId, section }; this._dialogService.openDialog('editDossier', null, data, async () => { - await firstValueFrom(this._filesService.loadAll(this.dossier.dossierId, this.dossier.routerPath)); + await firstValueFrom(this._filesService.loadAll(this.dossier.dossierId)); }); } } diff --git a/apps/red-ui/src/app/modules/dossier-overview/components/screen-header/dossier-overview-screen-header.component.html b/apps/red-ui/src/app/modules/dossier-overview/components/screen-header/dossier-overview-screen-header.component.html index c0a317eba..c8e337ebf 100644 --- a/apps/red-ui/src/app/modules/dossier-overview/components/screen-header/dossier-overview-screen-header.component.html +++ b/apps/red-ui/src/app/modules/dossier-overview/components/screen-header/dossier-overview-screen-header.component.html @@ -1,5 +1,5 @@ imple get #dossierFilesChange$() { return this._dossiersService.dossierFileChanges$.pipe( filter(dossierId => dossierId === this.dossierId), - switchMap(dossierId => this._filesService.loadAll(dossierId, this._dossiersService.routerPath)), + switchMap(dossierId => this._filesService.loadAll(dossierId)), ); } diff --git a/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.ts b/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.ts index a7a060260..abcdf8c98 100644 --- a/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.ts +++ b/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.ts @@ -139,7 +139,7 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti this._loadingService.start(); await firstValueFrom(this._trashService.deleteDossier(this.dossier)); this._editDossierDialogRef.close(); - await this._router.navigate(['main', 'dossiers']); + await this._router.navigate([this.dossier.dossiersListRouterLink]); this._loadingService.stop(); this._toaster.success(_('edit-dossier-dialog.delete-successful'), { params: this.dossier }); }); @@ -161,7 +161,7 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti if (result === ConfirmOptions.CONFIRM) { this._loadingService.start(); await firstValueFrom(this._archivedDossiersService.archive([this.dossier])); - await this._router.navigate(['main', 'dossiers']); + await this._router.navigate([this.dossier.dossiersListRouterLink]); this._toaster.success(_('dossier-listing.archive.archive-succeeded'), { params: this.dossier }); this._editDossierDialogRef.close(); this._loadingService.stop(); diff --git a/apps/red-ui/src/app/modules/file-preview/services/file-preview-state.service.ts b/apps/red-ui/src/app/modules/file-preview/services/file-preview-state.service.ts index 34e546838..ddf8ac2e2 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/file-preview-state.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/file-preview-state.service.ts @@ -81,7 +81,7 @@ export class FilePreviewStateService { #dossierFilesChange$() { return this._dossiersService.dossierFileChanges$.pipe( filter(dossierId => dossierId === this.dossierId), - switchMap(dossierId => this._filesService.loadAll(dossierId, this._dossiersService.routerPath)), + switchMap(dossierId => this._filesService.loadAll(dossierId)), ); } diff --git a/apps/red-ui/src/app/modules/shared/components/dossiers-type-switch/dossiers-type-switch.component.html b/apps/red-ui/src/app/modules/shared/components/dossiers-type-switch/dossiers-type-switch.component.html index 773a1e2b2..885248299 100644 --- a/apps/red-ui/src/app/modules/shared/components/dossiers-type-switch/dossiers-type-switch.component.html +++ b/apps/red-ui/src/app/modules/shared/components/dossiers-type-switch/dossiers-type-switch.component.html @@ -1,8 +1,8 @@ - + {{ 'dossiers-type-switch.active' | translate }} - + {{ 'dossiers-type-switch.archive' | translate }} diff --git a/apps/red-ui/src/app/modules/shared/components/dossiers-type-switch/dossiers-type-switch.component.ts b/apps/red-ui/src/app/modules/shared/components/dossiers-type-switch/dossiers-type-switch.component.ts index 3f4a5b308..7488e01da 100644 --- a/apps/red-ui/src/app/modules/shared/components/dossiers-type-switch/dossiers-type-switch.component.ts +++ b/apps/red-ui/src/app/modules/shared/components/dossiers-type-switch/dossiers-type-switch.component.ts @@ -1,4 +1,5 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { ARCHIVE_ROUTE, DOSSIERS_ROUTE } from '@utils/constants'; @Component({ selector: 'redaction-dossiers-type-switch', @@ -6,4 +7,7 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; styleUrls: ['./dossiers-type-switch.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, }) -export class DossiersTypeSwitchComponent {} +export class DossiersTypeSwitchComponent { + readonly DOSSIERS_ROUTE = DOSSIERS_ROUTE; + readonly ARCHIVE_ROUTE = ARCHIVE_ROUTE; +} diff --git a/apps/red-ui/src/app/modules/upload-download/services/file-upload.service.ts b/apps/red-ui/src/app/modules/upload-download/services/file-upload.service.ts index 5a7e86f1c..9d669a7f3 100644 --- a/apps/red-ui/src/app/modules/upload-download/services/file-upload.service.ts +++ b/apps/red-ui/src/app/modules/upload-download/services/file-upload.service.ts @@ -42,7 +42,7 @@ export class FileUploadService extends GenericService impleme super(_injector, 'upload'); const fileFetch$ = this._fetchFiles$.pipe( throttleTime(250), - switchMap(dossierId => this._filesService.loadAll(dossierId, 'dossiers')), + switchMap(dossierId => this._filesService.loadAll(dossierId)), ); this._subscriptions.add(fileFetch$.subscribe()); const interval$ = interval(2500).pipe(tap(() => this._handleUploads())); diff --git a/apps/red-ui/src/app/services/breadcrumbs.service.ts b/apps/red-ui/src/app/services/breadcrumbs.service.ts index 0ac465ea4..1cd1d22aa 100644 --- a/apps/red-ui/src/app/services/breadcrumbs.service.ts +++ b/apps/red-ui/src/app/services/breadcrumbs.service.ts @@ -136,7 +136,7 @@ export class BreadcrumbsService { name$: this._dossierTemplatesService.getEntityChanged$(dossierTemplateId).pipe(pluck('name')), type: 'text' as BreadcrumbDisplayType, options: { - routerLink: ['/main', dossierTemplateId], + routerLink: ['/main', dossierTemplateId, this._dossiersService.routerPath], routerLinkActiveOptions: { exact: true }, clamp: true, }, @@ -146,12 +146,11 @@ export class BreadcrumbsService { private _addDossierBreadcrumb(params: Record): void { const dossiersService = this._dossiersService; const dossierId: string = params[DOSSIER_ID]; - const dossierTemplateId: string = params[DOSSIER_TEMPLATE_ID]; this._append({ name$: dossiersService.getEntityChanged$(dossierId).pipe(pluck('dossierName')), type: 'text' as BreadcrumbDisplayType, options: { - routerLink: ['/main', dossierTemplateId, dossiersService.routerPath, dossierId], + routerLink: [dossiersService.find(dossierId).routerLink], routerLinkActiveOptions: { exact: true }, clamp: true, }, @@ -159,15 +158,13 @@ export class BreadcrumbsService { } private _addFileBreadcrumb(params: Record): void { - const dossierTemplateId: string = params[DOSSIER_TEMPLATE_ID]; const dossierId: string = params[DOSSIER_ID]; const fileId: string = params[FILE_ID]; - const dossiersService = this._dossiersService; this._append({ name$: this._filesMapService.watch$(dossierId, fileId).pipe(pluck('filename')), type: 'text' as BreadcrumbDisplayType, options: { - routerLink: ['/main', dossierTemplateId, dossiersService.routerPath, dossierId, 'file', fileId], + routerLink: [this._filesMapService.get(dossierId, fileId).routerLink], clamp: true, }, }); diff --git a/apps/red-ui/src/app/services/dossiers/active-dossiers.service.ts b/apps/red-ui/src/app/services/dossiers/active-dossiers.service.ts index 0112b0ac6..95291300e 100644 --- a/apps/red-ui/src/app/services/dossiers/active-dossiers.service.ts +++ b/apps/red-ui/src/app/services/dossiers/active-dossiers.service.ts @@ -1,7 +1,7 @@ import { Injectable, Injector } from '@angular/core'; import { switchMap, tap } from 'rxjs/operators'; import { timer } from 'rxjs'; -import { CHANGED_CHECK_INTERVAL } from '@utils/constants'; +import { CHANGED_CHECK_INTERVAL, DOSSIERS_ROUTE } from '@utils/constants'; import { DossiersService } from './dossiers.service'; export interface IDossiersStats { @@ -14,7 +14,7 @@ export interface IDossiersStats { }) export class ActiveDossiersService extends DossiersService { constructor(protected readonly _injector: Injector) { - super(_injector, 'dossier', 'dossiers'); + super(_injector, 'dossier', DOSSIERS_ROUTE); timer(CHANGED_CHECK_INTERVAL, CHANGED_CHECK_INTERVAL) .pipe( diff --git a/apps/red-ui/src/app/services/dossiers/archived-dossiers.service.ts b/apps/red-ui/src/app/services/dossiers/archived-dossiers.service.ts index 0f496c809..739933d98 100644 --- a/apps/red-ui/src/app/services/dossiers/archived-dossiers.service.ts +++ b/apps/red-ui/src/app/services/dossiers/archived-dossiers.service.ts @@ -7,7 +7,7 @@ import { ActiveDossiersService } from './active-dossiers.service'; import { DossiersService } from './dossiers.service'; import { FilesMapService } from '../entity-services/files-map.service'; import { FeaturesService } from '@services/features.service'; -import { DOSSIERS_ARCHIVE } from '@utils/constants'; +import { ARCHIVE_ROUTE, DOSSIERS_ARCHIVE } from '@utils/constants'; @Injectable({ providedIn: 'root' }) export class ArchivedDossiersService extends DossiersService { @@ -17,7 +17,7 @@ export class ArchivedDossiersService extends DossiersService { private readonly _filesMapService: FilesMapService, private readonly _featuresService: FeaturesService, ) { - super(_injector, 'archived-dossiers', 'archive'); + super(_injector, 'archived-dossiers', ARCHIVE_ROUTE); } archive(dossiers: Dossier[]): Observable { diff --git a/apps/red-ui/src/app/services/dossiers/dossiers.service.ts b/apps/red-ui/src/app/services/dossiers/dossiers.service.ts index 9f8f9d5a2..32d44d88f 100644 --- a/apps/red-ui/src/app/services/dossiers/dossiers.service.ts +++ b/apps/red-ui/src/app/services/dossiers/dossiers.service.ts @@ -61,7 +61,7 @@ export abstract class DossiersService extends EntitiesService loadAll(): Observable { const dossierIds = (dossiers: Dossier[]) => dossiers.map(d => d.id); return this.getAll().pipe( - mapEach(entity => new Dossier(entity, this.routerPath)), + mapEach(entity => new Dossier(entity)), /* Load stats before updating entities */ switchMap(dossiers => this._dossierStatsService.getFor(dossierIds(dossiers)).pipe(map(() => dossiers))), switchMap(dossiers => this._dossierStateService.loadAllForAllTemplates().pipe(map(() => dossiers))), @@ -81,7 +81,7 @@ export abstract class DossiersService extends EntitiesService private _load(id: string): Observable { const queryParams: List = [{ key: 'includeArchived', value: this._path === 'archived-dossiers' }]; return super._getOne([id], this._defaultModelPath, queryParams).pipe( - map(entity => new Dossier(entity, 'dossiers')), + map(entity => new Dossier(entity)), tap(dossier => this.replace(dossier)), switchMap(dossier => this._dossierStatsService.getFor([dossier.dossierId])), ); diff --git a/apps/red-ui/src/app/services/entity-services/file-management.service.ts b/apps/red-ui/src/app/services/entity-services/file-management.service.ts index 0d26bb4cd..a37a33a07 100644 --- a/apps/red-ui/src/app/services/entity-services/file-management.service.ts +++ b/apps/red-ui/src/app/services/entity-services/file-management.service.ts @@ -1,11 +1,11 @@ -import { GenericService, HeadersConfiguration, IRouterPath, List, QueryParam, RequiredParam, Validate } from '@iqser/common-ui'; +import { GenericService, HeadersConfiguration, List, QueryParam, RequiredParam, Validate } from '@iqser/common-ui'; import { Injectable, Injector } from '@angular/core'; import { HttpHeaders, HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs'; import { switchMap } from 'rxjs/operators'; import { FilesService } from '@services/entity-services/files.service'; import { DossierStatsService } from '@services/dossiers/dossier-stats.service'; -import { IPageRotationRequest } from '@red/domain'; +import { File, IPageRotationRequest } from '@red/domain'; @Injectable({ providedIn: 'root', @@ -20,10 +20,9 @@ export class FileManagementService extends GenericService { } @Validate() - delete(@RequiredParam() files: List, @RequiredParam() dossierId: string) { + delete(@RequiredParam() files: List, @RequiredParam() dossierId: string) { const fileIds = files.map(f => f.id); - const routerPath: string = files[0].routerPath; - return super._post(fileIds, `delete/${dossierId}`).pipe(switchMap(() => this._filesService.loadAll(dossierId, routerPath))); + return super._post(fileIds, `delete/${dossierId}`).pipe(switchMap(() => this._filesService.loadAll(dossierId))); } @Validate() diff --git a/apps/red-ui/src/app/services/entity-services/files-map.service.ts b/apps/red-ui/src/app/services/entity-services/files-map.service.ts index bfe6587aa..d71f717d1 100644 --- a/apps/red-ui/src/app/services/entity-services/files-map.service.ts +++ b/apps/red-ui/src/app/services/entity-services/files-map.service.ts @@ -12,11 +12,7 @@ export class FilesMapService extends EntitiesMapService { replaceFiles(files: File[], property: keyof IFile, generateValue: Function) { const newFiles = files.map( file => - new File( - { ...file, [property]: generateValue(file[property]), lastUpdated: new Date().toISOString() }, - file.reviewerName, - file.routerPath, - ), + new File({ ...file, [property]: generateValue(file[property]), lastUpdated: new Date().toISOString() }, file.reviewerName), ); this.replace(newFiles); } diff --git a/apps/red-ui/src/app/services/entity-services/files.service.ts b/apps/red-ui/src/app/services/entity-services/files.service.ts index 3569e678b..9d8b48ef2 100644 --- a/apps/red-ui/src/app/services/entity-services/files.service.ts +++ b/apps/red-ui/src/app/services/entity-services/files.service.ts @@ -1,5 +1,5 @@ import { Injectable, Injector } from '@angular/core'; -import { EntitiesService, IRouterPath, List, mapEach, RequiredParam, Validate } from '@iqser/common-ui'; +import { EntitiesService, List, mapEach, RequiredParam, Validate } from '@iqser/common-ui'; import { File, IFile } from '@red/domain'; import { Observable } from 'rxjs'; import { UserService } from '../user.service'; @@ -23,9 +23,9 @@ export class FilesService extends EntitiesService { } /** Reload dossier files + stats. */ - loadAll(dossierId: string, routerPath: string) { + loadAll(dossierId: string) { const files$ = this.getFor(dossierId).pipe( - mapEach(file => new File(file, this._userService.getNameForId(file.assignee), routerPath)), + mapEach(file => new File(file, this._userService.getNameForId(file.assignee))), tap(() => this._logger.info('[FILE] Loaded')), ); const loadStats$ = files$.pipe(switchMap(files => this._dossierStatsService.getFor([dossierId]).pipe(map(() => files)))); @@ -34,7 +34,7 @@ export class FilesService extends EntitiesService { reload(dossierId: string, file: File): Observable { return super._getOne([dossierId, file.id]).pipe( - map(_file => new File(_file, this._userService.getNameForId(_file.assignee), file.routerPath)), + map(_file => new File(_file, this._userService.getNameForId(_file.assignee))), switchMap(_file => this._dossierStatsService.getFor([dossierId]).pipe(map(() => _file))), map(_file => this._filesMapService.replace([_file])), tap(() => this._logger.info('[FILE] Reloaded')), @@ -42,56 +42,46 @@ export class FilesService extends EntitiesService { } @Validate() - setUnassigned(@RequiredParam() files: List, @RequiredParam() dossierId: string) { + setUnassigned(@RequiredParam() files: List, @RequiredParam() dossierId: string) { const url = `${this._defaultModelPath}/set-assignee/${dossierId}/bulk`; const fileIds = files.map(f => f.id); - const routerPath: string = files[0].routerPath; - return this._post(fileIds, url).pipe(switchMap(() => this.loadAll(dossierId, routerPath))); + return this._post(fileIds, url).pipe(switchMap(() => this.loadAll(dossierId))); } @Validate() - setToNewFor(@RequiredParam() files: List, @RequiredParam() dossierId: string) { + setToNewFor(@RequiredParam() files: List, @RequiredParam() dossierId: string) { const url = `${this._defaultModelPath}/new/${dossierId}/bulk`; const fileIds = files.map(f => f.id); - const routerPath: string = files[0].routerPath; - return this._post(fileIds, url).pipe(switchMap(() => this.loadAll(dossierId, routerPath))); + return this._post(fileIds, url).pipe(switchMap(() => this.loadAll(dossierId))); } @Validate() - setUnderApprovalFor(@RequiredParam() files: List, @RequiredParam() dossierId: string, assigneeId: string) { + setUnderApprovalFor(@RequiredParam() files: List, @RequiredParam() dossierId: string, assigneeId: string) { const url = `${this._defaultModelPath}/under-approval/${dossierId}/bulk`; const fileIds = files.map(f => f.id); - const routerPath: string = files[0].routerPath; - return this._post(fileIds, url, [{ key: 'assigneeId', value: assigneeId }]).pipe( - switchMap(() => this.loadAll(dossierId, routerPath)), - ); + return this._post(fileIds, url, [{ key: 'assigneeId', value: assigneeId }]).pipe(switchMap(() => this.loadAll(dossierId))); } @Validate() - setReviewerFor(@RequiredParam() files: List, @RequiredParam() dossierId: string, assigneeId: string) { + setReviewerFor(@RequiredParam() files: List, @RequiredParam() dossierId: string, assigneeId: string) { const url = `${this._defaultModelPath}/under-review/${dossierId}/bulk`; const fileIds = files.map(f => f.id); - const routerPath: string = files[0].routerPath; - return this._post(fileIds, url, [{ key: 'assigneeId', value: assigneeId }]).pipe( - switchMap(() => this.loadAll(dossierId, routerPath)), - ); + return this._post(fileIds, url, [{ key: 'assigneeId', value: assigneeId }]).pipe(switchMap(() => this.loadAll(dossierId))); } @Validate() - setApprovedFor(@RequiredParam() files: List, @RequiredParam() dossierId: string) { + setApprovedFor(@RequiredParam() files: List, @RequiredParam() dossierId: string) { const fileIds = files.map(f => f.id); - const routerPath: string = files[0].routerPath; return this._post(fileIds, `${this._defaultModelPath}/approved/${dossierId}/bulk`).pipe( - switchMap(() => this.loadAll(dossierId, routerPath)), + switchMap(() => this.loadAll(dossierId)), ); } @Validate() - setUnderReviewFor(@RequiredParam() files: List, @RequiredParam() dossierId: string) { + setUnderReviewFor(@RequiredParam() files: List, @RequiredParam() dossierId: string) { const fileIds = files.map(f => f.id); - const routerPath: string = files[0].routerPath; return this._post(fileIds, `${this._defaultModelPath}/under-review/${dossierId}/bulk`).pipe( - switchMap(() => this.loadAll(dossierId, routerPath)), + switchMap(() => this.loadAll(dossierId)), ); } } diff --git a/apps/red-ui/src/app/services/entity-services/platform-search.service.ts b/apps/red-ui/src/app/services/entity-services/platform-search.service.ts index d729373d4..a0d03df4f 100644 --- a/apps/red-ui/src/app/services/entity-services/platform-search.service.ts +++ b/apps/red-ui/src/app/services/entity-services/platform-search.service.ts @@ -56,6 +56,6 @@ export class PlatformSearchService extends GenericService { } private _loadFilesFor$(dossiers: Dossier[]) { - return zip(...dossiers.map(dossier => this._filesService.loadAll(dossier.id, dossier.routerPath))); + return zip(...dossiers.map(dossier => this._filesService.loadAll(dossier.id))); } } diff --git a/apps/red-ui/src/app/services/entity-services/trash.service.ts b/apps/red-ui/src/app/services/entity-services/trash.service.ts index 06153fc4c..841bda468 100644 --- a/apps/red-ui/src/app/services/entity-services/trash.service.ts +++ b/apps/red-ui/src/app/services/entity-services/trash.service.ts @@ -81,7 +81,7 @@ export class TrashService extends GenericService { getFiles(dossierIds = this._activeDossiersService.all.map(d => d.id)): Observable { return this._post>(dossierIds, 'status/softdeleted').pipe( map(res => flatMap(Object.values(res))), - mapEach(file => new File(file, this._userService.getNameForId(file.assignee), this._activeDossiersService.routerPath)), + mapEach(file => new File(file, this._userService.getNameForId(file.assignee))), mapEach(file => { const dossier = this._activeDossiersService.find(file.dossierId); return new TrashFile( @@ -133,6 +133,6 @@ export class TrashService extends GenericService { } private _restoreFiles(@RequiredParam() dossierId: string, @RequiredParam() fileIds: List) { - return this._post(fileIds, `delete/restore/${dossierId}`).pipe(switchMap(() => this._filesService.loadAll(dossierId, 'dossiers'))); + return this._post(fileIds, `delete/restore/${dossierId}`).pipe(switchMap(() => this._filesService.loadAll(dossierId))); } } diff --git a/apps/red-ui/src/app/services/reanalysis.service.ts b/apps/red-ui/src/app/services/reanalysis.service.ts index d58a2e406..243c98b21 100644 --- a/apps/red-ui/src/app/services/reanalysis.service.ts +++ b/apps/red-ui/src/app/services/reanalysis.service.ts @@ -1,5 +1,5 @@ import { Injectable, Injector } from '@angular/core'; -import { GenericService, IRouterPath, List, QueryParam, RequiredParam, Toaster, Validate } from '@iqser/common-ui'; +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'; import { FilesService } from './entity-services/files.service'; @@ -36,9 +36,8 @@ export class ReanalysisService extends GenericService { } @Validate() - reanalyzeFilesForDossier(@RequiredParam() files: List, @RequiredParam() dossierId: string, params?: ReanalyzeQueryParams) { + reanalyzeFilesForDossier(@RequiredParam() files: List, @RequiredParam() dossierId: string, params?: ReanalyzeQueryParams) { const fileIds = files.map(f => f.id); - const routerPath: string = files[0].routerPath; const queryParams: QueryParam[] = []; if (params?.force) { queryParams.push({ key: 'force', value: true }); @@ -47,22 +46,19 @@ export class ReanalysisService extends GenericService { queryParams.push({ key: 'triggeredByUser', value: true }); } - return this._post(fileIds, `reanalyze/${dossierId}/bulk`, queryParams).pipe( - switchMap(() => this._filesService.loadAll(dossierId, routerPath)), - ); + return this._post(fileIds, `reanalyze/${dossierId}/bulk`, queryParams).pipe(switchMap(() => this._filesService.loadAll(dossierId))); } @Validate() - toggleAnalysis(@RequiredParam() dossierId: string, @RequiredParam() files: List, excluded?: boolean) { + toggleAnalysis(@RequiredParam() dossierId: string, @RequiredParam() files: List, excluded?: boolean) { const fileIds = files.map(f => f.id); - const routerPath: string = files[0].routerPath; const queryParams: QueryParam[] = []; if (excluded) { queryParams.push({ key: 'excluded', value: excluded }); } return this._post(fileIds, `toggle-analysis/${dossierId}/bulk`, queryParams).pipe( - switchMap(() => this._filesService.loadAll(dossierId, routerPath)), + switchMap(() => this._filesService.loadAll(dossierId)), ); } @@ -86,24 +82,19 @@ export class ReanalysisService extends GenericService { } @Validate() - ocrFiles(@RequiredParam() files: List, @RequiredParam() dossierId: string) { + ocrFiles(@RequiredParam() files: List, @RequiredParam() dossierId: string) { const fileIds = files.map(f => f.id); - const routerPath: string = files[0].routerPath; - return this._post(fileIds, `ocr/reanalyze/${dossierId}/bulk`).pipe( - switchMap(() => this._filesService.loadAll(dossierId, routerPath)), - ); + return this._post(fileIds, `ocr/reanalyze/${dossierId}/bulk`).pipe(switchMap(() => this._filesService.loadAll(dossierId))); } @Validate() reanalyzeDossier(@RequiredParam() dossier: Dossier, force?: boolean) { - const { dossierId, routerPath } = dossier; + const { dossierId } = dossier; const queryParams: QueryParam[] = []; if (force) { queryParams.push({ key: 'force', value: force }); } - return this._post({}, `reanalyze/${dossierId}`, queryParams).pipe( - switchMap(() => this._filesService.loadAll(dossierId, routerPath)), - ); + return this._post({}, `reanalyze/${dossierId}`, queryParams).pipe(switchMap(() => this._filesService.loadAll(dossierId))); } } diff --git a/apps/red-ui/src/app/utils/constants.ts b/apps/red-ui/src/app/utils/constants.ts index 1f808d01d..4fb7381f9 100644 --- a/apps/red-ui/src/app/utils/constants.ts +++ b/apps/red-ui/src/app/utils/constants.ts @@ -5,3 +5,6 @@ export const FILE_ID = 'fileId'; export const DOSSIER_TEMPLATE_ID = 'dossierTemplateId'; export const ENTITY_TYPE = 'entity'; export const DOSSIERS_ARCHIVE = 'DOSSIERS_ARCHIVE'; + +export const ARCHIVE_ROUTE = 'archive'; +export const DOSSIERS_ROUTE = 'dossiers'; diff --git a/apps/red-ui/src/assets/config/config.json b/apps/red-ui/src/assets/config/config.json index 684210fa7..0cb5f13c3 100644 --- a/apps/red-ui/src/assets/config/config.json +++ b/apps/red-ui/src/assets/config/config.json @@ -1,7 +1,7 @@ { "ADMIN_CONTACT_NAME": null, "ADMIN_CONTACT_URL": null, - "API_URL": "https://dev-08.iqser.cloud/redaction-gateway-v1", + "API_URL": "https://dev-04.iqser.cloud/redaction-gateway-v1", "APP_NAME": "RedactManager", "AUTO_READ_TIME": 3, "BACKEND_APP_VERSION": "4.4.40", @@ -17,7 +17,7 @@ "MAX_RETRIES_ON_SERVER_ERROR": 3, "OAUTH_CLIENT_ID": "redaction", "OAUTH_IDP_HINT": null, - "OAUTH_URL": "https://dev-08.iqser.cloud/auth/realms/redaction", + "OAUTH_URL": "https://dev-04.iqser.cloud/auth/realms/redaction", "RECENT_PERIOD_IN_HOURS": 24, "SELECTION_MODE": "structural", "MANUAL_BASE_URL": "https://docs.redactmanager.com/preview" diff --git a/libs/common-ui b/libs/common-ui index 7bc942ae1..f06c007be 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit 7bc942ae164164dadba94045f1f249a6cbb17284 +Subproject commit f06c007bec1a7da5c257e68d6df8c806419ceb2b diff --git a/libs/red-domain/src/lib/dossiers/dossier.model.ts b/libs/red-domain/src/lib/dossiers/dossier.model.ts index f50d5ecec..6a2bb1727 100644 --- a/libs/red-domain/src/lib/dossiers/dossier.model.ts +++ b/libs/red-domain/src/lib/dossiers/dossier.model.ts @@ -1,8 +1,9 @@ -import { IListable, IRouterPath, List } from '@iqser/common-ui'; +import { IListable, List } from '@iqser/common-ui'; import { IDossier } from './dossier'; import { DownloadFileType } from '../shared'; +import { ARCHIVE_ROUTE, DOSSIERS_ROUTE } from '@utils/constants'; -export class Dossier implements IDossier, IListable, IRouterPath { +export class Dossier implements IDossier, IListable { readonly dossierId: string; readonly dossierTemplateId: string; readonly ownerId: string; @@ -23,7 +24,7 @@ export class Dossier implements IDossier, IListable, IRouterPath { readonly archivedTime: string; readonly hasReviewers: boolean; - constructor(dossier: IDossier, readonly routerPath: string) { + constructor(dossier: IDossier) { this.dossierId = dossier.dossierId; this.approverIds = dossier.approverIds; this.date = dossier.date; @@ -50,7 +51,12 @@ export class Dossier implements IDossier, IListable, IRouterPath { } get routerLink(): string { - return `/main/${this.dossierTemplateId}/${this.routerPath}/${this.dossierId}`; + return `${this.dossiersListRouterLink}/${this.dossierId}`; + } + + get dossiersListRouterLink(): string { + const routerPath = this.isArchived ? ARCHIVE_ROUTE : DOSSIERS_ROUTE; + return `/main/${this.dossierTemplateId}/${routerPath}`; } get searchKey(): string { diff --git a/libs/red-domain/src/lib/files/file.model.ts b/libs/red-domain/src/lib/files/file.model.ts index 5ec6048dc..764ea776e 100644 --- a/libs/red-domain/src/lib/files/file.model.ts +++ b/libs/red-domain/src/lib/files/file.model.ts @@ -1,4 +1,4 @@ -import { Entity, IRouterPath } from '@iqser/common-ui'; +import { Entity } from '@iqser/common-ui'; import { StatusSorter } from '../shared'; import { isFullProcessingStatuses, @@ -10,8 +10,9 @@ import { } from './types'; import { IFile } from './file'; import { FileAttributes } from '../file-attributes'; +import { ARCHIVE_ROUTE, DOSSIERS_ROUTE } from '@utils/constants'; -export class File extends Entity implements IFile, IRouterPath { +export class File extends Entity implements IFile { readonly added?: string; readonly allManualRedactionsApplied: boolean; readonly analysisDuration?: number; @@ -51,6 +52,8 @@ export class File extends Entity implements IFile, IRouterPath { readonly redactionModificationDate: string; readonly lastManualChangeDate?: string; readonly hasHighlights: boolean; + readonly dossierArchived: boolean; + readonly dossierTemplateId: string; readonly statusSort: number; readonly cacheIdentifier?: string; @@ -70,7 +73,7 @@ export class File extends Entity implements IFile, IRouterPath { readonly canBeOpened: boolean; readonly canBeOCRed: boolean; - constructor(file: IFile, readonly reviewerName: string, readonly routerPath: string, readonly dossierTemplateId?: string) { + constructor(file: IFile, readonly reviewerName: string) { super(file); this.added = file.added; this.allManualRedactionsApplied = !!file.allManualRedactionsApplied; @@ -112,6 +115,8 @@ export class File extends Entity implements IFile, IRouterPath { this.redactionModificationDate = file.redactionModificationDate ?? ''; this.lastManualChangeDate = file.lastManualChangeDate; this.hasHighlights = file.hasHighlights; + this.dossierArchived = file.dossierArchived; + this.dossierTemplateId = file.dossierTemplateId; this.statusSort = StatusSorter[this.workflowStatus]; this.cacheIdentifier = btoa(this.fileManipulationDate ?? ''); @@ -146,6 +151,7 @@ export class File extends Entity implements IFile, IRouterPath { } get routerLink(): string | undefined { - return this.canBeOpened ? `/main/${this.dossierTemplateId}/${this.routerPath}/${this.dossierId}/file/${this.fileId}` : undefined; + const routerPath = this.dossierArchived ? ARCHIVE_ROUTE : DOSSIERS_ROUTE; + return this.canBeOpened ? `/main/${this.dossierTemplateId}/${routerPath}/${this.dossierId}/file/${this.fileId}` : undefined; } } diff --git a/libs/red-domain/src/lib/files/file.ts b/libs/red-domain/src/lib/files/file.ts index cbdd0e21e..59ba00cd8 100644 --- a/libs/red-domain/src/lib/files/file.ts +++ b/libs/red-domain/src/lib/files/file.ts @@ -149,6 +149,10 @@ export interface IFile { readonly hasHighlights: boolean; + readonly dossierArchived: boolean; + + readonly dossierTemplateId: string; + /** * Last time the actual file was touched */