fix RED-3519: show imported redactions after converting highlights
This commit is contained in:
parent
3a19bf7b07
commit
b016254bac
@ -111,7 +111,7 @@ const components = [AppComponent, AuthErrorComponent, NotificationsComponent, Sp
|
||||
useValue: {
|
||||
level: environment.production ? NgxLoggerLevel.ERROR : NgxLoggerLevel.DEBUG,
|
||||
enableSourceMaps: true,
|
||||
timestampFormat: 'hh:mm:ss SSS',
|
||||
timestampFormat: 'mm:ss:SSS',
|
||||
disableFileDetails: true,
|
||||
features: {
|
||||
ANNOTATIONS: {
|
||||
@ -119,6 +119,9 @@ const components = [AppComponent, AuthErrorComponent, NotificationsComponent, Sp
|
||||
enabled: true,
|
||||
level: NgxLoggerLevel.DEBUG,
|
||||
},
|
||||
FILTERS: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
} as ILoggerConfig,
|
||||
},
|
||||
|
||||
@ -24,7 +24,6 @@ export class AnnotationPermissions {
|
||||
const summedPermissions: AnnotationPermissions = new AnnotationPermissions();
|
||||
|
||||
for (const annotation of annotations) {
|
||||
console.log(annotation.pending);
|
||||
const permissions: AnnotationPermissions = new AnnotationPermissions();
|
||||
|
||||
permissions.canUndo = (!isApprover && annotation.isSuggestion) || annotation.pending;
|
||||
|
||||
@ -35,17 +35,17 @@ import { toPosition } from '../../../dossier/utils/pdf-calculation.utils';
|
||||
import { ViewModeService } from '../../services/view-mode.service';
|
||||
import { MultiSelectService } from '../../services/multi-select.service';
|
||||
import { FilePreviewStateService } from '../../services/file-preview-state.service';
|
||||
import { tap, withLatestFrom } from 'rxjs/operators';
|
||||
import { map, switchMap, tap, withLatestFrom } from 'rxjs/operators';
|
||||
import { FileManagementService } from '@services/entity-services/file-management.service';
|
||||
import { PageRotationService } from '../../services/page-rotation.service';
|
||||
import { ALLOWED_KEYBOARD_SHORTCUTS, HeaderElements, TextPopups } from '../../shared/constants';
|
||||
import { FilePreviewDialogService } from '../../services/file-preview-dialog.service';
|
||||
import { loadCompareDocumentWrapper } from '../../../dossier/utils/compare-mode.utils';
|
||||
import { fromEvent } from 'rxjs';
|
||||
import { from, fromEvent } from 'rxjs';
|
||||
import { FileDataService } from '../../services/file-data.service';
|
||||
import Tools = Core.Tools;
|
||||
import TextTool = Tools.TextTool;
|
||||
import Annotation = Core.Annotations.Annotation;
|
||||
import { FileDataService } from '../../services/file-data.service';
|
||||
|
||||
function getDivider(hiddenOn?: readonly ('desktop' | 'mobile' | 'tablet')[]) {
|
||||
return {
|
||||
@ -117,8 +117,8 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
|
||||
|
||||
this.addActiveScreenSubscription = this.stateService.blob$
|
||||
.pipe(
|
||||
switchMap(blob => from(this.pdf.lockDocument()).pipe(map(() => blob))),
|
||||
withLatestFrom(this.stateService.file$),
|
||||
tap(() => (this.pdf.ready = false)),
|
||||
tap(([blob, file]) => this._loadDocument(blob, file)),
|
||||
)
|
||||
.subscribe();
|
||||
@ -155,7 +155,6 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
|
||||
|
||||
const loadCompareDocument = async () => {
|
||||
this._loadingService.start();
|
||||
this.pdf.ready = false;
|
||||
const mergedDocument = await pdfNet.PDFDoc.create();
|
||||
const file = await this.stateService.file;
|
||||
await loadCompareDocumentWrapper(
|
||||
@ -690,16 +689,14 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
|
||||
return entry;
|
||||
}
|
||||
|
||||
private async _loadDocument(blob: Blob, file: File) {
|
||||
const document = await this.instance.Core.documentViewer.getDocument()?.getPDFDoc();
|
||||
await document?.lock();
|
||||
private _loadDocument(blob: Blob, file: File) {
|
||||
this.instance.UI.loadDocument(blob, { filename: file?.filename ?? 'document.pdf' });
|
||||
this._pageRotationService.clearRotationsHideActions();
|
||||
}
|
||||
|
||||
private _setReadyAndInitialState(): void {
|
||||
private _setReadyAndInitialState() {
|
||||
this._ngZone.run(() => {
|
||||
this.pdf.documentLoaded$.next(true);
|
||||
this.pdf.emitDocumentLoaded();
|
||||
const routePageNumber: number = this._activatedRoute.snapshot.queryParams.page;
|
||||
this.pageChanged.emit(routePageNumber || 1);
|
||||
this._setInitialDisplayMode();
|
||||
|
||||
@ -9,7 +9,6 @@ import {
|
||||
ErrorService,
|
||||
FilterService,
|
||||
LoadingService,
|
||||
log,
|
||||
NestedFilter,
|
||||
OnAttach,
|
||||
OnDetach,
|
||||
@ -143,11 +142,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
}
|
||||
|
||||
async updateViewMode(): Promise<void> {
|
||||
if (!this.pdf.ready) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.pdf.deleteAnnotations(this._fileDataService.textHighlights.map(a => a.id));
|
||||
this._logger.debug(`[PDF] Update ${this._viewModeService.viewMode} view mode`);
|
||||
|
||||
const annotations = this.pdf.getAnnotations(a => a.getCustomData('redact-manager'));
|
||||
const redactions = annotations.filter(a => a.getCustomData('redaction'));
|
||||
@ -233,14 +228,8 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
this.displayPdfViewer = true;
|
||||
}
|
||||
|
||||
async rebuildFilters(deletePreviousAnnotations = false) {
|
||||
async rebuildFilters() {
|
||||
const startTime = new Date().getTime();
|
||||
if (deletePreviousAnnotations) {
|
||||
this.pdf.deleteAnnotations();
|
||||
|
||||
console.log(`[REDACTION] Delete previous annotations time: ${new Date().getTime() - startTime} ms`);
|
||||
}
|
||||
const processStartTime = new Date().getTime();
|
||||
|
||||
const visibleAnnotations = await this._fileDataService.visibleAnnotations;
|
||||
const annotationFilters = this._annotationProcessingService.getAnnotationFilter(visibleAnnotations);
|
||||
@ -260,8 +249,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
),
|
||||
});
|
||||
|
||||
this._logger.debug(`[REDACTION] Process time: ${new Date().getTime() - processStartTime} ms`);
|
||||
this._logger.debug(`[REDACTION] Filter rebuild time: ${new Date().getTime() - startTime}`);
|
||||
this._logger.debug(`[FILTERS] Rebuild time: ${new Date().getTime() - startTime} ms`);
|
||||
}
|
||||
|
||||
async handleAnnotationSelected(annotationIds: string[]) {
|
||||
@ -370,8 +358,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
|
||||
viewerReady() {
|
||||
this.ready = true;
|
||||
this.pdf.ready = true;
|
||||
|
||||
this._setExcludedPageStyles();
|
||||
|
||||
this.pdf.documentViewer.addEventListener('pageComplete', () => {
|
||||
@ -426,7 +412,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
let start;
|
||||
return combineLatest([documentLoaded$, this._fileDataService.annotations$]).pipe(
|
||||
debounceTime(300),
|
||||
log(),
|
||||
tap(() => (start = new Date().getTime())),
|
||||
map(([, annotations]) => annotations),
|
||||
startWith({} as Record<string, AnnotationWrapper>),
|
||||
@ -451,7 +436,10 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
|
||||
drawChangedAnnotations(oldAnnotations: Record<string, AnnotationWrapper>, newAnnotations: Record<string, AnnotationWrapper>) {
|
||||
let annotationsToDraw: readonly AnnotationWrapper[];
|
||||
if (this.pdf.hasAnnotations) {
|
||||
const ann = this.pdf.annotationManager.getAnnotationsList().map(a => oldAnnotations[a.Id]);
|
||||
const hasAnnotations = ann.filter(a => !!a).length > 0;
|
||||
|
||||
if (hasAnnotations) {
|
||||
annotationsToDraw = this.#getAnnotationsToDraw(newAnnotations, oldAnnotations);
|
||||
} else {
|
||||
annotationsToDraw = Object.values(newAnnotations);
|
||||
@ -511,18 +499,18 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
}
|
||||
|
||||
private async _stampPDF() {
|
||||
const pdfDoc = await this.pdf.documentViewer.getDocument().getPDFDoc();
|
||||
const file = await this.stateService.file;
|
||||
const allPages = [...Array(file.numberOfPages).keys()].map(page => page + 1);
|
||||
|
||||
if (!pdfDoc || !this.pdf.ready) {
|
||||
const pdfDoc = await this.pdf.documentViewer.getDocument()?.getPDFDoc();
|
||||
if (!pdfDoc) {
|
||||
return;
|
||||
}
|
||||
|
||||
const file = await this.stateService.file;
|
||||
const allPages = [...Array(file.numberOfPages).keys()].map(page => page + 1);
|
||||
|
||||
try {
|
||||
await clearStamps(pdfDoc, this.pdf.PDFNet, allPages);
|
||||
} catch (e) {
|
||||
this._logger.debug('Error clearing stamps: ', e);
|
||||
this._logger.error('Error clearing stamps: ', e);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -616,10 +604,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
}
|
||||
|
||||
private async _cleanupAndRedrawAnnotations(newAnnotations: readonly AnnotationWrapper[]) {
|
||||
if (!this.pdf.ready) {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentFilters = this._filterService.getGroup('primaryFilters')?.filters || [];
|
||||
await this.rebuildFilters();
|
||||
|
||||
|
||||
@ -37,10 +37,6 @@ export class AnnotationDrawService {
|
||||
) {}
|
||||
|
||||
drawAnnotations(annotationWrappers: readonly AnnotationWrapper[]) {
|
||||
if (!this._pdf.instance || !this._pdf.ready) {
|
||||
return;
|
||||
}
|
||||
|
||||
const licenceKey = environment.licenseKey ? atob(environment.licenseKey) : null;
|
||||
return this._pdf.PDFNet.runWithCleanup(() => this._drawAnnotations(annotationWrappers), licenceKey);
|
||||
}
|
||||
@ -89,13 +85,6 @@ export class AnnotationDrawService {
|
||||
}
|
||||
|
||||
private async _drawAnnotations(annotationWrappers: readonly AnnotationWrapper[]) {
|
||||
const document = await this._pdf.documentViewer.getDocument()?.getPDFDoc();
|
||||
if (!this._pdf.ready || !document) {
|
||||
return;
|
||||
}
|
||||
|
||||
await document.lock();
|
||||
|
||||
const annotations = annotationWrappers.map(annotation => this._computeAnnotation(annotation)).filter(a => !!a);
|
||||
this._pdf.annotationManager.addAnnotations(annotations, { imported: true });
|
||||
await this._pdf.annotationManager.drawAnnotationsFromList(annotations);
|
||||
|
||||
@ -21,7 +21,7 @@ import { DictionariesMapService } from '../../../services/entity-services/dictio
|
||||
import { map, switchMap, tap, withLatestFrom } from 'rxjs/operators';
|
||||
import { PermissionsService } from '../../../services/permissions.service';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { log, shareDistinctLast, shareLast, Toaster } from '../../../../../../../libs/common-ui/src';
|
||||
import { shareDistinctLast, shareLast, Toaster } from '../../../../../../../libs/common-ui/src';
|
||||
import { RedactionLogService } from '../../dossier/services/redaction-log.service';
|
||||
import { TextHighlightService } from '../../dossier/services/text-highlight.service';
|
||||
import { ViewModeService } from './view-mode.service';
|
||||
@ -66,7 +66,6 @@ export class FileDataService {
|
||||
this.annotations$.pipe(map(annotations => this.getVisibleAnnotations(Object.values(annotations), viewMode))),
|
||||
),
|
||||
),
|
||||
log('Visible annotations: '),
|
||||
shareDistinctLast(),
|
||||
);
|
||||
}
|
||||
|
||||
@ -7,20 +7,37 @@ import { Inject, Injectable } from '@angular/core';
|
||||
import { BASE_HREF } from '../../../tokens';
|
||||
import { environment } from '@environments/environment';
|
||||
import { DISABLED_HOTKEYS } from '../shared/constants';
|
||||
import { Subject } from 'rxjs';
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
import { NGXLogger } from 'ngx-logger';
|
||||
import { tap } from 'rxjs/operators';
|
||||
import { shareLast } from '../../../../../../../libs/common-ui/src';
|
||||
import Annotation = Core.Annotations.Annotation;
|
||||
import DocumentViewer = Core.DocumentViewer;
|
||||
import AnnotationManager = Core.AnnotationManager;
|
||||
|
||||
@Injectable()
|
||||
export class PdfViewer {
|
||||
ready = false;
|
||||
instance: WebViewerInstance;
|
||||
documentViewer: DocumentViewer;
|
||||
annotationManager: AnnotationManager;
|
||||
readonly documentLoaded$ = new Subject();
|
||||
instance?: WebViewerInstance;
|
||||
|
||||
constructor(@Inject(BASE_HREF) private readonly _baseHref: string, readonly viewModeService: ViewModeService) {}
|
||||
readonly documentLoaded$: Observable<boolean>;
|
||||
readonly #documentLoaded$ = new Subject<boolean>();
|
||||
|
||||
constructor(
|
||||
@Inject(BASE_HREF) private readonly _baseHref: string,
|
||||
private readonly _viewModeService: ViewModeService,
|
||||
private readonly _logger: NGXLogger,
|
||||
) {
|
||||
this.documentLoaded$ = this.#documentLoaded$.asObservable().pipe(
|
||||
tap(() => this._logger.debug('[PDF] Loaded')),
|
||||
shareLast(),
|
||||
);
|
||||
}
|
||||
|
||||
get documentViewer() {
|
||||
return this.instance?.Core.documentViewer;
|
||||
}
|
||||
|
||||
get annotationManager() {
|
||||
return this.instance?.Core.annotationManager;
|
||||
}
|
||||
|
||||
get UI() {
|
||||
return this.instance.UI;
|
||||
@ -39,19 +56,15 @@ export class PdfViewer {
|
||||
}
|
||||
|
||||
get paginationOffset() {
|
||||
return this.viewModeService.isCompare ? 2 : 1;
|
||||
return this._viewModeService.isCompare ? 2 : 1;
|
||||
}
|
||||
|
||||
get currentPage() {
|
||||
return this.viewModeService.isCompare ? Math.ceil(this._currentInternalPage / 2) : this._currentInternalPage;
|
||||
return this._viewModeService.isCompare ? Math.ceil(this._currentInternalPage / 2) : this._currentInternalPage;
|
||||
}
|
||||
|
||||
get totalPages() {
|
||||
if (!this.ready) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.viewModeService.isCompare ? Math.ceil(this._totalInternalPages / 2) : this._totalInternalPages;
|
||||
return this._viewModeService.isCompare ? Math.ceil(this._totalInternalPages / 2) : this._totalInternalPages;
|
||||
}
|
||||
|
||||
private get _currentInternalPage() {
|
||||
@ -67,6 +80,28 @@ export class PdfViewer {
|
||||
}
|
||||
}
|
||||
|
||||
async lockDocument() {
|
||||
const document = await this.documentViewer.getDocument()?.getPDFDoc();
|
||||
if (!document) {
|
||||
return false;
|
||||
}
|
||||
|
||||
await document.lock();
|
||||
this._logger.debug('[PDF] Locked');
|
||||
return true;
|
||||
}
|
||||
|
||||
async unlockDocument() {
|
||||
const document = await this.documentViewer.getDocument()?.getPDFDoc();
|
||||
if (!document) {
|
||||
return false;
|
||||
}
|
||||
|
||||
await document.unlock();
|
||||
this._logger.debug('[PDF] Unlocked');
|
||||
return true;
|
||||
}
|
||||
|
||||
hideAnnotations(annotations: Annotation[]): void {
|
||||
this.annotationManager.hideAnnotations(annotations);
|
||||
}
|
||||
@ -88,6 +123,11 @@ export class PdfViewer {
|
||||
return [];
|
||||
}
|
||||
|
||||
emitDocumentLoaded() {
|
||||
this.deleteAnnotations();
|
||||
this.#documentLoaded$.next(true);
|
||||
}
|
||||
|
||||
async loadViewer(htmlElement: HTMLElement) {
|
||||
this.instance = await WebViewer(
|
||||
{
|
||||
@ -100,9 +140,6 @@ export class PdfViewer {
|
||||
htmlElement,
|
||||
);
|
||||
|
||||
this.documentViewer = this.instance.Core.documentViewer;
|
||||
this.annotationManager = this.instance.Core.annotationManager;
|
||||
|
||||
return this.instance;
|
||||
}
|
||||
|
||||
@ -138,11 +175,7 @@ export class PdfViewer {
|
||||
}
|
||||
|
||||
deselectAllAnnotations() {
|
||||
if (!this.ready) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.annotationManager.deselectAllAnnotations();
|
||||
this.annotationManager?.deselectAllAnnotations();
|
||||
}
|
||||
|
||||
selectAnnotations(annotations: AnnotationWrapper[], multiSelectActive: boolean = false) {
|
||||
@ -167,10 +200,6 @@ export class PdfViewer {
|
||||
}
|
||||
|
||||
deleteAnnotations(annotationsIds?: readonly string[]) {
|
||||
if (!this.ready) {
|
||||
return;
|
||||
}
|
||||
|
||||
let annotations: Annotation[];
|
||||
if (!annotationsIds) {
|
||||
annotations = this.getAnnotations();
|
||||
@ -180,7 +209,6 @@ export class PdfViewer {
|
||||
|
||||
try {
|
||||
this.annotationManager.deleteAnnotations(annotations, {
|
||||
imported: true,
|
||||
force: true,
|
||||
});
|
||||
} catch (error) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user