Merge branch 'master' into VM/RED-7340
This commit is contained in:
commit
d67bef3001
@ -1,29 +1,31 @@
|
||||
<div
|
||||
*ngIf="noSelection && changesTooltip"
|
||||
[matTooltip]="changesTooltip"
|
||||
class="chip"
|
||||
matTooltipClass="multiline"
|
||||
matTooltipPosition="above"
|
||||
>
|
||||
<mat-icon [svgIcon]="'red:redaction-changes'"></mat-icon>
|
||||
</div>
|
||||
@if (_noSelection() && _changesTooltip()) {
|
||||
<div [matTooltip]="_changesTooltip()" class="chip" matTooltipClass="multiline" matTooltipPosition="above">
|
||||
<mat-icon [svgIcon]="'red:redaction-changes'"></mat-icon>
|
||||
</div>
|
||||
}
|
||||
|
||||
<ng-container *ngIf="noSelection && engines">
|
||||
<div #trigger="cdkOverlayOrigin" (mouseout)="isPopoverOpen = false" (mouseover)="isPopoverOpen = true" cdkOverlayOrigin class="chip">
|
||||
<mat-icon *ngFor="let engine of engines" [svgIcon]="engine.icon"></mat-icon>
|
||||
@if (_noSelection() && _engines()) {
|
||||
<div
|
||||
#trigger="cdkOverlayOrigin"
|
||||
(mouseout)="_isPopoverOpen.set(false)"
|
||||
(mouseover)="_isPopoverOpen.set(true)"
|
||||
cdkOverlayOrigin
|
||||
class="chip"
|
||||
>
|
||||
<mat-icon *ngFor="let engine of _engines()" [svgIcon]="engine.icon"></mat-icon>
|
||||
</div>
|
||||
|
||||
<ng-template
|
||||
[cdkConnectedOverlayOffsetY]="-8"
|
||||
[cdkConnectedOverlayOpen]="isPopoverOpen"
|
||||
[cdkConnectedOverlayOpen]="_isPopoverOpen()"
|
||||
[cdkConnectedOverlayOrigin]="trigger"
|
||||
cdkConnectedOverlay
|
||||
>
|
||||
<div class="popover">
|
||||
<div *ngFor="let engine of engines" class="flex-align-items-center">
|
||||
<div *ngFor="let engine of _engines()" class="flex-align-items-center">
|
||||
<mat-icon [svgIcon]="engine.icon"></mat-icon>
|
||||
<span [innerHTML]="engine.description | translate : engine.translateParams"></span>
|
||||
<span [innerHTML]="engine.description | translate: engine.translateParams"></span>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Component, inject, Input, OnChanges } from '@angular/core';
|
||||
import { Component, computed, inject, input, signal } from '@angular/core';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { KeysOf } from '@iqser/common-ui/lib/utils';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
@ -33,30 +33,27 @@ const changesProperties: KeysOf<AnnotationWrapper>[] = [
|
||||
];
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-annotation-details [annotation]',
|
||||
selector: 'redaction-annotation-details',
|
||||
templateUrl: './annotation-details.component.html',
|
||||
styleUrls: ['./annotation-details.component.scss'],
|
||||
standalone: true,
|
||||
imports: [NgIf, MatTooltip, MatIcon, CdkOverlayOrigin, NgForOf, CdkConnectedOverlay, TranslateModule],
|
||||
})
|
||||
export class AnnotationDetailsComponent implements OnChanges {
|
||||
@Input() annotation: ListItem<AnnotationWrapper>;
|
||||
isPopoverOpen = false;
|
||||
engines: Engine[];
|
||||
changesTooltip: string;
|
||||
noSelection: boolean;
|
||||
export class AnnotationDetailsComponent {
|
||||
readonly annotation = input.required<ListItem<AnnotationWrapper>>();
|
||||
protected readonly _isPopoverOpen = signal(false);
|
||||
protected readonly _engines = computed(() => this.#extractEngines(this.annotation().item).filter(engine => engine.show));
|
||||
private readonly _translateService = inject(TranslateService);
|
||||
private readonly _multiSelectService = inject(MultiSelectService);
|
||||
protected readonly _changesTooltip = computed(() => {
|
||||
const annotation = this.annotation().item;
|
||||
const changes = changesProperties.filter(key => annotation[key]);
|
||||
|
||||
getChangesTooltip(): string | undefined {
|
||||
const changes = changesProperties.filter(key => this.annotation.item[key]);
|
||||
|
||||
if (!changes.length && !this.annotation.item.engines?.includes(LogEntryEngines.MANUAL)) {
|
||||
if (!changes.length && !annotation.engines?.includes(LogEntryEngines.MANUAL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const details = [];
|
||||
if (this.annotation.item.engines?.includes(LogEntryEngines.MANUAL)) {
|
||||
if (annotation.engines?.includes(LogEntryEngines.MANUAL)) {
|
||||
details.push(this._translateService.instant(_('annotation-changes.added-locally')));
|
||||
}
|
||||
|
||||
@ -66,13 +63,9 @@ export class AnnotationDetailsComponent implements OnChanges {
|
||||
|
||||
const header = this._translateService.instant(_('annotation-changes.header'));
|
||||
return [header, ...details.map(change => `• ${change}`)].join('\n');
|
||||
}
|
||||
|
||||
ngOnChanges() {
|
||||
this.engines = this.#extractEngines(this.annotation.item).filter(engine => engine.show);
|
||||
this.changesTooltip = this.getChangesTooltip();
|
||||
this.noSelection = !this.annotation.isSelected || this._multiSelectService.inactive();
|
||||
}
|
||||
});
|
||||
private readonly _multiSelectService = inject(MultiSelectService);
|
||||
protected readonly _noSelection = computed(() => !this.annotation().isSelected || this._multiSelectService.inactive());
|
||||
|
||||
#extractEngines(annotation: AnnotationWrapper): Engine[] {
|
||||
return [
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<div class="active-bar-marker"></div>
|
||||
|
||||
<div [class.removed]="annotation().item.isRemoved" class="annotation">
|
||||
<div #annotationDiv [class.removed]="annotation().item.isRemoved" class="annotation">
|
||||
<redaction-annotation-card
|
||||
[annotation]="annotation().item"
|
||||
[isSelected]="annotation().isSelected"
|
||||
@ -24,13 +24,15 @@
|
||||
}
|
||||
|
||||
@if (multiSelectService.inactive()) {
|
||||
<div class="actions">
|
||||
<redaction-annotation-actions
|
||||
[actionsHelpModeKey]="actionsHelpModeKey()"
|
||||
[annotations]="[annotation().item]"
|
||||
[canPerformAnnotationActions]="pdfProxyService.canPerformActions()"
|
||||
></redaction-annotation-actions>
|
||||
</div>
|
||||
@defer (on hover(annotationDiv)) {
|
||||
<div class="actions">
|
||||
<redaction-annotation-actions
|
||||
[actionsHelpModeKey]="actionsHelpModeKey()"
|
||||
[annotations]="[annotation().item]"
|
||||
[canPerformAnnotationActions]="pdfProxyService.canPerformActions()"
|
||||
></redaction-annotation-actions>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ import { AnnotationReferencesService } from '../../services/annotation-reference
|
||||
import { AnnotationsListingService } from '../../services/annotations-listing.service';
|
||||
import { MultiSelectService } from '../../services/multi-select.service';
|
||||
import { ViewModeService } from '../../services/view-mode.service';
|
||||
import { NgForOf, NgIf } from '@angular/common';
|
||||
import { JsonPipe, NgForOf, NgIf } from '@angular/common';
|
||||
import { HighlightsSeparatorComponent } from '../highlights-separator/highlights-separator.component';
|
||||
import { AnnotationWrapperComponent } from '../annotation-wrapper/annotation-wrapper.component';
|
||||
import { AnnotationReferencesListComponent } from '../annotation-references-list/annotation-references-list.component';
|
||||
@ -21,7 +21,7 @@ import { AnnotationReferencesListComponent } from '../annotation-references-list
|
||||
templateUrl: './annotations-list.component.html',
|
||||
styleUrls: ['./annotations-list.component.scss'],
|
||||
standalone: true,
|
||||
imports: [NgForOf, NgIf, HighlightsSeparatorComponent, AnnotationWrapperComponent, AnnotationReferencesListComponent],
|
||||
imports: [NgForOf, NgIf, HighlightsSeparatorComponent, AnnotationWrapperComponent, AnnotationReferencesListComponent, JsonPipe],
|
||||
})
|
||||
export class AnnotationsListComponent extends HasScrollbarDirective {
|
||||
readonly annotations = input.required<ListItem<AnnotationWrapper>[]>();
|
||||
|
||||
@ -32,11 +32,11 @@
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
|
||||
@if (displayedAnnotations$ | async; as annotations) {
|
||||
@if (filteredAnnotations$ | async; as annotations) {
|
||||
<div class="right-content">
|
||||
<ng-container *ngIf="!isDocumine">
|
||||
<redaction-readonly-banner
|
||||
*ngIf="showAnalysisDisabledBanner; else readOnlyBanner"
|
||||
*ngIf="showAnalysisDisabledBanner(); else readOnlyBanner"
|
||||
[customTranslation]="translations.analysisDisabled"
|
||||
></redaction-readonly-banner>
|
||||
<ng-template #readOnlyBanner>
|
||||
@ -112,7 +112,7 @@
|
||||
></iqser-circle-button>
|
||||
|
||||
<span
|
||||
[translateParams]="{ page: pdf.currentPage(), count: activeAnnotations.length }"
|
||||
[translateParams]="{ page: pdf.currentPage(), count: activeAnnotations().length }"
|
||||
[translate]="'page'"
|
||||
class="all-caps-label"
|
||||
></span>
|
||||
@ -200,7 +200,7 @@
|
||||
|
||||
<redaction-annotations-list
|
||||
(pagesPanelActive)="pagesPanelActive = $event"
|
||||
[annotations]="annotations.get(pdf.currentPage())"
|
||||
[annotations]="annotationsList$ | async"
|
||||
></redaction-annotations-list>
|
||||
</div>
|
||||
}
|
||||
@ -224,7 +224,7 @@
|
||||
</ng-template>
|
||||
|
||||
<ng-template #documineHeader>
|
||||
<span [translate]="'annotations'" [attr.help-mode-key]="'annotations_list'"></span>
|
||||
<span [attr.help-mode-key]="'annotations_list'" [translate]="'annotations'"></span>
|
||||
<ng-container *ngTemplateOutlet="annotationsFilter"></ng-container>
|
||||
</ng-template>
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@ import {
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
TemplateRef,
|
||||
untracked,
|
||||
viewChild,
|
||||
} from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
@ -89,23 +90,30 @@ const ALL_HOTKEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'];
|
||||
],
|
||||
})
|
||||
export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, OnDestroy {
|
||||
private readonly _annotationsElement = viewChild<ElementRef>('annotationsElement');
|
||||
private readonly _quickNavigationElement = viewChild<ElementRef>('quickNavigation');
|
||||
readonly multiSelectTemplate = viewChild<TemplateRef<any>>('multiSelect');
|
||||
readonly #isIqserDevMode = this._userPreferenceService.isIqserDevMode;
|
||||
readonly annotationsList$: Observable<ListItem<AnnotationWrapper>[]>;
|
||||
readonly allPages = computed(() => Array.from({ length: this.state.file()?.numberOfPages }, (_x, i) => i + 1));
|
||||
protected readonly iconButtonTypes = IconButtonTypes;
|
||||
protected readonly circleButtonTypes = CircleButtonTypes;
|
||||
protected readonly displayedAnnotations$: Observable<Map<number, ListItem<AnnotationWrapper>[]>>;
|
||||
protected readonly filteredAnnotations$: Observable<Map<number, ListItem<AnnotationWrapper>[]>>;
|
||||
protected readonly title = computed(() =>
|
||||
this.viewModeService.isEarmarks() ? _('file-preview.tabs.highlights.label') : _('file-preview.tabs.annotations.label'),
|
||||
);
|
||||
protected readonly currentPageIsExcluded = computed(() => this.state.file().excludedPages.includes(this.pdf.currentPage()));
|
||||
protected readonly translations = workloadTranslations;
|
||||
protected readonly isDocumine = getConfig().IS_DOCUMINE;
|
||||
readonly showAnalysisDisabledBanner = computed(() => {
|
||||
const file = this.state.file();
|
||||
return this.isDocumine && file.excludedFromAutomaticAnalysis && file.workflowStatus !== WorkflowFileStatuses.APPROVED;
|
||||
});
|
||||
protected displayedAnnotations = new Map<number, AnnotationWrapper[]>();
|
||||
readonly activeAnnotations = computed(() => this.displayedAnnotations.get(this.pdf.currentPage()) || []);
|
||||
protected displayedPages: number[] = [];
|
||||
protected pagesPanelActive = true;
|
||||
protected enabledFilters = [];
|
||||
private readonly _annotationsElement = viewChild<ElementRef>('annotationsElement');
|
||||
private readonly _quickNavigationElement = viewChild<ElementRef>('quickNavigation');
|
||||
readonly #isIqserDevMode = this._userPreferenceService.isIqserDevMode;
|
||||
#displayedPagesChanged = false;
|
||||
|
||||
constructor(
|
||||
@ -129,10 +137,9 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
|
||||
) {
|
||||
super();
|
||||
|
||||
// TODO: ngOnDetach is not called here, so we need to unsubscribe manually
|
||||
this.addActiveScreenSubscription = this.pdf.currentPage$.subscribe(pageNumber => {
|
||||
effect(() => {
|
||||
this._scrollViews();
|
||||
this.scrollAnnotationsToPage(pageNumber, 'always');
|
||||
this.scrollAnnotationsToPage(this.pdf.currentPage(), 'always');
|
||||
});
|
||||
|
||||
this.addActiveScreenSubscription = this.listingService.selected$.subscribe(annotationIds => {
|
||||
@ -146,7 +153,11 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
|
||||
this.handleKeyEvent($event);
|
||||
});
|
||||
|
||||
this.displayedAnnotations$ = this._displayedAnnotations$;
|
||||
this.filteredAnnotations$ = this._filteredAnnotations$;
|
||||
|
||||
this.annotationsList$ = combineLatest([this.filteredAnnotations$, this.pdf.currentPage$]).pipe(
|
||||
map(([annotations, page]) => annotations.get(page)),
|
||||
);
|
||||
|
||||
effect(() => {
|
||||
if (this.multiSelectService.inactive()) {
|
||||
@ -169,20 +180,11 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
|
||||
);
|
||||
}
|
||||
|
||||
get activeAnnotations(): AnnotationWrapper[] {
|
||||
return this.displayedAnnotations.get(this.pdf.currentPage()) || [];
|
||||
}
|
||||
|
||||
get showAnalysisDisabledBanner() {
|
||||
const file = this.state.file();
|
||||
return this.isDocumine && file.excludedFromAutomaticAnalysis && file.workflowStatus !== WorkflowFileStatuses.APPROVED;
|
||||
}
|
||||
|
||||
private get _firstSelectedAnnotation() {
|
||||
return this.listingService.selected.length ? this.listingService.selected[0] : null;
|
||||
}
|
||||
|
||||
private get _displayedAnnotations$(): Observable<Map<number, ListItem<AnnotationWrapper>[]>> {
|
||||
private get _filteredAnnotations$(): Observable<Map<number, ListItem<AnnotationWrapper>[]>> {
|
||||
const primary$ = this.filterService.getFilterModels$('primaryFilters');
|
||||
const secondary$ = this.filterService.getFilterModels$('secondaryFilters');
|
||||
|
||||
@ -205,10 +207,6 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
|
||||
);
|
||||
}
|
||||
|
||||
get #allPages() {
|
||||
return Array.from({ length: this.state.file()?.numberOfPages }, (_x, i) => i + 1);
|
||||
}
|
||||
|
||||
private static _scrollToFirstElement(elements: HTMLElement[], mode: 'always' | 'if-needed' = 'if-needed') {
|
||||
if (elements.length > 0) {
|
||||
scrollIntoView(elements[0], {
|
||||
@ -222,12 +220,13 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
|
||||
|
||||
ngOnInit(): void {
|
||||
setTimeout(() => {
|
||||
const showExcludePages = getLocalStorageDataByFileId(this.state.file()?.id, 'show-exclude-pages') ?? false;
|
||||
const file = untracked(this.state.file);
|
||||
const showExcludePages = getLocalStorageDataByFileId(file?.id, 'show-exclude-pages') ?? false;
|
||||
if (showExcludePages) {
|
||||
this.excludedPagesService.show();
|
||||
}
|
||||
|
||||
const showDocumentInfo = getLocalStorageDataByFileId(this.state.file()?.id, 'show-document-info') ?? false;
|
||||
const showDocumentInfo = getLocalStorageDataByFileId(file?.id, 'show-document-info') ?? false;
|
||||
if (showDocumentInfo) {
|
||||
this.documentInfoService.show();
|
||||
}
|
||||
@ -235,16 +234,20 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
|
||||
}
|
||||
|
||||
selectAllOnActivePage() {
|
||||
this.listingService.selectAnnotations(this.activeAnnotations);
|
||||
const activeAnnotations = untracked(this.activeAnnotations);
|
||||
this.listingService.selectAnnotations(activeAnnotations);
|
||||
}
|
||||
|
||||
deselectAllOnActivePage(): void {
|
||||
this.listingService.deselect(this.activeAnnotations);
|
||||
this.annotationManager.deselect(this.activeAnnotations);
|
||||
const activeAnnotations = untracked(this.activeAnnotations);
|
||||
this.listingService.deselect(activeAnnotations);
|
||||
this.annotationManager.deselect(activeAnnotations);
|
||||
}
|
||||
|
||||
@HostListener('window:keyup', ['$event'])
|
||||
handleKeyEvent($event: KeyboardEvent): void {
|
||||
const multiSelectServiceInactive = untracked(this.multiSelectService.inactive);
|
||||
|
||||
if (
|
||||
!ALL_HOTKEY_ARRAY.includes($event.key) ||
|
||||
this._dialog.openDialogs.length ||
|
||||
@ -264,7 +267,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
|
||||
// if we activated annotationsPanel -
|
||||
// select first annotation from this page in case there is no
|
||||
// selected annotation on this page and not in multi select mode
|
||||
if (!this.pagesPanelActive && this.multiSelectService.inactive()) {
|
||||
if (!this.pagesPanelActive && multiSelectServiceInactive) {
|
||||
this._documentViewer.clearSelection();
|
||||
this.#selectFirstAnnotationOnCurrentPageIfNecessary();
|
||||
}
|
||||
@ -275,7 +278,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
|
||||
if (!this.pagesPanelActive) {
|
||||
// Disable annotation navigation in multi select mode
|
||||
// => TODO: maybe implement selection on enter?
|
||||
if (this.multiSelectService.inactive()) {
|
||||
if (multiSelectServiceInactive) {
|
||||
this.navigateAnnotations($event);
|
||||
}
|
||||
} else {
|
||||
@ -286,7 +289,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
|
||||
}
|
||||
|
||||
scrollAnnotations(): void {
|
||||
const currentPage = this.pdf.currentPage();
|
||||
const currentPage = untracked(this.pdf.currentPage);
|
||||
if (this._firstSelectedAnnotation?.pageNumber === currentPage) {
|
||||
return;
|
||||
}
|
||||
@ -294,27 +297,27 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
|
||||
}
|
||||
|
||||
scrollAnnotationsToPage(page: number, mode: 'always' | 'if-needed' = 'if-needed'): void {
|
||||
if (this._annotationsElement()) {
|
||||
const elements: HTMLElement[] = this._annotationsElement().nativeElement.querySelectorAll(
|
||||
`div[anotation-page-header="${page}"]`,
|
||||
);
|
||||
const annotationsElement = untracked(this._annotationsElement);
|
||||
if (annotationsElement) {
|
||||
const elements: HTMLElement[] = annotationsElement.nativeElement.querySelectorAll(`div[anotation-page-header="${page}"]`);
|
||||
FileWorkloadComponent._scrollToFirstElement(elements, mode);
|
||||
}
|
||||
}
|
||||
|
||||
@Debounce()
|
||||
scrollToSelectedAnnotation(): void {
|
||||
if (this.listingService.selected.length === 0 || !this._annotationsElement()) {
|
||||
const annotationsElement = untracked(this._annotationsElement);
|
||||
if (this.listingService.selected.length === 0 || annotationsElement) {
|
||||
return;
|
||||
}
|
||||
const elements: HTMLElement[] = this._annotationsElement().nativeElement.querySelectorAll(
|
||||
const elements: HTMLElement[] = annotationsElement.nativeElement.querySelectorAll(
|
||||
`[annotation-id="${this._firstSelectedAnnotation?.id}"]`,
|
||||
);
|
||||
FileWorkloadComponent._scrollToFirstElement(elements);
|
||||
}
|
||||
|
||||
scrollQuickNavigation(): void {
|
||||
const currentPage = this.pdf.currentPage();
|
||||
const currentPage = untracked(this.pdf.currentPage);
|
||||
let quickNavPageIndex = this.displayedPages.findIndex(p => p >= currentPage);
|
||||
if (quickNavPageIndex === -1 || this.displayedPages[quickNavPageIndex] !== currentPage) {
|
||||
quickNavPageIndex = Math.max(0, quickNavPageIndex - 1);
|
||||
@ -327,7 +330,8 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
|
||||
}
|
||||
|
||||
scrollQuickNavLast() {
|
||||
this.pdf.navigateTo(this.state.file().numberOfPages);
|
||||
const file = untracked(this.state.file);
|
||||
this.pdf.navigateTo(file.numberOfPages);
|
||||
}
|
||||
|
||||
preventKeyDefault($event: KeyboardEvent): void {
|
||||
@ -345,11 +349,12 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
|
||||
}
|
||||
|
||||
navigateAnnotations($event: KeyboardEvent) {
|
||||
const currentPage = this.pdf.currentPage();
|
||||
const currentPage = untracked(this.pdf.currentPage);
|
||||
const activeAnnotations = untracked(this.activeAnnotations);
|
||||
if (!this._firstSelectedAnnotation || currentPage !== this._firstSelectedAnnotation.pageNumber) {
|
||||
if (this.displayedPages.indexOf(currentPage) !== -1) {
|
||||
// Displayed page has annotations
|
||||
return this.listingService.selectAnnotations(this.activeAnnotations ? this.activeAnnotations[0] : null);
|
||||
return this.listingService.selectAnnotations(activeAnnotations ? activeAnnotations[0] : null);
|
||||
}
|
||||
// Displayed page doesn't have annotations
|
||||
if ($event.key === 'ArrowDown') {
|
||||
@ -422,14 +427,16 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
|
||||
secondary: INestedFilter[] = [],
|
||||
componentReferenceIds: string[],
|
||||
): Map<number, AnnotationWrapper[]> {
|
||||
const onlyPageWithAnnotations = this.viewModeService.onlyPagesWithAnnotations();
|
||||
const onlyPageWithAnnotations = untracked(this.viewModeService.onlyPagesWithAnnotations);
|
||||
const isRedacted = untracked(this.viewModeService.isRedacted);
|
||||
const allPages = untracked(this.allPages);
|
||||
if (!primary || primary.length === 0) {
|
||||
const pages = onlyPageWithAnnotations ? [] : this.#allPages;
|
||||
const pages = onlyPageWithAnnotations ? [] : allPages;
|
||||
this.#setDisplayedPages(pages);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.viewModeService.isRedacted()) {
|
||||
if (isRedacted) {
|
||||
annotations = annotations.filter(a => !a.isRemoved);
|
||||
}
|
||||
|
||||
@ -447,7 +454,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
|
||||
this.enabledFilters = this.filterService.enabledFlatFilters;
|
||||
if (this.enabledFilters.some(f => f.id === 'pages-without-annotations')) {
|
||||
if (this.enabledFilters.length === 1 && !onlyPageWithAnnotations) {
|
||||
const pages = this.#allPages.filter(page => !pagesThatDisplayAnnotations.includes(page));
|
||||
const pages = allPages.filter(page => !pagesThatDisplayAnnotations.includes(page));
|
||||
this.#setDisplayedPages(pages);
|
||||
} else {
|
||||
this.#setDisplayedPages([]);
|
||||
@ -456,7 +463,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
|
||||
} else if (this.enabledFilters.length || onlyPageWithAnnotations || componentReferenceIds) {
|
||||
this.#setDisplayedPages(pagesThatDisplayAnnotations);
|
||||
} else {
|
||||
this.#setDisplayedPages(this.#allPages);
|
||||
this.#setDisplayedPages(allPages);
|
||||
}
|
||||
this.displayedPages.sort((a, b) => a - b);
|
||||
|
||||
@ -464,18 +471,20 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
|
||||
}
|
||||
|
||||
#selectFirstAnnotationOnCurrentPageIfNecessary() {
|
||||
const currentPage = this.pdf.currentPage();
|
||||
const currentPage = untracked(this.pdf.currentPage);
|
||||
const activeAnnotations = untracked(this.activeAnnotations);
|
||||
if (
|
||||
(!this._firstSelectedAnnotation || currentPage !== this._firstSelectedAnnotation.pageNumber) &&
|
||||
this.displayedPages.indexOf(currentPage) >= 0 &&
|
||||
this.activeAnnotations.length > 0
|
||||
activeAnnotations.length > 0
|
||||
) {
|
||||
this.listingService.selectAnnotations(this.activeAnnotations[0]);
|
||||
this.listingService.selectAnnotations(activeAnnotations[0]);
|
||||
}
|
||||
}
|
||||
|
||||
#navigatePages($event: KeyboardEvent) {
|
||||
const pageIdx = this.displayedPages.indexOf(this.pdf.currentPage());
|
||||
const currentPage = untracked(this.pdf.currentPage);
|
||||
const pageIdx = this.displayedPages.indexOf(currentPage);
|
||||
|
||||
if ($event.key !== 'ArrowDown') {
|
||||
if (pageIdx === -1) {
|
||||
@ -507,9 +516,10 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
|
||||
}
|
||||
|
||||
#nextPageWithAnnotations() {
|
||||
const currentPage = untracked(this.pdf.currentPage);
|
||||
let idx = 0;
|
||||
for (const page of this.displayedPages) {
|
||||
if (page > this.pdf.currentPage() && this.displayedAnnotations.get(page)) {
|
||||
if (page > currentPage && this.displayedAnnotations.get(page)) {
|
||||
break;
|
||||
}
|
||||
++idx;
|
||||
@ -518,10 +528,11 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
|
||||
}
|
||||
|
||||
#prevPageWithAnnotations() {
|
||||
const currentPage = untracked(this.pdf.currentPage);
|
||||
let idx = this.displayedPages.length - 1;
|
||||
const reverseDisplayedPages = [...this.displayedPages].reverse();
|
||||
for (const page of reverseDisplayedPages) {
|
||||
if (page < this.pdf.currentPage() && this.displayedAnnotations.get(page)) {
|
||||
if (page < currentPage && this.displayedAnnotations.get(page)) {
|
||||
break;
|
||||
}
|
||||
--idx;
|
||||
@ -530,8 +541,9 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
|
||||
}
|
||||
|
||||
#scrollQuickNavigationToPage(page: number) {
|
||||
if (this._quickNavigationElement()) {
|
||||
const elements: HTMLElement[] = this._quickNavigationElement().nativeElement.querySelectorAll(`#quick-nav-page-${page}`);
|
||||
const quickNavigationElement = untracked(this._quickNavigationElement);
|
||||
if (quickNavigationElement) {
|
||||
const elements: HTMLElement[] = quickNavigationElement.nativeElement.querySelectorAll(`#quick-nav-page-${page}`);
|
||||
FileWorkloadComponent._scrollToFirstElement(elements);
|
||||
}
|
||||
}
|
||||
@ -552,7 +564,8 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
|
||||
}
|
||||
|
||||
#scrollToFirstAnnotationPage(annotations: Map<number, ListItem<AnnotationWrapper>[]>) {
|
||||
if (this.isDocumine && annotations.size && this.#displayedPagesChanged && !this.displayedPages.includes(this.pdf.currentPage())) {
|
||||
const currentPage = untracked(this.pdf.currentPage);
|
||||
if (this.isDocumine && annotations.size && this.#displayedPagesChanged && !this.displayedPages.includes(currentPage)) {
|
||||
const page = annotations.keys().next().value;
|
||||
this.pdf.navigateTo(page);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user