show confirmation dialog when there are unapplied rotations

This commit is contained in:
Dan Percic 2022-03-08 15:21:14 +02:00
parent 7baa9b9f56
commit b78620b8a7
6 changed files with 96 additions and 41 deletions

View File

@ -358,7 +358,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
dataElement: HeaderElements.APPLY_ROTATION,
render: () => {
const paragraph = document.createElement('p');
paragraph.innerText = 'APPLY';
paragraph.innerText = this._translateService.instant('page-rotation.apply');
paragraph.style.cssText = `
font-size: 11px;
font-weight: 600;
@ -377,7 +377,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
dataElement: HeaderElements.DISCARD_ROTATION,
render: () => {
const paragraph = document.createElement('p');
paragraph.innerText = 'DISCARD';
paragraph.innerText = this._translateService.instant('page-rotation.discard');
paragraph.style.cssText = `
font-size: 11px;
font-weight: 600;

View File

@ -50,6 +50,7 @@ import { FilePreviewStateService } from './services/file-preview-state.service';
import { FileDataModel } from '../../../../models/file/file-data.model';
import { filePreviewScreenProviders } from './file-preview-providers';
import { ManualAnnotationService } from '../../services/manual-annotation.service';
import { PageRotationService } from './services/page-rotation.service';
import Annotation = Core.Annotations.Annotation;
import PDFNet = Core.PDFNet;
@ -106,6 +107,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
private readonly _dossiersService: DossiersService,
private readonly _reanalysisService: ReanalysisService,
private readonly _errorService: ErrorService,
private readonly _pageRotationService: PageRotationService,
private readonly _skippedService: SkippedService,
private readonly _manualAnnotationService: ManualAnnotationService,
readonly excludedPagesService: ExcludedPagesService,
@ -215,6 +217,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
}
ngOnDetach(): void {
this._pageRotationService.clearRotations();
this.displayPdfViewer = false;
super.ngOnDetach();
this._changeDetectorRef.markForCheck();
@ -387,11 +390,12 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
}
}
viewerPageChanged($event: any) {
async viewerPageChanged($event: any) {
if (typeof $event !== 'number') {
return;
}
await firstValueFrom(this._pageRotationService.showConfirmationDialogIfHasRotations());
this._scrollViews();
this.multiSelectService.deactivate();
@ -401,7 +405,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
queryParamsHandling: 'merge',
replaceUrl: true,
};
this._router.navigate([], extras).then();
await this._router.navigate([], extras);
this._setActiveViewerPage();
this._changeDetectorRef.markForCheck();

View File

@ -1,70 +1,78 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject, firstValueFrom } from 'rxjs';
import { BehaviorSubject, firstValueFrom, of } from 'rxjs';
import { PermissionsService } from '@services/permissions.service';
import { RotationType, RotationTypes } from '@red/domain';
import { FileManagementService } from '@services/entity-services/file-management.service';
import { FilePreviewStateService } from './file-preview-state.service';
import { distinctUntilChanged, map } from 'rxjs/operators';
import { distinctUntilChanged, map, tap } from 'rxjs/operators';
import { PdfViewer } from './pdf-viewer.service';
import { HeaderElements } from '../shared/constants';
import {
ConfirmationDialogComponent,
ConfirmationDialogInput,
ConfirmOptions,
defaultDialogConfig,
LoadingService,
} from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { MatDialog } from '@angular/material/dialog';
const confirmationButtons = [HeaderElements.APPLY_ROTATION, HeaderElements.DISCARD_ROTATION];
const actionButtons = [HeaderElements.APPLY_ROTATION, HeaderElements.DISCARD_ROTATION];
const oneRotationDegree = 90;
@Injectable()
export class PageRotationService {
readonly rotations$ = new BehaviorSubject<Record<number, number>>({});
readonly #rotations$ = new BehaviorSubject<Record<number, number>>({});
constructor(
private readonly _pdf: PdfViewer,
private readonly _dialog: MatDialog,
private readonly _loadingService: LoadingService,
private readonly _screenState: FilePreviewStateService,
private readonly _permissionsService: PermissionsService,
private readonly _fileManagementService: FileManagementService,
private readonly _screenState: FilePreviewStateService,
private readonly _pdf: PdfViewer,
) {}
get canRotate() {
return this._screenState.file.then(file => this._permissionsService.isFileAssignee(file));
}
isRotated(page: number) {
return this.rotations$.pipe(
return this.#rotations$.pipe(
map(rotations => !!rotations[page]),
distinctUntilChanged(),
);
}
hasRotations() {
return Object.values(this.rotations$.value).filter(v => !!v).length > 0;
return Object.values(this.#rotations$.value).filter(v => !!v).length > 0;
}
applyRotation() {
const pages = this.rotations$.value;
this._loadingService.start();
const pages = this.#rotations$.value;
const { dossierId, fileId } = this._screenState;
const request = this._fileManagementService.rotatePage({ pages }, dossierId, fileId);
this.clearRotations();
this.clearRotationsHideActions();
return firstValueFrom(request);
return firstValueFrom(request.pipe(tap(() => this._loadingService.stop())));
}
discardRotation() {
const rotations = this.rotations$.value;
const rotations = this.#rotations$.value;
for (const page of Object.keys(rotations)) {
const times = rotations[page] / oneRotationDegree;
for (let i = 1; i <= times; i++) {
this._pdf.documentViewer.rotateCounterClockwise(Number(page));
this._pdf?.documentViewer?.rotateCounterClockwise(Number(page));
}
}
this.clearRotations();
this.clearRotationsHideActions();
}
addRotation(rotation: RotationType): void {
const pageNumber = this._pdf.currentPage;
const pageRotation = this.rotations$.value[pageNumber];
const pageRotation = this.#rotations$.value[pageNumber];
const rotationValue = pageRotation ? (pageRotation + Number(rotation)) % 360 : rotation;
this.rotations$.next({ ...this.rotations$.value, [pageNumber]: rotationValue });
this.#rotations$.next({ ...this.#rotations$.value, [pageNumber]: rotationValue });
if (rotation === RotationTypes.LEFT) {
this._pdf.documentViewer.rotateCounterClockwise(pageNumber);
@ -73,22 +81,46 @@ export class PageRotationService {
}
if (this.hasRotations()) {
this.#showConfirmationButtons();
this.#showActionButtons();
} else {
this.#hideConfirmationButtons();
this.#hideActionButtons();
}
}
clearRotations() {
this.rotations$.next({});
this.#hideConfirmationButtons();
this.#rotations$.next({});
}
#showConfirmationButtons() {
this._pdf.UI.enableElements(confirmationButtons);
clearRotationsHideActions() {
this.clearRotations();
this.#hideActionButtons();
}
#hideConfirmationButtons() {
this._pdf.UI.disableElements(confirmationButtons);
showConfirmationDialog() {
const ref = this._dialog.open(ConfirmationDialogComponent, {
...defaultDialogConfig,
data: new ConfirmationDialogInput({
title: _('page-rotation.confirmation-dialog.title'),
question: _('page-rotation.confirmation-dialog.question'),
confirmationText: _('page-rotation.apply'),
discardChangesText: _('page-rotation.discard'),
}),
});
return ref
.afterClosed()
.pipe(tap((option: ConfirmOptions) => (option === ConfirmOptions.CONFIRM ? this.applyRotation() : this.discardRotation())));
}
showConfirmationDialogIfHasRotations() {
return this.hasRotations() ? this.showConfirmationDialog() : of(ConfirmOptions.DISCARD_CHANGES);
}
#showActionButtons() {
this._pdf.UI.enableElements(actionButtons);
}
#hideActionButtons() {
this._pdf.UI.disableElements(actionButtons);
}
}

