From 2a6859b5847fa1fed5d09a80512291f28263beed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Tue, 27 Oct 2020 04:02:15 +0200 Subject: [PATCH] Some arrow navigation fixes --- apps/red-ui/src/app/dialogs/dialog.service.ts | 111 +++++++++++------- .../file-preview-screen.component.html | 8 +- .../file-preview-screen.component.scss | 1 + .../file-preview-screen.component.ts | 31 +++-- 4 files changed, 93 insertions(+), 58 deletions(-) diff --git a/apps/red-ui/src/app/dialogs/dialog.service.ts b/apps/red-ui/src/app/dialogs/dialog.service.ts index 14629083d..be912d86c 100644 --- a/apps/red-ui/src/app/dialogs/dialog.service.ts +++ b/apps/red-ui/src/app/dialogs/dialog.service.ts @@ -1,6 +1,6 @@ -import {Injectable} from '@angular/core'; -import {FileDetailsDialogComponent} from './file-details-dialog/file-details-dialog.component'; -import {MatDialog} from '@angular/material/dialog'; +import { Injectable } from '@angular/core'; +import { FileDetailsDialogComponent } from './file-details-dialog/file-details-dialog.component'; +import { MatDialog, MatDialogRef } from '@angular/material/dialog'; import { FileStatus, FileUploadControllerService, @@ -8,15 +8,15 @@ import { ManualRedactionEntry, Project } from '@redaction/red-ui-http'; -import {ConfirmationDialogComponent} from '../common/confirmation-dialog/confirmation-dialog.component'; -import {NotificationService, NotificationType} from '../notification/notification.service'; -import {TranslateService} from '@ngx-translate/core'; -import {AppStateService, ProjectWrapper} from '../state/app-state.service'; -import {AddEditProjectDialogComponent} from './add-edit-project-dialog/add-edit-project-dialog.component'; -import {AssignOwnerDialogComponent} from './assign-owner-dialog/assign-owner-dialog.component'; -import {ProjectDetailsDialogComponent} from './project-details-dialog/project-details-dialog.component'; -import {ManualRedactionDialogComponent} from './manual-redaction-dialog/manual-redaction-dialog.component'; -import {Annotations} from '@pdftron/webviewer'; +import { ConfirmationDialogComponent } from '../common/confirmation-dialog/confirmation-dialog.component'; +import { NotificationService, NotificationType } from '../notification/notification.service'; +import { TranslateService } from '@ngx-translate/core'; +import { AppStateService, ProjectWrapper } from '../state/app-state.service'; +import { AddEditProjectDialogComponent } from './add-edit-project-dialog/add-edit-project-dialog.component'; +import { AssignOwnerDialogComponent } from './assign-owner-dialog/assign-owner-dialog.component'; +import { ProjectDetailsDialogComponent } from './project-details-dialog/project-details-dialog.component'; +import { ManualRedactionDialogComponent } from './manual-redaction-dialog/manual-redaction-dialog.component'; +import { Annotations } from '@pdftron/webviewer'; const dialogConfig = { width: '600px', @@ -38,17 +38,19 @@ export class DialogService { } - public openFileDetailsDialog($event: MouseEvent, file: FileStatus) { + public openFileDetailsDialog($event: MouseEvent, file: FileStatus): MatDialogRef { $event.stopPropagation(); - this._dialog.open(FileDetailsDialogComponent, { + return this._dialog.open(FileDetailsDialogComponent, { ...dialogConfig, data: file }); } - public openDeleteFileDialog($event: MouseEvent, projectId: string, fileId: string, cb?: Function) { + public openDeleteFileDialog($event: MouseEvent, projectId: string, fileId: string, cb?: Function): MatDialogRef { $event.stopPropagation(); - this._dialog.open(ConfirmationDialogComponent, dialogConfig).afterClosed().subscribe(result => { + const ref = this._dialog.open(ConfirmationDialogComponent, dialogConfig); + + ref.afterClosed().subscribe(result => { if (result) { const file = this._appStateService.getFileById(projectId, fileId); this._fileUploadControllerService.deleteFile(file.projectId, file.fileId).subscribe(async () => { @@ -62,28 +64,34 @@ export class DialogService { }); } }); + + return ref; } - public openManualRedactionDialog($event: ManualRedactionEntry, cb?: Function) { - this._dialog.open(ManualRedactionDialogComponent, { + public openManualRedactionDialog($event: ManualRedactionEntry, cb?: Function): MatDialogRef { + const ref = this._dialog.open(ManualRedactionDialogComponent, { ...dialogConfig, autoFocus: true, data: $event - }).afterClosed().subscribe(result => { + }); + + ref.afterClosed().subscribe(result => { if (cb) { cb(result); } }); + + return ref; } - public acceptSuggestionAnnotation($event: MouseEvent, annotation: Annotations.Annotation, projectId: string, fileId: string) { + public acceptSuggestionAnnotation($event: MouseEvent, annotation: Annotations.Annotation, projectId: string, fileId: string): MatDialogRef { $event.stopPropagation(); const parts = annotation.Id.split(':'); const annotationId = parts[parts.length - 1]; - this._dialog.open(ConfirmationDialogComponent, dialogConfig) - .afterClosed().subscribe(result => { + const ref = this._dialog.open(ConfirmationDialogComponent, dialogConfig); + ref.afterClosed().subscribe(result => { if (result) { this._manualRedactionControllerService.approveRequest(projectId, fileId, annotationId).subscribe(() => { this._notificationService.showToastNotification(this._translateService.instant('manual-redaction.confirm-annotation.success.label'), null, NotificationType.SUCCESS); @@ -92,18 +100,22 @@ export class DialogService { }); } }); + + return ref; } - public suggestRemoveAnnotation($event: MouseEvent, annotation: Annotations.Annotation, projectId: string, fileId: string) { + public suggestRemoveAnnotation($event: MouseEvent, annotation: Annotations.Annotation, projectId: string, fileId: string): MatDialogRef { $event.stopPropagation(); const parts = annotation.Id.split(':'); const annotationId = parts[parts.length - 1]; - this._dialog.open(ConfirmationDialogComponent, { + const ref = this._dialog.open(ConfirmationDialogComponent, { width: '400px', maxWidth: '90vw' - }).afterClosed().subscribe(result => { + }); + + ref.afterClosed().subscribe(result => { if (result) { this._manualRedactionControllerService.undo(projectId, fileId, annotationId).subscribe(ok => { this._notificationService.showToastNotification(this._translateService.instant('manual-redaction.remove-annotation.success.label'), null, NotificationType.SUCCESS); @@ -113,63 +125,74 @@ export class DialogService { } }); + return ref; } - public openEditProjectDialog($event: MouseEvent, project: Project) { + public openEditProjectDialog($event: MouseEvent, project: Project): MatDialogRef { $event.stopPropagation(); - this._dialog.open(AddEditProjectDialogComponent, { + return this._dialog.open(AddEditProjectDialogComponent, { ...dialogConfig, autoFocus: true, data: project }); } - public openDeleteProjectDialog($event: MouseEvent, project: Project, cb?: Function) { + public openDeleteProjectDialog($event: MouseEvent, project: Project, cb?: Function): MatDialogRef { $event.stopPropagation(); - this._dialog.open(ConfirmationDialogComponent, dialogConfig) - .afterClosed().subscribe(async result => { + const ref = this._dialog.open(ConfirmationDialogComponent, dialogConfig); + ref.afterClosed().subscribe(async result => { if (result) { await this._appStateService.deleteProject(project); if (cb) cb(); } }); + return ref; } - public openAssignProjectMembersAndOwnerDialog($event: MouseEvent, project: Project, cb?: Function) { + public openAssignProjectMembersAndOwnerDialog($event: MouseEvent, project: Project, cb?: Function): MatDialogRef { $event?.stopPropagation(); - this._dialog.open(AssignOwnerDialogComponent, { + const ref = this._dialog.open(AssignOwnerDialogComponent, { ...dialogConfig, - data: {type: 'project', project: project} - }).afterClosed().subscribe(result => { + data: { type: 'project', project: project } + }); + ref.afterClosed().subscribe(result => { if (result && cb) cb(); }); + return ref; } - public openAssignFileOwnerDialog($event: MouseEvent, file: FileStatus, cb?: Function) { + public openAssignFileOwnerDialog($event: MouseEvent, file: FileStatus, cb?: Function): MatDialogRef { $event.stopPropagation(); - this._dialog.open(AssignOwnerDialogComponent, { + const ref = this._dialog.open(AssignOwnerDialogComponent, { ...dialogConfig, - data: {type: 'file', file: file} - }).afterClosed().subscribe(() => { + data: { type: 'file', file: file } + }); + + ref.afterClosed().subscribe(() => { if (cb) cb(); }); + + return ref; } - public openProjectDetailsDialog($event: MouseEvent, project: ProjectWrapper) { + public openProjectDetailsDialog($event: MouseEvent, project: ProjectWrapper): MatDialogRef { $event.stopPropagation(); - this._dialog.open(ProjectDetailsDialogComponent, { + return this._dialog.open(ProjectDetailsDialogComponent, { ...dialogConfig, data: project }); } - public openAddProjectDialog(cb?: Function): void { - this._dialog.open(AddEditProjectDialogComponent, { + public openAddProjectDialog(cb?: Function): MatDialogRef { + const ref = this._dialog.open(AddEditProjectDialogComponent, { ...dialogConfig, autoFocus: true - }).afterClosed().subscribe(result => { + }); + + ref.afterClosed().subscribe(result => { if (result && cb) cb(); }); - } + return ref; + } } diff --git a/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.html b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.html index 92fe4d1f8..e792e566b 100644 --- a/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.html +++ b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.html @@ -127,7 +127,9 @@
diff --git a/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.scss b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.scss index 491fa77d4..07cda4c1f 100644 --- a/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.scss +++ b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.scss @@ -63,6 +63,7 @@ redaction-pdf-viewer { .pages, .annotations { overflow-y: scroll; @include no-scroll-bar(); + outline: none; &.activePanel { background-color: #FAFAFA; diff --git a/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.ts b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.ts index 58371212b..651ef114e 100644 --- a/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.ts +++ b/apps/red-ui/src/app/screens/file/file-preview-screen/file-preview-screen.component.ts @@ -14,6 +14,7 @@ import { FileDownloadService } from '../service/file-download.service'; import { saveAs } from 'file-saver'; import { FileType } from '../model/file-type'; import { DialogService } from '../../../dialogs/dialog.service'; +import { MatDialogRef, MatDialogState } from '@angular/material/dialog'; @Component({ selector: 'redaction-file-preview-screen', @@ -25,6 +26,7 @@ export class FilePreviewScreenComponent implements OnInit { private projectId: string; private _activeViewer: 'ANNOTATED' | 'REDACTED' = 'ANNOTATED'; private instance: WebViewerInstance; + private _dialogRef: MatDialogRef; @ViewChild(PdfViewerComponent) private _viewerComponent: PdfViewerComponent; @ViewChild('annotations') private _annotationsElement: ElementRef; @@ -37,7 +39,7 @@ export class FilePreviewScreenComponent implements OnInit { public displayedAnnotations: { [key: number]: { annotations: Annotations.Annotation[] } } = {}; public selectedAnnotation: Annotations.Annotation; public filters: AnnotationFilters; - public expandedFilters: AnnotationFilters = {hint: false}; + public expandedFilters: AnnotationFilters = { hint: false }; public pagesPanelActive = true; constructor( @@ -84,11 +86,11 @@ export class FilePreviewScreenComponent implements OnInit { localStorage.clear(); this._reloadFiles(); this.appStateService.fileStatusChanged.subscribe((fileStatus) => { - if(fileStatus.fileId === this.fileId) { + if (fileStatus.fileId === this.fileId) { console.log(fileStatus); this._reloadFiles(); } - }) + }); } private _reloadFiles() { @@ -103,7 +105,7 @@ export class FilePreviewScreenComponent implements OnInit { } public openFileDetailsDialog($event: MouseEvent) { - this._dialogService.openFileDetailsDialog($event, this.appStateService.activeFile); + this._dialogRef = this._dialogService.openFileDetailsDialog($event, this.appStateService.activeFile); } public reanalyseFile($event: MouseEvent) { @@ -114,17 +116,16 @@ export class FilePreviewScreenComponent implements OnInit { } public openDeleteFileDialog($event: MouseEvent) { - this._dialogService.openDeleteFileDialog($event, this.projectId, this.fileId, () => { + this._dialogRef = this._dialogService.openDeleteFileDialog($event, this.projectId, this.fileId, () => { this._router.navigate([`/ui/projects/${this.projectId}`]); }); } public openAssignFileOwnerDialog($event: MouseEvent) { const file = this.appStateService.getFileById(this.projectId, this.fileId); - this._dialogService.openAssignFileOwnerDialog($event, file); + this._dialogRef = this._dialogService.openAssignFileOwnerDialog($event, file); } - public get activeViewer() { return this.instance; } @@ -162,7 +163,7 @@ export class FilePreviewScreenComponent implements OnInit { public openManualRedactionDialog($event: ManualRedactionEntry) { this.ngZone.run(() => { - this._dialogService.openManualRedactionDialog($event, () => { + this._dialogRef = this._dialogService.openManualRedactionDialog($event, () => { }); }); @@ -212,13 +213,13 @@ export class FilePreviewScreenComponent implements OnInit { public acceptSuggestionAnnotation($event: MouseEvent, annotation: Annotations.Annotation) { this.ngZone.run(() => { - this._dialogService.acceptSuggestionAnnotation($event, annotation, this.projectId, this.fileId); + this._dialogRef = this._dialogService.acceptSuggestionAnnotation($event, annotation, this.projectId, this.fileId); }); } public suggestRemoveAnnotation($event: MouseEvent, annotation: Annotations.Annotation) { this.ngZone.run(() => { - this._dialogService.suggestRemoveAnnotation($event, annotation, this.projectId, this.fileId); + this._dialogRef = this._dialogService.suggestRemoveAnnotation($event, annotation, this.projectId, this.fileId); }); } @@ -272,6 +273,12 @@ export class FilePreviewScreenComponent implements OnInit { @HostListener('window:keyup', ['$event']) handleKeyEvent($event: KeyboardEvent) { + const keyArray = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown']; + + if (!keyArray.includes($event.key) || this._dialogRef?.getState() === MatDialogState.OPEN) { + return; + } + if ($event.key === 'ArrowLeft' || $event.key === 'ArrowRight') { this.pagesPanelActive = !this.pagesPanelActive; this._changeDetectorRef.detectChanges(); @@ -391,9 +398,9 @@ export class FilePreviewScreenComponent implements OnInit { // handle comments annotations.forEach(a => { a['comments'] = a['Mi'] ? a['Mi'].map(m => { - return {value: m.eC} + return { value: m.eC }; }) : []; - }) + }); AnnotationUtils.addAnnotations(this.annotations, annotations); this.applyFilters();