View archived files
This commit is contained in:
parent
670e19f98e
commit
97d956c11c
@ -26,7 +26,7 @@ export class DossierFilesGuard implements CanActivate {
|
||||
}
|
||||
|
||||
if (!this._filesMapService.has(dossierId)) {
|
||||
await firstValueFrom(this._filesService.loadAll(dossierId));
|
||||
await firstValueFrom(this._filesService.loadAll(dossierId, dossiersService.routerPath));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1,22 +1,25 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, Injector, ProviderToken } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, CanActivate, Router } from '@angular/router';
|
||||
import { FilesMapService } from '@services/entity-services/files-map.service';
|
||||
import { ActiveDossiersService } from '@services/entity-services/active-dossiers.service';
|
||||
import { DOSSIER_ID, FILE_ID } from '@utils/constants';
|
||||
import { DossiersService } from '../services/entity-services/dossiers.service';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class FilePreviewGuard implements CanActivate {
|
||||
constructor(
|
||||
private readonly _filesMapService: FilesMapService,
|
||||
private readonly _activeDossiersService: ActiveDossiersService,
|
||||
private readonly _router: Router,
|
||||
private readonly _injector: Injector,
|
||||
) {}
|
||||
|
||||
async canActivate(route: ActivatedRouteSnapshot): Promise<boolean> {
|
||||
const token: ProviderToken<DossiersService> = route.data.dossiersService;
|
||||
const dossiersService: DossiersService = this._injector.get<DossiersService>(token);
|
||||
|
||||
const dossierId = route.paramMap.get(DOSSIER_ID);
|
||||
const fileId = route.paramMap.get(FILE_ID);
|
||||
|
||||
const dossier = this._activeDossiersService.find(dossierId);
|
||||
const dossier = dossiersService.find(dossierId);
|
||||
|
||||
if (!this._filesMapService.get(dossierId, fileId)) {
|
||||
await this._router.navigate([dossier.routerLink]);
|
||||
|
||||
@ -2,10 +2,11 @@ import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { BreadcrumbTypes } from '@red/domain';
|
||||
import { ArchivedDossiersScreenComponent } from './screens/archived-dossiers-screen/archived-dossiers-screen.component';
|
||||
import { DOSSIER_ID } from '@utils/constants';
|
||||
import { DOSSIER_ID, FILE_ID } from '@utils/constants';
|
||||
import { CompositeRouteGuard } from '@iqser/common-ui';
|
||||
import { ARCHIVED_DOSSIERS_SERVICE } from '../../tokens';
|
||||
import { DossierFilesGuard } from '@guards/dossier-files-guard';
|
||||
import { FilePreviewGuard } from '../../guards/file-preview.guard';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
@ -24,6 +25,16 @@ const routes: Routes = [
|
||||
},
|
||||
loadChildren: () => import('../dossier/screens/dossier-overview/dossier-overview.module').then(m => m.DossierOverviewModule),
|
||||
},
|
||||
{
|
||||
path: `:${DOSSIER_ID}/file/:${FILE_ID}`,
|
||||
canActivate: [CompositeRouteGuard],
|
||||
data: {
|
||||
routeGuards: [DossierFilesGuard, FilePreviewGuard],
|
||||
breadcrumbs: [BreadcrumbTypes.archive, BreadcrumbTypes.dossier, BreadcrumbTypes.file],
|
||||
dossiersService: ARCHIVED_DOSSIERS_SERVICE,
|
||||
},
|
||||
loadChildren: () => import('../dossier/screens/file-preview-screen/file-preview.module').then(m => m.FilePreviewModule),
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
||||
@ -102,28 +102,11 @@ export class AssignReviewerApproverDialogComponent {
|
||||
this._loadingService.start();
|
||||
try {
|
||||
if (!this.selectedUser) {
|
||||
await firstValueFrom(
|
||||
this._filesService.setUnassigned(
|
||||
this.data.files.map(f => f.fileId),
|
||||
this.dossier.id,
|
||||
),
|
||||
);
|
||||
await firstValueFrom(this._filesService.setUnassigned(this.data.files, this.dossier.id));
|
||||
} else if (this.data.mode === 'reviewer') {
|
||||
await firstValueFrom(
|
||||
this._filesService.setReviewerFor(
|
||||
this.data.files.map(f => f.fileId),
|
||||
this.dossier.id,
|
||||
this.selectedUser,
|
||||
),
|
||||
);
|
||||
await firstValueFrom(this._filesService.setReviewerFor(this.data.files, this.dossier.id, this.selectedUser));
|
||||
} else {
|
||||
await firstValueFrom(
|
||||
this._filesService.setUnderApprovalFor(
|
||||
this.data.files.map(f => f.fileId),
|
||||
this.dossier.id,
|
||||
this.selectedUser,
|
||||
),
|
||||
);
|
||||
await firstValueFrom(this._filesService.setUnderApprovalFor(this.data.files, this.dossier.id, this.selectedUser));
|
||||
}
|
||||
} catch (error) {
|
||||
this._toaster.error(_('error.http.generic'), { params: error });
|
||||
|
||||
@ -25,10 +25,10 @@ export class DocumentInfoDialogComponent extends BaseDialogComponent implements
|
||||
private readonly _filesService: FilesService,
|
||||
protected readonly _injector: Injector,
|
||||
protected readonly _dialogRef: MatDialogRef<DocumentInfoDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) readonly data: File,
|
||||
@Inject(MAT_DIALOG_DATA) readonly file: File,
|
||||
) {
|
||||
super(_injector, _dialogRef);
|
||||
this._dossier = this._activeDossiersService.find(this.data.dossierId);
|
||||
this._dossier = this._activeDossiersService.find(this.file.dossierId);
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
@ -42,11 +42,11 @@ export class DocumentInfoDialogComponent extends BaseDialogComponent implements
|
||||
|
||||
async save() {
|
||||
const attributeIdToValue = {
|
||||
...this.data.fileAttributes?.attributeIdToValue,
|
||||
...this.file.fileAttributes?.attributeIdToValue,
|
||||
...this.form.getRawValue(),
|
||||
};
|
||||
await firstValueFrom(this._fileAttributesService.setFileAttributes({ attributeIdToValue }, this.data.dossierId, this.data.fileId));
|
||||
await firstValueFrom(this._filesService.reload(this.data.dossierId, this.data.fileId));
|
||||
await firstValueFrom(this._fileAttributesService.setFileAttributes({ attributeIdToValue }, this.file.dossierId, this.file.fileId));
|
||||
await firstValueFrom(this._filesService.reload(this.file.dossierId, this.file));
|
||||
this._dialogRef.close(true);
|
||||
}
|
||||
|
||||
@ -55,7 +55,7 @@ export class DocumentInfoDialogComponent extends BaseDialogComponent implements
|
||||
this.attributes.reduce(
|
||||
(acc, attr) => ({
|
||||
...acc,
|
||||
[attr.id]: [this.data.fileAttributes?.attributeIdToValue[attr.id]],
|
||||
[attr.id]: [this.file.fileAttributes?.attributeIdToValue[attr.id]],
|
||||
}),
|
||||
{},
|
||||
),
|
||||
|
||||
@ -6,6 +6,7 @@ import {
|
||||
ConfirmationDialogInput,
|
||||
DefaultListingServices,
|
||||
IListable,
|
||||
IRouterPath,
|
||||
ListingComponent,
|
||||
LoadingService,
|
||||
SortingOrders,
|
||||
@ -25,7 +26,7 @@ import { workflowFileStatusTranslations } from '../../../translations/file-statu
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { UserService } from '@services/user.service';
|
||||
|
||||
interface FileListItem extends IFile, IListable {
|
||||
interface FileListItem extends IFile, IListable, IRouterPath {
|
||||
readonly canHardDelete: boolean;
|
||||
readonly canRestore: boolean;
|
||||
readonly restoreDate: string;
|
||||
@ -129,14 +130,13 @@ export class EditDossierDeletedDocumentsComponent extends ListingComponent<FileL
|
||||
disabledFn = (file: FileListItem) => !file.canRestore;
|
||||
|
||||
private async _restore(files: FileListItem[]): Promise<void> {
|
||||
const fileIds = files.map(f => f.fileId);
|
||||
await firstValueFrom(this._fileManagementService.restore(fileIds, this.dossier.id));
|
||||
const fileIds = files.map(f => f.id);
|
||||
await firstValueFrom(this._fileManagementService.restore(files, this.dossier.id));
|
||||
this._removeFromList(fileIds);
|
||||
await firstValueFrom(this._filesService.loadAll(files[0].dossierId));
|
||||
}
|
||||
|
||||
private async _hardDelete(files: FileListItem[]) {
|
||||
const fileIds = files.map(f => f.fileId);
|
||||
const fileIds = files.map(f => f.id);
|
||||
await firstValueFrom(this._fileManagementService.hardDelete(this.dossier.id, fileIds));
|
||||
this._removeFromList(fileIds);
|
||||
}
|
||||
@ -151,7 +151,7 @@ export class EditDossierDeletedDocumentsComponent extends ListingComponent<FileL
|
||||
}
|
||||
|
||||
private _toListItem(_file: IFile): FileListItem {
|
||||
const file = new File(_file, this._userService.getNameForId(_file.assignee));
|
||||
const file = new File(_file, this._userService.getNameForId(_file.assignee), this.dossier.routerPath);
|
||||
const restoreDate = this._getRestoreDate(_file.softDeleted);
|
||||
return {
|
||||
id: file.fileId,
|
||||
|
||||
@ -182,7 +182,7 @@ export class DossierOverviewBulkActionsComponent implements OnChanges {
|
||||
|
||||
this.#canToggleAnalysis = this._permissionsService.canToggleAnalysis(this.selectedFiles);
|
||||
|
||||
this.#canOcr = this.selectedFiles.reduce((acc, file) => acc && file.canBeOCRed, true);
|
||||
this.#canOcr = this._permissionsService.canOcrFile(this.selectedFiles);
|
||||
|
||||
this.#canSetToUnderReview = this._permissionsService.canSetUnderReview(this.selectedFiles) && !isWorkflow;
|
||||
|
||||
|
||||
@ -43,7 +43,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));
|
||||
await firstValueFrom(this._filesService.loadAll(this.dossier.dossierId, this.dossier.routerPath));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="downloadDossierAsCSV()"
|
||||
*ngIf="permissionsService.canDownloadCsvReport(dossier)"
|
||||
[disabled]="listingService.areSomeSelected$ | async"
|
||||
[tooltip]="'dossier-overview.header-actions.download-csv' | translate"
|
||||
icon="iqser:csv"
|
||||
|
||||
@ -57,7 +57,7 @@ export class DossierOverviewScreenHeaderComponent implements OnInit {
|
||||
async reanalyseDossier() {
|
||||
this._loadingService.start();
|
||||
try {
|
||||
await firstValueFrom(this._reanalysisService.reanalyzeDossier(this.dossier.dossierId, true));
|
||||
await firstValueFrom(this._reanalysisService.reanalyzeDossier(this.dossier, true));
|
||||
this._toaster.success(_('dossier-overview.reanalyse-dossier.success'));
|
||||
} catch (e) {
|
||||
this._toaster.error(_('dossier-overview.reanalyse-dossier.error'));
|
||||
|
||||
@ -142,7 +142,7 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
|
||||
this.addSubscription = this._dossiersService.dossierFileChanges$
|
||||
.pipe(
|
||||
filter(dossierId => dossierId === this.dossierId),
|
||||
switchMap(dossierId => this._filesService.loadAll(dossierId)),
|
||||
switchMap(dossierId => this._filesService.loadAll(dossierId, this._dossiersService.routerPath)),
|
||||
)
|
||||
.subscribe();
|
||||
|
||||
|
||||
@ -29,13 +29,7 @@ export class BulkActionsService {
|
||||
this._assignFiles(files, 'approver', true);
|
||||
} else {
|
||||
this._loadingService.start();
|
||||
await firstValueFrom(
|
||||
this._filesService.setUnderApprovalFor(
|
||||
files.map(f => f.id),
|
||||
dossier.id,
|
||||
dossier.approverIds[0],
|
||||
),
|
||||
);
|
||||
await firstValueFrom(this._filesService.setUnderApprovalFor(files, dossier.id, dossier.approverIds[0]));
|
||||
this._loadingService.stop();
|
||||
}
|
||||
}
|
||||
@ -46,12 +40,7 @@ export class BulkActionsService {
|
||||
|
||||
async ocr(files: File[]) {
|
||||
this._loadingService.start();
|
||||
await firstValueFrom(
|
||||
this._reanalysisService.ocrFiles(
|
||||
files.map(f => f.fileId),
|
||||
files[0].dossierId,
|
||||
),
|
||||
);
|
||||
await firstValueFrom(this._reanalysisService.ocrFiles(files, files[0].dossierId));
|
||||
this._loadingService.stop();
|
||||
}
|
||||
|
||||
@ -65,12 +54,7 @@ export class BulkActionsService {
|
||||
}),
|
||||
async () => {
|
||||
this._loadingService.start();
|
||||
await firstValueFrom(
|
||||
this._fileManagementService.delete(
|
||||
files.map(item => item.fileId),
|
||||
files[0].dossierId,
|
||||
),
|
||||
);
|
||||
await firstValueFrom(this._fileManagementService.delete(files, files[0].dossierId));
|
||||
this._loadingService.stop();
|
||||
},
|
||||
);
|
||||
@ -78,9 +62,8 @@ export class BulkActionsService {
|
||||
|
||||
async reanalyse(files: File[]) {
|
||||
this._loadingService.start();
|
||||
const fileIds = files.map(file => file.fileId);
|
||||
await firstValueFrom(
|
||||
this._reanalysisService.reanalyzeFilesForDossier(fileIds, files[0].dossierId, { force: true, triggeredByUser: true }),
|
||||
this._reanalysisService.reanalyzeFilesForDossier(files, files[0].dossierId, { force: true, triggeredByUser: true }),
|
||||
);
|
||||
this._loadingService.stop();
|
||||
}
|
||||
@ -93,24 +76,13 @@ export class BulkActionsService {
|
||||
|
||||
async toggleAnalysis(files: File[], excluded: boolean) {
|
||||
this._loadingService.start();
|
||||
await firstValueFrom(
|
||||
this._reanalysisService.toggleAnalysis(
|
||||
files[0].dossierId,
|
||||
files.map(f => f.id),
|
||||
excluded,
|
||||
),
|
||||
);
|
||||
await firstValueFrom(this._reanalysisService.toggleAnalysis(files[0].dossierId, files, excluded));
|
||||
this._loadingService.stop();
|
||||
}
|
||||
|
||||
async backToUnderReview(files: File[]): Promise<void> {
|
||||
this._loadingService.start();
|
||||
await firstValueFrom(
|
||||
this._filesService.setUnderReviewFor(
|
||||
files.map(f => f.id),
|
||||
files[0].dossierId,
|
||||
),
|
||||
);
|
||||
await firstValueFrom(this._filesService.setUnderReviewFor(files, files[0].dossierId));
|
||||
this._loadingService.stop();
|
||||
}
|
||||
|
||||
@ -135,23 +107,13 @@ export class BulkActionsService {
|
||||
}),
|
||||
async () => {
|
||||
this._loadingService.start();
|
||||
await firstValueFrom(
|
||||
this._filesService.setApprovedFor(
|
||||
files.map(f => f.id),
|
||||
files[0].dossierId,
|
||||
),
|
||||
);
|
||||
await firstValueFrom(this._filesService.setApprovedFor(files, files[0].dossierId));
|
||||
this._loadingService.stop();
|
||||
},
|
||||
);
|
||||
} else {
|
||||
this._loadingService.start();
|
||||
await firstValueFrom(
|
||||
this._filesService.setApprovedFor(
|
||||
files.map(f => f.id),
|
||||
files[0].dossierId,
|
||||
),
|
||||
);
|
||||
await firstValueFrom(this._filesService.setApprovedFor(files, files[0].dossierId));
|
||||
this._loadingService.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,15 +2,15 @@
|
||||
<iqser-circle-button
|
||||
(action)="openEditDossierDialog($event, dossier.dossierId)"
|
||||
*ngIf="currentUser.isUser"
|
||||
[icon]="currentUser.isManager ? 'iqser:edit' : 'red:info'"
|
||||
[scrollableParentView]="scrollableParentView"
|
||||
[tooltip]="(currentUser.isManager ? 'dossier-listing.edit.action' : 'dossier-listing.dossier-info.action') | translate"
|
||||
[type]="circleButtonTypes.dark"
|
||||
[icon]="currentUser.isManager ? 'iqser:edit' : 'red:info'"
|
||||
iqserHelpMode="edit_dossier"
|
||||
[scrollableParentView]="scrollableParentView"
|
||||
></iqser-circle-button>
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="reanalyseDossier($event, dossier.dossierId)"
|
||||
(action)="reanalyseDossier($event, dossier)"
|
||||
*ngIf="displayReanalyseBtn"
|
||||
[tooltip]="'dossier-listing.reanalyse.action' | translate"
|
||||
[type]="circleButtonTypes.dark"
|
||||
@ -19,8 +19,8 @@
|
||||
|
||||
<redaction-file-download-btn
|
||||
[files]="files"
|
||||
[scrollableParentView]="scrollableParentView"
|
||||
[type]="circleButtonTypes.dark"
|
||||
iqserHelpMode="download_dossier"
|
||||
[scrollableParentView]="scrollableParentView"
|
||||
></redaction-file-download-btn>
|
||||
</div>
|
||||
|
||||
@ -56,8 +56,8 @@ export class DossiersListingActionsComponent implements OnChanges {
|
||||
this._dialogService.openDialog('editDossier', $event, { dossierId });
|
||||
}
|
||||
|
||||
async reanalyseDossier($event: MouseEvent, id: string): Promise<void> {
|
||||
async reanalyseDossier($event: MouseEvent, dossier: Dossier): Promise<void> {
|
||||
$event.stopPropagation();
|
||||
await firstValueFrom(this._reanalysisService.reanalyzeDossier(id));
|
||||
await firstValueFrom(this._reanalysisService.reanalyzeDossier(dossier));
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ import { MultiSelectService } from '../../services/multi-select.service';
|
||||
import { AnnotationReferencesService } from '../../services/annotation-references.service';
|
||||
import { ViewModeService } from '../../services/view-mode.service';
|
||||
import { FilePreviewStateService } from '../../services/file-preview-state.service';
|
||||
import { UserPreferenceService } from '../../../../../../services/user-preference.service';
|
||||
import { UserPreferenceService } from '@services/user-preference.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-annotations-list',
|
||||
|
||||
@ -34,7 +34,7 @@
|
||||
<div *ngIf="state.isReadonly$ | async" class="justify-center banner read-only d-flex">
|
||||
<div class="flex-center">
|
||||
<mat-icon class="primary-white" svgIcon="red:read-only"></mat-icon>
|
||||
<span class="read-only-text" translate="readonly"></span>
|
||||
<span [translate]="(state.dossier$ | async).isActive ? 'readonly' : 'readonly-archived'" class="read-only-text"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -67,7 +67,7 @@ export class PageExclusionComponent {
|
||||
endPage,
|
||||
};
|
||||
});
|
||||
const excludePages$ = this._reanalysisService.excludePages({ pageRanges }, this._state.dossierId, this._state.fileId);
|
||||
const excludePages$ = this._reanalysisService.excludePages({ pageRanges }, file.dossierId, file);
|
||||
await firstValueFrom(excludePages$);
|
||||
this._inputComponent.reset();
|
||||
} catch (e) {
|
||||
@ -78,12 +78,13 @@ export class PageExclusionComponent {
|
||||
|
||||
async includePagesRange(range: IPageRange): Promise<void> {
|
||||
this._loadingService.start();
|
||||
const file = await this._state.file;
|
||||
const includePages$ = this._reanalysisService.includePages(
|
||||
{
|
||||
pageRanges: [range],
|
||||
},
|
||||
this._state.dossierId,
|
||||
this._state.fileId,
|
||||
file.dossierId,
|
||||
file,
|
||||
);
|
||||
await firstValueFrom(includePages$);
|
||||
this._inputComponent.reset();
|
||||
|
||||
@ -96,15 +96,15 @@ export class UserManagementComponent {
|
||||
const assigneeId = typeof user === 'string' ? user : user?.id;
|
||||
const reviewerName = this.userService.getNameForId(assigneeId);
|
||||
|
||||
const { dossierId, fileId, filename } = file;
|
||||
const { dossierId, filename } = file;
|
||||
this.loadingService.start();
|
||||
|
||||
if (!assigneeId) {
|
||||
await firstValueFrom(this.filesService.setUnassigned([fileId], dossierId));
|
||||
await firstValueFrom(this.filesService.setUnassigned([file], dossierId));
|
||||
} else if (file.isNew || file.isUnderReview) {
|
||||
await firstValueFrom(this.filesService.setReviewerFor([fileId], dossierId, assigneeId));
|
||||
await firstValueFrom(this.filesService.setReviewerFor([file], dossierId, assigneeId));
|
||||
} else if (file.isUnderApproval) {
|
||||
await firstValueFrom(this.filesService.setUnderApprovalFor([fileId], dossierId, assigneeId));
|
||||
await firstValueFrom(this.filesService.setUnderApprovalFor([file], dossierId, assigneeId));
|
||||
}
|
||||
|
||||
this.loadingService.stop();
|
||||
|
||||
@ -219,7 +219,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
|
||||
const file = await this.stateService.file;
|
||||
if (file?.analysisRequired && !file.excludedFromAutomaticAnalysis) {
|
||||
const reanalyzeFiles = this._reanalysisService.reanalyzeFilesForDossier([this.fileId], this.dossierId, { force: true });
|
||||
const reanalyzeFiles = this._reanalysisService.reanalyzeFilesForDossier([file], this.dossierId, { force: true });
|
||||
await firstValueFrom(reanalyzeFiles);
|
||||
}
|
||||
|
||||
@ -416,7 +416,8 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
|
||||
async annotationsChangedByReviewAction(annotation?: AnnotationWrapper) {
|
||||
this.multiSelectService.deactivate();
|
||||
const fileReloaded = await firstValueFrom(this._filesService.reload(this.dossierId, this.fileId));
|
||||
const file = await this.stateService.file;
|
||||
const fileReloaded = await firstValueFrom(this._filesService.reload(this.dossierId, file));
|
||||
if (!fileReloaded) {
|
||||
await this._reloadAnnotationsForPage(annotation?.pageNumber ?? this.activeViewerPage);
|
||||
}
|
||||
@ -541,7 +542,10 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
|
||||
private _subscribeToFileUpdates(): void {
|
||||
this.addActiveScreenSubscription = timer(0, 5000)
|
||||
.pipe(switchMap(() => this._filesService.reload(this.dossierId, this.fileId)))
|
||||
.pipe(
|
||||
switchMap(() => this.stateService.file$),
|
||||
switchMap(file => this._filesService.reload(this.dossierId, file)),
|
||||
)
|
||||
.subscribe();
|
||||
|
||||
this.addActiveScreenSubscription = this._activeDossiersService
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, Injector } 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 { 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';
|
||||
@ -10,6 +9,8 @@ import { boolFactory, shareLast } from '@iqser/common-ui';
|
||||
import { filter, startWith } from 'rxjs/operators';
|
||||
import { FileManagementService } from '@services/entity-services/file-management.service';
|
||||
import { DOSSIER_ID, FILE_ID } from '@utils/constants';
|
||||
import { DossiersService } from '@services/entity-services/dossiers.service';
|
||||
import { dossiersServiceResolver } from '@services/entity-services/dossiers.service.provider';
|
||||
|
||||
@Injectable()
|
||||
export class FilePreviewStateService {
|
||||
@ -27,19 +28,19 @@ export class FilePreviewStateService {
|
||||
readonly #fileData$ = new BehaviorSubject<FileDataModel | undefined>(undefined);
|
||||
|
||||
constructor(
|
||||
activeDossiersService: ActiveDossiersService,
|
||||
filesMapService: FilesMapService,
|
||||
permissionsService: PermissionsService,
|
||||
activatedRoute: ActivatedRoute,
|
||||
private readonly _fileManagementService: FileManagementService,
|
||||
private readonly _injector: Injector,
|
||||
private readonly _route: ActivatedRoute,
|
||||
private readonly _filesMapService: FilesMapService,
|
||||
private readonly _permissionsService: PermissionsService,
|
||||
) {
|
||||
this.fileId = activatedRoute.snapshot.paramMap.get(FILE_ID);
|
||||
this.dossierId = activatedRoute.snapshot.paramMap.get(DOSSIER_ID);
|
||||
this.dossierTemplateId = activeDossiersService.find(this.dossierId).dossierTemplateId;
|
||||
this.fileId = _route.snapshot.paramMap.get(FILE_ID);
|
||||
this.dossierId = _route.snapshot.paramMap.get(DOSSIER_ID);
|
||||
this.dossierTemplateId = this._dossiersService.find(this.dossierId).dossierTemplateId;
|
||||
|
||||
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));
|
||||
this.dossier$ = this._dossiersService.getEntityChanged$(this.dossierId);
|
||||
this.file$ = _filesMapService.watch$(this.dossierId, this.fileId);
|
||||
[this.isReadonly$, this.isWritable$] = boolFactory(this.file$, file => !_permissionsService.canPerformAnnotationActions(file));
|
||||
|
||||
this.fileData$ = this.#fileData$.asObservable().pipe(filter(value => !!value));
|
||||
this.blob$ = this.#blob$;
|
||||
@ -65,6 +66,10 @@ export class FilePreviewStateService {
|
||||
return firstValueFrom(this.blob$);
|
||||
}
|
||||
|
||||
private get _dossiersService(): DossiersService {
|
||||
return dossiersServiceResolver(this._injector);
|
||||
}
|
||||
|
||||
get #blob$() {
|
||||
return this.file$.pipe(
|
||||
startWith(undefined),
|
||||
|
||||
@ -74,6 +74,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
|
||||
showUnderApproval = false;
|
||||
showApprove = false;
|
||||
canToggleAnalysis = false;
|
||||
showToggleAnalysis = false;
|
||||
showStatusBar = false;
|
||||
showOpenDocument = false;
|
||||
showReanalyseFilePreview = false;
|
||||
@ -127,28 +128,28 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
|
||||
return [
|
||||
{
|
||||
type: ActionTypes.circleBtn,
|
||||
action: $event => this._openDeleteFileDialog($event),
|
||||
action: ($event: MouseEvent) => this._openDeleteFileDialog($event),
|
||||
tooltip: _('dossier-overview.delete.action'),
|
||||
icon: 'iqser:trash',
|
||||
show: this.showDelete,
|
||||
},
|
||||
{
|
||||
type: ActionTypes.circleBtn,
|
||||
action: $event => this._assign($event),
|
||||
action: ($event: MouseEvent) => this._assign($event),
|
||||
tooltip: this.assignTooltip,
|
||||
icon: 'red:assign',
|
||||
show: this.showAssign,
|
||||
},
|
||||
{
|
||||
type: ActionTypes.circleBtn,
|
||||
action: $event => this._assignToMe($event),
|
||||
action: ($event: MouseEvent) => this._assignToMe($event),
|
||||
tooltip: _('dossier-overview.assign-me'),
|
||||
icon: 'red:assign-me',
|
||||
show: this.showAssignToSelf,
|
||||
},
|
||||
{
|
||||
type: ActionTypes.circleBtn,
|
||||
action: $event => this._triggerImportRedactions($event),
|
||||
action: ($event: MouseEvent) => this._triggerImportRedactions($event),
|
||||
tooltip: _('dossier-overview.import-redactions'),
|
||||
icon: 'iqser:upload',
|
||||
show: this.showImportRedactions,
|
||||
@ -178,21 +179,21 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
|
||||
},
|
||||
{
|
||||
type: ActionTypes.circleBtn,
|
||||
action: $event => this._setFileUnderApproval($event),
|
||||
action: ($event: MouseEvent) => this._setFileUnderApproval($event),
|
||||
tooltip: _('dossier-overview.under-approval'),
|
||||
icon: 'red:ready-for-approval',
|
||||
show: this.showUnderApproval,
|
||||
},
|
||||
{
|
||||
type: ActionTypes.circleBtn,
|
||||
action: $event => this._setFileUnderReview($event),
|
||||
action: ($event: MouseEvent) => this._setFileUnderReview($event),
|
||||
tooltip: _('dossier-overview.under-review'),
|
||||
icon: 'red:undo',
|
||||
show: this.showUnderReview,
|
||||
},
|
||||
{
|
||||
type: ActionTypes.circleBtn,
|
||||
action: $event => this.setFileApproved($event),
|
||||
action: ($event: MouseEvent) => this.setFileApproved($event),
|
||||
tooltip: this.file.canBeApproved ? _('dossier-overview.approve') : _('dossier-overview.approve-disabled'),
|
||||
icon: 'red:approved',
|
||||
disabled: !this.file.canBeApproved,
|
||||
@ -200,14 +201,14 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
|
||||
},
|
||||
{
|
||||
type: ActionTypes.circleBtn,
|
||||
action: $event => this.toggleAutomaticAnalysis($event),
|
||||
action: ($event: MouseEvent) => this.toggleAutomaticAnalysis($event),
|
||||
tooltip: _('dossier-overview.disable-auto-analysis'),
|
||||
icon: 'red:stop',
|
||||
show: this.canDisableAutoAnalysis,
|
||||
},
|
||||
{
|
||||
type: ActionTypes.circleBtn,
|
||||
action: $event => this._reanalyseFile($event),
|
||||
action: ($event: MouseEvent) => this._reanalyseFile($event),
|
||||
tooltip: _('file-preview.reanalyse-notification'),
|
||||
tooltipClass: 'warn small',
|
||||
icon: 'iqser:refresh',
|
||||
@ -215,7 +216,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
|
||||
},
|
||||
{
|
||||
type: ActionTypes.circleBtn,
|
||||
action: $event => this.toggleAutomaticAnalysis($event),
|
||||
action: ($event: MouseEvent) => this.toggleAutomaticAnalysis($event),
|
||||
tooltip: _('dossier-overview.enable-auto-analysis'),
|
||||
buttonType: this.isFilePreview ? CircleButtonTypes.warn : CircleButtonTypes.default,
|
||||
icon: 'red:play',
|
||||
@ -223,21 +224,21 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
|
||||
},
|
||||
{
|
||||
type: ActionTypes.circleBtn,
|
||||
action: $event => this._setFileUnderApproval($event),
|
||||
action: ($event: MouseEvent) => this._setFileUnderApproval($event),
|
||||
tooltip: _('dossier-overview.under-approval'),
|
||||
icon: 'red:undo',
|
||||
show: this.showUndoApproval,
|
||||
},
|
||||
{
|
||||
type: ActionTypes.circleBtn,
|
||||
action: $event => this._ocrFile($event),
|
||||
action: ($event: MouseEvent) => this._ocrFile($event),
|
||||
tooltip: _('dossier-overview.ocr-file'),
|
||||
icon: 'iqser:ocr',
|
||||
show: this.showOCR,
|
||||
},
|
||||
{
|
||||
type: ActionTypes.circleBtn,
|
||||
action: $event => this._reanalyseFile($event),
|
||||
action: ($event: MouseEvent) => this._reanalyseFile($event),
|
||||
tooltip: _('dossier-overview.reanalyse.action'),
|
||||
icon: 'iqser:refresh',
|
||||
show: this.showReanalyseDossierOverview,
|
||||
@ -249,7 +250,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
|
||||
tooltip: this.toggleTooltip,
|
||||
class: { 'mr-24': this.isDossierOverviewList },
|
||||
checked: !this.file.excluded,
|
||||
show: true,
|
||||
show: this.showToggleAnalysis,
|
||||
},
|
||||
].filter(btn => btn.show);
|
||||
}
|
||||
@ -331,7 +332,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
|
||||
this._loadingService.start();
|
||||
try {
|
||||
const dossier = this._activeDossiersService.find(this.file.dossierId);
|
||||
await firstValueFrom(this._fileManagementService.delete([this.file.fileId], this.file.dossierId));
|
||||
await firstValueFrom(this._fileManagementService.delete([this.file], this.file.dossierId));
|
||||
await this._router.navigate([dossier.routerLink]);
|
||||
} catch (error) {
|
||||
this._toaster.error(_('error.http.generic'), { params: error });
|
||||
@ -360,7 +361,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
|
||||
force: true,
|
||||
triggeredByUser: true,
|
||||
};
|
||||
await firstValueFrom(this._reanalysisService.reanalyzeFilesForDossier([this.file.fileId], this.file.dossierId, params));
|
||||
await firstValueFrom(this._reanalysisService.reanalyzeFilesForDossier([this.file], this.file.dossierId, params));
|
||||
}
|
||||
|
||||
private async toggleAutomaticAnalysis($event: MouseEvent) {
|
||||
@ -378,7 +379,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
|
||||
private async _ocrFile($event: MouseEvent) {
|
||||
$event.stopPropagation();
|
||||
this._loadingService.start();
|
||||
await firstValueFrom(this._reanalysisService.ocrFiles([this.file.fileId], this.file.dossierId));
|
||||
await firstValueFrom(this._reanalysisService.ocrFiles([this.file], this.file.dossierId));
|
||||
this._loadingService.stop();
|
||||
}
|
||||
|
||||
@ -388,7 +389,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
|
||||
|
||||
private async _toggleAnalysis() {
|
||||
this._loadingService.start();
|
||||
await firstValueFrom(this._reanalysisService.toggleAnalysis(this.file.dossierId, [this.file.fileId], !this.file.excluded));
|
||||
await firstValueFrom(this._reanalysisService.toggleAnalysis(this.file.dossierId, [this.file], !this.file.excluded));
|
||||
this._loadingService.stop();
|
||||
}
|
||||
|
||||
@ -410,8 +411,9 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
|
||||
this.showApprove = this._permissionsService.isReadyForApproval(this.file) && !this.isDossierOverviewWorkflow;
|
||||
|
||||
this.canToggleAnalysis = this._permissionsService.canToggleAnalysis(this.file);
|
||||
this.showToggleAnalysis = this._permissionsService.showToggleAnalysis(this.file);
|
||||
this.showDelete = this._permissionsService.canDeleteFile(this.file);
|
||||
this.showOCR = this.file.canBeOCRed;
|
||||
this.showOCR = this._permissionsService.canOcrFile(this.file);
|
||||
this.canReanalyse = this._permissionsService.canReanalyseFile(this.file);
|
||||
this.canDisableAutoAnalysis = this._permissionsService.canDisableAutoAnalysis([this.file]);
|
||||
this.canEnableAutoAnalysis = this._permissionsService.canEnableAutoAnalysis([this.file]);
|
||||
@ -437,7 +439,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
|
||||
|
||||
private async _setFileApproved() {
|
||||
this._loadingService.start();
|
||||
await firstValueFrom(this._filesService.setApprovedFor([this.file.id], this.file.dossierId));
|
||||
await firstValueFrom(this._filesService.setApprovedFor([this.file], this.file.dossierId));
|
||||
this._loadingService.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,28 +81,11 @@ export class FileAssignService {
|
||||
this._loadingService.start();
|
||||
try {
|
||||
if (!userId) {
|
||||
await firstValueFrom(
|
||||
this._filesService.setUnassigned(
|
||||
files.map(f => f.fileId),
|
||||
files[0].dossierId,
|
||||
),
|
||||
);
|
||||
await firstValueFrom(this._filesService.setUnassigned(files, files[0].dossierId));
|
||||
} else if (mode === 'reviewer') {
|
||||
await firstValueFrom(
|
||||
this._filesService.setReviewerFor(
|
||||
files.map(f => f.fileId),
|
||||
files[0].dossierId,
|
||||
userId,
|
||||
),
|
||||
);
|
||||
await firstValueFrom(this._filesService.setReviewerFor(files, files[0].dossierId, userId));
|
||||
} else {
|
||||
await firstValueFrom(
|
||||
this._filesService.setUnderApprovalFor(
|
||||
files.map(f => f.fileId),
|
||||
files[0].dossierId,
|
||||
userId,
|
||||
),
|
||||
);
|
||||
await firstValueFrom(this._filesService.setUnderApprovalFor(files, files[0].dossierId, userId));
|
||||
}
|
||||
} catch (error) {
|
||||
this._toaster.error(_('error.http.generic'), { params: error });
|
||||
@ -117,11 +100,7 @@ export class FileAssignService {
|
||||
private _assignReviewerToCurrentUser(files: File[]): Observable<any> {
|
||||
this._loadingService.start();
|
||||
return this._filesService
|
||||
.setReviewerFor(
|
||||
files.map(f => f.fileId),
|
||||
files[0].dossierId,
|
||||
this._userService.currentUser.id,
|
||||
)
|
||||
.setReviewerFor(files, files[0].dossierId, this._userService.currentUser.id)
|
||||
.pipe(tap(() => this._loadingService.stop()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ export class FileDownloadBtnComponent implements OnChanges {
|
||||
async downloadFiles($event: MouseEvent) {
|
||||
$event.stopPropagation();
|
||||
const dossierId = this.files[0].dossierId;
|
||||
const filesIds = this.files.map(f => f.fileId);
|
||||
const filesIds = this.files.map(f => f.id);
|
||||
await firstValueFrom(this._fileDownloadService.downloadFiles(filesIds, dossierId));
|
||||
this._toaster.info(_('download-status.queued'));
|
||||
}
|
||||
|
||||
@ -29,6 +29,10 @@ export class ExpandableFileActionsComponent implements OnChanges {
|
||||
private readonly _permissionsService: PermissionsService,
|
||||
) {}
|
||||
|
||||
get scrollableParentView(): ScrollableParentView {
|
||||
return this.helpModeKey === 'document_features' ? ScrollableParentViews.VIRTUAL_SCROLL : undefined;
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
if (changes.actions || changes.maxWidth) {
|
||||
if (this.maxWidth) {
|
||||
@ -59,12 +63,8 @@ export class ExpandableFileActionsComponent implements OnChanges {
|
||||
private async _downloadFiles($event: MouseEvent, files: File[]) {
|
||||
$event.stopPropagation();
|
||||
const dossierId = files[0].dossierId;
|
||||
const filesIds = files.map(f => f.fileId);
|
||||
const filesIds = files.map(f => f.id);
|
||||
await firstValueFrom(this._fileDownloadService.downloadFiles(filesIds, dossierId));
|
||||
this._toaster.info(_('download-status.queued'));
|
||||
}
|
||||
|
||||
get scrollableParentView(): ScrollableParentView {
|
||||
return this.helpModeKey === 'document_features' ? ScrollableParentViews.VIRTUAL_SCROLL : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ export class FileUploadService extends GenericService<IFileUploadResult> impleme
|
||||
super(_injector, 'upload');
|
||||
const fileFetch$ = this._fetchFiles$.pipe(
|
||||
throttleTime(250),
|
||||
switchMap(dossierId => this._filesService.loadAll(dossierId)),
|
||||
switchMap(dossierId => this._filesService.loadAll(dossierId, 'dossiers')),
|
||||
);
|
||||
this._subscriptions.add(fileFetch$.subscribe());
|
||||
const interval$ = interval(2500).pipe(tap(() => this._handleUploads()));
|
||||
|
||||
@ -90,7 +90,8 @@ export abstract class DossiersService extends EntitiesService<Dossier, IDossier>
|
||||
dossierChanges.filter(change => change.fileChanges).forEach(change => this.dossierFileChanges$.next(change.dossierId));
|
||||
}
|
||||
|
||||
private _load(id: string, queryParams?: List<QueryParam>): Observable<DossierStats[]> {
|
||||
private _load(id: string): Observable<DossierStats[]> {
|
||||
const queryParams: List<QueryParam> = [{ key: 'includeArchived', value: this._path === 'archived-dossiers' }];
|
||||
return super._getOne([id], this._defaultModelPath, queryParams).pipe(
|
||||
map(entity => new Dossier(entity, 'dossiers')),
|
||||
tap(dossier => this.replace(dossier)),
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { GenericService, HeadersConfiguration, List, QueryParam, RequiredParam, Validate } from '@iqser/common-ui';
|
||||
import { GenericService, HeadersConfiguration, IRouterPath, 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';
|
||||
@ -19,8 +19,10 @@ export class FileManagementService extends GenericService<unknown> {
|
||||
}
|
||||
|
||||
@Validate()
|
||||
delete(@RequiredParam() fileIds: List, @RequiredParam() dossierId: string) {
|
||||
return super._post(fileIds, `delete/${dossierId}`).pipe(switchMap(() => this._filesService.loadAll(dossierId)));
|
||||
delete(@RequiredParam() files: List<IRouterPath>, @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)));
|
||||
}
|
||||
|
||||
@Validate()
|
||||
@ -32,8 +34,10 @@ export class FileManagementService extends GenericService<unknown> {
|
||||
}
|
||||
|
||||
@Validate()
|
||||
restore(@RequiredParam() body: List, @RequiredParam() dossierId: string) {
|
||||
return this._post(body, `delete/restore/${dossierId}`).pipe(switchMap(() => this._filesService.loadAll(dossierId)));
|
||||
restore(@RequiredParam() files: List<IRouterPath>, @RequiredParam() dossierId: string) {
|
||||
const fileIds = files.map(f => f.id);
|
||||
const routerPath: string = files[0].routerPath;
|
||||
return this._post(fileIds, `delete/restore/${dossierId}`).pipe(switchMap(() => this._filesService.loadAll(dossierId, routerPath)));
|
||||
}
|
||||
|
||||
downloadOriginalFile(dossierId: string, fileId: string, observe?: 'body', indicator?: string): Observable<Blob>;
|
||||
|
||||
@ -12,7 +12,11 @@ export class FilesMapService extends EntitiesMapService<File, IFile> {
|
||||
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),
|
||||
new File(
|
||||
{ ...file, [property]: generateValue(file[property]), lastUpdated: new Date().toISOString() },
|
||||
file.reviewerName,
|
||||
file.routerPath,
|
||||
),
|
||||
);
|
||||
this.replace(newFiles);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { EntitiesService, List, mapEach, RequiredParam, Validate } from '@iqser/common-ui';
|
||||
import { EntitiesService, IRouterPath, List, mapEach, RequiredParam, Validate } from '@iqser/common-ui';
|
||||
import { File, IFile } from '@red/domain';
|
||||
import { Observable } from 'rxjs';
|
||||
import { UserService } from '../user.service';
|
||||
@ -21,40 +21,50 @@ export class FilesService extends EntitiesService<File, IFile> {
|
||||
}
|
||||
|
||||
/** Reload dossier files + stats. */
|
||||
loadAll(dossierId: string) {
|
||||
const files$ = this.getFor(dossierId).pipe(mapEach(file => new File(file, this._userService.getNameForId(file.assignee))));
|
||||
loadAll(dossierId: string, routerPath: string) {
|
||||
const files$ = this.getFor(dossierId).pipe(
|
||||
mapEach(file => new File(file, this._userService.getNameForId(file.assignee), routerPath)),
|
||||
);
|
||||
const loadStats$ = files$.pipe(switchMap(files => this._dossierStatsService.getFor([dossierId]).pipe(mapTo(files))));
|
||||
return loadStats$.pipe(tap(files => this._filesMapService.set(dossierId, files)));
|
||||
}
|
||||
|
||||
reload(dossierId: string, fileId: string): Observable<boolean> {
|
||||
return super._getOne([dossierId, fileId]).pipe(
|
||||
map(file => new File(file, this._userService.getNameForId(file.assignee))),
|
||||
switchMap(file => this._dossierStatsService.getFor([dossierId]).pipe(mapTo(file))),
|
||||
map(file => this._filesMapService.replace([file])),
|
||||
reload(dossierId: string, file: File): Observable<boolean> {
|
||||
return super._getOne([dossierId, file.id]).pipe(
|
||||
map(_file => new File(_file, this._userService.getNameForId(_file.assignee), file.routerPath)),
|
||||
switchMap(_file => this._dossierStatsService.getFor([dossierId]).pipe(mapTo(_file))),
|
||||
map(_file => this._filesMapService.replace([_file])),
|
||||
);
|
||||
}
|
||||
|
||||
@Validate()
|
||||
setUnassigned(@RequiredParam() fileIds: List, @RequiredParam() dossierId: string) {
|
||||
setUnassigned(@RequiredParam() files: List<IRouterPath>, @RequiredParam() dossierId: string) {
|
||||
const url = `${this._defaultModelPath}/set-assignee/${dossierId}/bulk`;
|
||||
return this._post<unknown>(fileIds, url).pipe(switchMap(() => this.loadAll(dossierId)));
|
||||
const fileIds = files.map(f => f.id);
|
||||
const routerPath: string = files[0].routerPath;
|
||||
return this._post<unknown>(fileIds, url).pipe(switchMap(() => this.loadAll(dossierId, routerPath)));
|
||||
}
|
||||
|
||||
@Validate()
|
||||
setUnderApprovalFor(@RequiredParam() fileIds: List, @RequiredParam() dossierId: string, assigneeId: string) {
|
||||
setUnderApprovalFor(@RequiredParam() files: List<IRouterPath>, @RequiredParam() dossierId: string, assigneeId: string) {
|
||||
const url = `${this._defaultModelPath}/under-approval/${dossierId}/bulk`;
|
||||
return this._post<unknown>(fileIds, url, [{ key: 'assigneeId', value: assigneeId }]).pipe(switchMap(() => this.loadAll(dossierId)));
|
||||
const fileIds = files.map(f => f.id);
|
||||
const routerPath: string = files[0].routerPath;
|
||||
return this._post<unknown>(fileIds, url, [{ key: 'assigneeId', value: assigneeId }]).pipe(
|
||||
switchMap(() => this.loadAll(dossierId, routerPath)),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a reviewer for a list of files.
|
||||
*/
|
||||
@Validate()
|
||||
setReviewerFor(@RequiredParam() filesIds: List, @RequiredParam() dossierId: string, assigneeId: string) {
|
||||
setReviewerFor(@RequiredParam() files: List<IRouterPath>, @RequiredParam() dossierId: string, assigneeId: string) {
|
||||
const url = `${this._defaultModelPath}/under-review/${dossierId}/bulk`;
|
||||
return this._post<unknown>(filesIds, url, [{ key: 'assigneeId', value: assigneeId }]).pipe(
|
||||
switchMap(() => this.loadAll(dossierId)),
|
||||
const fileIds = files.map(f => f.id);
|
||||
const routerPath: string = files[0].routerPath;
|
||||
return this._post<unknown>(fileIds, url, [{ key: 'assigneeId', value: assigneeId }]).pipe(
|
||||
switchMap(() => this.loadAll(dossierId, routerPath)),
|
||||
);
|
||||
}
|
||||
|
||||
@ -62,9 +72,11 @@ export class FilesService extends EntitiesService<File, IFile> {
|
||||
* Sets the status APPROVED for a list of files.
|
||||
*/
|
||||
@Validate()
|
||||
setApprovedFor(@RequiredParam() filesIds: List, @RequiredParam() dossierId: string) {
|
||||
return this._post<unknown>(filesIds, `${this._defaultModelPath}/approved/${dossierId}/bulk`).pipe(
|
||||
switchMap(() => this.loadAll(dossierId)),
|
||||
setApprovedFor(@RequiredParam() files: List<IRouterPath>, @RequiredParam() dossierId: string) {
|
||||
const fileIds = files.map(f => f.id);
|
||||
const routerPath: string = files[0].routerPath;
|
||||
return this._post<unknown>(fileIds, `${this._defaultModelPath}/approved/${dossierId}/bulk`).pipe(
|
||||
switchMap(() => this.loadAll(dossierId, routerPath)),
|
||||
);
|
||||
}
|
||||
|
||||
@ -72,9 +84,11 @@ export class FilesService extends EntitiesService<File, IFile> {
|
||||
* Sets the status UNDER_REVIEW for a list of files.
|
||||
*/
|
||||
@Validate()
|
||||
setUnderReviewFor(@RequiredParam() filesIds: List, @RequiredParam() dossierId: string) {
|
||||
return this._post<unknown>(filesIds, `${this._defaultModelPath}/under-review/${dossierId}/bulk`).pipe(
|
||||
switchMap(() => this.loadAll(dossierId)),
|
||||
setUnderReviewFor(@RequiredParam() files: List<IRouterPath>, @RequiredParam() dossierId: string) {
|
||||
const fileIds = files.map(f => f.id);
|
||||
const routerPath: string = files[0].routerPath;
|
||||
return this._post<unknown>(fileIds, `${this._defaultModelPath}/under-review/${dossierId}/bulk`).pipe(
|
||||
switchMap(() => this.loadAll(dossierId, routerPath)),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { GenericService } from '@iqser/common-ui';
|
||||
import { IMatchedDocument, ISearchInput, ISearchRequest, ISearchResponse } from '@red/domain';
|
||||
import { Dossier, IMatchedDocument, ISearchInput, ISearchRequest, ISearchResponse } from '@red/domain';
|
||||
import { Observable, of, zip } from 'rxjs';
|
||||
import { mapTo, switchMap } from 'rxjs/operators';
|
||||
import { ActiveDossiersService } from './active-dossiers.service';
|
||||
@ -44,11 +44,11 @@ export class PlatformSearchService extends GenericService<ISearchResponse> {
|
||||
const fileNotLoaded = ({ dossierId, fileId }: IMatchedDocument) => !this._filesMapService.get(dossierId, fileId);
|
||||
const dossiersWithNotLoadedFiles = documentsOfActiveDossiers.filter(fileNotLoaded).map(document => document.dossierId);
|
||||
|
||||
const dossierIds = Array.from(new Set(dossiersWithNotLoadedFiles));
|
||||
return dossierIds.length ? this._loadFilesFor$(dossierIds).pipe(mapTo(searchResponse)) : of(searchResponse);
|
||||
const dossiers = Array.from(new Set(dossiersWithNotLoadedFiles)).map(dossierId => this._activeDossiersService.find(dossierId));
|
||||
return dossiers.length ? this._loadFilesFor$(dossiers).pipe(mapTo(searchResponse)) : of(searchResponse);
|
||||
}
|
||||
|
||||
private _loadFilesFor$(dossierIds: string[]) {
|
||||
return zip(...dossierIds.map(dossierId => this._filesService.loadAll(dossierId)));
|
||||
private _loadFilesFor$(dossiers: Dossier[]) {
|
||||
return zip(...dossiers.map(dossier => this._filesService.loadAll(dossier.id, dossier.routerPath)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,6 +30,10 @@ export class PermissionsService {
|
||||
return dossier.isActive;
|
||||
}
|
||||
|
||||
canDownloadCsvReport(dossier: Dossier): boolean {
|
||||
return dossier.isActive;
|
||||
}
|
||||
|
||||
canEditFileAttributes(file: File): boolean {
|
||||
const dossier = this._getDossier(file);
|
||||
return ((file.isUnderReview || file.isNew) && this.isDossierMember(dossier)) || (file.isUnderApproval && this.isApprover(dossier));
|
||||
@ -41,6 +45,11 @@ export class PermissionsService {
|
||||
return sameState && files.reduce((acc, _file) => this._canToggleAnalysis(_file) && acc, true);
|
||||
}
|
||||
|
||||
showToggleAnalysis(file: File | File[]): boolean {
|
||||
const files = file instanceof File ? [file] : file;
|
||||
return this._isActive(files[0]);
|
||||
}
|
||||
|
||||
canReanalyseFile(file: File | File[]): boolean {
|
||||
const files = file instanceof File ? [file] : file;
|
||||
return files.reduce((acc, _file) => this._canReanalyseFile(_file) && acc, true);
|
||||
@ -64,6 +73,12 @@ export class PermissionsService {
|
||||
return files.reduce((acc, _file) => this._canDeleteFile(_file, dossier) && acc, true);
|
||||
}
|
||||
|
||||
canOcrFile(file: File | File[]): boolean {
|
||||
const files = file instanceof File ? [file] : file;
|
||||
const dossier = this._getDossier(files[0]);
|
||||
return files.reduce((acc, _file) => this._canOcrFile(_file, dossier) && acc, true);
|
||||
}
|
||||
|
||||
canAssignToSelf(file: File | File[]): boolean {
|
||||
const files = file instanceof File ? [file] : file;
|
||||
const dossier = this._getDossier(files[0]);
|
||||
@ -120,7 +135,7 @@ export class PermissionsService {
|
||||
|
||||
// TODO: Remove '?', after we make sure file is loaded before page
|
||||
canPerformAnnotationActions(file: File): boolean {
|
||||
return !file.excluded && (file?.isUnderReview || file?.isUnderApproval) && this.isFileAssignee(file);
|
||||
return this._isActive(file) && !file.excluded && (file?.isUnderReview || file?.isUnderApproval) && this.isFileAssignee(file);
|
||||
}
|
||||
|
||||
canUndoApproval(file: File | File[]): boolean {
|
||||
@ -171,54 +186,60 @@ export class PermissionsService {
|
||||
}
|
||||
|
||||
canImportRedactions(file: File) {
|
||||
return (this.isFileAssignee(file) || this.isApprover(this._getDossier(file))) && !file.isApproved;
|
||||
return this._isActive(file) && (this.isFileAssignee(file) || this.isApprover(this._getDossier(file))) && !file.isApproved;
|
||||
}
|
||||
|
||||
private _canOcrFile(file: File, dossier: Dossier): boolean {
|
||||
return dossier.isActive && file.canBeOCRed;
|
||||
}
|
||||
|
||||
private _canToggleAnalysis(file: File): boolean {
|
||||
return this.isFileAssignee(file) && (file.isNew || file.isUnderReview || file.isUnderApproval);
|
||||
return this._isActive(file) && this.isFileAssignee(file) && (file.isNew || file.isUnderReview || file.isUnderApproval);
|
||||
}
|
||||
|
||||
// https://jira.iqser.com/browse/RED-2787
|
||||
private _canDeleteFile(file: File, dossier: Dossier): boolean {
|
||||
return (
|
||||
file.isNew ||
|
||||
(file.isUnderReview && !file.assignee && this.isDossierMember(dossier)) ||
|
||||
(file.isUnderApproval && !file.assignee && this.isApprover(dossier)) ||
|
||||
(file.assignee && !file.isApproved && (this.isFileAssignee(file) || this.isOwner(dossier)))
|
||||
dossier.isActive &&
|
||||
(file.isNew ||
|
||||
(file.isUnderReview && !file.assignee && this.isDossierMember(dossier)) ||
|
||||
(file.isUnderApproval && !file.assignee && this.isApprover(dossier)) ||
|
||||
(file.assignee && !file.isApproved && (this.isFileAssignee(file) || this.isOwner(dossier))))
|
||||
);
|
||||
}
|
||||
|
||||
private _canReanalyseFile(file: File): boolean {
|
||||
return this.isReviewerOrApprover(file) && file.analysisRequired;
|
||||
return this._isActive(file) && this.isReviewerOrApprover(file) && file.analysisRequired;
|
||||
}
|
||||
|
||||
private _canEnableAutoAnalysis(file: File): boolean {
|
||||
return file.excludedFromAutomaticAnalysis && file.assignee === this._userService.currentUser.id;
|
||||
return this._isActive(file) && file.excludedFromAutomaticAnalysis && file.assignee === this._userService.currentUser.id;
|
||||
}
|
||||
|
||||
private _canDisableAutoAnalysis(file: File): boolean {
|
||||
return !file.excludedFromAutomaticAnalysis && file.assignee === this._userService.currentUser.id;
|
||||
return this._isActive(file) && !file.excludedFromAutomaticAnalysis && file.assignee === this._userService.currentUser.id;
|
||||
}
|
||||
|
||||
private _canAssignToSelf(file: File, dossier: Dossier): boolean {
|
||||
const precondition = this.isDossierMember(dossier) && !this.isFileAssignee(file) && !file.isError && !file.isProcessing;
|
||||
const precondition =
|
||||
this._isActive(file) && this.isDossierMember(dossier) && !this.isFileAssignee(file) && !file.isError && !file.isProcessing;
|
||||
return precondition && (file.isNew || file.isUnderReview || (file.isUnderApproval && this.isApprover(dossier)));
|
||||
}
|
||||
|
||||
private _canSetUnderApproval(file: File): boolean {
|
||||
return file.isUnderReview && this.isReviewerOrApprover(file);
|
||||
return this._isActive(file) && file.isUnderReview && this.isReviewerOrApprover(file);
|
||||
}
|
||||
|
||||
private _canUndoApproval(file: File, dossier: Dossier): boolean {
|
||||
return file.isApproved && this.isApprover(dossier);
|
||||
return this._isActive(file) && file.isApproved && this.isApprover(dossier);
|
||||
}
|
||||
|
||||
private _canBeApproved(file: File): boolean {
|
||||
return file.canBeApproved;
|
||||
return this._isActive(file) && file.canBeApproved;
|
||||
}
|
||||
|
||||
private _canAssignUser(file: File, dossier: Dossier) {
|
||||
const precondition = !file.isProcessing && !file.isError && !file.isApproved && this.isApprover(dossier);
|
||||
const precondition = this._isActive(file) && !file.isProcessing && !file.isError && !file.isApproved && this.isApprover(dossier);
|
||||
|
||||
if (precondition) {
|
||||
if ((file.isNew || file.isUnderReview) && dossier.hasReviewers) {
|
||||
@ -232,14 +253,20 @@ export class PermissionsService {
|
||||
}
|
||||
|
||||
private _canUnassignUser(file: File, dossier: Dossier) {
|
||||
return (file.isUnderReview || file.isUnderApproval) && (this.isFileAssignee(file) || this.isApprover(dossier));
|
||||
return (
|
||||
this._isActive(file) && (file.isUnderReview || file.isUnderApproval) && (this.isFileAssignee(file) || this.isApprover(dossier))
|
||||
);
|
||||
}
|
||||
|
||||
private _canSetUnderReview(file: File): boolean {
|
||||
return file.isUnderApproval;
|
||||
return this._isActive(file) && file.isUnderApproval;
|
||||
}
|
||||
|
||||
private _getDossier(file: File): Dossier {
|
||||
return this._dossiersService.find(file.dossierId);
|
||||
}
|
||||
|
||||
private _isActive(file: File): boolean {
|
||||
return this._getDossier(file).isActive;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { GenericService, List, QueryParam, RequiredParam, Toaster, Validate } from '@iqser/common-ui';
|
||||
import { File, IPageExclusionRequest } from '@red/domain';
|
||||
import { GenericService, IRouterPath, 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';
|
||||
import { FilesMapService } from './entity-services/files-map.service';
|
||||
@ -26,17 +26,19 @@ export class ReanalysisService extends GenericService<unknown> {
|
||||
}
|
||||
|
||||
@Validate()
|
||||
excludePages(@RequiredParam() body: IPageExclusionRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
|
||||
return this._post(body, `exclude-pages/${dossierId}/${fileId}`).pipe(switchMap(() => this._filesService.reload(dossierId, fileId)));
|
||||
excludePages(@RequiredParam() body: IPageExclusionRequest, @RequiredParam() dossierId: string, @RequiredParam() file: File) {
|
||||
return this._post(body, `exclude-pages/${dossierId}/${file.id}`).pipe(switchMap(() => this._filesService.reload(dossierId, file)));
|
||||
}
|
||||
|
||||
@Validate()
|
||||
includePages(@RequiredParam() body: IPageExclusionRequest, @RequiredParam() dossierId: string, @RequiredParam() fileId: string) {
|
||||
return this._post(body, `include-pages/${dossierId}/${fileId}`).pipe(switchMap(() => this._filesService.reload(dossierId, fileId)));
|
||||
includePages(@RequiredParam() body: IPageExclusionRequest, @RequiredParam() dossierId: string, @RequiredParam() file: File) {
|
||||
return this._post(body, `include-pages/${dossierId}/${file.id}`).pipe(switchMap(() => this._filesService.reload(dossierId, file)));
|
||||
}
|
||||
|
||||
@Validate()
|
||||
reanalyzeFilesForDossier(@RequiredParam() fileIds: List, @RequiredParam() dossierId: string, params?: ReanalyzeQueryParams) {
|
||||
reanalyzeFilesForDossier(@RequiredParam() files: List<IRouterPath>, @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 });
|
||||
@ -45,18 +47,22 @@ export class ReanalysisService extends GenericService<unknown> {
|
||||
queryParams.push({ key: 'triggeredByUser', value: true });
|
||||
}
|
||||
|
||||
return this._post(fileIds, `reanalyze/${dossierId}/bulk`, queryParams).pipe(switchMap(() => this._filesService.loadAll(dossierId)));
|
||||
return this._post(fileIds, `reanalyze/${dossierId}/bulk`, queryParams).pipe(
|
||||
switchMap(() => this._filesService.loadAll(dossierId, routerPath)),
|
||||
);
|
||||
}
|
||||
|
||||
@Validate()
|
||||
toggleAnalysis(@RequiredParam() dossierId: string, @RequiredParam() fileIds: string[], excluded?: boolean) {
|
||||
toggleAnalysis(@RequiredParam() dossierId: string, @RequiredParam() files: List<IRouterPath>, 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)),
|
||||
switchMap(() => this._filesService.loadAll(dossierId, routerPath)),
|
||||
);
|
||||
}
|
||||
|
||||
@ -80,17 +86,24 @@ export class ReanalysisService extends GenericService<unknown> {
|
||||
}
|
||||
|
||||
@Validate()
|
||||
ocrFiles(@RequiredParam() fileIds: List, @RequiredParam() dossierId: string) {
|
||||
return this._post(fileIds, `ocr/reanalyze/${dossierId}/bulk`).pipe(switchMap(() => this._filesService.loadAll(dossierId)));
|
||||
ocrFiles(@RequiredParam() files: List<IRouterPath>, @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)),
|
||||
);
|
||||
}
|
||||
|
||||
@Validate()
|
||||
reanalyzeDossier(@RequiredParam() dossierId: string, force?: boolean) {
|
||||
reanalyzeDossier(@RequiredParam() dossier: Dossier, force?: boolean) {
|
||||
const { dossierId, routerPath } = dossier;
|
||||
const queryParams: QueryParam[] = [];
|
||||
if (force) {
|
||||
queryParams.push({ key: 'force', value: force });
|
||||
}
|
||||
|
||||
return this._post({}, `reanalyze/${dossierId}`, queryParams).pipe(switchMap(() => this._filesService.loadAll(dossierId)));
|
||||
return this._post({}, `reanalyze/${dossierId}`, queryParams).pipe(
|
||||
switchMap(() => this._filesService.loadAll(dossierId, routerPath)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"ADMIN_CONTACT_NAME": null,
|
||||
"ADMIN_CONTACT_URL": null,
|
||||
"API_URL": "https://dev-04.iqser.cloud/redaction-gateway-v1",
|
||||
"API_URL": "https://dev-05.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-04.iqser.cloud/auth/realms/redaction",
|
||||
"OAUTH_URL": "https://dev-05.iqser.cloud/auth/realms/redaction",
|
||||
"RECENT_PERIOD_IN_HOURS": 24,
|
||||
"SELECTION_MODE": "structural",
|
||||
"MANUAL_BASE_URL": "https://docs.redactmanager.com/preview"
|
||||
|
||||
@ -322,7 +322,7 @@
|
||||
},
|
||||
"table-col-names": {
|
||||
"dossier-status": "Dossier Status",
|
||||
"last-modified": "Last Modified",
|
||||
"last-modified": "Archived Time",
|
||||
"name": "Name",
|
||||
"owner": "Owner"
|
||||
},
|
||||
@ -1251,6 +1251,7 @@
|
||||
"reanalyse-notification": "This document was not processed with the latest rule/dictionary set. Analyze now to get updated annotations.",
|
||||
"redacted": "Preview",
|
||||
"redacted-tooltip": "Redaction preview shows only redactions. Consider this a preview for the final redacted version. This view is only available if the file has no pending changes & doesn't require a reanalysis",
|
||||
"reset-filters": "",
|
||||
"standard": "Standard",
|
||||
"standard-tooltip": "Standard Workload view shows all hints, redactions, recommendations & suggestions. This view allows editing.",
|
||||
"tabs": {
|
||||
@ -1587,6 +1588,7 @@
|
||||
"processing": "Processing"
|
||||
},
|
||||
"readonly": "Read only",
|
||||
"readonly-archived": "Read only (archived)",
|
||||
"recategorize-image-dialog": {
|
||||
"actions": {
|
||||
"cancel": "Cancel",
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit f480a52cc384eea5ab54fb3b7bbc5db431c1506c
|
||||
Subproject commit 242789330301767bc38fe62651ea777297159bb3
|
||||
@ -1,9 +1,9 @@
|
||||
import { IListable, List } from '@iqser/common-ui';
|
||||
import { IListable, IRouterPath, List } from '@iqser/common-ui';
|
||||
import { IDossier } from './dossier';
|
||||
import { DossierStatus, DossierStatuses } from './types';
|
||||
import { DownloadFileType } from '../shared';
|
||||
|
||||
export class Dossier implements IDossier, IListable {
|
||||
export class Dossier implements IDossier, IListable, IRouterPath {
|
||||
readonly dossierId: string;
|
||||
readonly dossierTemplateId: string;
|
||||
readonly ownerId: string;
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import { Entity } from '@iqser/common-ui';
|
||||
import { Entity, IRouterPath } from '@iqser/common-ui';
|
||||
import { StatusSorter } from '../shared';
|
||||
import { isProcessingStatuses, ProcessingFileStatus, ProcessingFileStatuses, WorkflowFileStatus, WorkflowFileStatuses } from './types';
|
||||
import { IFile } from './file';
|
||||
import { FileAttributes } from '../file-attributes';
|
||||
|
||||
export class File extends Entity<IFile> implements IFile {
|
||||
export class File extends Entity<IFile> implements IFile, IRouterPath {
|
||||
readonly added?: string;
|
||||
readonly allManualRedactionsApplied: boolean;
|
||||
readonly analysisDuration?: number;
|
||||
@ -57,7 +57,7 @@ export class File extends Entity<IFile> implements IFile {
|
||||
readonly canBeOpened: boolean;
|
||||
readonly canBeOCRed: boolean;
|
||||
|
||||
constructor(file: IFile, readonly reviewerName: string) {
|
||||
constructor(file: IFile, readonly reviewerName: string, readonly routerPath: string) {
|
||||
super(file);
|
||||
this.added = file.added;
|
||||
this.allManualRedactionsApplied = !!file.allManualRedactionsApplied;
|
||||
@ -125,6 +125,6 @@ export class File extends Entity<IFile> implements IFile {
|
||||
}
|
||||
|
||||
get routerLink(): string | undefined {
|
||||
return this.canBeOpened ? `/main/dossiers/${this.dossierId}/file/${this.fileId}` : undefined;
|
||||
return this.canBeOpened ? `/main/${this.routerPath}/${this.dossierId}/file/${this.fileId}` : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user