View File

@ -39,6 +39,7 @@ import { DocumentInfoService } from '../../../screens/file-preview-screen/servic
import { ExpandableFileActionsComponent } from '@shared/components/expandable-file-actions/expandable-file-actions.component';
import { firstValueFrom } from 'rxjs';
import { RedactionImportService } from '../../services/redaction-import.service';
import { PageRotationService } from '../../../screens/file-preview-screen/services/page-rotation.service';
@Component({
selector: 'redaction-file-actions [file] [type]',
@ -92,6 +93,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
constructor(
@Optional() private readonly _excludedPagesService: ExcludedPagesService,
@Optional() private readonly _documentInfoService: DocumentInfoService,
@Optional() private readonly _pageRotationService: PageRotationService,
private readonly _permissionsService: PermissionsService,
private readonly _dossiersService: DossiersService,
private readonly _dialogService: DossiersDialogService,
@ -200,7 +202,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
},
{
type: ActionTypes.circleBtn,
action: $event => this.toggleAutomaticAnalysis($event),
action: $event => this._toggleAutomaticAnalysis($event),
tooltip: _('dossier-overview.stop-auto-analysis'),
icon: 'red:disable-analysis',
show: this.canDisableAutoAnalysis,
@ -215,7 +217,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
},
{
type: ActionTypes.circleBtn,
action: $event => this.toggleAutomaticAnalysis($event),
action: $event => this._toggleAutomaticAnalysis($event),
tooltip: _('dossier-overview.start-auto-analysis'),
buttonType: this.isFilePreview ? CircleButtonTypes.warn : CircleButtonTypes.default,
icon: 'red:enable-analysis',
@ -363,7 +365,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
await firstValueFrom(this._reanalysisService.reanalyzeFilesForDossier([this.file.fileId], this.file.dossierId, params));
}
private async toggleAutomaticAnalysis($event: MouseEvent) {
private async _toggleAutomaticAnalysis($event: MouseEvent) {
$event.stopPropagation();
this._loadingService.start();
await firstValueFrom(this._reanalysisService.toggleAutomaticAnalysis(this.file.dossierId, [this.file]));
@ -377,6 +379,9 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
private async _ocrFile($event: MouseEvent) {
$event.stopPropagation();
if (this._pageRotationService) {
await firstValueFrom(this._pageRotationService.showConfirmationDialogIfHasRotations());
}
this._loadingService.start();
await firstValueFrom(this._reanalysisService.ocrFiles([this.file.fileId], this.file.dossierId));
this._loadingService.stop();

View File

@ -733,7 +733,6 @@
"documents-status": "",
"dossier-status": "",
"name": "Name",
"last-modified": "",
"needs-work": "Arbeitsvorrat",
"owner": "Besitzer"
},
@ -754,7 +753,6 @@
"delete": {
"action": "Datei löschen"
},
"stop-auto-analysis": "",
"dossier-details": {
"attributes": {
"expand": "{count} {count, plural, one{benutzerdefiniertes Attribut} other{benutzerdefinierte Attribute}}",
@ -778,7 +776,6 @@
},
"download-file": "Herunterladen",
"download-file-disabled": "Nur genehmigte Dateien können heruntergeladen werden",
"start-auto-analysis": "",
"file-listing": {
"file-entry": {
"file-error": "Reanalyse erforderlich",
@ -824,6 +821,8 @@
"reanalyse": {
"action": "Datei analysieren"
},
"start-auto-analysis": "",
"stop-auto-analysis": "",
"table-col-names": {
"added-on": "Hinzugefügt",
"assigned-to": "Zugewiesen an",
@ -1573,6 +1572,14 @@
"title": "Das Dokument existiert bereits!"
},
"page": "Seite",
"page-rotation": {
"apply": "",
"confirmation-dialog": {
"question": "",
"title": ""
},
"discard": ""
},
"pagination": {
"next": "Nächste",
"previous": "Vorherige"

View File

@ -733,7 +733,6 @@
"documents-status": "Documents Status",
"dossier-status": "Dossier Status",
"name": "Name",
"last-modified": "Last modified",
"needs-work": "Workload",
"owner": "Owner"
},
@ -754,7 +753,6 @@
"delete": {
"action": "Delete File"
},
"stop-auto-analysis": "Stop auto-analysis",
"dossier-details": {
"attributes": {
"expand": "{count} custom {count, plural, one{attribute} other{attributes}}",
@ -778,7 +776,6 @@
},
"download-file": "Download",
"download-file-disabled": "You need to be approver in the dossier and the {count, plural, one{file needs} other{files need}} to be approved in order to download.",
"start-auto-analysis": "Start auto-analysis",
"file-listing": {
"file-entry": {
"file-error": "Re-processing required",
@ -824,6 +821,8 @@
"reanalyse": {
"action": "Analyze File"
},
"start-auto-analysis": "Start auto-analysis",
"stop-auto-analysis": "Stop auto-analysis",
"table-col-names": {
"added-on": "Added",
"assigned-to": "Assigned to",
@ -1573,6 +1572,14 @@
"title": "Document already exists!"
},
"page": "Page",
"page-rotation": {
"apply": "APPLY",
"confirmation-dialog": {
"question": "You have unapplied page rotations. Choose how to proceed:",
"title": "Pending page rotations"
},
"discard": "DISCARD"
},
"pagination": {
"next": "Next",
"previous": "Prev"