RED-3603: Annotations arrow navigation improvement
This commit is contained in:
parent
f31a127a66
commit
51c1574554
@ -132,11 +132,11 @@
|
||||
tooltipPosition="above"
|
||||
></iqser-circle-button>
|
||||
|
||||
<span class="all-caps-label">
|
||||
<span translate="page"></span> {{ activeViewerPage }} -
|
||||
{{ activeAnnotations?.length || 0 }}
|
||||
<span [translate]="activeAnnotations?.length === 1 ? 'annotation' : 'annotations'"></span>
|
||||
</span>
|
||||
<span
|
||||
[translateParams]="{ page: activeViewerPage, count: activeAnnotations.length }"
|
||||
[translate]="'page'"
|
||||
class="all-caps-label"
|
||||
></span>
|
||||
</span>
|
||||
|
||||
<div *ngIf="multiSelectService.active$ | async">
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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'])
|
||||
|
||||
@ -7,6 +7,7 @@ import { shareDistinctLast } from '@iqser/common-ui';
|
||||
export class CommentingService {
|
||||
private _activeAnnotations = new BehaviorSubject<Set<string>>(new Set<string>());
|
||||
|
||||
/** Annotations with active comments section */
|
||||
isActive$(annotationId: string): Observable<boolean> {
|
||||
return this._activeAnnotations.pipe(
|
||||
map(annotations => annotations.has(annotationId)),
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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": ""
|
||||
|
||||
@ -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": "<b>{filename}</b> 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": {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user