diff --git a/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.html b/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.html index 7c944134a..ee2e15342 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.html +++ b/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.html @@ -132,11 +132,11 @@ tooltipPosition="above" > - - {{ activeViewerPage }} - - {{ activeAnnotations?.length || 0 }} - - +
diff --git a/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts b/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts index 5c752ddf6..3fd565de0 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts @@ -89,8 +89,8 @@ export class FileWorkloadComponent { this.title$ = this._title$; } - get activeAnnotations(): AnnotationWrapper[] | undefined { - return this.displayedAnnotations.get(this.activeViewerPage); + get activeAnnotations(): AnnotationWrapper[] { + return this.displayedAnnotations.get(this.activeViewerPage) || []; } get currentPageIsExcluded(): boolean { @@ -186,6 +186,7 @@ export class FileWorkloadComponent { if ($event.key === 'ArrowLeft') { this.pagesPanelActive = true; + this._changeDetectorRef.markForCheck(); return; } @@ -197,6 +198,7 @@ export class FileWorkloadComponent { if (!this.pagesPanelActive && !this.multiSelectService.isActive) { this._selectFirstAnnotationOnCurrentPageIfNecessary(); } + this._changeDetectorRef.markForCheck(); return; } @@ -370,7 +372,8 @@ export class FileWorkloadComponent { private _selectFirstAnnotationOnCurrentPageIfNecessary() { if ( (!this._firstSelectedAnnotation || this.activeViewerPage !== this._firstSelectedAnnotation.pageNumber) && - this.displayedPages.indexOf(this.activeViewerPage) >= 0 + this.displayedPages.indexOf(this.activeViewerPage) >= 0 && + this.activeAnnotations.length > 0 ) { this.selectAnnotations.emit([this.activeAnnotations[0]]); } @@ -411,24 +414,24 @@ export class FileWorkloadComponent { private _nextPageWithAnnotations() { let idx = 0; for (const page of this.displayedPages) { - if (page > this.activeViewerPage) { + if (page > this.activeViewerPage && this.displayedAnnotations.get(page)) { break; } ++idx; } - return idx < this.displayedPages.length ? this.displayedPages[idx] : null; + return idx < this.displayedPages.length ? this.displayedPages[idx] : this.displayedPages[this.displayedPages.length - 1]; } private _prevPageWithAnnotations() { let idx = this.displayedPages.length - 1; const reverseDisplayedPages = [...this.displayedPages].reverse(); for (const page of reverseDisplayedPages) { - if (page < this.activeViewerPage) { + if (page < this.activeViewerPage && this.displayedAnnotations.get(page)) { break; } --idx; } - return idx >= 0 ? this.displayedPages[idx] : null; + return idx >= 0 ? this.displayedPages[idx] : this.displayedPages[0]; } private _scrollQuickNavigationToPage(page: number) { diff --git a/apps/red-ui/src/app/modules/file-preview/components/pdf-viewer/pdf-viewer.component.ts b/apps/red-ui/src/app/modules/file-preview/components/pdf-viewer/pdf-viewer.component.ts index 7dff9d817..2a4c4dbf9 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/pdf-viewer/pdf-viewer.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/pdf-viewer/pdf-viewer.component.ts @@ -257,7 +257,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha return this._handleCustomActions(); }); - fromEvent(this.documentViewer, 'pageNumberUpdated').subscribe(console.log); + fromEvent(this.documentViewer, 'pageNumberUpdated').subscribe((page: number) => console.log(`Navigated to page ${page}`)); this.documentViewer.addEventListener('documentLoaded', this._setReadyAndInitialState); @@ -489,7 +489,9 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha } const visibleAnnotations = await this._fileDataService.visibleAnnotations; - const annotationWrappers = viewerAnnotations.map(va => visibleAnnotations.find(a => a.id === va.Id)).filter(va => !!va); + const annotationWrappers: AnnotationWrapper[] = viewerAnnotations + .map(va => visibleAnnotations.find(a => a.id === va.Id)) + .filter(va => !!va); this.instance.UI.annotationPopup.update([]); if (annotationWrappers.length === 0) { diff --git a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts index c3aa09a7e..72f052648 100644 --- a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts @@ -261,6 +261,9 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni } async handleAnnotationSelected(annotationIds: string[]) { + if (annotationIds.length > 0) { + this._workloadComponent.pagesPanelActive = false; + } const visibleAnnotations = await this._fileDataService.visibleAnnotations; this.selectedAnnotations = annotationIds .map(id => visibleAnnotations.find(annotation => annotation.id === id)) @@ -273,7 +276,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni } @Debounce(10) - selectAnnotations(annotations?: AnnotationWrapper[]) { + selectAnnotations(annotations: AnnotationWrapper[]) { if (annotations) { const annotationsToSelect = this.multiSelectService.isActive ? [...this.selectedAnnotations, ...annotations] : annotations; this.pdf.selectAnnotations(annotationsToSelect, this.multiSelectService.isActive); @@ -313,11 +316,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni } handleArrowEvent($event: KeyboardEvent): void { - if (['ArrowUp', 'ArrowDown'].includes($event.key)) { - if (this.selectedAnnotations.length === 1) { - this._workloadComponent?.navigateAnnotations($event); - } - } + this._workloadComponent.handleKeyEvent($event); } @HostListener('window:keyup', ['$event']) diff --git a/apps/red-ui/src/app/modules/file-preview/services/commenting.service.ts b/apps/red-ui/src/app/modules/file-preview/services/commenting.service.ts index 523631f3a..90cd0b16d 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/commenting.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/commenting.service.ts @@ -7,6 +7,7 @@ import { shareDistinctLast } from '@iqser/common-ui'; export class CommentingService { private _activeAnnotations = new BehaviorSubject>(new Set()); + /** Annotations with active comments section */ isActive$(annotationId: string): Observable { return this._activeAnnotations.pipe( map(annotations => annotations.has(annotationId)), diff --git a/apps/red-ui/src/app/modules/file-preview/services/pdf-viewer.service.ts b/apps/red-ui/src/app/modules/file-preview/services/pdf-viewer.service.ts index d18711d77..db545fa8c 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/pdf-viewer.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/pdf-viewer.service.ts @@ -82,7 +82,7 @@ export class PdfViewer { getAnnotationsById(ids: readonly string[]) { if (this.annotationManager) { - return ids.map(id => this.annotationManager.getAnnotationById(id)); + return ids.map(id => this.annotationManager.getAnnotationById(id)).filter(a => !!a); } return []; @@ -129,9 +129,7 @@ export class PdfViewer { } disableHotkeys(): void { - for (const hotkey of DISABLED_HOTKEYS) { - this.instance.UI.hotkeys.off(hotkey); - } + DISABLED_HOTKEYS.forEach(key => this.instance.UI.hotkeys.off(key)); } translateQuad(page: number, quad: Core.Math.Quad) { @@ -147,16 +145,23 @@ export class PdfViewer { this.annotationManager.deselectAllAnnotations(); } - selectAnnotations(annotations?: AnnotationWrapper[], multiSelectActive: boolean = false) { + selectAnnotations(annotations: AnnotationWrapper[], multiSelectActive: boolean = false) { if (!annotations) { return; } + const filteredAnnotations = annotations.filter(a => !!a); + + if (!filteredAnnotations.length) { + return; + } + if (!multiSelectActive) { this.deselectAllAnnotations(); } - const annotationsFromViewer = this.getAnnotationsById(annotations.map(a => a.id)); + const annotationsFromViewer = this.getAnnotationsById(filteredAnnotations.map(a => a.id)); + this.annotationManager.jumpToAnnotation(annotationsFromViewer[0]); this.annotationManager.selectAnnotations(annotationsFromViewer); } diff --git a/apps/red-ui/src/assets/i18n/de.json b/apps/red-ui/src/assets/i18n/de.json index 938c9abdb..f5e14b6b7 100644 --- a/apps/red-ui/src/assets/i18n/de.json +++ b/apps/red-ui/src/assets/i18n/de.json @@ -159,7 +159,6 @@ "dossier-templates": "Dossier-Vorlage", "settings": "Einstellungen" }, - "annotation": "Anmerkung", "annotation-actions": { "accept-recommendation": { "label": "Empfehlung annehmen" @@ -319,7 +318,6 @@ "suggestion-resize": "Vorgeschlagene Größenänderung", "text-highlight": "" }, - "annotations": "Anmerkungen", "archived-dossiers-listing": { "no-data": { "title": "" diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json index c1a6547bd..33bbbb6f3 100644 --- a/apps/red-ui/src/assets/i18n/en.json +++ b/apps/red-ui/src/assets/i18n/en.json @@ -159,7 +159,6 @@ "dossier-templates": "Dossier Templates", "settings": "Settings" }, - "annotation": "Annotation", "annotation-actions": { "accept-recommendation": { "label": "Accept Recommendation" @@ -319,7 +318,6 @@ "suggestion-resize": "Suggested Resize", "text-highlight": "Highlight" }, - "annotations": "Annotations", "archived-dossiers-listing": { "no-data": { "title": "No archived dossiers." @@ -1595,7 +1593,7 @@ "question": "{filename} already exists. Choose how to proceed:", "title": "Document already exists!" }, - "page": "Page", + "page": "Page {page} - {count} {count, plural, one{annotation} other{annotations}}", "page-rotation": { "apply": "APPLY", "confirmation-dialog": {