RED-3988: improve annotation manager
This commit is contained in:
parent
08c9de05de
commit
a989708d08
@ -59,7 +59,7 @@ export class AnnotationActionsComponent implements OnChanges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get viewerAnnotations() {
|
get viewerAnnotations() {
|
||||||
return this._annotationManager.getAnnotations(this._annotations);
|
return this._annotationManager.get(this._annotations);
|
||||||
}
|
}
|
||||||
|
|
||||||
get isVisible() {
|
get isVisible() {
|
||||||
@ -94,15 +94,15 @@ export class AnnotationActionsComponent implements OnChanges {
|
|||||||
|
|
||||||
hideAnnotation($event: MouseEvent) {
|
hideAnnotation($event: MouseEvent) {
|
||||||
$event.stopPropagation();
|
$event.stopPropagation();
|
||||||
this._annotationManager.hideAnnotations(this.viewerAnnotations);
|
this._annotationManager.hide(this.viewerAnnotations);
|
||||||
this._annotationManager.deselectAnnotations();
|
this._annotationManager.deselect();
|
||||||
this._fileDataService.updateHiddenAnnotations(this.viewerAnnotations, true);
|
this._fileDataService.updateHiddenAnnotations(this.viewerAnnotations, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
showAnnotation($event: MouseEvent) {
|
showAnnotation($event: MouseEvent) {
|
||||||
$event.stopPropagation();
|
$event.stopPropagation();
|
||||||
this._annotationManager.showAnnotations(this.viewerAnnotations);
|
this._annotationManager.show(this.viewerAnnotations);
|
||||||
this._annotationManager.deselectAnnotations();
|
this._annotationManager.deselect();
|
||||||
this._fileDataService.updateHiddenAnnotations(this.viewerAnnotations, false);
|
this._fileDataService.updateHiddenAnnotations(this.viewerAnnotations, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -70,7 +70,7 @@ 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.deselectAnnotation(annotation);
|
this._annotationManager.deselect(annotation);
|
||||||
} else {
|
} else {
|
||||||
const canMultiSelect = this._multiSelectService.isEnabled;
|
const canMultiSelect = this._multiSelectService.isEnabled;
|
||||||
if (canMultiSelect && ($event?.ctrlKey || $event?.metaKey) && this._listingService.selected.length > 0) {
|
if (canMultiSelect && ($event?.ctrlKey || $event?.metaKey) && this._listingService.selected.length > 0) {
|
||||||
|
|||||||
@ -48,7 +48,7 @@
|
|||||||
<div *ngIf="multiSelectService.active$ | async" class="multi-select">
|
<div *ngIf="multiSelectService.active$ | async" class="multi-select">
|
||||||
<div class="selected-wrapper">
|
<div class="selected-wrapper">
|
||||||
<iqser-round-checkbox
|
<iqser-round-checkbox
|
||||||
(click)="annotationManager.deselectAnnotations()"
|
(click)="annotationManager.deselect()"
|
||||||
[indeterminate]="listingService.areSomeSelected$ | async"
|
[indeterminate]="listingService.areSomeSelected$ | async"
|
||||||
type="with-bg"
|
type="with-bg"
|
||||||
></iqser-round-checkbox>
|
></iqser-round-checkbox>
|
||||||
|
|||||||
@ -136,7 +136,7 @@ export class FileWorkloadComponent {
|
|||||||
return this.multiSelectService.inactive$.pipe(
|
return this.multiSelectService.inactive$.pipe(
|
||||||
tap(value => {
|
tap(value => {
|
||||||
if (value) {
|
if (value) {
|
||||||
this.annotationManager.deselectAnnotations();
|
this.annotationManager.deselect();
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
shareDistinctLast(),
|
shareDistinctLast(),
|
||||||
@ -185,7 +185,7 @@ export class FileWorkloadComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deselectAllOnActivePage(): void {
|
deselectAllOnActivePage(): void {
|
||||||
this.annotationManager.deselectAnnotations(this.activeAnnotations);
|
this.annotationManager.deselect(this.activeAnnotations);
|
||||||
}
|
}
|
||||||
|
|
||||||
@HostListener('window:keyup', ['$event'])
|
@HostListener('window:keyup', ['$event'])
|
||||||
|
|||||||
@ -190,13 +190,13 @@ export class PdfPaginatorComponent extends AutoUnsubscribe implements OnInit, On
|
|||||||
|
|
||||||
if (action === 'deselected') {
|
if (action === 'deselected') {
|
||||||
// Remove deselected annotations from selected list
|
// Remove deselected annotations from selected list
|
||||||
nextAnnotations = this._annotationManager.selectedAnnotations.filter(ann => !annotations.some(a => a.Id === ann.Id));
|
nextAnnotations = this._annotationManager.selected.filter(ann => !annotations.some(a => a.Id === ann.Id));
|
||||||
} else if (!this._multiSelectService.isEnabled) {
|
} else if (!this._multiSelectService.isEnabled) {
|
||||||
// Only choose the last selected annotation, to bypass viewer multi select
|
// Only choose the last selected annotation, to bypass viewer multi select
|
||||||
nextAnnotations = annotations;
|
nextAnnotations = annotations;
|
||||||
} else {
|
} else {
|
||||||
// Get selected annotations from the manager, no intervention needed
|
// Get selected annotations from the manager, no intervention needed
|
||||||
nextAnnotations = this._annotationManager.selectedAnnotations;
|
nextAnnotations = this._annotationManager.selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this.annotationSelected.emit(nextAnnotations.map(ann => ann.Id));
|
// this.annotationSelected.emit(nextAnnotations.map(ann => ann.Id));
|
||||||
@ -207,7 +207,7 @@ export class PdfPaginatorComponent extends AutoUnsubscribe implements OnInit, On
|
|||||||
|
|
||||||
if (!this._multiSelectService.isEnabled) {
|
if (!this._multiSelectService.isEnabled) {
|
||||||
const notSelected = this._fileDataService.all.filter(wrapper => !nextAnnotations.some(ann => ann.Id === wrapper.id));
|
const notSelected = this._fileDataService.all.filter(wrapper => !nextAnnotations.some(ann => ann.Id === wrapper.id));
|
||||||
this._annotationManager.deselectAnnotations(notSelected);
|
this._annotationManager.deselect(notSelected);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.#configureAnnotationSpecificActions(annotations);
|
this.#configureAnnotationSpecificActions(annotations);
|
||||||
@ -286,11 +286,11 @@ export class PdfPaginatorComponent extends AutoUnsubscribe implements OnInit, On
|
|||||||
onClick: () => {
|
onClick: () => {
|
||||||
this._ngZone.run(() => {
|
this._ngZone.run(() => {
|
||||||
if (allAreVisible) {
|
if (allAreVisible) {
|
||||||
this._annotationManager.hideAnnotations(viewerAnnotations);
|
this._annotationManager.hide(viewerAnnotations);
|
||||||
} else {
|
} else {
|
||||||
this._annotationManager.showAnnotations(viewerAnnotations);
|
this._annotationManager.show(viewerAnnotations);
|
||||||
}
|
}
|
||||||
this._annotationManager.deselectAnnotations();
|
this._annotationManager.deselect();
|
||||||
this._fileDataService.updateHiddenAnnotations(viewerAnnotations, allAreVisible);
|
this._fileDataService.updateHiddenAnnotations(viewerAnnotations, allAreVisible);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -317,7 +317,7 @@ export class PdfPaginatorComponent extends AutoUnsubscribe implements OnInit, On
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _addRectangleManualRedaction() {
|
private _addRectangleManualRedaction() {
|
||||||
const activeAnnotation = this._annotationManager.selectedAnnotations[0];
|
const activeAnnotation = this._annotationManager.selected[0];
|
||||||
const activePage = activeAnnotation.getPageNumber();
|
const activePage = activeAnnotation.getPageNumber();
|
||||||
const quads = [this._annotationDrawService.annotationToQuads(activeAnnotation)];
|
const quads = [this._annotationDrawService.annotationToQuads(activeAnnotation)];
|
||||||
const manualRedactionEntry = this._getManualRedaction({ [activePage]: quads });
|
const manualRedactionEntry = this._getManualRedaction({ [activePage]: quads });
|
||||||
|
|||||||
@ -120,7 +120,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
}
|
}
|
||||||
|
|
||||||
get changed() {
|
get changed() {
|
||||||
return this._pageRotationService.hasRotations();
|
return this._pageRotationService.hasRotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
get scrollableParentView(): ScrollableParentView {
|
get scrollableParentView(): ScrollableParentView {
|
||||||
@ -147,7 +147,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
async updateViewMode(): Promise<void> {
|
async updateViewMode(): Promise<void> {
|
||||||
this._logger.info(`[PDF] Update ${this._viewModeService.viewMode} view mode`);
|
this._logger.info(`[PDF] Update ${this._viewModeService.viewMode} view mode`);
|
||||||
|
|
||||||
const annotations = this._annotationManager.getAnnotations(a => Boolean(a.getCustomData('redact-manager')));
|
const annotations = this._annotationManager.get(a => Boolean(a.getCustomData('redact-manager')));
|
||||||
const redactions = annotations.filter(a => a.getCustomData('redaction'));
|
const redactions = annotations.filter(a => a.getCustomData('redaction'));
|
||||||
|
|
||||||
switch (this._viewModeService.viewMode) {
|
switch (this._viewModeService.viewMode) {
|
||||||
@ -160,8 +160,8 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
.filter(a => !ocrAnnotationIds.includes(a.Id));
|
.filter(a => !ocrAnnotationIds.includes(a.Id));
|
||||||
const nonStandardEntries = annotations.filter(a => a.getCustomData('changeLogRemoved') === 'true');
|
const nonStandardEntries = annotations.filter(a => a.getCustomData('changeLogRemoved') === 'true');
|
||||||
this._setAnnotationsOpacity(standardEntries, true);
|
this._setAnnotationsOpacity(standardEntries, true);
|
||||||
this._annotationManager.showAnnotations(standardEntries);
|
this._annotationManager.show(standardEntries);
|
||||||
this._annotationManager.hideAnnotations(nonStandardEntries);
|
this._annotationManager.hide(nonStandardEntries);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'DELTA': {
|
case 'DELTA': {
|
||||||
@ -169,21 +169,21 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
const nonChangeLogEntries = annotations.filter(a => a.getCustomData('changeLog') === 'false');
|
const nonChangeLogEntries = annotations.filter(a => a.getCustomData('changeLog') === 'false');
|
||||||
this._setAnnotationsColor(redactions, 'annotationColor');
|
this._setAnnotationsColor(redactions, 'annotationColor');
|
||||||
this._setAnnotationsOpacity(changeLogEntries, true);
|
this._setAnnotationsOpacity(changeLogEntries, true);
|
||||||
this._annotationManager.showAnnotations(changeLogEntries);
|
this._annotationManager.show(changeLogEntries);
|
||||||
this._annotationManager.hideAnnotations(nonChangeLogEntries);
|
this._annotationManager.hide(nonChangeLogEntries);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'REDACTED': {
|
case 'REDACTED': {
|
||||||
const nonRedactionEntries = annotations.filter(a => a.getCustomData('redaction') === 'false');
|
const nonRedactionEntries = annotations.filter(a => a.getCustomData('redaction') === 'false');
|
||||||
this._setAnnotationsOpacity(redactions);
|
this._setAnnotationsOpacity(redactions);
|
||||||
this._setAnnotationsColor(redactions, 'redactionColor');
|
this._setAnnotationsColor(redactions, 'redactionColor');
|
||||||
this._annotationManager.showAnnotations(redactions);
|
this._annotationManager.show(redactions);
|
||||||
this._annotationManager.hideAnnotations(nonRedactionEntries);
|
this._annotationManager.hide(nonRedactionEntries);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'TEXT_HIGHLIGHTS': {
|
case 'TEXT_HIGHLIGHTS': {
|
||||||
this._loadingService.start();
|
this._loadingService.start();
|
||||||
this._annotationManager.hideAnnotations(annotations);
|
this._annotationManager.hide(annotations);
|
||||||
const highlights = await this._fileDataService.loadTextHighlights();
|
const highlights = await this._fileDataService.loadTextHighlights();
|
||||||
await this._annotationDrawService.draw(highlights);
|
await this._annotationDrawService.draw(highlights);
|
||||||
this._loadingService.stop();
|
this._loadingService.stop();
|
||||||
@ -253,9 +253,9 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
null,
|
null,
|
||||||
{ manualRedactionEntryWrapper, dossierId: this.dossierId, file },
|
{ manualRedactionEntryWrapper, dossierId: this.dossierId, file },
|
||||||
(wrappers: ManualRedactionEntryWrapper[]) => {
|
(wrappers: ManualRedactionEntryWrapper[]) => {
|
||||||
const selectedAnnotations = this._annotationManager.selectedAnnotations;
|
const selectedAnnotations = this._annotationManager.selected;
|
||||||
if (selectedAnnotations.length > 0) {
|
if (selectedAnnotations.length > 0) {
|
||||||
this._annotationManager.deleteAnnotations([selectedAnnotations[0].Id]);
|
this._annotationManager.delete([selectedAnnotations[0].Id]);
|
||||||
}
|
}
|
||||||
const manualRedactionService = this._injector.get(ManualRedactionService);
|
const manualRedactionService = this._injector.get(ManualRedactionService);
|
||||||
const add$ = manualRedactionService.addAnnotation(
|
const add$ = manualRedactionService.addAnnotation(
|
||||||
@ -380,7 +380,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._logger.info('[ANNOTATIONS] To delete: ', annotationsToDelete);
|
this._logger.info('[ANNOTATIONS] To delete: ', annotationsToDelete);
|
||||||
this._annotationManager.deleteAnnotations(annotationsToDelete);
|
this._annotationManager.delete(annotationsToDelete);
|
||||||
}
|
}
|
||||||
|
|
||||||
drawChangedAnnotations(oldAnnotations: AnnotationWrapper[], newAnnotations: AnnotationWrapper[]) {
|
drawChangedAnnotations(oldAnnotations: AnnotationWrapper[], newAnnotations: AnnotationWrapper[]) {
|
||||||
@ -400,7 +400,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._logger.info('[ANNOTATIONS] To draw: ', annotationsToDraw);
|
this._logger.info('[ANNOTATIONS] To draw: ', annotationsToDraw);
|
||||||
this._annotationManager.deleteAnnotations(annotationsToDraw);
|
this._annotationManager.delete(annotationsToDraw);
|
||||||
return this._cleanupAndRedrawAnnotations(annotationsToDraw);
|
return this._cleanupAndRedrawAnnotations(annotationsToDraw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,7 +476,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
|
|
||||||
#deactivateMultiSelect() {
|
#deactivateMultiSelect() {
|
||||||
this.multiSelectService.deactivate();
|
this.multiSelectService.deactivate();
|
||||||
this._annotationManager.deselectAnnotations();
|
this._annotationManager.deselect();
|
||||||
this.handleAnnotationSelected([]);
|
this.handleAnnotationSelected([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -397,9 +397,9 @@ export class AnnotationActionsService {
|
|||||||
|
|
||||||
annotationWrapper.resizing = true;
|
annotationWrapper.resizing = true;
|
||||||
|
|
||||||
const viewerAnnotation = this._annotationManager.getAnnotation(annotationWrapper);
|
const viewerAnnotation = this._annotationManager.get(annotationWrapper);
|
||||||
if (annotationWrapper.rectangle || annotationWrapper.imported || annotationWrapper.isImage) {
|
if (annotationWrapper.rectangle || annotationWrapper.imported || annotationWrapper.isImage) {
|
||||||
this._annotationManager.deleteAnnotation(annotationWrapper);
|
this._annotationManager.delete(annotationWrapper);
|
||||||
const rectangleAnnotation = this.#generateRectangle(annotationWrapper);
|
const rectangleAnnotation = this.#generateRectangle(annotationWrapper);
|
||||||
this._pdf.annotationManager.addAnnotation(rectangleAnnotation, { imported: true });
|
this._pdf.annotationManager.addAnnotation(rectangleAnnotation, { imported: true });
|
||||||
await this._pdf.annotationManager.drawAnnotationsFromList([rectangleAnnotation]);
|
await this._pdf.annotationManager.drawAnnotationsFromList([rectangleAnnotation]);
|
||||||
@ -437,9 +437,9 @@ export class AnnotationActionsService {
|
|||||||
|
|
||||||
annotationWrapper.resizing = false;
|
annotationWrapper.resizing = false;
|
||||||
|
|
||||||
this._annotationManager.deleteAnnotation(annotationWrapper);
|
this._annotationManager.delete(annotationWrapper);
|
||||||
await this._annotationDrawService.draw([annotationWrapper]);
|
await this._annotationDrawService.draw([annotationWrapper]);
|
||||||
this._annotationManager.deselectAnnotations();
|
this._annotationManager.deselect();
|
||||||
await this._fileDataService.annotationsChanged();
|
await this._fileDataService.annotationsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,7 +529,7 @@ export class AnnotationActionsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _extractTextAndPositions(annotationId: string) {
|
private async _extractTextAndPositions(annotationId: string) {
|
||||||
const viewerAnnotation = this._annotationManager.getAnnotation(annotationId);
|
const viewerAnnotation = this._annotationManager.get(annotationId);
|
||||||
|
|
||||||
const document = await this._pdf.PDFDoc;
|
const document = await this._pdf.PDFDoc;
|
||||||
const page = await document.getPage(viewerAnnotation.getPageNumber());
|
const page = await document.getPage(viewerAnnotation.getPageNumber());
|
||||||
|
|||||||
@ -28,39 +28,30 @@ export class AnnotationsListingService extends ListingService<AnnotationWrapper>
|
|||||||
|
|
||||||
selectAnnotations(annotations?: AnnotationWrapper[]) {
|
selectAnnotations(annotations?: AnnotationWrapper[]) {
|
||||||
if (!annotations) {
|
if (!annotations) {
|
||||||
return this._annotationManager.deselectAnnotations();
|
return this._annotationManager.deselect();
|
||||||
}
|
}
|
||||||
|
|
||||||
const annotationsToSelect = this._multiSelectService.isActive ? [...this.selected, ...annotations] : annotations;
|
const annotationsToSelect = this._multiSelectService.isActive ? [...this.selected, ...annotations] : annotations;
|
||||||
this.#selectAnnotations(annotationsToSelect);
|
this.#selectAnnotations(annotationsToSelect);
|
||||||
}
|
}
|
||||||
|
|
||||||
#selectAnnotations(annotations: AnnotationWrapper[] = []) {
|
#selectAnnotations(annotations: AnnotationWrapper[]) {
|
||||||
const filteredAnnotationsIds = annotations.filter(a => !!a).map(a => a.id);
|
if (!annotations.length) {
|
||||||
|
|
||||||
if (!filteredAnnotationsIds.length) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this._multiSelectService.isActive) {
|
if (!this._multiSelectService.isActive) {
|
||||||
this._annotationManager.deselectAnnotations();
|
this._annotationManager.deselect();
|
||||||
}
|
}
|
||||||
|
|
||||||
const pageNumber = annotations[0].pageNumber;
|
const pageNumber = annotations[0].pageNumber;
|
||||||
|
|
||||||
if (pageNumber === this._pdf.currentPage) {
|
if (pageNumber === this._pdf.currentPage) {
|
||||||
return this.#jumpAndSelectAnnotations(filteredAnnotationsIds);
|
return this._annotationManager.jumpAndSelect(annotations);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._pdf.navigateTo(pageNumber);
|
this._pdf.navigateTo(pageNumber);
|
||||||
// wait for page to be loaded and to draw annotations
|
// wait for page to be loaded and to draw annotations
|
||||||
setTimeout(() => this.#jumpAndSelectAnnotations(filteredAnnotationsIds), 300);
|
setTimeout(() => this._annotationManager.jumpAndSelect(annotations), 300);
|
||||||
}
|
|
||||||
|
|
||||||
#jumpAndSelectAnnotations(annotationIds: readonly string[]) {
|
|
||||||
const annotationsFromViewer = this._annotationManager.getAnnotations(annotationIds);
|
|
||||||
|
|
||||||
this._pdf.annotationManager.jumpToAnnotation(annotationsFromViewer[0]);
|
|
||||||
this._pdf.annotationManager.selectAnnotations(annotationsFromViewer);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,11 +28,11 @@ export class SkippedService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _handleIgnoreAnnotationsDrawing(hideSkipped: boolean): void {
|
private _handleIgnoreAnnotationsDrawing(hideSkipped: boolean): void {
|
||||||
const ignored = this._annotationManager.getAnnotations(a => Boolean(a.getCustomData('skipped')));
|
const ignored = this._annotationManager.get(a => Boolean(a.getCustomData('skipped')));
|
||||||
if (hideSkipped) {
|
if (hideSkipped) {
|
||||||
this._annotationManager.hideAnnotations(ignored);
|
this._annotationManager.hide(ignored);
|
||||||
} else {
|
} else {
|
||||||
this._annotationManager.showAnnotations(ignored);
|
this._annotationManager.show(ignored);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,14 @@
|
|||||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, HostBinding, Input, OnChanges, Optional, ViewChild } from '@angular/core';
|
import {
|
||||||
|
ChangeDetectionStrategy,
|
||||||
|
ChangeDetectorRef,
|
||||||
|
Component,
|
||||||
|
HostBinding,
|
||||||
|
Injector,
|
||||||
|
Input,
|
||||||
|
OnChanges,
|
||||||
|
Optional,
|
||||||
|
ViewChild,
|
||||||
|
} from '@angular/core';
|
||||||
import { PermissionsService } from '@services/permissions.service';
|
import { PermissionsService } from '@services/permissions.service';
|
||||||
import { Action, ActionTypes, Dossier, File } from '@red/domain';
|
import { Action, ActionTypes, Dossier, File } from '@red/domain';
|
||||||
import { DossiersDialogService } from '../../services/dossiers-dialog.service';
|
import { DossiersDialogService } from '../../services/dossiers-dialog.service';
|
||||||
@ -36,7 +46,7 @@ import { ROTATION_ACTION_BUTTONS } from '../../../shared/components/pdf-viewer/c
|
|||||||
})
|
})
|
||||||
export class FileActionsComponent implements OnChanges {
|
export class FileActionsComponent implements OnChanges {
|
||||||
readonly circleButtonTypes = CircleButtonTypes;
|
readonly circleButtonTypes = CircleButtonTypes;
|
||||||
readonly currentUser = this._userService.currentUser;
|
readonly currentUser;
|
||||||
|
|
||||||
@Input() file: File;
|
@Input() file: File;
|
||||||
@Input() dossier: Dossier;
|
@Input() dossier: Dossier;
|
||||||
@ -77,24 +87,25 @@ export class FileActionsComponent implements OnChanges {
|
|||||||
private readonly _expandableActionsComponent: ExpandableFileActionsComponent;
|
private readonly _expandableActionsComponent: ExpandableFileActionsComponent;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Optional() private readonly _excludedPagesService: ExcludedPagesService,
|
userService: UserService,
|
||||||
@Optional() private readonly _documentInfoService: DocumentInfoService,
|
private readonly _injector: Injector,
|
||||||
private readonly _pageRotationService: PageRotationService,
|
private readonly _filesService: FilesService,
|
||||||
private readonly _viewerHeaderService: ViewerHeaderService,
|
private readonly _changeRef: ChangeDetectorRef,
|
||||||
private readonly _permissionsService: PermissionsService,
|
private readonly _loadingService: LoadingService,
|
||||||
private readonly _activeDossiersService: ActiveDossiersService,
|
|
||||||
private readonly _dialogService: DossiersDialogService,
|
private readonly _dialogService: DossiersDialogService,
|
||||||
private readonly _fileAssignService: FileAssignService,
|
private readonly _fileAssignService: FileAssignService,
|
||||||
private readonly _loadingService: LoadingService,
|
|
||||||
private readonly _fileManagementService: FileManagementService,
|
|
||||||
private readonly _filesService: FilesService,
|
|
||||||
private readonly _userService: UserService,
|
|
||||||
private readonly _toaster: Toaster,
|
|
||||||
private readonly _userPreferenceService: UserPreferenceService,
|
|
||||||
private readonly _reanalysisService: ReanalysisService,
|
private readonly _reanalysisService: ReanalysisService,
|
||||||
private readonly _router: Router,
|
private readonly _permissionsService: PermissionsService,
|
||||||
private readonly _changeRef: ChangeDetectorRef,
|
private readonly _pageRotationService: PageRotationService,
|
||||||
) {}
|
private readonly _viewerHeaderService: ViewerHeaderService,
|
||||||
|
private readonly _activeDossiersService: ActiveDossiersService,
|
||||||
|
private readonly _fileManagementService: FileManagementService,
|
||||||
|
private readonly _userPreferenceService: UserPreferenceService,
|
||||||
|
@Optional() private readonly _documentInfoService: DocumentInfoService,
|
||||||
|
@Optional() private readonly _excludedPagesService: ExcludedPagesService,
|
||||||
|
) {
|
||||||
|
this.currentUser = userService.currentUser;
|
||||||
|
}
|
||||||
|
|
||||||
@HostBinding('class.keep-visible')
|
@HostBinding('class.keep-visible')
|
||||||
get expanded() {
|
get expanded() {
|
||||||
@ -312,9 +323,9 @@ export class FileActionsComponent implements OnChanges {
|
|||||||
try {
|
try {
|
||||||
const dossier = this._activeDossiersService.find(this.file.dossierId);
|
const dossier = this._activeDossiersService.find(this.file.dossierId);
|
||||||
await firstValueFrom(this._fileManagementService.delete([this.file], this.file.dossierId));
|
await firstValueFrom(this._fileManagementService.delete([this.file], this.file.dossierId));
|
||||||
await this._router.navigate([dossier.routerLink]);
|
await this._injector.get(Router).navigate([dossier.routerLink]);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this._toaster.error(_('error.http.generic'), { params: error });
|
this._injector.get(Toaster).error(_('error.http.generic'), { params: error });
|
||||||
}
|
}
|
||||||
this._loadingService.stop();
|
this._loadingService.stop();
|
||||||
},
|
},
|
||||||
@ -363,10 +374,12 @@ export class FileActionsComponent implements OnChanges {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this._pageRotationService) {
|
|
||||||
await firstValueFrom(this._pageRotationService.showConfirmationDialogIfHasRotations());
|
const pageRotationService = this._injector.get(PageRotationService);
|
||||||
this._viewerHeaderService.disable(ROTATION_ACTION_BUTTONS);
|
await firstValueFrom(pageRotationService.showConfirmationDialogIfHasRotations());
|
||||||
}
|
const viewerHeaderService = this._injector.get(ViewerHeaderService);
|
||||||
|
viewerHeaderService.disable(ROTATION_ACTION_BUTTONS);
|
||||||
|
|
||||||
this._loadingService.start();
|
this._loadingService.start();
|
||||||
await firstValueFrom(this._reanalysisService.ocrFiles([this.file], this.file.dossierId));
|
await firstValueFrom(this._reanalysisService.ocrFiles([this.file], this.file.dossierId));
|
||||||
this._loadingService.stop();
|
this._loadingService.stop();
|
||||||
|
|||||||
@ -2,10 +2,10 @@ import { Injectable } from '@angular/core';
|
|||||||
import { Core } from '@pdftron/webviewer';
|
import { Core } from '@pdftron/webviewer';
|
||||||
import type { List } from '@iqser/common-ui';
|
import type { List } from '@iqser/common-ui';
|
||||||
import { AnnotationPredicate, DeleteAnnotationsOptions } from '@shared/components/pdf-viewer/types';
|
import { AnnotationPredicate, DeleteAnnotationsOptions } from '@shared/components/pdf-viewer/types';
|
||||||
import type { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||||
import { fromEvent, Observable } from 'rxjs';
|
import { fromEvent, Observable } from 'rxjs';
|
||||||
import { tap } from 'rxjs/operators';
|
import { tap } from 'rxjs/operators';
|
||||||
import { getIds } from '@shared/components/pdf-viewer/functions';
|
import { getId, isStringOrWrapper } from '@shared/components/pdf-viewer/functions';
|
||||||
import AnnotationManager = Core.AnnotationManager;
|
import AnnotationManager = Core.AnnotationManager;
|
||||||
import Annotation = Core.Annotations.Annotation;
|
import Annotation = Core.Annotations.Annotation;
|
||||||
|
|
||||||
@ -16,12 +16,12 @@ export class REDAnnotationManager {
|
|||||||
annotationSelected$: Observable<[Annotation[], string]>;
|
annotationSelected$: Observable<[Annotation[], string]>;
|
||||||
#manager: AnnotationManager;
|
#manager: AnnotationManager;
|
||||||
|
|
||||||
get selectedAnnotations() {
|
get selected() {
|
||||||
return this.#manager.getSelectedAnnotations();
|
return this.#manager.getSelectedAnnotations();
|
||||||
}
|
}
|
||||||
|
|
||||||
get annotations() {
|
get annotations() {
|
||||||
return this.#getAnnotations();
|
return this.#get();
|
||||||
}
|
}
|
||||||
|
|
||||||
get #annotationSelected$() {
|
get #annotationSelected$() {
|
||||||
@ -35,57 +35,56 @@ export class REDAnnotationManager {
|
|||||||
this.#autoSelectRectangleAfterCreation();
|
this.#autoSelectRectangleAfterCreation();
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteAnnotation(annotation: AnnotationWrapper | string) {
|
delete(annotations?: List | List<AnnotationWrapper> | string | AnnotationWrapper) {
|
||||||
const id = typeof annotation === 'string' ? annotation : annotation.id;
|
const items = isStringOrWrapper(annotations) ? [this.get(annotations)] : this.get(annotations);
|
||||||
return this.deleteAnnotations([id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteAnnotations(annotations: List<AnnotationWrapper>);
|
|
||||||
|
|
||||||
deleteAnnotations(annotationsIds?: List);
|
|
||||||
|
|
||||||
deleteAnnotations(annotationsIds?: List<string | AnnotationWrapper>) {
|
|
||||||
const annotations = this.getAnnotations(getIds(annotationsIds));
|
|
||||||
const options: DeleteAnnotationsOptions = { force: true };
|
const options: DeleteAnnotationsOptions = { force: true };
|
||||||
this.#manager.deleteAnnotations(annotations, options);
|
this.#manager.deleteAnnotations(items, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
getAnnotations(annotations: List<AnnotationWrapper | string>): Annotation[];
|
get(annotation: AnnotationWrapper | string): Annotation;
|
||||||
|
get(annotations: List | List<AnnotationWrapper>): Annotation[];
|
||||||
|
|
||||||
getAnnotations(predicate?: (value: Annotation) => boolean): Annotation[];
|
get(predicate?: (value: Annotation) => boolean): Annotation[];
|
||||||
|
|
||||||
|
get(argument?: AnnotationPredicate | List<AnnotationWrapper> | List | AnnotationWrapper | string): Annotation | Annotation[] {
|
||||||
|
if (isStringOrWrapper(argument)) {
|
||||||
|
return this.#getById(argument);
|
||||||
|
}
|
||||||
|
|
||||||
getAnnotations(argument?: AnnotationPredicate | List<AnnotationWrapper | string>): Annotation[] {
|
|
||||||
const isList = argument instanceof Array;
|
const isList = argument instanceof Array;
|
||||||
return isList ? this.#getAnnotationsById(getIds(argument)) : this.#getAnnotations(argument);
|
return isList ? this.#getByIds(argument) : this.#get(argument);
|
||||||
}
|
}
|
||||||
|
|
||||||
getAnnotation(annotation: AnnotationWrapper | string) {
|
deselect(annotation: string | AnnotationWrapper);
|
||||||
const id = typeof annotation === 'string' ? annotation : annotation.id;
|
deselect(annotations?: List | List<AnnotationWrapper>);
|
||||||
return this.#manager.getAnnotationById(id);
|
deselect(argument?: string | AnnotationWrapper | List | List<AnnotationWrapper>) {
|
||||||
}
|
if (!argument) {
|
||||||
|
|
||||||
deselectAnnotations(annotations?: List<AnnotationWrapper | string>) {
|
|
||||||
if (!annotations) {
|
|
||||||
return this.#manager.deselectAllAnnotations();
|
return this.#manager.deselectAllAnnotations();
|
||||||
}
|
}
|
||||||
|
|
||||||
const ann = this.#getAnnotationsById(getIds(annotations));
|
const ann = isStringOrWrapper(argument) ? [this.#getById(argument)] : this.#getByIds(argument);
|
||||||
this.#manager.deselectAnnotations(ann);
|
this.#manager.deselectAnnotations(ann);
|
||||||
}
|
}
|
||||||
|
|
||||||
deselectAnnotation(annotation: AnnotationWrapper | string) {
|
hide(annotations: Annotation[]): void {
|
||||||
const id = typeof annotation === 'string' ? annotation : annotation.id;
|
|
||||||
this.deselectAnnotations([id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
hideAnnotations(annotations: Annotation[]): void {
|
|
||||||
this.#manager.hideAnnotations(annotations);
|
this.#manager.hideAnnotations(annotations);
|
||||||
}
|
}
|
||||||
|
|
||||||
showAnnotations(annotations: Annotation[]): void {
|
show(annotations: Annotation[]): void {
|
||||||
this.#manager.showAnnotations(annotations);
|
this.#manager.showAnnotations(annotations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jumpAndSelect(annotations: List | List<AnnotationWrapper>) {
|
||||||
|
const annotationsFromViewer = this.get(annotations);
|
||||||
|
|
||||||
|
this.#manager.jumpToAnnotation(annotationsFromViewer[0]);
|
||||||
|
this.#manager.selectAnnotations(annotationsFromViewer);
|
||||||
|
}
|
||||||
|
|
||||||
|
#getById(annotation: AnnotationWrapper | string) {
|
||||||
|
return this.#manager.getAnnotationById(getId(annotation));
|
||||||
|
}
|
||||||
|
|
||||||
#autoSelectRectangleAfterCreation() {
|
#autoSelectRectangleAfterCreation() {
|
||||||
this.#manager.addEventListener('annotationChanged', (annotations: Annotation[]) => {
|
this.#manager.addEventListener('annotationChanged', (annotations: Annotation[]) => {
|
||||||
// when a rectangle is drawn,
|
// when a rectangle is drawn,
|
||||||
@ -98,11 +97,11 @@ export class REDAnnotationManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#getAnnotationsById(ids: List) {
|
#getByIds(annotations: List | List<AnnotationWrapper>) {
|
||||||
return ids.map(id => this.#manager.getAnnotationById(id)).filter(a => !!a);
|
return annotations.map((item: string | AnnotationWrapper) => this.#getById(item)).filter(a => !!a);
|
||||||
}
|
}
|
||||||
|
|
||||||
#getAnnotations(predicate?: AnnotationPredicate) {
|
#get(predicate?: AnnotationPredicate) {
|
||||||
const annotations = this.#manager.getAnnotationsList();
|
const annotations = this.#manager.getAnnotationsList();
|
||||||
return predicate ? annotations.filter(predicate) : annotations;
|
return predicate ? annotations.filter(predicate) : annotations;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,10 +13,28 @@ export function stopAndPreventIfNotAllowed($event: KeyboardEvent) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getIds(items?: List<string | AnnotationWrapper>): List | undefined {
|
export function getId(item: string | AnnotationWrapper) {
|
||||||
return items?.map(value => (typeof value === 'string' ? value : value.id));
|
return typeof item === 'string' ? item : item.annotationId;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function asList(dataElements: string[] | string): string[] {
|
export function getIds(items?: List | List<AnnotationWrapper>): List | undefined {
|
||||||
return typeof dataElements === 'string' ? [dataElements] : dataElements;
|
return items?.map(getId);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isStringOrWrapper(value: unknown): value is string | AnnotationWrapper {
|
||||||
|
return typeof value === 'string' || value instanceof AnnotationWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function asList(items: string[] | string): string[];
|
||||||
|
export function asList(items: AnnotationWrapper[] | AnnotationWrapper): AnnotationWrapper[];
|
||||||
|
export function asList(items: string[] | string | AnnotationWrapper[] | AnnotationWrapper): string[] | AnnotationWrapper[] {
|
||||||
|
if (typeof items === 'string') {
|
||||||
|
return [items];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (items instanceof AnnotationWrapper) {
|
||||||
|
return [items];
|
||||||
|
}
|
||||||
|
|
||||||
|
return items;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable, Injector } from '@angular/core';
|
||||||
import { BehaviorSubject, firstValueFrom, of } from 'rxjs';
|
import { BehaviorSubject, firstValueFrom, of } from 'rxjs';
|
||||||
import { RotationType, RotationTypes } from '@red/domain';
|
import { RotationType, RotationTypes } from '@red/domain';
|
||||||
import { FileManagementService } from '../../../../services/files/file-management.service';
|
import { FileManagementService } from '../../../../services/files/file-management.service';
|
||||||
@ -28,15 +28,19 @@ export class PageRotationService {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly _pdf: PdfViewer,
|
private readonly _pdf: PdfViewer,
|
||||||
private readonly _dialog: MatDialog,
|
|
||||||
private readonly _loadingService: LoadingService,
|
private readonly _loadingService: LoadingService,
|
||||||
private readonly _activatedRoute: ActivatedRoute,
|
private readonly _activatedRoute: ActivatedRoute,
|
||||||
private readonly _logger: NGXLogger,
|
private readonly _logger: NGXLogger,
|
||||||
|
private readonly _injector: Injector,
|
||||||
private readonly _fileManagementService: FileManagementService,
|
private readonly _fileManagementService: FileManagementService,
|
||||||
private readonly _filesService: FilesService,
|
private readonly _filesService: FilesService,
|
||||||
private readonly _filesMapService: FilesMapService,
|
private readonly _filesMapService: FilesMapService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
get hasRotations() {
|
||||||
|
return Object.values(this.#rotations$.value).filter(v => !!v).length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
isRotated$(page: number) {
|
isRotated$(page: number) {
|
||||||
return this.#rotations$.pipe(
|
return this.#rotations$.pipe(
|
||||||
map(rotations => !!rotations[page]),
|
map(rotations => !!rotations[page]),
|
||||||
@ -44,10 +48,6 @@ export class PageRotationService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
hasRotations() {
|
|
||||||
return Object.values(this.#rotations$.value).filter(v => !!v).length > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
applyRotation() {
|
applyRotation() {
|
||||||
this._loadingService.start();
|
this._loadingService.start();
|
||||||
const pages = this.#rotations$.value;
|
const pages = this.#rotations$.value;
|
||||||
@ -104,11 +104,11 @@ export class PageRotationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
showConfirmationDialogIfHasRotations() {
|
showConfirmationDialogIfHasRotations() {
|
||||||
return this.hasRotations() ? this.#showConfirmationDialog() : of(ConfirmOptions.DISCARD_CHANGES);
|
return this.hasRotations ? this.#showConfirmationDialog() : of(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#showConfirmationDialog() {
|
#showConfirmationDialog() {
|
||||||
const ref = this._dialog.open(ConfirmationDialogComponent, {
|
const ref = this._injector.get(MatDialog).open(ConfirmationDialogComponent, {
|
||||||
...defaultDialogConfig,
|
...defaultDialogConfig,
|
||||||
data: new ConfirmationDialogInput({
|
data: new ConfirmationDialogInput({
|
||||||
title: _('page-rotation.confirmation-dialog.title'),
|
title: _('page-rotation.confirmation-dialog.title'),
|
||||||
@ -118,8 +118,8 @@ export class PageRotationService {
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
return ref
|
const closed$ = ref.afterClosed().pipe(map((option: ConfirmOptions) => option === ConfirmOptions.CONFIRM));
|
||||||
.afterClosed()
|
|
||||||
.pipe(tap((option: ConfirmOptions) => (option === ConfirmOptions.CONFIRM ? this.applyRotation() : this.discardRotation())));
|
return closed$.pipe(tap(apply => (apply ? this.applyRotation() : this.discardRotation())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -141,7 +141,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(tap(() => this._annotationManager.deselectAnnotations()));
|
return page$.pipe(tap(() => this._annotationManager.deselect()));
|
||||||
}
|
}
|
||||||
|
|
||||||
navigateTo(page: string | number) {
|
navigateTo(page: string | number) {
|
||||||
|
|||||||
@ -170,7 +170,7 @@ export class ViewerHeaderService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#toggleRotationActionButtons() {
|
#toggleRotationActionButtons() {
|
||||||
if (this._rotationService.hasRotations()) {
|
if (this._rotationService.hasRotations) {
|
||||||
this.enable(ROTATION_ACTION_BUTTONS);
|
this.enable(ROTATION_ACTION_BUTTONS);
|
||||||
} else {
|
} else {
|
||||||
this.disable(ROTATION_ACTION_BUTTONS);
|
this.disable(ROTATION_ACTION_BUTTONS);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user