add new files map service
This commit is contained in:
parent
9ba4120aa0
commit
fc05e3bd42
@ -51,6 +51,8 @@ import { DossierTemplatesService } from '@services/entity-services/dossier-templ
|
||||
import { LongPressEvent } from '@shared/directives/long-press.directive';
|
||||
import { UserPreferenceService } from '@services/user-preference.service';
|
||||
import { saveAsCSV } from '@utils/csv-utils';
|
||||
import { FilesService } from '@services/entity-services/files.service';
|
||||
import { FilesMapService } from '@services/entity-services/files-map.service';
|
||||
|
||||
@Component({
|
||||
templateUrl: './dossier-overview-screen.component.html',
|
||||
@ -70,7 +72,7 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
|
||||
analysisForced: boolean;
|
||||
displayedInFileListAttributes: IFileAttributeConfig[] = [];
|
||||
displayedAttributes: IFileAttributeConfig[] = [];
|
||||
readonly workflowConfig: WorkflowConfig<File, FileStatus> = this._configService.workflowConfig(() => this.reloadDossiers());
|
||||
readonly workflowConfig: WorkflowConfig<File, FileStatus> = this._configService.workflowConfig(() => this.reloadFiles());
|
||||
readonly actionConfigs: readonly ActionConfig[];
|
||||
readonly dossier$: Observable<Dossier>;
|
||||
readonly dossierId: string;
|
||||
@ -102,6 +104,8 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
|
||||
private readonly _fileAttributesService: FileAttributesService,
|
||||
private readonly _configService: ConfigService,
|
||||
private readonly _userPreferenceService: UserPreferenceService,
|
||||
private readonly _filesService: FilesService,
|
||||
private readonly _fileMapService: FilesMapService,
|
||||
activatedRoute: ActivatedRoute,
|
||||
) {
|
||||
super(_injector);
|
||||
@ -109,6 +113,11 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
|
||||
this.actionConfigs = this._configService.actionConfig(this.dossierId);
|
||||
this.dossier$ = this._dossiersService.getEntityChanged$(this.dossierId);
|
||||
this.currentDossier = this._dossiersService.find(this.dossierId);
|
||||
|
||||
this.fileAttributeConfigs = this._fileAttributesService.getFileAttributeConfig(
|
||||
this.currentDossier.dossierTemplateId,
|
||||
)?.fileAttributeConfigs;
|
||||
this.tableColumnConfigs = this._configService.tableConfig(this.displayedAttributes);
|
||||
}
|
||||
|
||||
private _fileAttributeConfigs: IFileAttributeConfig[];
|
||||
@ -129,10 +138,10 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
|
||||
|
||||
async actionPerformed(action?: string, file?: File) {
|
||||
if (action === 'assign-reviewer') {
|
||||
return this.reloadDossiers();
|
||||
return this.reloadFiles();
|
||||
}
|
||||
|
||||
this.calculateData();
|
||||
await this.calculateData();
|
||||
|
||||
if (action === 'navigate') {
|
||||
await this._router.navigate([file.routerLink]);
|
||||
@ -144,30 +153,20 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
|
||||
lastOpenedFn = (fileStatus: File) => fileStatus.lastOpened;
|
||||
|
||||
async ngOnInit(): Promise<void> {
|
||||
this._loadingService.start();
|
||||
this._loadEntitiesFromState();
|
||||
this.fileAttributeConfigs = this._fileAttributesService.getFileAttributeConfig(
|
||||
this.currentDossier.dossierTemplateId,
|
||||
)?.fileAttributeConfigs;
|
||||
this.tableColumnConfigs = this._configService.tableConfig(this.displayedAttributes);
|
||||
await this._loadEntitiesFromState();
|
||||
try {
|
||||
this._fileDropOverlayService.initFileDropHandling();
|
||||
|
||||
this.calculateData();
|
||||
await this.calculateData();
|
||||
|
||||
this.addSubscription = timer(0, 20 * 1000).subscribe(async () => {
|
||||
await this._appStateService.reloadActiveDossierFiles();
|
||||
this.calculateData();
|
||||
await this.reloadFiles();
|
||||
});
|
||||
|
||||
this.addSubscription = this.listingMode$.subscribe(() => {
|
||||
this._computeAllFilters();
|
||||
});
|
||||
|
||||
// this.addSubscription = this._appStateService.fileChanged$.subscribe(() => {
|
||||
// this.calculateData();
|
||||
// });
|
||||
|
||||
this.addSubscription = this._dossierTemplatesService.entityChanged$.subscribe(() => {
|
||||
this.fileAttributeConfigs = this._fileAttributesService.getFileAttributeConfig(
|
||||
this.currentDossier.dossierTemplateId,
|
||||
@ -192,8 +191,8 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
|
||||
}
|
||||
|
||||
async ngOnAttach() {
|
||||
await this._appStateService.reloadActiveDossierFiles();
|
||||
this._loadEntitiesFromState();
|
||||
// await this._appStateService.reloadActiveDossierFiles();
|
||||
// await this._loadEntitiesFromState();
|
||||
await this.ngOnInit();
|
||||
this._tableComponent.scrollViewport.scrollToIndex(this._lastScrolledIndex, 'smooth');
|
||||
}
|
||||
@ -209,24 +208,25 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
|
||||
async reanalyseDossier() {
|
||||
try {
|
||||
await this._appStateService.reanalyzeDossier();
|
||||
await this.reloadDossiers();
|
||||
await this.reloadFiles();
|
||||
this._toaster.success(_('dossier-overview.reanalyse-dossier.success'));
|
||||
} catch (e) {
|
||||
this._toaster.error(_('dossier-overview.reanalyse-dossier.error'));
|
||||
}
|
||||
}
|
||||
|
||||
async reloadDossiers() {
|
||||
await this._appStateService.getFiles(this.currentDossier, false);
|
||||
this.calculateData();
|
||||
async reloadFiles() {
|
||||
const files = await this._appStateService.getFiles(this.currentDossier);
|
||||
this.entitiesService.setEntities(files);
|
||||
await this.calculateData();
|
||||
}
|
||||
|
||||
calculateData(): void {
|
||||
async calculateData(): Promise<void> {
|
||||
if (!this.dossierId) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._loadEntitiesFromState();
|
||||
await this._loadEntitiesFromState();
|
||||
this._computeAllFilters();
|
||||
|
||||
this._changeDetectorRef.markForCheck();
|
||||
@ -278,18 +278,18 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
|
||||
}
|
||||
|
||||
async bulkActionPerformed(): Promise<void> {
|
||||
await this.reloadDossiers();
|
||||
await this.reloadFiles();
|
||||
}
|
||||
|
||||
openAssignDossierMembersDialog(): void {
|
||||
const data = { dossierId: this.dossierId, section: 'members' };
|
||||
this._dialogService.openDialog('editDossier', null, data, async () => this.reloadDossiers());
|
||||
this._dialogService.openDialog('editDossier', null, data, async () => this.reloadFiles());
|
||||
}
|
||||
|
||||
openDossierDictionaryDialog() {
|
||||
const data = { dossierId: this.dossierId, section: 'dossierDictionary' };
|
||||
this._dialogService.openDialog('editDossier', null, data, async () => {
|
||||
await this.reloadDossiers();
|
||||
await this.reloadFiles();
|
||||
});
|
||||
}
|
||||
|
||||
@ -300,11 +300,14 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
|
||||
recentlyModifiedChecker = (file: File) =>
|
||||
moment(file.lastUpdated).add(this._appConfigService.values.RECENT_PERIOD_IN_HOURS, 'hours').isAfter(moment());
|
||||
|
||||
private _loadEntitiesFromState() {
|
||||
private async _loadEntitiesFromState() {
|
||||
this.currentDossier = this._dossiersService.find(this.dossierId);
|
||||
if (this.currentDossier) {
|
||||
this.entitiesService.setEntities([...this.currentDossier.files]);
|
||||
if (!this._fileMapService.has(this.dossierId)) {
|
||||
this._loadingService.start();
|
||||
await this._appStateService.getFiles(this.currentDossier);
|
||||
}
|
||||
|
||||
this.entitiesService.setEntities(this._fileMapService.get(this.dossierId));
|
||||
}
|
||||
|
||||
private async _uploadFiles(files: FileUploadModel[]) {
|
||||
|
||||
@ -22,6 +22,7 @@ import { DefaultListingServicesTmp, EntitiesService, ListingComponent, OnAttach,
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { ConfigService } from '../config.service';
|
||||
import { DossiersService } from '@services/entity-services/dossiers.service';
|
||||
import { FilesService } from '@services/entity-services/files.service';
|
||||
|
||||
@Component({
|
||||
templateUrl: './dossiers-listing-screen.component.html',
|
||||
@ -59,6 +60,7 @@ export class DossiersListingScreenComponent
|
||||
private readonly _dialogService: DossiersDialogService,
|
||||
private readonly _translateChartService: TranslateChartService,
|
||||
private readonly _configService: ConfigService,
|
||||
private readonly _filesService: FilesService,
|
||||
) {
|
||||
super(_injector);
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<section *ngIf="appStateService.activeFile as file" [class.fullscreen]="fullScreen">
|
||||
<section *ngIf="file$ | async as file" [class.fullscreen]="fullScreen">
|
||||
<div class="page-header">
|
||||
<div class="flex flex-1">
|
||||
<div
|
||||
@ -29,21 +29,21 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="dossiersService.activeDossier$ | async as dossier" class="flex-1 actions-container">
|
||||
<div *ngIf="dossier$ | async as dossier" class="flex-1 actions-container">
|
||||
<ng-container *ngIf="!file.excluded">
|
||||
<ng-container *ngIf="!file.isProcessing">
|
||||
<iqser-status-bar [configs]="statusBarConfig" [small]="true"></iqser-status-bar>
|
||||
|
||||
<div class="all-caps-label mr-16 ml-8">
|
||||
{{ translations[status] | translate }}
|
||||
{{ translations[file.status] | translate }}
|
||||
<span *ngIf="isUnderReviewOrApproval">{{ 'by' | translate }}:</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<redaction-initials-avatar
|
||||
*ngIf="!editingReviewer"
|
||||
[user]="currentReviewer"
|
||||
[withName]="!!currentReviewer"
|
||||
[user]="file.currentReviewer"
|
||||
[withName]="!!file.currentReviewer"
|
||||
tooltipPosition="below"
|
||||
></redaction-initials-avatar>
|
||||
<div
|
||||
@ -59,13 +59,13 @@
|
||||
(save)="assignReviewer($event)"
|
||||
*ngIf="editingReviewer"
|
||||
[options]="singleUsersSelectOptions(dossier)"
|
||||
[value]="currentReviewer"
|
||||
[value]="file.currentReviewer"
|
||||
></redaction-assign-user-dropdown>
|
||||
|
||||
<div *ngIf="canAssign" class="assign-actions-wrapper">
|
||||
<div *ngIf="canAssign(file)" class="assign-actions-wrapper">
|
||||
<iqser-circle-button
|
||||
(action)="editingReviewer = true"
|
||||
*ngIf="(permissionsService.canAssignUser() || permissionsService.canUnassignUser()) && !!currentReviewer"
|
||||
*ngIf="(permissionsService.canAssignUser(file) || permissionsService.canUnassignUser(file)) && !!file.currentReviewer"
|
||||
[tooltip]="assignTooltip"
|
||||
icon="iqser:edit"
|
||||
tooltipPosition="below"
|
||||
@ -73,17 +73,17 @@
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="assignToMe()"
|
||||
*ngIf="permissionsService.canAssignToSelf()"
|
||||
*ngIf="permissionsService.canAssignToSelf(file)"
|
||||
[tooltip]="'file-preview.assign-me' | translate"
|
||||
icon="red:assign-me"
|
||||
tooltipPosition="below"
|
||||
></iqser-circle-button>
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="permissionsService.isApprover() && !!lastReviewer">
|
||||
<ng-container *ngIf="permissionsService.isApprover(dossier) && !!file.lastReviewer">
|
||||
<div class="vertical-line"></div>
|
||||
<div class="all-caps-label mr-16 ml-8" translate="file-preview.last-reviewer"></div>
|
||||
<redaction-initials-avatar [user]="lastReviewer" [withName]="true"></redaction-initials-avatar>
|
||||
<redaction-initials-avatar [user]="file.lastReviewer" [withName]="true"></redaction-initials-avatar>
|
||||
</ng-container>
|
||||
<div class="vertical-line"></div>
|
||||
|
||||
@ -92,6 +92,7 @@
|
||||
(actionPerformed)="fileActionPerformed($event)"
|
||||
[activeDocumentInfo]="viewDocumentInfo"
|
||||
[activeExcludePages]="excludePages"
|
||||
[file]="file"
|
||||
type="file-preview"
|
||||
></redaction-file-actions>
|
||||
|
||||
|
||||
@ -1,4 +1,14 @@
|
||||
import { ChangeDetectorRef, Component, HostListener, NgZone, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
HostListener,
|
||||
NgZone,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
TemplateRef,
|
||||
ViewChild,
|
||||
} from '@angular/core';
|
||||
import { ActivatedRoute, ActivatedRouteSnapshot, NavigationExtras, Router } from '@angular/router';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { Core, WebViewerInstance } from '@pdftron/webviewer';
|
||||
@ -23,9 +33,9 @@ import { AnnotationData, FileDataModel } from '@models/file/file-data.model';
|
||||
import { FileActionService } from '../../shared/services/file-action.service';
|
||||
import { AnnotationDrawService } from '../../services/annotation-draw.service';
|
||||
import { AnnotationProcessingService } from '../../services/annotation-processing.service';
|
||||
import { Dossier, FileStatus, User, ViewMode } from '@red/domain';
|
||||
import { Dossier, File, FileStatus, User, ViewMode } from '@red/domain';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { timer } from 'rxjs';
|
||||
import { Observable, timer } from 'rxjs';
|
||||
import { UserPreferenceService } from '@services/user-preference.service';
|
||||
import { UserService } from '@services/user.service';
|
||||
import { PdfViewerDataService } from '../../services/pdf-viewer-data.service';
|
||||
@ -42,6 +52,7 @@ import { FilesService } from '@services/entity-services/files.service';
|
||||
import { DossiersService } from '@services/entity-services/dossiers.service';
|
||||
import { FileManagementService } from '../../shared/services/file-management.service';
|
||||
import { filter, switchMapTo, tap } from 'rxjs/operators';
|
||||
import { FilesMapService } from '@services/entity-services/files-map.service';
|
||||
import Annotation = Core.Annotations.Annotation;
|
||||
|
||||
const ALL_HOTKEY_ARRAY = ['Escape', 'F', 'f'];
|
||||
@ -50,6 +61,7 @@ const ALL_HOTKEY_ARRAY = ['Escape', 'F', 'f'];
|
||||
templateUrl: './file-preview-screen.component.html',
|
||||
styleUrls: ['./file-preview-screen.component.scss'],
|
||||
providers: [FilterService],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnInit, OnDestroy, OnAttach, OnDetach {
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
@ -71,6 +83,10 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
@ViewChild(PdfViewerComponent) readonly viewerComponent: PdfViewerComponent;
|
||||
@ViewChild('fileActions') fileActions: FileActionsComponent;
|
||||
readonly dossierId: string;
|
||||
readonly dossier$: Observable<Dossier>;
|
||||
readonly file$: Observable<File>;
|
||||
readonly fileId: string;
|
||||
file: File;
|
||||
private _instance: WebViewerInstance;
|
||||
private _lastPage: string;
|
||||
private _reloadFileOnReanalysis = false;
|
||||
@ -102,10 +118,16 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
private readonly _loadingService: LoadingService,
|
||||
private readonly _filterService: FilterService,
|
||||
private readonly _translateService: TranslateService,
|
||||
private readonly _filesMapService: FilesMapService,
|
||||
private readonly _dossiersService: DossiersService,
|
||||
) {
|
||||
super();
|
||||
this.dossierId = _activatedRoute.snapshot.paramMap.get('dossierId');
|
||||
this._loadingService.start();
|
||||
this.dossierId = _activatedRoute.snapshot.paramMap.get('dossierId');
|
||||
this.dossier$ = this._dossiersService.getEntityChanged$(this.dossierId);
|
||||
this.fileId = _activatedRoute.snapshot.paramMap.get('fileId');
|
||||
this.file = _filesMapService.get(this.dossierId, this.fileId);
|
||||
this.file$ = _filesMapService.watch$(this.dossierId, this.fileId);
|
||||
document.documentElement.addEventListener('fullscreenchange', () => {
|
||||
if (!document.fullscreenElement) {
|
||||
this.fullScreen = false;
|
||||
@ -114,7 +136,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
}
|
||||
|
||||
get assignTooltip(): string {
|
||||
return this.appStateService.activeFile.isUnderApproval
|
||||
return this.file.isUnderApproval
|
||||
? this._translateService.instant('dossier-overview.assign-approver')
|
||||
: this.assignOrChangeReviewerTooltip;
|
||||
}
|
||||
@ -147,62 +169,44 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
return this.fileData?.hasChangeLog;
|
||||
}
|
||||
|
||||
get canAssign(): boolean {
|
||||
return (
|
||||
!this.editingReviewer &&
|
||||
(this.permissionsService.canAssignUser() ||
|
||||
this.permissionsService.canAssignToSelf() ||
|
||||
this.permissionsService.canUnassignUser())
|
||||
);
|
||||
}
|
||||
|
||||
get displayData(): Blob {
|
||||
return this.fileData?.fileData;
|
||||
}
|
||||
|
||||
get fileId(): string {
|
||||
return this.appStateService.activeFileId;
|
||||
}
|
||||
|
||||
get multiSelectActive(): boolean {
|
||||
return !!this._workloadComponent?.multiSelectActive;
|
||||
}
|
||||
|
||||
get lastReviewer(): string | undefined {
|
||||
return this.appStateService.activeFile.lastReviewer;
|
||||
}
|
||||
|
||||
get assignOrChangeReviewerTooltip(): string {
|
||||
return this.currentReviewer
|
||||
return this.file.currentReviewer
|
||||
? this._translateService.instant('file-preview.change-reviewer')
|
||||
: this._translateService.instant('file-preview.assign-reviewer');
|
||||
}
|
||||
|
||||
get currentReviewer(): string {
|
||||
return this.appStateService.activeFile.currentReviewer;
|
||||
}
|
||||
|
||||
get status(): FileStatus {
|
||||
return this.appStateService.activeFile.status;
|
||||
}
|
||||
|
||||
get statusBarConfig(): [{ length: number; color: FileStatus }] {
|
||||
return [{ length: 1, color: this.status }];
|
||||
return [{ length: 1, color: this.file.status }];
|
||||
}
|
||||
|
||||
get isUnderReviewOrApproval(): boolean {
|
||||
return this.status === 'UNDER_REVIEW' || this.status === 'UNDER_APPROVAL';
|
||||
return this.file.status === 'UNDER_REVIEW' || this.file.status === 'UNDER_APPROVAL';
|
||||
}
|
||||
|
||||
canAssign(file: File): boolean {
|
||||
return (
|
||||
!this.editingReviewer &&
|
||||
(this.permissionsService.canAssignUser(file) ||
|
||||
this.permissionsService.canAssignToSelf(file) ||
|
||||
this.permissionsService.canUnassignUser(file))
|
||||
);
|
||||
}
|
||||
|
||||
singleUsersSelectOptions(dossier: Dossier): List {
|
||||
const unassignUser = this.permissionsService.canUnassignUser() ? [undefined] : [];
|
||||
return this.appStateService.activeFile?.isUnderApproval
|
||||
? [...dossier.approverIds, ...unassignUser]
|
||||
: [...dossier.memberIds, ...unassignUser];
|
||||
const unassignUser = this.permissionsService.canUnassignUser(this.file) ? [undefined] : [];
|
||||
return this.file?.isUnderApproval ? [...dossier.approverIds, ...unassignUser] : [...dossier.memberIds, ...unassignUser];
|
||||
}
|
||||
|
||||
canAssignReviewer(dossier: Dossier): boolean {
|
||||
return !this.currentReviewer && this.permissionsService.canAssignUser() && dossier.hasReviewers;
|
||||
return !this.file.currentReviewer && this.permissionsService.canAssignUser(this.file) && dossier.hasReviewers;
|
||||
}
|
||||
|
||||
updateViewMode(): void {
|
||||
@ -246,7 +250,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
}
|
||||
|
||||
async ngOnAttach(previousRoute: ActivatedRouteSnapshot): Promise<boolean> {
|
||||
if (!this.appStateService.activeFile.canBeOpened) {
|
||||
if (!this.file.canBeOpened) {
|
||||
return this._router.navigate([this.dossiersService.find(this.dossierId)?.routerLink]);
|
||||
}
|
||||
|
||||
@ -280,8 +284,9 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
}
|
||||
console.log(`[REDACTION] Delete previous annotations time: ${new Date().getTime() - startTime} ms`);
|
||||
const processStartTime = new Date().getTime();
|
||||
const dossier = this._dossiersService.find(this.dossierId);
|
||||
const newAnnotationsData = this.fileData.getAnnotations(
|
||||
this.appStateService.dictionaryData[this.dossiersService.activeDossier.dossierTemplateId],
|
||||
this.appStateService.dictionaryData[dossier.dossierTemplateId],
|
||||
this.userService.currentUser,
|
||||
this.viewMode,
|
||||
this.userPreferenceService.areDevFeaturesEnabled,
|
||||
@ -456,7 +461,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
return this.dossiersService.goToActiveDossier();
|
||||
return this._router.navigate([this.dossiersService.find(this.dossierId).routerLink]);
|
||||
|
||||
case 'reanalyse':
|
||||
await this._loadFileData(true);
|
||||
@ -600,7 +605,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
}
|
||||
|
||||
private async _loadFileData(performUpdate = false): Promise<void> {
|
||||
const fileData = await this._fileDownloadService.loadActiveFileData().toPromise();
|
||||
const fileData = await this._fileDownloadService.loadDataFor(this.file).toPromise();
|
||||
|
||||
if (!fileData.file?.isPending && !fileData.file?.isError) {
|
||||
if (performUpdate) {
|
||||
@ -617,7 +622,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
}
|
||||
|
||||
if (fileData.file.isError) {
|
||||
await this.dossiersService.goToActiveDossier();
|
||||
await this._router.navigate([this.dossiersService.find(this.dossierId).routerLink]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -630,7 +635,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
/* Get the documentElement (<html>) to display the page in fullscreen */
|
||||
|
||||
private _cleanupAndRedrawManualAnnotations$() {
|
||||
return this._fileDownloadService.loadActiveFileRedactionLog().pipe(
|
||||
return this._fileDownloadService.loadRedactionLogFor(this.dossierId, this.fileId).pipe(
|
||||
tap(redactionLog => (this.fileData.redactionLog = redactionLog)),
|
||||
switchMapTo(this._redrawAnnotations()),
|
||||
);
|
||||
@ -641,7 +646,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
const currentPageAnnotationIds = currentPageAnnotations.map(a => a.id);
|
||||
|
||||
this.fileData.file = await this.appStateService.reloadActiveFile();
|
||||
this.fileData.redactionLog = await this._fileDownloadService.loadActiveFileRedactionLog().toPromise();
|
||||
this.fileData.redactionLog = await this._fileDownloadService.loadRedactionLogFor(this.dossierId, this.fileId).toPromise();
|
||||
|
||||
this.rebuildFilters();
|
||||
|
||||
|
||||
@ -2,10 +2,8 @@ import { Injectable } from '@angular/core';
|
||||
import { forkJoin, Observable, of } from 'rxjs';
|
||||
import { catchError, map, tap } from 'rxjs/operators';
|
||||
import { FileDataModel } from '@models/file/file-data.model';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { File } from '@red/domain';
|
||||
import { DossiersService } from '@services/entity-services/dossiers.service';
|
||||
import { FileManagementService } from '../shared/services/file-management.service';
|
||||
import { RedactionLogService } from './redaction-log.service';
|
||||
import { ViewedPagesService } from '../shared/services/viewed-pages.service';
|
||||
@ -13,36 +11,30 @@ import { ViewedPagesService } from '../shared/services/viewed-pages.service';
|
||||
@Injectable()
|
||||
export class PdfViewerDataService {
|
||||
constructor(
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _dossiersService: DossiersService,
|
||||
private readonly _permissionsService: PermissionsService,
|
||||
private readonly _fileManagementService: FileManagementService,
|
||||
private readonly _redactionLogService: RedactionLogService,
|
||||
private readonly _viewedPagesService: ViewedPagesService,
|
||||
) {}
|
||||
|
||||
loadActiveFileRedactionLog() {
|
||||
return this._redactionLogService.getRedactionLog(this._dossiersService.activeDossierId, this._appStateService.activeFileId).pipe(
|
||||
loadRedactionLogFor(dossierId: string, fileId: string) {
|
||||
return this._redactionLogService.getRedactionLog(dossierId, fileId).pipe(
|
||||
tap(redactionLog => redactionLog.redactionLogEntry.sort((a, b) => a.positions[0].page - b.positions[0].page)),
|
||||
catchError(() => of({})),
|
||||
);
|
||||
}
|
||||
|
||||
loadActiveFileData(): Observable<FileDataModel> {
|
||||
const file$ = this.downloadOriginalFile(this._appStateService.activeFile);
|
||||
const reactionLog$ = this.loadActiveFileRedactionLog();
|
||||
const viewedPages$ = this.getViewedPagesForActiveFile();
|
||||
loadDataFor(file: File): Observable<FileDataModel> {
|
||||
const file$ = this.downloadOriginalFile(file);
|
||||
const reactionLog$ = this.loadRedactionLogFor(file.dossierId, file.fileId);
|
||||
const viewedPages$ = this.getViewedPagesFor(file);
|
||||
|
||||
return forkJoin([file$, reactionLog$, viewedPages$]).pipe(
|
||||
map(data => new FileDataModel(this._appStateService.activeFile, ...data)),
|
||||
);
|
||||
return forkJoin([file$, reactionLog$, viewedPages$]).pipe(map(data => new FileDataModel(file, ...data)));
|
||||
}
|
||||
|
||||
getViewedPagesForActiveFile() {
|
||||
if (this._permissionsService.canMarkPagesAsViewed()) {
|
||||
return this._viewedPagesService
|
||||
.getViewedPages(this._dossiersService.activeDossierId, this._appStateService.activeFileId)
|
||||
.pipe(catchError(() => of([])));
|
||||
getViewedPagesFor(file: File) {
|
||||
if (this._permissionsService.canMarkPagesAsViewed(file)) {
|
||||
return this._viewedPagesService.getViewedPages(file.dossierId, file.fileId).pipe(catchError(() => of([])));
|
||||
}
|
||||
return of([]);
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { File, FileStatus } from '@red/domain';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
@ -9,29 +9,33 @@ import {
|
||||
CircleButtonTypes,
|
||||
ConfirmationDialogInput,
|
||||
LoadingService,
|
||||
OnChange,
|
||||
Required,
|
||||
StatusBarConfig,
|
||||
Toaster,
|
||||
} from '@iqser/common-ui';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { UserService } from '@services/user.service';
|
||||
import { filter } from 'rxjs/operators';
|
||||
import { UserPreferenceService } from '@services/user-preference.service';
|
||||
import { LongPressEvent } from '@shared/directives/long-press.directive';
|
||||
import { FileActionService } from '../../services/file-action.service';
|
||||
import { DossiersService } from '@services/entity-services/dossiers.service';
|
||||
import { FileManagementService } from '../../services/file-management.service';
|
||||
import { FilesMapService } from '@services/entity-services/files-map.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-file-actions',
|
||||
templateUrl: './file-actions.component.html',
|
||||
styleUrls: ['./file-actions.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnDestroy, OnChanges {
|
||||
export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnDestroy {
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly currentUser = this._userService.currentUser;
|
||||
|
||||
@Input() file: File;
|
||||
@Input()
|
||||
@OnChange<File, FileActionsComponent>('setup')
|
||||
file: File;
|
||||
@Input() activeDocumentInfo: boolean;
|
||||
@Input() activeExcludePages: boolean;
|
||||
@Input() @Required() type: 'file-preview' | 'dossier-overview-list' | 'dossier-overview-workflow';
|
||||
@ -67,6 +71,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
|
||||
private readonly _fileActionService: FileActionService,
|
||||
private readonly _loadingService: LoadingService,
|
||||
private readonly _fileManagementService: FileManagementService,
|
||||
private readonly _filesMapService: FilesMapService,
|
||||
private readonly _userService: UserService,
|
||||
private readonly _toaster: Toaster,
|
||||
private readonly _userPreferenceService: UserPreferenceService,
|
||||
@ -99,17 +104,14 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
if (!this.file) {
|
||||
this.file = this.appStateService.activeFile;
|
||||
}
|
||||
this._setup();
|
||||
this.addSubscription = this.appStateService.fileChanged$.pipe(filter(file => file.fileId === this.file?.fileId)).subscribe(file => {
|
||||
this.setup();
|
||||
this.addSubscription = this._filesMapService.watch$(this.file.dossierId, this.file.fileId).subscribe(file => {
|
||||
this.file = file;
|
||||
this._setup();
|
||||
this.setup();
|
||||
});
|
||||
|
||||
this.addSubscription = this.dossiersService.entityChanged$.subscribe(() => {
|
||||
this._setup();
|
||||
this.addSubscription = this.dossiersService.getEntityChanged$(this.file.dossierId).subscribe(() => {
|
||||
this.setup();
|
||||
});
|
||||
}
|
||||
|
||||
@ -160,7 +162,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
|
||||
$event.stopPropagation();
|
||||
|
||||
await this._fileActionService.assignToMe([this.file], () => {
|
||||
this.reloadDossiers('reanalyse');
|
||||
this.reloadFiles('reanalyse');
|
||||
});
|
||||
}
|
||||
|
||||
@ -169,22 +171,22 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
|
||||
$event.stopPropagation();
|
||||
}
|
||||
this.addSubscription = this._fileActionService.reanalyseFile(this.file).subscribe(() => {
|
||||
this.reloadDossiers('reanalyse');
|
||||
this.reloadFiles('reanalyse');
|
||||
});
|
||||
}
|
||||
|
||||
setFileUnderApproval($event: MouseEvent) {
|
||||
$event.stopPropagation();
|
||||
if (this.dossiersService.activeDossier.approverIds.length > 1) {
|
||||
this._fileActionService.assignFile('approver', $event, this.file, () => this.reloadDossiers('assign-reviewer'), true);
|
||||
this._fileActionService.assignFile('approver', $event, this.file, () => this.reloadFiles('assign-reviewer'), true);
|
||||
} else {
|
||||
this.addSubscription = this._fileActionService.setFilesUnderApproval([this.file]).subscribe(() => {
|
||||
this.reloadDossiers('set-under-approval');
|
||||
this.reloadFiles('set-under-approval');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
setFileApproved($event: MouseEvent) {
|
||||
async setFileApproved($event: MouseEvent) {
|
||||
$event.stopPropagation();
|
||||
if (this.file.hasUpdates) {
|
||||
this._dialogService.openDialog(
|
||||
@ -194,61 +196,43 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
|
||||
title: _('confirmation-dialog.approve-file.title'),
|
||||
question: _('confirmation-dialog.approve-file.question'),
|
||||
}),
|
||||
() => {
|
||||
this._setFileApproved();
|
||||
async () => {
|
||||
await this._setFileApproved();
|
||||
},
|
||||
);
|
||||
} else {
|
||||
this._setFileApproved();
|
||||
await this._setFileApproved();
|
||||
}
|
||||
}
|
||||
|
||||
ocrFile($event: MouseEvent) {
|
||||
$event.stopPropagation();
|
||||
this.addSubscription = this._fileActionService.ocrFiles([this.file]).subscribe(() => {
|
||||
this.reloadDossiers('ocr-file');
|
||||
this.reloadFiles('ocr-file');
|
||||
});
|
||||
}
|
||||
|
||||
setFileUnderReview($event: MouseEvent, ignoreDialogChanges = false) {
|
||||
this._fileActionService.assignFile(
|
||||
'reviewer',
|
||||
$event,
|
||||
this.file,
|
||||
() => this.reloadDossiers('assign-reviewer'),
|
||||
ignoreDialogChanges,
|
||||
);
|
||||
this._fileActionService.assignFile('reviewer', $event, this.file, () => this.reloadFiles('assign-reviewer'), ignoreDialogChanges);
|
||||
}
|
||||
|
||||
reloadDossiers(action: string) {
|
||||
this.appStateService.getFiles().then(() => {
|
||||
reloadFiles(action: string) {
|
||||
this.appStateService.getFiles(this.dossiersService.find(this.file.dossierId)).then(() => {
|
||||
this.actionPerformed.emit(action);
|
||||
});
|
||||
}
|
||||
|
||||
async toggleAnalysis() {
|
||||
await this._fileActionService.toggleAnalysis(this.file).toPromise();
|
||||
await this.appStateService.getFiles();
|
||||
await this.appStateService.getFiles(this.dossiersService.find(this.file.dossierId));
|
||||
this.actionPerformed.emit(this.file?.excluded ? 'enable-analysis' : 'disable-analysis');
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
if (changes.file) {
|
||||
this._setup();
|
||||
}
|
||||
}
|
||||
|
||||
forceReanalysisAction($event: LongPressEvent) {
|
||||
this.analysisForced = !$event.touchEnd && this._userPreferenceService.areDevFeaturesEnabled;
|
||||
}
|
||||
|
||||
private _setFileApproved() {
|
||||
this.addSubscription = this._fileActionService.setFilesApproved([this.file]).subscribe(() => {
|
||||
this.reloadDossiers('set-approved');
|
||||
});
|
||||
}
|
||||
|
||||
private _setup() {
|
||||
setup() {
|
||||
this.statusBarConfig = [{ color: this.file.status, length: 1 }];
|
||||
this.tooltipPosition = this.isFilePreview ? 'below' : 'above';
|
||||
this.assignTooltip = this.file.isUnderApproval ? _('dossier-overview.assign-approver') : _('dossier-overview.assign-reviewer');
|
||||
@ -261,7 +245,8 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
|
||||
this.showApprove = this.permissionsService.isReadyForApproval(this.file) && !this.isDossierOverviewWorkflow;
|
||||
|
||||
this.canToggleAnalysis = this.permissionsService.canToggleAnalysis(this.file);
|
||||
this.showDelete = this.permissionsService.canDeleteFile(this.file);
|
||||
const dossier = this.dossiersService.find(this.file.dossierId);
|
||||
this.showDelete = this.permissionsService.canDeleteFile(this.file, dossier);
|
||||
this.showOCR = this.file.canBeOCRed;
|
||||
this.canReanalyse = this.permissionsService.canReanalyseFile(this.file);
|
||||
|
||||
@ -277,4 +262,13 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
|
||||
this.showExcludePages = this.isFilePreview;
|
||||
this.showDocumentInfo = this.isFilePreview;
|
||||
}
|
||||
|
||||
private async _setFileApproved() {
|
||||
await this._fileActionService
|
||||
.setFilesApproved([this.file])
|
||||
.toPromise()
|
||||
.then(() => {
|
||||
this.reloadFiles('set-approved');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@ import { Injectable } from '@angular/core';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { UserService } from '@services/user.service';
|
||||
import { File } from '@red/domain';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { DossiersDialogService } from '../../services/dossiers-dialog.service';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { FilesService } from '@services/entity-services/files.service';
|
||||
@ -14,13 +13,11 @@ import { ReanalysisService } from '@services/reanalysis.service';
|
||||
export class FileActionService {
|
||||
constructor(
|
||||
private readonly _dialogService: DossiersDialogService,
|
||||
private readonly _permissionsService: PermissionsService,
|
||||
private readonly _userService: UserService,
|
||||
private readonly _fileService: FilesService,
|
||||
private readonly _filesService: FilesService,
|
||||
private readonly _reanalysisService: ReanalysisService,
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _dossiersService: DossiersService,
|
||||
private readonly _filesService: FilesService,
|
||||
private readonly _toaster: Toaster,
|
||||
) {}
|
||||
|
||||
@ -58,7 +55,7 @@ export class FileActionService {
|
||||
approverId = this._dossiersService.activeDossier.approverIds[0];
|
||||
}
|
||||
|
||||
return this._fileService.setUnderApprovalFor(
|
||||
return this._filesService.setUnderApprovalFor(
|
||||
files.map(f => f.fileId),
|
||||
this._dossiersService.activeDossierId,
|
||||
approverId,
|
||||
@ -66,14 +63,14 @@ export class FileActionService {
|
||||
}
|
||||
|
||||
setFilesApproved(files: File[]) {
|
||||
return this._fileService.setApprovedFor(
|
||||
return this._filesService.setApprovedFor(
|
||||
files.map(f => f.fileId),
|
||||
this._dossiersService.activeDossierId,
|
||||
);
|
||||
}
|
||||
|
||||
setFilesUnderReview(files: File[]) {
|
||||
return this._fileService.setUnderReviewFor(
|
||||
return this._filesService.setUnderReviewFor(
|
||||
files.map(f => f.fileId),
|
||||
this._dossiersService.activeDossierId,
|
||||
);
|
||||
@ -141,7 +138,7 @@ export class FileActionService {
|
||||
}
|
||||
|
||||
private async _assignReviewerToCurrentUser(files: File[], callback?: Function) {
|
||||
await this._fileService
|
||||
await this._filesService
|
||||
.setReviewerFor(
|
||||
files.map(f => f.fileId),
|
||||
this._dossiersService.activeDossierId,
|
||||
|
||||
@ -70,10 +70,6 @@ export class DossiersService extends EntitiesService<Dossier, IDossier> {
|
||||
return this._activeDossier$.value?.dossierId;
|
||||
}
|
||||
|
||||
goToActiveDossier(): Promise<void> {
|
||||
return this._router.navigate([this.activeDossier?.routerLink]).then();
|
||||
}
|
||||
|
||||
find(dossierId: string): Dossier | undefined;
|
||||
find(dossierId: string, fileId: string): File | undefined;
|
||||
find(dossierId: string, fileId?: string): Dossier | File | undefined {
|
||||
|
||||
@ -0,0 +1,64 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { FilesService } from '@services/entity-services/files.service';
|
||||
import { BehaviorSubject, Observable, Subject } from 'rxjs';
|
||||
import { File } from '@red/domain';
|
||||
import { filter, startWith } from 'rxjs/operators';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class FilesMapService {
|
||||
readonly fileReanalysed$ = new Subject<File>();
|
||||
private readonly _entityChanged$ = new Subject<File>();
|
||||
private readonly _map = new Map<string, BehaviorSubject<File[]>>();
|
||||
|
||||
constructor(private readonly _filesService: FilesService) {}
|
||||
|
||||
get$(dossierId: string) {
|
||||
return this._map.get(dossierId).asObservable();
|
||||
}
|
||||
|
||||
has(dossierId: string) {
|
||||
return this._map.has(dossierId);
|
||||
}
|
||||
|
||||
get(key: string): File[] | undefined;
|
||||
get(key: string, id: string): File | undefined;
|
||||
get(key: string, id?: string): File | File[] | undefined {
|
||||
const value = this._map.get(key)?.value;
|
||||
if (!id) {
|
||||
return value;
|
||||
}
|
||||
return value?.find(item => item.id === id);
|
||||
}
|
||||
|
||||
set(key: string, entities: File[]): void {
|
||||
if (!this._map.has(key)) {
|
||||
this._map.set(key, new BehaviorSubject<File[]>(entities));
|
||||
return entities.forEach(entity => this._entityChanged$.next(entity));
|
||||
}
|
||||
|
||||
// Keep old object references for unchanged entities
|
||||
const newEntities = entities.map(newEntity => {
|
||||
const oldEntity = this.get(key, newEntity.id);
|
||||
|
||||
if (oldEntity.lastProcessed !== newEntity.lastProcessed) {
|
||||
this.fileReanalysed$.next(newEntity);
|
||||
}
|
||||
|
||||
if (newEntity.isEqual(oldEntity)) {
|
||||
return oldEntity;
|
||||
}
|
||||
|
||||
this._entityChanged$.next(newEntity);
|
||||
return newEntity;
|
||||
});
|
||||
|
||||
this._map.get(key).next(newEntities);
|
||||
}
|
||||
|
||||
watch$(key: string, entityId: string): Observable<File> {
|
||||
return this._entityChanged$.pipe(
|
||||
filter(entity => entity.id === entityId),
|
||||
startWith(this.get(key, entityId)),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -13,10 +13,6 @@ export class FilesService extends EntitiesService<File, IFile> {
|
||||
super(_injector, File, 'status');
|
||||
}
|
||||
|
||||
getExistingFilesFor(dossierId: string): List<File> {
|
||||
return this.all.filter(file => file.dossierId === dossierId);
|
||||
}
|
||||
|
||||
fetch() {
|
||||
this.get().pipe(map(files => files.map(file => new File(file, this._userService.getNameForId(file.currentReviewer)))));
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import { AppStateService } from './app-state.service';
|
||||
import { UserService } from '@services/user.service';
|
||||
import { DossiersService } from '@services/entity-services/dossiers.service';
|
||||
import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service';
|
||||
import { FilesMapService } from '@services/entity-services/files-map.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
@ -12,6 +13,7 @@ export class AppStateGuard implements CanActivate {
|
||||
constructor(
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _dossiersService: DossiersService,
|
||||
private readonly _filesMapService: FilesMapService,
|
||||
private readonly _dossierTemplatesService: DossierTemplatesService,
|
||||
private readonly _userService: UserService,
|
||||
private readonly _router: Router,
|
||||
@ -29,7 +31,7 @@ export class AppStateGuard implements CanActivate {
|
||||
}
|
||||
|
||||
if (this._userService.currentUser.isUser) {
|
||||
await this._dossiersService.loadAllIfEmpty();
|
||||
await this._appStateService.loadAllDossiersIfNecessary();
|
||||
}
|
||||
|
||||
const { dossierId, fileId, dossierTemplateId, type } = route.params;
|
||||
@ -39,7 +41,7 @@ export class AppStateGuard implements CanActivate {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fileId && !this._dossiersService.find(dossierId, fileId)) {
|
||||
if (fileId && !this._filesMapService.get(dossierId, fileId)) {
|
||||
await this._router.navigate(['main', 'dossiers', dossierId]);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Dictionary, Dossier, DossierTemplate, File, IColors, IDossier, IFile } from '@red/domain';
|
||||
import { Dictionary, Dossier, DossierTemplate, File, IColors, IDossier } from '@red/domain';
|
||||
import { ActivationEnd, Router } from '@angular/router';
|
||||
import { UserService } from '@services/user.service';
|
||||
import { forkJoin, Observable, of, Subject } from 'rxjs';
|
||||
@ -13,6 +13,7 @@ import { DossierTemplatesService } from '@services/entity-services/dossier-templ
|
||||
import { FileAttributesService } from '@services/entity-services/file-attributes.service';
|
||||
import { ReanalysisService } from '@services/reanalysis.service';
|
||||
import { DossierStatsService } from '@services/entity-services/dossier-stats.service';
|
||||
import { FilesMapService } from '@services/entity-services/files-map.service';
|
||||
|
||||
export interface AppState {
|
||||
activeFileId?: string;
|
||||
@ -38,6 +39,7 @@ export class AppStateService {
|
||||
private readonly _dossierTemplatesService: DossierTemplatesService,
|
||||
private readonly _dossierStatsService: DossierStatsService,
|
||||
private readonly _fileAttributesService: FileAttributesService,
|
||||
private readonly _filesMapService: FilesMapService,
|
||||
private readonly _userPreferenceService: UserPreferenceService,
|
||||
) {
|
||||
_router.events.pipe(currentComponentRoute).subscribe(async (event: ActivationEnd) => {
|
||||
@ -85,7 +87,7 @@ export class AppStateService {
|
||||
}
|
||||
|
||||
get activeFile(): File | undefined {
|
||||
return this._dossiersService.activeDossier?.files.find(f => f.fileId === this.activeFileId);
|
||||
return this._filesMapService.get(this._dossiersService.activeDossierId, this.activeFileId);
|
||||
}
|
||||
|
||||
get activeFileId(): string | undefined {
|
||||
@ -133,6 +135,7 @@ export class AppStateService {
|
||||
const oldDossier = this._dossiersService.find(p.dossierId);
|
||||
const type = oldDossier?.type ?? (await this._getDictionaryFor(p));
|
||||
const stats = dossierStats.find(s => s.dossierId === p.dossierId);
|
||||
console.log(stats);
|
||||
this._dossiersService.replace(new Dossier(p, stats, [], type));
|
||||
});
|
||||
return Promise.all(mappedDossiers$);
|
||||
@ -160,10 +163,17 @@ export class AppStateService {
|
||||
return activeFile;
|
||||
}
|
||||
|
||||
async getFiles(dossier = this._dossiersService.activeDossier, emitEvents = true) {
|
||||
async getFiles(dossier = this._dossiersService.activeDossier) {
|
||||
const files = await this._filesService.getFor(dossier.id).toPromise();
|
||||
|
||||
return this._processFiles(dossier, files, emitEvents);
|
||||
const fileAttributes = this._fileAttributesService.getFileAttributeConfig(dossier.dossierTemplateId);
|
||||
const newFiles = files.map(iFile => new File(iFile, this._userService.getNameForId(iFile.currentReviewer), fileAttributes));
|
||||
|
||||
const lastOpenedFileId = this._userPreferenceService.getLastOpenedFileForDossier(dossier.id);
|
||||
newFiles.forEach(file => (file.lastOpened = file.fileId === lastOpenedFileId));
|
||||
this._filesMapService.set(dossier.dossierId, newFiles);
|
||||
|
||||
return newFiles;
|
||||
}
|
||||
|
||||
async reanalyzeDossier({ id } = this._dossiersService.activeDossier) {
|
||||
@ -174,12 +184,9 @@ export class AppStateService {
|
||||
if (this._dossiersService.activeDossierId === dossierId && this.activeFileId === fileId) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._dossiersService.activeDossier) {
|
||||
this._appState.activeFileId = fileId;
|
||||
if (!this.activeFile) {
|
||||
this._appState.activeFileId = null;
|
||||
await this._dossiersService.goToActiveDossier();
|
||||
}
|
||||
}
|
||||
await this._updateLastActiveFileForDossier(dossierId, fileId);
|
||||
}
|
||||
@ -201,7 +208,7 @@ export class AppStateService {
|
||||
|
||||
async reloadActiveDossierFiles() {
|
||||
if (this._dossiersService.activeDossierId) {
|
||||
await this.getFiles();
|
||||
return this.getFiles();
|
||||
}
|
||||
}
|
||||
|
||||
@ -471,37 +478,4 @@ export class AppStateService {
|
||||
|
||||
await this._userPreferenceService.saveLastOpenedFileForDossier(dossierId, fileId);
|
||||
}
|
||||
|
||||
private _processFiles(dossier: Dossier, iFiles: IFile[], emitEvents = true) {
|
||||
const oldFiles = dossier.files;
|
||||
const fileAttributes = this._fileAttributesService.getFileAttributeConfig(dossier.dossierTemplateId);
|
||||
const newFiles = iFiles.map(iFile => new File(iFile, this._userService.getNameForId(iFile.currentReviewer), fileAttributes));
|
||||
|
||||
const lastOpenedFileId = this._userPreferenceService.getLastOpenedFileForDossier(dossier.id);
|
||||
newFiles.forEach(file => (file.lastOpened = file.fileId === lastOpenedFileId));
|
||||
|
||||
for (const newFile of newFiles) {
|
||||
let found = false;
|
||||
|
||||
for (const oldFile of oldFiles) {
|
||||
if (oldFile.fileId === newFile.fileId) {
|
||||
// emit when analysis count changed
|
||||
if (JSON.stringify(oldFile) !== JSON.stringify(newFile) && emitEvents) {
|
||||
this.fileChanged$.next(newFile);
|
||||
}
|
||||
if (oldFile.lastProcessed !== newFile.lastProcessed && emitEvents) {
|
||||
this.fileReanalysed$.next(newFile);
|
||||
}
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// emit for new file
|
||||
if (!found && emitEvents) {
|
||||
this.fileChanged$.next(newFile);
|
||||
}
|
||||
}
|
||||
|
||||
return newFiles;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user