From c1e3d342fad3418ba8bb76da2e744b319703b3c7 Mon Sep 17 00:00:00 2001 From: Dan Percic Date: Wed, 15 Jun 2022 16:22:02 +0300 Subject: [PATCH] RED-3837: wip select annotations on multiple pages --- .../annotations-list.component.ts | 15 ++++++++------- .../file-workload/file-workload.component.ts | 17 +++++++++-------- .../file-preview-screen.component.ts | 17 +++++++++++++---- .../services/annotations-listing.service.ts | 5 ++++- .../file-preview/services/pdf-proxy.service.ts | 5 ++++- .../pdf-viewer/services/pdf-viewer.service.ts | 6 ++---- libs/common-ui | 2 +- 7 files changed, 41 insertions(+), 26 deletions(-) diff --git a/apps/red-ui/src/app/modules/file-preview/components/annotations-list/annotations-list.component.ts b/apps/red-ui/src/app/modules/file-preview/components/annotations-list/annotations-list.component.ts index 4f680b1d9..974904441 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/annotations-list/annotations-list.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/annotations-list/annotations-list.component.ts @@ -70,14 +70,15 @@ export class AnnotationsListComponent extends HasScrollbarDirective implements O this.pagesPanelActive.emit(false); if (this._listingService.isSelected(annotation)) { - this._annotationManager.deselect(annotation); - } else { - const canMultiSelect = this._multiSelectService.isEnabled; - if (canMultiSelect && ($event?.ctrlKey || $event?.metaKey) && this._listingService.selected.length > 0) { - this._multiSelectService.activate(); - } - this._listingService.selectAnnotations([annotation]); + this._listingService.deselect(annotation); + return this._annotationManager.deselect(annotation); } + + const canMultiSelect = this._multiSelectService.isEnabled; + if (canMultiSelect && ($event?.ctrlKey || $event?.metaKey) && this._listingService.selected.length > 0) { + this._multiSelectService.activate(); + } + this._listingService.selectAnnotations(annotation); } referenceClicked(annotation: AnnotationWrapper): void { 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 d8d8967f8..2c1970eff 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 @@ -194,6 +194,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnDestroy } deselectAllOnActivePage(): void { + this.listingService.deselect(this.activeAnnotations); this.annotationManager.deselect(this.activeAnnotations); } @@ -302,19 +303,19 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnDestroy if (!this._firstSelectedAnnotation || this.activeViewerPage !== this._firstSelectedAnnotation.pageNumber) { if (this.displayedPages.indexOf(this.activeViewerPage) !== -1) { // Displayed page has annotations - return this.listingService.selectAnnotations(this.activeAnnotations ? [this.activeAnnotations[0]] : null); + return this.listingService.selectAnnotations(this.activeAnnotations ? this.activeAnnotations[0] : null); } // Displayed page doesn't have annotations if ($event.key === 'ArrowDown') { const nextPage = this._nextPageWithAnnotations(); - return this.listingService.selectAnnotations([this.displayedAnnotations.get(nextPage)[0]]); + return this.listingService.selectAnnotations(this.displayedAnnotations.get(nextPage)[0]); } const prevPage = this._prevPageWithAnnotations(); const prevPageAnnotations = this.displayedAnnotations.get(prevPage); - return this.listingService.selectAnnotations([prevPageAnnotations[prevPageAnnotations.length - 1]]); + return this.listingService.selectAnnotations(prevPageAnnotations[prevPageAnnotations.length - 1]); } const page = this._firstSelectedAnnotation.pageNumber; @@ -327,13 +328,13 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnDestroy if ($event.key === 'ArrowDown') { if (idx + 1 !== annotationsOnPage.length) { // If not last item in page - this.listingService.selectAnnotations([annotationsOnPage[idx + 1]]); + this.listingService.selectAnnotations(annotationsOnPage[idx + 1]); } else if (nextPageIdx < this.displayedPages.length) { // If not last page for (let i = nextPageIdx; i < this.displayedPages.length; i++) { const nextPageAnnotations = this.displayedAnnotations.get(this.displayedPages[i]); if (nextPageAnnotations) { - this.listingService.selectAnnotations([nextPageAnnotations[0]]); + this.listingService.selectAnnotations(nextPageAnnotations[0]); break; } } @@ -343,7 +344,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnDestroy if (idx !== 0) { // If not first item in page - return this.listingService.selectAnnotations([annotationsOnPage[idx - 1]]); + return this.listingService.selectAnnotations(annotationsOnPage[idx - 1]); } if (pageIdx) { @@ -351,7 +352,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnDestroy for (let i = previousPageIdx; i >= 0; i--) { const prevPageAnnotations = this.displayedAnnotations.get(this.displayedPages[i]); if (prevPageAnnotations) { - this.listingService.selectAnnotations([prevPageAnnotations[prevPageAnnotations.length - 1]]); + this.listingService.selectAnnotations(prevPageAnnotations[prevPageAnnotations.length - 1]); break; } } @@ -405,7 +406,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnDestroy this.displayedPages.indexOf(this.activeViewerPage) >= 0 && this.activeAnnotations.length > 0 ) { - this.listingService.selectAnnotations([this.activeAnnotations[0]]); + this.listingService.selectAnnotations(this.activeAnnotations[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 7e2cb17ab..9cb35048c 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 @@ -307,7 +307,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni } viewerPageChanged(page: number) { - this.multiSelectService.deactivate(); + // this.multiSelectService.deactivate(); return this.#updateQueryParamsPage(page); } @@ -374,6 +374,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni pairwise(), tap(annotations => this.deleteAnnotations(...annotations)), switchMap(annotations => this.drawChangedAnnotations(...annotations)), + tap(([, newAnnotations]) => this.#highlightSelectedAnnotations(newAnnotations)), tap(() => this._logger.info(`[ANNOTATIONS] Processing time: ${new Date().getTime() - start}`)), tap(() => this.updateViewMode()), ); @@ -391,7 +392,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni this._annotationManager.delete(annotationsToDelete); } - drawChangedAnnotations(oldAnnotations: AnnotationWrapper[], newAnnotations: AnnotationWrapper[]) { + async drawChangedAnnotations(oldAnnotations: AnnotationWrapper[], newAnnotations: AnnotationWrapper[]) { let annotationsToDraw: readonly AnnotationWrapper[]; const annotations = this._annotationManager.annotations; const ann = annotations.map(a => oldAnnotations.some(oldAnnotation => oldAnnotation.id === a.Id)); @@ -404,12 +405,13 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni } if (annotationsToDraw.length === 0) { - return firstValueFrom(of({})); + return [oldAnnotations, newAnnotations]; } this._logger.info('[ANNOTATIONS] To draw: ', annotationsToDraw); this._annotationManager.delete(annotationsToDraw); - return this._cleanupAndRedrawAnnotations(annotationsToDraw); + await this._cleanupAndRedrawAnnotations(annotationsToDraw); + return [oldAnnotations, newAnnotations]; } getActionsHelpModeKey(annotation: AnnotationWrapper): string { @@ -628,4 +630,11 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni this._logger.info('Navigating to ', this.state.dossier.dossierName); return this._router.navigate([this.state.dossier.routerLink]); } + + #highlightSelectedAnnotations(newAnnotations: AnnotationWrapper[]) { + const annotationsIds = newAnnotations.map(annotation => annotation.id); + const selected = this.listingService.selected.filter(a => annotationsIds.includes(a.id)); + const annotations = this._annotationManager.get(selected); + this._annotationManager.select(annotations); + } } diff --git a/apps/red-ui/src/app/modules/file-preview/services/annotations-listing.service.ts b/apps/red-ui/src/app/modules/file-preview/services/annotations-listing.service.ts index 94cb26a09..ddce07afe 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/annotations-listing.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/annotations-listing.service.ts @@ -26,10 +26,13 @@ export class AnnotationsListingService extends ListingService .subscribe(); } - selectAnnotations(annotations?: AnnotationWrapper[]) { + selectAnnotations(annotation: AnnotationWrapper); + selectAnnotations(annotations?: AnnotationWrapper[]); + selectAnnotations(annotations?: AnnotationWrapper[] | AnnotationWrapper) { if (!annotations) { return this._annotationManager.deselect(); } + annotations = Array.isArray(annotations) ? annotations : [annotations]; const annotationsToSelect = this._multiSelectService.isActive ? [...this.selected, ...annotations] : annotations; this.#selectAnnotations(annotationsToSelect); diff --git a/apps/red-ui/src/app/modules/file-preview/services/pdf-proxy.service.ts b/apps/red-ui/src/app/modules/file-preview/services/pdf-proxy.service.ts index c79ed6a4c..ac25fe331 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/pdf-proxy.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/pdf-proxy.service.ts @@ -16,7 +16,7 @@ import { shareDistinctLast } from '@iqser/common-ui'; import { toPosition } from '../utils/pdf-calculation.utils'; import { MultiSelectService } from './multi-select.service'; import { FilePreviewStateService } from './file-preview-state.service'; -import { map, tap } from 'rxjs/operators'; +import { filter, map, tap } from 'rxjs/operators'; import { HeaderElements, TextPopups } from '../utils/constants'; import { FileDataService } from './file-data.service'; import { ViewerHeaderService } from '../../pdf-viewer/services/viewer-header.service'; @@ -89,6 +89,7 @@ export class PdfProxyService { get #annotationSelected$() { return this._annotationManager.annotationSelected$.pipe( + filter(([, action]) => !(this._multiSelectService.isActive && action === 'deselected')), map(value => this.#processSelectedAnnotations(...value)), tap(annotations => this.handleAnnotationSelected(annotations)), ); @@ -107,10 +108,12 @@ export class PdfProxyService { #deactivateMultiSelect() { this._multiSelectService.deactivate(); this._annotationManager.deselect(); + console.log('deactivated multi select'); this.handleAnnotationSelected([]); } #processSelectedAnnotations(annotations: Annotation[], action) { + console.log('processSelectedAnnotations', annotations, action); let nextAnnotations: Annotation[]; if (action === 'deselected') { diff --git a/apps/red-ui/src/app/modules/pdf-viewer/services/pdf-viewer.service.ts b/apps/red-ui/src/app/modules/pdf-viewer/services/pdf-viewer.service.ts index b27acefef..a47bb6ea7 100644 --- a/apps/red-ui/src/app/modules/pdf-viewer/services/pdf-viewer.service.ts +++ b/apps/red-ui/src/app/modules/pdf-viewer/services/pdf-viewer.service.ts @@ -4,14 +4,13 @@ import { BASE_HREF_FN, BaseHrefFn } from '../../../tokens'; import { File, IHeaderElement } from '@red/domain'; import { ErrorService, shareDistinctLast } from '@iqser/common-ui'; import { ActivatedRoute } from '@angular/router'; -import { map, startWith, tap } from 'rxjs/operators'; +import { map, startWith } from 'rxjs/operators'; import { BehaviorSubject, combineLatest, fromEvent, Observable } from 'rxjs'; import { ConfigService } from '@services/config.service'; import { NGXLogger } from 'ngx-logger'; import { DISABLED_HOTKEYS, DOCUMENT_LOADING_ERROR, SEARCH_OPTIONS, USELESS_ELEMENTS } from '../utils/constants'; import { Rgb } from '../utils/types'; import { asList } from '../utils/functions'; -import { REDAnnotationManager } from './annotation-manager.service'; import { TranslateService } from '@ngx-translate/core'; import { LicenseService } from '@services/license.service'; import TextTool = Core.Tools.TextTool; @@ -54,7 +53,6 @@ export class PdfViewer { private readonly _activatedRoute: ActivatedRoute, private readonly _licenseService: LicenseService, private readonly _translateService: TranslateService, - private readonly _annotationManager: REDAnnotationManager, @Inject(BASE_HREF_FN) private readonly _convertPath: BaseHrefFn, ) {} @@ -102,7 +100,7 @@ export class PdfViewer { get #pageChanged$() { const page$ = fromEvent(this.documentViewer, 'pageNumberUpdated'); return page$.pipe( - tap(() => this._annotationManager.deselect()), + // tap(() => this._annotationManager.deselect()), map(page => this.#adjustPage(page)), ); } diff --git a/libs/common-ui b/libs/common-ui index 0a6b0c49b..cca7401d2 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit 0a6b0c49bb211a158d30935af52758fb54c40339 +Subproject commit cca7401d26751800eab72b00c8522a5bba981f28