RED-3837: wip select annotations on multiple pages

This commit is contained in:
Dan Percic 2022-06-15 16:22:02 +03:00
parent eb29e6d7ea
commit c1e3d342fa
7 changed files with 41 additions and 26 deletions

View File

@ -70,14 +70,15 @@ export class AnnotationsListComponent extends HasScrollbarDirective implements O
this.pagesPanelActive.emit(false); this.pagesPanelActive.emit(false);
if (this._listingService.isSelected(annotation)) { if (this._listingService.isSelected(annotation)) {
this._annotationManager.deselect(annotation); this._listingService.deselect(annotation);
} else { 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]);
} }
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 { referenceClicked(annotation: AnnotationWrapper): void {

View File

@ -194,6 +194,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnDestroy
} }
deselectAllOnActivePage(): void { deselectAllOnActivePage(): void {
this.listingService.deselect(this.activeAnnotations);
this.annotationManager.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._firstSelectedAnnotation || this.activeViewerPage !== this._firstSelectedAnnotation.pageNumber) {
if (this.displayedPages.indexOf(this.activeViewerPage) !== -1) { if (this.displayedPages.indexOf(this.activeViewerPage) !== -1) {
// Displayed page has annotations // 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 // Displayed page doesn't have annotations
if ($event.key === 'ArrowDown') { if ($event.key === 'ArrowDown') {
const nextPage = this._nextPageWithAnnotations(); 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 prevPage = this._prevPageWithAnnotations();
const prevPageAnnotations = this.displayedAnnotations.get(prevPage); 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; const page = this._firstSelectedAnnotation.pageNumber;
@ -327,13 +328,13 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnDestroy
if ($event.key === 'ArrowDown') { if ($event.key === 'ArrowDown') {
if (idx + 1 !== annotationsOnPage.length) { if (idx + 1 !== annotationsOnPage.length) {
// If not last item in page // If not last item in page
this.listingService.selectAnnotations([annotationsOnPage[idx + 1]]); this.listingService.selectAnnotations(annotationsOnPage[idx + 1]);
} else if (nextPageIdx < this.displayedPages.length) { } else if (nextPageIdx < this.displayedPages.length) {
// If not last page // If not last page
for (let i = nextPageIdx; i < this.displayedPages.length; i++) { for (let i = nextPageIdx; i < this.displayedPages.length; i++) {
const nextPageAnnotations = this.displayedAnnotations.get(this.displayedPages[i]); const nextPageAnnotations = this.displayedAnnotations.get(this.displayedPages[i]);
if (nextPageAnnotations) { if (nextPageAnnotations) {
this.listingService.selectAnnotations([nextPageAnnotations[0]]); this.listingService.selectAnnotations(nextPageAnnotations[0]);
break; break;
} }
} }
@ -343,7 +344,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnDestroy
if (idx !== 0) { if (idx !== 0) {
// If not first item in page // If not first item in page
return this.listingService.selectAnnotations([annotationsOnPage[idx - 1]]); return this.listingService.selectAnnotations(annotationsOnPage[idx - 1]);
} }
if (pageIdx) { if (pageIdx) {
@ -351,7 +352,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnDestroy
for (let i = previousPageIdx; i >= 0; i--) { for (let i = previousPageIdx; i >= 0; i--) {
const prevPageAnnotations = this.displayedAnnotations.get(this.displayedPages[i]); const prevPageAnnotations = this.displayedAnnotations.get(this.displayedPages[i]);
if (prevPageAnnotations) { if (prevPageAnnotations) {
this.listingService.selectAnnotations([prevPageAnnotations[prevPageAnnotations.length - 1]]); this.listingService.selectAnnotations(prevPageAnnotations[prevPageAnnotations.length - 1]);
break; break;
} }
} }
@ -405,7 +406,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnDestroy
this.displayedPages.indexOf(this.activeViewerPage) >= 0 && this.displayedPages.indexOf(this.activeViewerPage) >= 0 &&
this.activeAnnotations.length > 0 this.activeAnnotations.length > 0
) { ) {
this.listingService.selectAnnotations([this.activeAnnotations[0]]); this.listingService.selectAnnotations(this.activeAnnotations[0]);
} }
} }

View File

@ -307,7 +307,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
} }
viewerPageChanged(page: number) { viewerPageChanged(page: number) {
this.multiSelectService.deactivate(); // this.multiSelectService.deactivate();
return this.#updateQueryParamsPage(page); return this.#updateQueryParamsPage(page);
} }
@ -374,6 +374,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
pairwise(), pairwise(),
tap(annotations => this.deleteAnnotations(...annotations)), tap(annotations => this.deleteAnnotations(...annotations)),
switchMap(annotations => this.drawChangedAnnotations(...annotations)), switchMap(annotations => this.drawChangedAnnotations(...annotations)),
tap(([, newAnnotations]) => this.#highlightSelectedAnnotations(newAnnotations)),
tap(() => this._logger.info(`[ANNOTATIONS] Processing time: ${new Date().getTime() - start}`)), tap(() => this._logger.info(`[ANNOTATIONS] Processing time: ${new Date().getTime() - start}`)),
tap(() => this.updateViewMode()), tap(() => this.updateViewMode()),
); );
@ -391,7 +392,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
this._annotationManager.delete(annotationsToDelete); this._annotationManager.delete(annotationsToDelete);
} }
drawChangedAnnotations(oldAnnotations: AnnotationWrapper[], newAnnotations: AnnotationWrapper[]) { async drawChangedAnnotations(oldAnnotations: AnnotationWrapper[], newAnnotations: AnnotationWrapper[]) {
let annotationsToDraw: readonly AnnotationWrapper[]; let annotationsToDraw: readonly AnnotationWrapper[];
const annotations = this._annotationManager.annotations; const annotations = this._annotationManager.annotations;
const ann = annotations.map(a => oldAnnotations.some(oldAnnotation => oldAnnotation.id === a.Id)); 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) { if (annotationsToDraw.length === 0) {
return firstValueFrom(of({})); return [oldAnnotations, newAnnotations];
} }
this._logger.info('[ANNOTATIONS] To draw: ', annotationsToDraw); this._logger.info('[ANNOTATIONS] To draw: ', annotationsToDraw);
this._annotationManager.delete(annotationsToDraw); this._annotationManager.delete(annotationsToDraw);
return this._cleanupAndRedrawAnnotations(annotationsToDraw); await this._cleanupAndRedrawAnnotations(annotationsToDraw);
return [oldAnnotations, newAnnotations];
} }
getActionsHelpModeKey(annotation: AnnotationWrapper): string { getActionsHelpModeKey(annotation: AnnotationWrapper): string {
@ -628,4 +630,11 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
this._logger.info('Navigating to ', this.state.dossier.dossierName); this._logger.info('Navigating to ', this.state.dossier.dossierName);
return this._router.navigate([this.state.dossier.routerLink]); 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);
}
} }

