refactor annotation filters
This commit is contained in:
parent
a339746cd1
commit
6f7f23f97f
@ -1,3 +1,6 @@
|
||||
<!-- This is a hack to subscribe to an observable using async pipe instead of component class -->
|
||||
<ng-container *ngIf="displayedAnnotations$ | async"></ng-container>
|
||||
|
||||
<div *ngIf="!excludePages" class="right-title heading" translate="file-preview.tabs.annotations.label">
|
||||
<div>
|
||||
<div
|
||||
@ -13,6 +16,7 @@
|
||||
></redaction-popup-filter>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="excludePages" class="right-title heading" translate="file-preview.tabs.exclude-pages.label">
|
||||
<div>
|
||||
<iqser-circle-button
|
||||
@ -23,6 +27,7 @@
|
||||
></iqser-circle-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="right-content">
|
||||
<div *ngIf="isReadOnly" [class.justify-center]="!isProcessing" class="read-only d-flex">
|
||||
<div *ngIf="isProcessing" class="flex-align-items-center">
|
||||
@ -34,6 +39,7 @@
|
||||
<span class="read-only-text" translate="readonly"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="multiSelectActive" class="multi-select">
|
||||
<div class="selected-wrapper">
|
||||
<iqser-round-checkbox
|
||||
@ -55,6 +61,7 @@
|
||||
</div>
|
||||
<iqser-circle-button (action)="multiSelectActive = false" icon="red:close" [type]="circleButtonTypes.primary"></iqser-circle-button>
|
||||
</div>
|
||||
|
||||
<div [class.lower-height]="multiSelectActive || isReadOnly" class="annotations-wrapper">
|
||||
<div
|
||||
#quickNavigation
|
||||
@ -80,7 +87,7 @@
|
||||
[activeSelection]="pageHasSelection(pageNumber)"
|
||||
[active]="pageNumber === activeViewerPage"
|
||||
[number]="pageNumber"
|
||||
[viewedPages]="fileData.viewedPages"
|
||||
[viewedPages]="fileData?.viewedPages"
|
||||
></redaction-page-indicator>
|
||||
</div>
|
||||
<div
|
||||
@ -99,8 +106,8 @@
|
||||
<div [attr.anotation-page-header]="activeViewerPage" class="page-separator">
|
||||
<span *ngIf="!!activeViewerPage" class="all-caps-label">
|
||||
<span translate="page"></span> {{ activeViewerPage }} -
|
||||
{{ activeAnnotationsLength || 0 }}
|
||||
<span [translate]="activeAnnotationsLength === 1 ? 'annotation' : 'annotations'"></span>
|
||||
{{ activeAnnotations?.length || 0 }}
|
||||
<span [translate]="activeAnnotations?.length === 1 ? 'annotation' : 'annotations'"></span>
|
||||
</span>
|
||||
|
||||
<div *ngIf="multiSelectActive">
|
||||
@ -126,7 +133,7 @@
|
||||
redactionHasScrollbar
|
||||
tabindex="1"
|
||||
>
|
||||
<ng-container *ngIf="activeViewerPage && !displayedAnnotations[activeViewerPage]">
|
||||
<ng-container *ngIf="activeViewerPage && !displayedAnnotations.get(activeViewerPage)?.length">
|
||||
<redaction-empty-state
|
||||
[horizontalPadding]="24"
|
||||
[text]="'file-preview.no-data.title' | translate"
|
||||
@ -165,7 +172,7 @@
|
||||
|
||||
<div
|
||||
(click)="annotationClicked(annotation, $event)"
|
||||
*ngFor="let annotation of displayedAnnotations[activeViewerPage]?.annotations"
|
||||
*ngFor="let annotation of displayedAnnotations.get(activeViewerPage)"
|
||||
[attr.annotation-id]="annotation.id"
|
||||
[attr.annotation-page]="activeViewerPage"
|
||||
[class.active]="isSelected(annotation)"
|
||||
|
||||
@ -15,11 +15,13 @@ import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { AnnotationProcessingService } from '../../services/annotation-processing.service';
|
||||
import { MatDialogRef, MatDialogState } from '@angular/material/dialog';
|
||||
import scrollIntoView from 'scroll-into-view-if-needed';
|
||||
import { CircleButtonTypes, Debounce, IconButtonTypes, NestedFilter } from '@iqser/common-ui';
|
||||
import { CircleButtonTypes, Debounce, FilterService, IconButtonTypes, NestedFilter } from '@iqser/common-ui';
|
||||
import { FileDataModel } from '@models/file/file-data.model';
|
||||
import { CommentsComponent } from '../comments/comments.component';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { WebViewerInstance } from '@pdftron/webviewer';
|
||||
import { BehaviorSubject, combineLatest, Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
const COMMAND_KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Escape'];
|
||||
const ALL_HOTKEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'];
|
||||
@ -33,40 +35,44 @@ export class FileWorkloadComponent {
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
|
||||
displayedAnnotations: { [key: number]: { annotations: AnnotationWrapper[] } } = {};
|
||||
displayedAnnotations = new Map<number, AnnotationWrapper[]>();
|
||||
@Input() selectedAnnotations: AnnotationWrapper[];
|
||||
@Input() activeViewerPage: number;
|
||||
@Input() shouldDeselectAnnotationsOnPageChange: boolean;
|
||||
@Input() dialogRef: MatDialogRef<any>;
|
||||
@Input() dialogRef: MatDialogRef<unknown>;
|
||||
@Input() fileData: FileDataModel;
|
||||
@Input() hideSkipped: boolean;
|
||||
@Input() excludePages: boolean;
|
||||
@Input() annotationActionsTemplate: TemplateRef<any>;
|
||||
@Input() annotationActionsTemplate: TemplateRef<unknown>;
|
||||
@Input() viewer: WebViewerInstance;
|
||||
@Output() shouldDeselectAnnotationsOnPageChangeChange = new EventEmitter<boolean>();
|
||||
@Output() selectAnnotations = new EventEmitter<AnnotationWrapper[] | { annotations: AnnotationWrapper[]; multiSelect: boolean }>();
|
||||
@Output() deselectAnnotations = new EventEmitter<AnnotationWrapper[]>();
|
||||
@Output() selectPage = new EventEmitter<number>();
|
||||
@Output() toggleSkipped = new EventEmitter<any>();
|
||||
@Output() annotationsChanged = new EventEmitter<AnnotationWrapper>();
|
||||
@Output() actionPerformed = new EventEmitter<string>();
|
||||
@Output() readonly shouldDeselectAnnotationsOnPageChangeChange = new EventEmitter<boolean>();
|
||||
@Output() readonly selectAnnotations = new EventEmitter<
|
||||
AnnotationWrapper[] | { annotations: AnnotationWrapper[]; multiSelect: boolean }
|
||||
>();
|
||||
@Output() readonly deselectAnnotations = new EventEmitter<AnnotationWrapper[]>();
|
||||
@Output() readonly selectPage = new EventEmitter<number>();
|
||||
@Output() readonly toggleSkipped = new EventEmitter<MouseEvent>();
|
||||
@Output() readonly annotationsChanged = new EventEmitter<AnnotationWrapper>();
|
||||
@Output() readonly actionPerformed = new EventEmitter<string>();
|
||||
displayedPages: number[] = [];
|
||||
pagesPanelActive = true;
|
||||
@ViewChildren(CommentsComponent) annotationCommentsComponents: QueryList<CommentsComponent>;
|
||||
@ViewChild('annotationsElement') private _annotationsElement: ElementRef;
|
||||
@ViewChild('quickNavigation') private _quickNavigationElement: ElementRef;
|
||||
@ViewChildren(CommentsComponent) readonly annotationCommentsComponents: QueryList<CommentsComponent>;
|
||||
@ViewChild('annotationsElement') private readonly _annotationsElement: ElementRef;
|
||||
@ViewChild('quickNavigation') private readonly _quickNavigationElement: ElementRef;
|
||||
|
||||
constructor(
|
||||
private readonly _permissionsService: PermissionsService,
|
||||
private readonly _changeDetectorRef: ChangeDetectorRef,
|
||||
private readonly _filterService: FilterService,
|
||||
private readonly _annotationProcessingService: AnnotationProcessingService
|
||||
) {}
|
||||
|
||||
private _annotations: AnnotationWrapper[];
|
||||
private _annotations$ = new BehaviorSubject<AnnotationWrapper[]>([]);
|
||||
readonly displayedAnnotations$ = this._displayedAnnotations$;
|
||||
|
||||
@Input()
|
||||
set annotations(value: AnnotationWrapper[]) {
|
||||
this._annotations = value;
|
||||
this._annotations$.next(value);
|
||||
}
|
||||
|
||||
private _multiSelectActive = false;
|
||||
@ -89,8 +95,8 @@ export class FileWorkloadComponent {
|
||||
return this.fileData?.fileStatus?.isProcessing;
|
||||
}
|
||||
|
||||
get activeAnnotationsLength(): number | undefined {
|
||||
return this.displayedAnnotations[this.activeViewerPage]?.annotations?.length;
|
||||
get activeAnnotations(): AnnotationWrapper[] | undefined {
|
||||
return this.displayedAnnotations.get(this.activeViewerPage);
|
||||
}
|
||||
|
||||
get isReadOnly(): boolean {
|
||||
@ -130,27 +136,25 @@ export class FileWorkloadComponent {
|
||||
}
|
||||
|
||||
selectAllOnActivePage() {
|
||||
this.selectAnnotations.emit(this.displayedAnnotations[this.activeViewerPage].annotations);
|
||||
this._changeDetectorRef.detectChanges();
|
||||
this.selectAnnotations.emit(this.activeAnnotations);
|
||||
}
|
||||
|
||||
deselectAllOnActivePage() {
|
||||
this.deselectAnnotations.emit(this.displayedAnnotations[this.activeViewerPage].annotations);
|
||||
this._changeDetectorRef.detectChanges();
|
||||
deselectAllOnActivePage(): void {
|
||||
this.deselectAnnotations.emit(this.activeAnnotations);
|
||||
}
|
||||
|
||||
@Debounce(0)
|
||||
filtersChanged(filters: { primary: NestedFilter[]; secondary?: NestedFilter[] }) {
|
||||
this.displayedAnnotations = this._annotationProcessingService.filterAndGroupAnnotations(
|
||||
this._annotations,
|
||||
filters.primary,
|
||||
filters.secondary
|
||||
);
|
||||
this.displayedPages = Object.keys(this.displayedAnnotations).map(key => Number(key));
|
||||
this._changeDetectorRef.markForCheck();
|
||||
private _filterAnnotations(
|
||||
annotations: AnnotationWrapper[],
|
||||
primary: NestedFilter[],
|
||||
secondary: NestedFilter[] = []
|
||||
): Map<number, AnnotationWrapper[]> {
|
||||
if (!primary) return;
|
||||
this.displayedAnnotations = this._annotationProcessingService.filterAndGroupAnnotations(annotations, primary, secondary);
|
||||
this.displayedPages = [...this.displayedAnnotations.keys()];
|
||||
return this.displayedAnnotations;
|
||||
}
|
||||
|
||||
annotationClicked(annotation: AnnotationWrapper, $event: MouseEvent) {
|
||||
annotationClicked(annotation: AnnotationWrapper, $event: MouseEvent): void {
|
||||
this.pagesPanelActive = false;
|
||||
this.logAnnotation(annotation);
|
||||
if (this.isSelected(annotation)) {
|
||||
@ -167,7 +171,7 @@ export class FileWorkloadComponent {
|
||||
}
|
||||
|
||||
@HostListener('window:keyup', ['$event'])
|
||||
handleKeyEvent($event: KeyboardEvent) {
|
||||
handleKeyEvent($event: KeyboardEvent): void {
|
||||
if (
|
||||
!ALL_HOTKEY_ARRAY.includes($event.key) ||
|
||||
this.dialogRef?.getState() === MatDialogState.OPEN ||
|
||||
@ -205,32 +209,32 @@ export class FileWorkloadComponent {
|
||||
this._changeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
scrollAnnotations() {
|
||||
scrollAnnotations(): void {
|
||||
if (this._firstSelectedAnnotation?.pageNumber === this.activeViewerPage) {
|
||||
return;
|
||||
}
|
||||
this.scrollAnnotationsToPage(this.activeViewerPage, 'always');
|
||||
}
|
||||
|
||||
scrollAnnotationsToPage(page: number, mode: 'always' | 'if-needed' = 'if-needed') {
|
||||
scrollAnnotationsToPage(page: number, mode: 'always' | 'if-needed' = 'if-needed'): void {
|
||||
if (this._annotationsElement) {
|
||||
const elements: any[] = this._annotationsElement.nativeElement.querySelectorAll(`div[anotation-page-header="${page}"]`);
|
||||
const elements = this._annotationsElement.nativeElement.querySelectorAll(`div[anotation-page-header="${page}"]`);
|
||||
FileWorkloadComponent._scrollToFirstElement(elements, mode);
|
||||
}
|
||||
}
|
||||
|
||||
@Debounce()
|
||||
scrollToSelectedAnnotation() {
|
||||
scrollToSelectedAnnotation(): void {
|
||||
if (!this.selectedAnnotations || this.selectedAnnotations.length === 0 || !this._annotationsElement) {
|
||||
return;
|
||||
}
|
||||
const elements: any[] = this._annotationsElement.nativeElement.querySelectorAll(
|
||||
const elements = this._annotationsElement.nativeElement.querySelectorAll(
|
||||
`div[annotation-id="${this._firstSelectedAnnotation?.id}"].active`
|
||||
);
|
||||
FileWorkloadComponent._scrollToFirstElement(elements);
|
||||
}
|
||||
|
||||
scrollQuickNavigation() {
|
||||
scrollQuickNavigation(): void {
|
||||
let quickNavPageIndex = this.displayedPages.findIndex(p => p >= this.activeViewerPage);
|
||||
if (quickNavPageIndex === -1 || this.displayedPages[quickNavPageIndex] !== this.activeViewerPage) {
|
||||
quickNavPageIndex = Math.max(0, quickNavPageIndex - 1);
|
||||
@ -238,39 +242,47 @@ export class FileWorkloadComponent {
|
||||
this._scrollQuickNavigationToPage(this.displayedPages[quickNavPageIndex]);
|
||||
}
|
||||
|
||||
scrollQuickNavFirst() {
|
||||
scrollQuickNavFirst(): void {
|
||||
this.selectPage.emit(1);
|
||||
}
|
||||
|
||||
scrollQuickNavLast() {
|
||||
scrollQuickNavLast(): void {
|
||||
this.selectPage.emit(this.fileData.fileStatus.numberOfPages);
|
||||
}
|
||||
|
||||
pageSelectedByClick($event: number) {
|
||||
pageSelectedByClick($event: number): void {
|
||||
this.pagesPanelActive = true;
|
||||
this.selectPage.emit($event);
|
||||
}
|
||||
|
||||
preventKeyDefault($event: KeyboardEvent) {
|
||||
preventKeyDefault($event: KeyboardEvent): void {
|
||||
if (COMMAND_KEY_ARRAY.includes($event.key) && !(($event.target as any).localName === 'input')) {
|
||||
$event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
jumpToPreviousWithAnnotations() {
|
||||
jumpToPreviousWithAnnotations(): void {
|
||||
this.selectPage.emit(this._prevPageWithAnnotations());
|
||||
}
|
||||
|
||||
jumpToNextWithAnnotations() {
|
||||
jumpToNextWithAnnotations(): void {
|
||||
this.selectPage.emit(this._nextPageWithAnnotations());
|
||||
}
|
||||
|
||||
private get _displayedAnnotations$(): Observable<Map<number, AnnotationWrapper[]>> {
|
||||
const primary$ = this._filterService.getFilterModels$('primaryFilters');
|
||||
const secondary$ = this._filterService.getFilterModels$('secondaryFilters');
|
||||
return combineLatest([this._annotations$, primary$, secondary$]).pipe(
|
||||
map(([annotations, primary, secondary]) => this._filterAnnotations(annotations, primary, secondary))
|
||||
);
|
||||
}
|
||||
|
||||
private _selectFirstAnnotationOnCurrentPageIfNecessary() {
|
||||
if (
|
||||
(!this._firstSelectedAnnotation || this.activeViewerPage !== this._firstSelectedAnnotation.pageNumber) &&
|
||||
this.displayedPages.indexOf(this.activeViewerPage) >= 0
|
||||
) {
|
||||
this.selectAnnotations.emit([this.displayedAnnotations[this.activeViewerPage].annotations[0]]);
|
||||
this.selectAnnotations.emit([this.activeAnnotations[0]]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -278,28 +290,28 @@ export class FileWorkloadComponent {
|
||||
if (!this._firstSelectedAnnotation || this.activeViewerPage !== this._firstSelectedAnnotation.pageNumber) {
|
||||
if (this.displayedPages.indexOf(this.activeViewerPage) !== -1) {
|
||||
// Displayed page has annotations
|
||||
return this.selectAnnotations.emit([this.displayedAnnotations[this.activeViewerPage].annotations[0]]);
|
||||
return this.selectAnnotations.emit([this.activeAnnotations[0]]);
|
||||
}
|
||||
// Displayed page doesn't have annotations
|
||||
if ($event.key === 'ArrowDown') {
|
||||
const nextPage = this._nextPageWithAnnotations();
|
||||
this.shouldDeselectAnnotationsOnPageChange = false;
|
||||
this.shouldDeselectAnnotationsOnPageChangeChange.emit(false);
|
||||
this.selectAnnotations.emit([this.displayedAnnotations[nextPage].annotations[0]]);
|
||||
this.selectAnnotations.emit([this.displayedAnnotations.get(nextPage)[0]]);
|
||||
return;
|
||||
}
|
||||
|
||||
const prevPage = this._prevPageWithAnnotations();
|
||||
this.shouldDeselectAnnotationsOnPageChange = false;
|
||||
this.shouldDeselectAnnotationsOnPageChangeChange.emit(false);
|
||||
const prevPageAnnotations = this.displayedAnnotations[prevPage].annotations;
|
||||
const prevPageAnnotations = this.displayedAnnotations.get(prevPage);
|
||||
this.selectAnnotations.emit([prevPageAnnotations[prevPageAnnotations.length - 1]]);
|
||||
return;
|
||||
}
|
||||
|
||||
const page = this._firstSelectedAnnotation.pageNumber;
|
||||
const pageIdx = this.displayedPages.indexOf(page);
|
||||
const annotationsOnPage = this.displayedAnnotations[page].annotations;
|
||||
const annotationsOnPage = this.displayedAnnotations.get(page);
|
||||
const idx = annotationsOnPage.findIndex(a => a.id === this._firstSelectedAnnotation.id);
|
||||
|
||||
if ($event.key === 'ArrowDown') {
|
||||
@ -308,7 +320,7 @@ export class FileWorkloadComponent {
|
||||
this.selectAnnotations.emit([annotationsOnPage[idx + 1]]);
|
||||
} else if (pageIdx + 1 < this.displayedPages.length) {
|
||||
// If not last page
|
||||
const nextPageAnnotations = this.displayedAnnotations[this.displayedPages[pageIdx + 1]].annotations;
|
||||
const nextPageAnnotations = this.displayedAnnotations.get(this.displayedPages[pageIdx + 1]);
|
||||
this.shouldDeselectAnnotationsOnPageChange = false;
|
||||
this.shouldDeselectAnnotationsOnPageChangeChange.emit(false);
|
||||
this.selectAnnotations.emit([nextPageAnnotations[0]]);
|
||||
@ -318,7 +330,7 @@ export class FileWorkloadComponent {
|
||||
this.selectAnnotations.emit([annotationsOnPage[idx - 1]]);
|
||||
} else if (pageIdx) {
|
||||
// If not first page
|
||||
const prevPageAnnotations = this.displayedAnnotations[this.displayedPages[pageIdx - 1]].annotations;
|
||||
const prevPageAnnotations = this.displayedAnnotations.get(this.displayedPages[pageIdx - 1]);
|
||||
this.shouldDeselectAnnotationsOnPageChange = false;
|
||||
this.shouldDeselectAnnotationsOnPageChangeChange.emit(false);
|
||||
this.selectAnnotations.emit([prevPageAnnotations[prevPageAnnotations.length - 1]]);
|
||||
@ -382,7 +394,7 @@ export class FileWorkloadComponent {
|
||||
|
||||
private _scrollQuickNavigationToPage(page: number) {
|
||||
if (this._quickNavigationElement) {
|
||||
const elements: any[] = this._quickNavigationElement.nativeElement.querySelectorAll(`#quick-nav-page-${page}`);
|
||||
const elements = this._quickNavigationElement.nativeElement.querySelectorAll(`#quick-nav-page-${page}`);
|
||||
FileWorkloadComponent._scrollToFirstElement(elements);
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly translations = fileStatusTranslations;
|
||||
|
||||
dialogRef: MatDialogRef<any>;
|
||||
dialogRef: MatDialogRef<unknown>;
|
||||
viewMode: ViewMode = 'STANDARD';
|
||||
fullScreen = false;
|
||||
editingReviewer = false;
|
||||
@ -61,11 +61,11 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
displayPDFViewer = false;
|
||||
viewDocumentInfo = false;
|
||||
excludePages = false;
|
||||
@ViewChild(PdfViewerComponent) viewerComponent: PdfViewerComponent;
|
||||
private _instance: WebViewerInstance;
|
||||
private _lastPage: string;
|
||||
private _reloadFileOnReanalysis = false;
|
||||
@ViewChild('fileWorkloadComponent') private _workloadComponent: FileWorkloadComponent;
|
||||
@ViewChild(PdfViewerComponent) readonly viewerComponent: PdfViewerComponent;
|
||||
@ViewChild('fileWorkloadComponent') private readonly _workloadComponent: FileWorkloadComponent;
|
||||
@ViewChild('annotationFilterTemplate', {
|
||||
read: TemplateRef,
|
||||
static: true
|
||||
@ -119,11 +119,11 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
return this.annotationData ? this.annotationData.visibleAnnotations : [];
|
||||
}
|
||||
|
||||
get activeViewer() {
|
||||
get activeViewer(): WebViewerInstance {
|
||||
return this._instance;
|
||||
}
|
||||
|
||||
get activeViewerPage() {
|
||||
get activeViewerPage(): number {
|
||||
const currentPage = this._instance?.docViewer?.getCurrentPage();
|
||||
if (!currentPage) {
|
||||
return 0;
|
||||
@ -135,11 +135,11 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
: (currentPage + 1) / 2;
|
||||
}
|
||||
|
||||
get canSwitchToRedactedView() {
|
||||
get canSwitchToRedactedView(): boolean {
|
||||
return this.fileData && !this.fileData.fileStatus.analysisRequired && !this.fileData.fileStatus.excluded;
|
||||
}
|
||||
|
||||
get canSwitchToDeltaView() {
|
||||
get canSwitchToDeltaView(): boolean {
|
||||
return this.fileData?.redactionChangeLog?.redactionLogEntry?.length > 0 && !this.fileData.fileStatus.excluded;
|
||||
}
|
||||
|
||||
@ -147,15 +147,15 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
return !this.editingReviewer && (this.permissionsService.canAssignUser() || this.permissionsService.canAssignToSelf());
|
||||
}
|
||||
|
||||
get displayData() {
|
||||
get displayData(): Blob {
|
||||
return this.fileData?.fileData;
|
||||
}
|
||||
|
||||
get dossierId() {
|
||||
get dossierId(): string {
|
||||
return this.appStateService.activeDossierId;
|
||||
}
|
||||
|
||||
get fileId() {
|
||||
get fileId(): string {
|
||||
return this.appStateService.activeFileId;
|
||||
}
|
||||
|
||||
@ -167,7 +167,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
return this.appStateService.activeFile.fileStatus.lastReviewer;
|
||||
}
|
||||
|
||||
get assignOrChangeReviewerTooltip() {
|
||||
get assignOrChangeReviewerTooltip(): string {
|
||||
return this.currentReviewer
|
||||
? this._translateService.instant('file-preview.change-reviewer')
|
||||
: this._translateService.instant('file-preview.assign-reviewer');
|
||||
@ -195,7 +195,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
);
|
||||
}
|
||||
|
||||
updateViewMode() {
|
||||
updateViewMode(): void {
|
||||
const annotations = this._getAnnotations(a => a.getCustomData('redacto-manager'));
|
||||
const redactions = annotations.filter(a => a.getCustomData('redaction'));
|
||||
|
||||
@ -230,12 +230,12 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
this._updateCanPerformActions();
|
||||
}
|
||||
|
||||
ngOnDetach() {
|
||||
ngOnDetach(): void {
|
||||
this.displayPDFViewer = false;
|
||||
super.ngOnDestroy();
|
||||
}
|
||||
|
||||
async ngOnAttach(previousRoute: ActivatedRouteSnapshot) {
|
||||
async ngOnAttach(previousRoute: ActivatedRouteSnapshot): Promise<void> {
|
||||
if (!this.appStateService.activeFile.canBeOpened) {
|
||||
await this._router.navigate(['/main/dossiers/' + this.dossierId]);
|
||||
return;
|
||||
@ -245,14 +245,14 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
this._lastPage = previousRoute.queryParams.page;
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
await this._loadFileData(false);
|
||||
async ngOnInit(): Promise<void> {
|
||||
await this._loadFileData();
|
||||
this.displayPDFViewer = true;
|
||||
this._updateCanPerformActions();
|
||||
this._subscribeToFileUpdates();
|
||||
}
|
||||
|
||||
rebuildFilters(deletePreviousAnnotations: boolean = false) {
|
||||
rebuildFilters(deletePreviousAnnotations = false): void {
|
||||
const startTime = new Date().getTime();
|
||||
if (deletePreviousAnnotations) {
|
||||
const annotationsToDelete = this._instance?.annotManager?.getAnnotationsList() || [];
|
||||
@ -571,7 +571,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
!this.viewerComponent?.utils.isCompareMode;
|
||||
}
|
||||
|
||||
private async _loadFileData(performUpdate: boolean = false): Promise<void> {
|
||||
private async _loadFileData(performUpdate = false): Promise<void> {
|
||||
const fileData = await this._fileDownloadService.loadActiveFileData().toPromise();
|
||||
if (!fileData.fileStatus?.isPending && !fileData.fileStatus?.isError) {
|
||||
if (performUpdate) {
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { SuperTypeSorter } from '@utils/sorters/super-type-sorter';
|
||||
import { handleCheckedValue } from '@iqser/common-ui';
|
||||
import { handleCheckedValue, NestedFilter } from '@iqser/common-ui';
|
||||
import { annotationTypesTranslations } from '../../../translations/annotation-types-translations';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { NestedFilter } from '@iqser/common-ui';
|
||||
|
||||
@Injectable()
|
||||
export class AnnotationProcessingService {
|
||||
@ -81,8 +80,8 @@ export class AnnotationProcessingService {
|
||||
annotations: AnnotationWrapper[],
|
||||
primaryFilters: NestedFilter[],
|
||||
secondaryFilters?: NestedFilter[]
|
||||
): { [key: number]: { annotations: AnnotationWrapper[] } } {
|
||||
const obj = {};
|
||||
): Map<number, AnnotationWrapper[]> {
|
||||
const obj = new Map<number, AnnotationWrapper[]>();
|
||||
|
||||
const primaryFlatFilters = this._getFlatFilters(primaryFilters, f => f.checked);
|
||||
const secondaryFlatFilters = this._getFlatFilters(secondaryFilters, f => f.checked);
|
||||
@ -103,22 +102,15 @@ export class AnnotationProcessingService {
|
||||
|
||||
const pageNumber = annotation.pageNumber;
|
||||
|
||||
if (!obj[pageNumber]) {
|
||||
obj[pageNumber] = {
|
||||
annotations: [],
|
||||
hint: 0,
|
||||
redaction: 0,
|
||||
request: 0,
|
||||
skipped: 0
|
||||
};
|
||||
if (!obj.has(pageNumber)) {
|
||||
obj.set(pageNumber, []);
|
||||
}
|
||||
|
||||
obj[pageNumber].annotations.push(annotation);
|
||||
obj[pageNumber][annotation.superType]++;
|
||||
obj.get(pageNumber).push(annotation);
|
||||
}
|
||||
|
||||
Object.keys(obj).map(page => {
|
||||
obj[page].annotations = this._sortAnnotations(obj[page].annotations);
|
||||
obj.forEach((values, page) => {
|
||||
obj.set(page, this._sortAnnotations(values));
|
||||
});
|
||||
|
||||
return obj;
|
||||
|
||||
@ -25,10 +25,10 @@
|
||||
<div class="breakdown-container">
|
||||
<div>
|
||||
<div
|
||||
(click)="selectValue(val.key)"
|
||||
(click)="val.key && selectValue(val.key)"
|
||||
*ngFor="let val of config"
|
||||
[class.active]="filterChecked$(val.key) | async"
|
||||
[class.filter-disabled]="(statusFilters$ | async)?.length === 0"
|
||||
[class.filter-disabled]="!val.key || (statusFilters$ | async)?.length === 0"
|
||||
>
|
||||
<iqser-status-bar
|
||||
[configs]="[
|
||||
|
||||
@ -19,7 +19,7 @@ export class UserPreferenceService {
|
||||
return this._userAttributes;
|
||||
}
|
||||
|
||||
get areDevFeaturesEnabled() {
|
||||
get areDevFeaturesEnabled(): boolean {
|
||||
const value = sessionStorage.getItem('redaction.enable-dev-features');
|
||||
return value ? value === 'true' : false;
|
||||
}
|
||||
@ -32,20 +32,23 @@ export class UserPreferenceService {
|
||||
return '';
|
||||
}
|
||||
|
||||
async saveLastOpenedFileForDossier(dossierId: string, fileId: string) {
|
||||
async saveLastOpenedFileForDossier(dossierId: string, fileId: string): Promise<void> {
|
||||
const key = `Dossier-Recent-${dossierId}`;
|
||||
this.userAttributes[key] = [fileId];
|
||||
await this._userPreferenceControllerService.savePreferences([fileId], key).toPromise();
|
||||
}
|
||||
|
||||
toggleDevFeatures() {
|
||||
toggleDevFeatures(): void {
|
||||
sessionStorage.setItem('redaction.enable-dev-features', `${!this.areDevFeaturesEnabled}`);
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
reload() {
|
||||
this._userPreferenceControllerService.getAllUserAttributes().subscribe(attributes => {
|
||||
this._userAttributes = attributes ?? {};
|
||||
});
|
||||
reload(): void {
|
||||
this._userPreferenceControllerService
|
||||
.getAllUserAttributes()
|
||||
.toPromise()
|
||||
.then(attributes => {
|
||||
this._userAttributes = attributes ?? {};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit 908256aacab10e189b04b7471cd7bf813723d76a
|
||||
Subproject commit 4527494d728d622bdd5d85aea72a7770fa1a8f14
|
||||
Loading…
x
Reference in New Issue
Block a user