RED-3687 - undone changes for file preview component

This commit is contained in:
Valentin Mihai 2022-07-15 15:26:38 +03:00
parent 3d682b665a
commit 3408655c82
5 changed files with 91 additions and 107 deletions

View File

@ -11,13 +11,18 @@ import { FilePreviewStateService } from '../../services/file-preview-state.servi
import { ManualRedactionService } from '../../services/manual-redaction.service';
import { ContextComponent } from '@utils/context.component';
interface CommentsTemplate {
dossier: Dossier;
file: File;
}
@Component({
selector: 'redaction-comments',
templateUrl: './comments.component.html',
styleUrls: ['./comments.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CommentsComponent extends ContextComponent implements OnInit {
export class CommentsComponent extends ContextComponent<CommentsTemplate> implements OnInit {
@Input() annotation: AnnotationWrapper;
readonly trackBy = trackByFactory();
readonly file$: Observable<File>;
@ -47,7 +52,11 @@ export class CommentsComponent extends ContextComponent implements OnInit {
}),
);
super._initContext([{ file: this.file$ }, { dossier: this.dossier$ }, this.hiddenComments$]);
super._initContext({
file: this.file$,
dossier: this.dossier$,
hiddenComments: this.hiddenComments$,
});
}
async addComment(value: string): Promise<void> {

View File

@ -1,22 +1,22 @@
<ng-container *ngIf="componentContext$ | async as ctx">
<section *ngIf="ctx.dossier && ctx.file" [class.fullscreen]="fullScreen">
<ng-container *ngIf="state.dossier$ | async as dossier">
<section *ngIf="file$ | async as file" [class.fullscreen]="fullScreen">
<div class="page-header">
<div class="flex flex-1">
<redaction-view-switch (switchView)="switchView($event)"></redaction-view-switch>
</div>
<div class="flex-1 actions-container">
<redaction-processing-indicator [file]="ctx.file" class="mr-16"></redaction-processing-indicator>
<redaction-processing-indicator [file]="file" class="mr-16"></redaction-processing-indicator>
<redaction-user-management></redaction-user-management>
<ng-container *ngIf="permissionsService.isApprover(ctx.dossier) && !!ctx.file.lastReviewer">
<ng-container *ngIf="permissionsService.isApprover(dossier) && !!file.lastReviewer">
<div class="vertical-line"></div>
<div class="all-caps-label mr-16 ml-8">
{{ 'file-preview.last-assignee' | translate: { status: ctx.file.workflowStatus } }}
{{ 'file-preview.last-assignee' | translate: { status: file.workflowStatus } }}
</div>
<redaction-initials-avatar
[user]="ctx.file.isApproved ? ctx.file.lastApprover : ctx.file.lastReviewer"
[user]="file.isApproved ? file.lastApprover : file.lastReviewer"
[withName]="true"
></redaction-initials-avatar>
</ng-container>
@ -24,8 +24,8 @@
<div class="vertical-line"></div>
<redaction-file-actions
[dossier]="ctx.dossier"
[file]="ctx.file"
[dossier]="dossier"
[file]="file"
fileActionsHelpModeKey="document_features_in_editor"
type="file-preview"
></redaction-file-actions>
@ -40,7 +40,7 @@
<!-- Dev Mode Features-->
<iqser-circle-button
(action)="downloadOriginalFile(ctx.file)"
(action)="downloadOriginalFile(file)"
*ngIf="userPreferenceService.areDevFeaturesEnabled"
[tooltip]="'file-preview.download-original-file' | translate"
[type]="circleButtonTypes.primary"
@ -53,7 +53,7 @@
<iqser-circle-button
(action)="closeFullScreen()"
*ngIf="!fullScreen"
[routerLink]="ctx.dossier.routerLink"
[routerLink]="dossier.routerLink"
[tooltip]="'common.close' | translate"
class="ml-8"
icon="iqser:close"

View File

@ -1,7 +1,8 @@
import { ChangeDetectorRef, Component, HostListener, Injector, NgZone, OnInit, TemplateRef, ViewChild } from '@angular/core';
import { ChangeDetectorRef, Component, HostListener, Injector, NgZone, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
import { ActivatedRoute, ActivatedRouteSnapshot, NavigationExtras, Router } from '@angular/router';
import { Core } from '@pdftron/webviewer';
import {
AutoUnsubscribe,
bool,
CircleButtonTypes,
CustomError,
@ -11,6 +12,7 @@ import {
LoadingService,
NestedFilter,
OnAttach,
OnDetach,
processFilters,
} from '@iqser/common-ui';
import { MatDialogState } from '@angular/material/dialog';
@ -50,7 +52,6 @@ import { REDDocumentViewer } from '../pdf-viewer/services/document-viewer.servic
import { AnnotationsListingService } from './services/annotations-listing.service';
import { PdfProxyService } from './services/pdf-proxy.service';
import Annotation = Core.Annotations.Annotation;
import { ContextComponent } from '@utils/context.component';
const textActions = [TextPopups.ADD_DICTIONARY, TextPopups.ADD_FALSE_POSITIVE];
@ -59,13 +60,13 @@ const textActions = [TextPopups.ADD_DICTIONARY, TextPopups.ADD_FALSE_POSITIVE];
styleUrls: ['./file-preview-screen.component.scss'],
providers: filePreviewScreenProviders,
})
export class FilePreviewScreenComponent extends ContextComponent implements OnInit, OnAttach, ComponentCanDeactivate {
readonly fileId = this.state.fileId;
readonly dossierId = this.state.dossierId;
readonly file$ = this.state.file$.pipe(tap(file => this._fileDataService.loadAnnotations(file)));
export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnInit, OnDestroy, OnAttach, OnDetach, ComponentCanDeactivate {
readonly circleButtonTypes = CircleButtonTypes;
fullScreen = false;
readonly fileId = this.state.fileId;
readonly dossierId = this.state.dossierId;
readonly file$ = this.state.file$.pipe(tap(file => this._fileDataService.loadAnnotations(file)));
@ViewChild('annotationFilterTemplate', {
read: TemplateRef,
static: false,
@ -191,6 +192,7 @@ export class FilePreviewScreenComponent extends ContextComponent implements OnIn
ngOnDetach() {
this._viewerHeaderService.resetCompareButtons();
super.ngOnDetach();
this._changeRef.markForCheck();
}
@ -217,7 +219,7 @@ export class FilePreviewScreenComponent extends ContextComponent implements OnIn
this._loadingService.start();
await this.userPreferenceService.saveLastOpenedFileForDossier(this.dossierId, this.fileId);
this._initContext();
this._subscribeToFileUpdates();
if (file?.analysisRequired && !file.excludedFromAutomaticAnalysis) {
const reanalysisService = this._injector.get(ReanalysisService);
@ -485,66 +487,59 @@ export class FilePreviewScreenComponent extends ContextComponent implements OnIn
}, 100);
}
protected _initContext(): void {
const loadAnnotations$ = this.loadAnnotations();
private _subscribeToFileUpdates(): void {
this.addActiveScreenSubscription = this.loadAnnotations().subscribe();
const handleDeletedDossier$ = this._dossiersService.getEntityDeleted$(this.dossierId).pipe(tap(() => this._handleDeletedDossier()));
this.addActiveScreenSubscription = this._dossiersService
.getEntityDeleted$(this.dossierId)
.pipe(tap(() => this._handleDeletedDossier()))
.subscribe();
const watchDeleted$ = this._filesMapService.watchDeleted$(this.fileId).pipe(tap(() => this._handleDeletedFile()));
this.addActiveScreenSubscription = this._filesMapService
.watchDeleted$(this.fileId)
.pipe(tap(() => this._handleDeletedFile()))
.subscribe();
const switchToStandard$ = combineLatest([this._viewModeService.viewMode$, this.state.file$]).pipe(
tap(([viewMode, file]) => {
if (viewMode === ViewModes.TEXT_HIGHLIGHTS && !file.hasHighlights) {
this._viewModeService.switchToStandard();
}
this.addActiveScreenSubscription = combineLatest([this._viewModeService.viewMode$, this.state.file$])
.pipe(
tap(([viewMode, file]) => {
if (viewMode === ViewModes.TEXT_HIGHLIGHTS && !file.hasHighlights) {
this._viewModeService.switchToStandard();
}
}),
)
.subscribe();
this.addActiveScreenSubscription = this._documentViewer.pageComplete$.subscribe(() => {
this._setExcludedPageStyles();
});
this.addActiveScreenSubscription = this._documentViewer.keyUp$.subscribe($event => {
this.handleKeyEvent($event);
});
this.addActiveScreenSubscription = this.#textSelected$.subscribe();
this.addActiveScreenSubscription = this.state.dossierFileChange$.subscribe();
this.addActiveScreenSubscription = this.state.blob$
.pipe(
switchMap(blob => from(this._documentViewer.lock()).pipe(map(() => blob))),
tap(() => this._errorService.clear()),
tap(blob => this.pdf.loadDocument(blob, this.state.file, () => this.state.reloadBlob())),
)
.subscribe();
this.addActiveScreenSubscription = this.pdfProxyService.manualAnnotationRequested$.subscribe($event => {
this.openManualAnnotationDialog($event);
});
this.addActiveScreenSubscription = this.pdfProxyService.pageChanged$.subscribe(page =>
this._ngZone.run(() => {
console.log('viewerPageChanged', page);
return this.#updateQueryParamsPage(page);
}),
);
const excludedPageStyles$ = this._documentViewer.pageComplete$.pipe(tap(() => this._setExcludedPageStyles()));
const handleKeyEvent$ = this._documentViewer.keyUp$.pipe(tap($event => this.handleKeyEvent($event)));
const textSelected$ = this.#textSelected$;
const blobLoadDocument$ = this.state.blob$.pipe(
switchMap(blob => from(this._documentViewer.lock()).pipe(map(() => blob))),
tap(() => this._errorService.clear()),
tap(blob => this.pdf.loadDocument(blob, this.state.file, () => this.state.reloadBlob())),
);
const openManualAnnotationDialog$ = this.pdfProxyService.manualAnnotationRequested$.pipe(
tap($event => {
this.openManualAnnotationDialog($event);
}),
);
const updateQueryParamsPage$ = this.pdfProxyService.pageChanged$.pipe(
tap(page => {
this._ngZone.run(() => {
console.log('viewerPageChanged', page);
return this.#updateQueryParamsPage(page);
});
}),
);
super._initContext([
{ dossier: this.state.dossier$ },
{ file: this.file$ },
this.pdf.currentPage$,
this.pdfProxyService.canPerformAnnotationActions$,
this.state.dossierFileChange$,
this.pdfProxyService.annotationSelected$,
loadAnnotations$,
handleDeletedDossier$,
watchDeleted$,
switchToStandard$,
excludedPageStyles$,
handleKeyEvent$,
textSelected$,
blobLoadDocument$,
openManualAnnotationDialog$,
updateQueryParamsPage$,
]);
this.addActiveScreenSubscription = this.pdfProxyService.annotationSelected$.subscribe();
}
private _handleDeletedDossier(): void {

View File

@ -136,7 +136,7 @@ export class ManualRedactionService extends GenericService<IManualAddResponse> {
}
getTitle(type: ManualRedactionEntryType, dossier: Dossier) {
if (dossier && this._permissionsService.isApprover(dossier)) {
if (this._permissionsService.isApprover(dossier)) {
switch (type) {
case 'DICTIONARY':
return _('manual-annotation.dialog.header.dictionary');

View File

@ -1,41 +1,21 @@
import { combineLatest, Observable, of } from 'rxjs';
import { combineLatest, Observable, ObservableInputTuple, of, pipe } from 'rxjs';
import { map, startWith } from 'rxjs/operators';
import { OnDetach, ValuesOf } from '@iqser/common-ui';
type ContextObservable = Observable<unknown> | { [key: string]: Observable<unknown> };
export class ContextComponent<C> implements OnDetach {
componentContext$: Observable<C> | null = of({} as C);
export class ContextComponent {
componentContext$: Observable<any> = of({});
#templateContextKeys = {};
#observables = [];
protected _initContext(observables: ContextObservable[]) {
this.#extractKeysAndObservables(observables);
this.componentContext$ = combineLatest(this.#observables).pipe(map(values => this.#mapContext(values)));
protected _initContext<T extends Record<string, ValuesOf<T>>>(context: ObservableInputTuple<T>): void {
const observables = Object.values(context).map(obs => obs.pipe(startWith(null)));
const keys = Object.keys(context);
this.componentContext$ = combineLatest(observables).pipe(map(values => this._mapKeysToObs(keys, values)));
}
#extractKeysAndObservables(observables: ContextObservable[]) {
observables.forEach((value, index) => {
const keys = Object.keys(value);
let observable: any;
if (keys.length === 1) {
this.#templateContextKeys[index] = keys[0];
observable = value[keys[0]];
} else {
observable = value;
}
this.#observables.push(observable.pipe(startWith(null)));
});
protected _mapKeysToObs<T>(keys: string[], observables: Observable<any>[]): T {
return keys.reduce((acc, key, index) => ({ ...acc, [key]: observables[index] }), {} as T);
}
#mapContext(values: Array<unknown>) {
const context = {};
values.forEach((value, index) => {
const key = this.#templateContextKeys[index];
context[key ? key : index] = value;
});
return context;
ngOnDetach() {
this.componentContext$ = null;
}
}