View File

@ -26,10 +26,13 @@ export class AnnotationsListingService extends ListingService<AnnotationWrapper>
.subscribe(); .subscribe();
} }
selectAnnotations(annotations?: AnnotationWrapper[]) { selectAnnotations(annotation: AnnotationWrapper);
selectAnnotations(annotations?: AnnotationWrapper[]);
selectAnnotations(annotations?: AnnotationWrapper[] | AnnotationWrapper) {
if (!annotations) { if (!annotations) {
return this._annotationManager.deselect(); return this._annotationManager.deselect();
} }
annotations = Array.isArray(annotations) ? annotations : [annotations];
const annotationsToSelect = this._multiSelectService.isActive ? [...this.selected, ...annotations] : annotations; const annotationsToSelect = this._multiSelectService.isActive ? [...this.selected, ...annotations] : annotations;
this.#selectAnnotations(annotationsToSelect); this.#selectAnnotations(annotationsToSelect);

View File

@ -16,7 +16,7 @@ import { shareDistinctLast } from '@iqser/common-ui';
import { toPosition } from '../utils/pdf-calculation.utils'; import { toPosition } from '../utils/pdf-calculation.utils';
import { MultiSelectService } from './multi-select.service'; import { MultiSelectService } from './multi-select.service';
import { FilePreviewStateService } from './file-preview-state.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 { HeaderElements, TextPopups } from '../utils/constants';
import { FileDataService } from './file-data.service'; import { FileDataService } from './file-data.service';
import { ViewerHeaderService } from '../../pdf-viewer/services/viewer-header.service'; import { ViewerHeaderService } from '../../pdf-viewer/services/viewer-header.service';
@ -89,6 +89,7 @@ export class PdfProxyService {
get #annotationSelected$() { get #annotationSelected$() {
return this._annotationManager.annotationSelected$.pipe( return this._annotationManager.annotationSelected$.pipe(
filter(([, action]) => !(this._multiSelectService.isActive && action === 'deselected')),
map(value => this.#processSelectedAnnotations(...value)), map(value => this.#processSelectedAnnotations(...value)),
tap(annotations => this.handleAnnotationSelected(annotations)), tap(annotations => this.handleAnnotationSelected(annotations)),
); );
@ -107,10 +108,12 @@ export class PdfProxyService {
#deactivateMultiSelect() { #deactivateMultiSelect() {
this._multiSelectService.deactivate(); this._multiSelectService.deactivate();
this._annotationManager.deselect(); this._annotationManager.deselect();
console.log('deactivated multi select');
this.handleAnnotationSelected([]); this.handleAnnotationSelected([]);
} }
#processSelectedAnnotations(annotations: Annotation[], action) { #processSelectedAnnotations(annotations: Annotation[], action) {
console.log('processSelectedAnnotations', annotations, action);
let nextAnnotations: Annotation[]; let nextAnnotations: Annotation[];
if (action === 'deselected') { if (action === 'deselected') {

View File

@ -4,14 +4,13 @@ import { BASE_HREF_FN, BaseHrefFn } from '../../../tokens';
import { File, IHeaderElement } from '@red/domain'; import { File, IHeaderElement } from '@red/domain';
import { ErrorService, shareDistinctLast } from '@iqser/common-ui'; import { ErrorService, shareDistinctLast } from '@iqser/common-ui';
import { ActivatedRoute } from '@angular/router'; 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 { BehaviorSubject, combineLatest, fromEvent, Observable } from 'rxjs';
import { ConfigService } from '@services/config.service'; import { ConfigService } from '@services/config.service';
import { NGXLogger } from 'ngx-logger'; import { NGXLogger } from 'ngx-logger';
import { DISABLED_HOTKEYS, DOCUMENT_LOADING_ERROR, SEARCH_OPTIONS, USELESS_ELEMENTS } from '../utils/constants'; import { DISABLED_HOTKEYS, DOCUMENT_LOADING_ERROR, SEARCH_OPTIONS, USELESS_ELEMENTS } from '../utils/constants';
import { Rgb } from '../utils/types'; import { Rgb } from '../utils/types';
import { asList } from '../utils/functions'; import { asList } from '../utils/functions';
import { REDAnnotationManager } from './annotation-manager.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { LicenseService } from '@services/license.service'; import { LicenseService } from '@services/license.service';
import TextTool = Core.Tools.TextTool; import TextTool = Core.Tools.TextTool;
@ -54,7 +53,6 @@ export class PdfViewer {
private readonly _activatedRoute: ActivatedRoute, private readonly _activatedRoute: ActivatedRoute,
private readonly _licenseService: LicenseService, private readonly _licenseService: LicenseService,
private readonly _translateService: TranslateService, private readonly _translateService: TranslateService,
private readonly _annotationManager: REDAnnotationManager,
@Inject(BASE_HREF_FN) private readonly _convertPath: BaseHrefFn, @Inject(BASE_HREF_FN) private readonly _convertPath: BaseHrefFn,
) {} ) {}
@ -102,7 +100,7 @@ export class PdfViewer {
get #pageChanged$() { get #pageChanged$() {
const page$ = fromEvent<number>(this.documentViewer, 'pageNumberUpdated'); const page$ = fromEvent<number>(this.documentViewer, 'pageNumberUpdated');
return page$.pipe( return page$.pipe(
tap(() => this._annotationManager.deselect()), // tap(() => this._annotationManager.deselect()),
map(page => this.#adjustPage(page)), map(page => this.#adjustPage(page)),
); );
} }

@ -1 +1 @@
Subproject commit 0a6b0c49bb211a158d30935af52758fb54c40339 Subproject commit cca7401d26751800eab72b00c8522a5bba981f28