From a8727c1d5b0408d3145469074e3b494c32dc97a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Thu, 22 Oct 2020 00:16:27 +0300 Subject: [PATCH] Moved some dialogs into a service --- .../add-edit-project-dialog.component.ts | 2 +- apps/red-ui/src/app/dialogs/dialog.service.ts | 78 +++++++++++++++++++ .../file-preview-screen.component.html | 25 ++++-- .../file-preview-screen.component.ts | 26 +++++-- .../project-listing-screen.component.ts | 26 ++++--- .../project-overview-screen.component.ts | 44 +++-------- .../red-ui/src/app/state/app-state.service.ts | 8 +- apps/red-ui/src/assets/icons/general/info.svg | 21 ++--- .../src/assets/styles/red-page-layout.scss | 6 -- 9 files changed, 153 insertions(+), 83 deletions(-) create mode 100644 apps/red-ui/src/app/dialogs/dialog.service.ts diff --git a/apps/red-ui/src/app/dialogs/add-edit-project-dialog/add-edit-project-dialog.component.ts b/apps/red-ui/src/app/dialogs/add-edit-project-dialog/add-edit-project-dialog.component.ts index 960c3e542..7704ac224 100644 --- a/apps/red-ui/src/app/dialogs/add-edit-project-dialog/add-edit-project-dialog.component.ts +++ b/apps/red-ui/src/app/dialogs/add-edit-project-dialog/add-edit-project-dialog.component.ts @@ -32,7 +32,7 @@ export class AddEditProjectDialogComponent implements OnInit { const project: Project = this._formToObject(); project.projectId = this.project?.projectId; await this._appStateService.addOrUpdateProject(project); - this.dialogRef.close(); + this.dialogRef.close(true); } private _formToObject(): Project { diff --git a/apps/red-ui/src/app/dialogs/dialog.service.ts b/apps/red-ui/src/app/dialogs/dialog.service.ts new file mode 100644 index 000000000..701c3908f --- /dev/null +++ b/apps/red-ui/src/app/dialogs/dialog.service.ts @@ -0,0 +1,78 @@ +import { Injectable } from '@angular/core'; +import { FileDetailsDialogComponent } from './file-details-dialog/file-details-dialog.component'; +import { MatDialog } from '@angular/material/dialog'; +import { FileStatus, FileUploadControllerService, 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 } from '../state/app-state.service'; +import { AddEditProjectDialogComponent } from './add-edit-project-dialog/add-edit-project-dialog.component'; + +const dialogConfig = { + width: '600px', + maxWidth: '90vw' +}; + +@Injectable({ + providedIn: 'root' +}) +export class DialogService { + + constructor(private readonly _dialog: MatDialog, + private readonly _translateService: TranslateService, + private readonly _appStateService: AppStateService, + private readonly _fileUploadControllerService: FileUploadControllerService, + private readonly _notificationService: NotificationService) { + + } + + public openFileDetailsDialog($event: MouseEvent, file: FileStatus) { + $event.stopPropagation(); + this._dialog.open(FileDetailsDialogComponent, { + ...dialogConfig, + data: file + }); + } + + public openDeleteFileDialog($event: MouseEvent, projectId: string, fileId: string, cb?: Function) { + $event.stopPropagation(); + const dialogRef = this._dialog.open(ConfirmationDialogComponent, { + ...dialogConfig, + autoFocus: false + }); + + dialogRef.afterClosed().subscribe(result => { + if (result) { + const file = this._appStateService.getFileById(projectId, fileId); + this._fileUploadControllerService.deleteFile(file.projectId, file.fileId).subscribe(async () => { + await this._appStateService.reloadActiveProjectFiles(); + if (cb) cb(); + }, () => { + this._notificationService.showToastNotification( + this._translateService.instant('delete-file-error.label', file), + null, + NotificationType.ERROR); + }); + } + }); + } + + public openEditProjectDialog($event: MouseEvent, project: Project) { + $event.stopPropagation(); + this._dialog.open(AddEditProjectDialogComponent, { + ...dialogConfig, + data: project + }); + } + + public openDeleteProjectDialog($event: MouseEvent, project: Project, cb?: Function) { + $event.stopPropagation(); + const dialogRef = this._dialog.open(ConfirmationDialogComponent, dialogConfig); + dialogRef.afterClosed().subscribe(async result => { + if (result) { + await this._appStateService.deleteProject(project); + if (cb) cb(); + } + }); + } +} 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 faa7648a6..d217227b9 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 @@ -8,11 +8,29 @@ -
+
{{ appStateService.activeFile.filename }}
-
+
+
+ + + + + +
+
- 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 2c0464fe4..4b1bda52e 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 @@ -1,18 +1,17 @@ import { ChangeDetectorRef, Component, ElementRef, NgZone, OnInit, ViewChild } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { - AddRedactionRequest, + AddRedactionRequest, FileStatus, FileUploadControllerService, ManualRedactionControllerService, ManualRedactionEntry, - ProjectControllerService, + ProjectControllerService, ReanalysisControllerService, StatusControllerService } from '@redaction/red-ui-http'; import { TranslateService } from '@ngx-translate/core'; import {NotificationService, NotificationType} from '../../../notification/notification.service'; import { MatDialog } from '@angular/material/dialog'; import { AppStateService } from '../../../state/app-state.service'; -import { FileDetailsDialogComponent } from '../../../dialogs/file-details-dialog/file-details-dialog.component'; import { ViewerSyncService } from '../service/viewer-sync.service'; import { Annotations } from '@pdftron/webviewer'; import { PdfViewerComponent } from '../pdf-viewer/pdf-viewer.component'; @@ -27,6 +26,7 @@ import { FileDownloadService } from '../service/file-download.service'; import { saveAs } from 'file-saver'; import { FileType } from '../model/file-type'; import { ConfirmationDialogComponent } from '../../../common/confirmation-dialog/confirmation-dialog.component'; +import { DialogService } from '../../../dialogs/dialog.service'; @Component({ selector: 'redaction-file-preview-screen', @@ -59,12 +59,14 @@ export class FilePreviewScreenComponent implements OnInit { private readonly _notificationService: NotificationService, private readonly _viewerSyncService: ViewerSyncService, private readonly _dialog: MatDialog, + private readonly _dialogService: DialogService, private readonly _router: Router, private readonly _manualRedactionControllerService: ManualRedactionControllerService, private readonly _userService: UserService, private readonly _fileDownloadService: FileDownloadService, private readonly _fileUploadControllerService: FileUploadControllerService, private readonly _projectControllerService: ProjectControllerService, + private readonly _reanalysisControllerService: ReanalysisControllerService, private readonly _filtersService: FiltersService, private ngZone: NgZone) { this._activatedRoute.params.subscribe(params => { @@ -102,12 +104,20 @@ export class FilePreviewScreenComponent implements OnInit { this._viewerSyncService.activateViewer('ANNOTATED'); } - public showDetailsDialog($event: MouseEvent) { + public openFileDetailsDialog($event: MouseEvent) { + this._dialogService.openFileDetailsDialog($event, this.appStateService.activeFile); + } + + public reanalyseFile($event: MouseEvent) { $event.stopPropagation(); - this._dialog.open(FileDetailsDialogComponent, { - width: '600px', - maxWidth: '90vw', - data: this.appStateService.activeFile + this._reanalysisControllerService.reanalyzeFile(this.appStateService.activeProject.project.projectId, this.fileId).subscribe(async () => { + await this.appStateService.reloadActiveProjectFiles(); + }); + } + + public openDeleteFileDialog($event: MouseEvent) { + this._dialogService.openDeleteFileDialog($event, this.projectId, this.fileId, () => { + this._router.navigate([`/ui/projects/${this.projectId}`]); }); } diff --git a/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.ts b/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.ts index 7b06b357e..8bcab7658 100644 --- a/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.ts +++ b/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.ts @@ -2,7 +2,6 @@ import { Component, OnInit } from '@angular/core'; import { Project, ProjectControllerService } from '@redaction/red-ui-http'; import { MatDialog } from '@angular/material/dialog'; import { AddEditProjectDialogComponent } from '../../dialogs/add-edit-project-dialog/add-edit-project-dialog.component'; -import { ConfirmationDialogComponent } from '../../common/confirmation-dialog/confirmation-dialog.component'; import { TranslateService } from '@ngx-translate/core'; import { NotificationService } from '../../notification/notification.service'; import { AppStateService, ProjectWrapper } from '../../state/app-state.service'; @@ -12,6 +11,7 @@ import { DoughnutChartConfig } from '../../components/simple-doughnut-chart/simp import { SortingOption } from '../../utils/types'; import { groupBy } from '../../utils/functions'; import { AssignOwnerDialogComponent } from '../../dialogs/assign-owner-dialog/assign-owner-dialog.component'; +import { DialogService } from '../../dialogs/dialog.service'; @Component({ selector: 'redaction-project-listing-screen', @@ -30,6 +30,7 @@ export class ProjectListingScreenComponent implements OnInit { constructor( public readonly appStateService: AppStateService, private readonly _userService: UserService, + private readonly _dialogService: DialogService, private readonly _projectControllerService: ProjectControllerService, private readonly _translateService: TranslateService, private readonly _notificationService: NotificationService, @@ -38,6 +39,10 @@ export class ProjectListingScreenComponent implements OnInit { ngOnInit(): void { this.appStateService.reset(); + this._calculateData(); + } + + private _calculateData() { this.projectsChartData = [ { value: this.activeProjects, color: 'ACTIVE', label: 'active' }, { value: this.inactiveProjects, color: 'DELETED', label: 'archived' } @@ -47,7 +52,6 @@ export class ProjectListingScreenComponent implements OnInit { for (const key of Object.keys(groups)) { this.documentsChartData.push({ value: groups[key].length, color: key, label: key }); } - } public get user() { @@ -79,27 +83,25 @@ export class ProjectListingScreenComponent implements OnInit { } public openAddProjectDialog(project?: Project): void { - this._dialog.open(AddEditProjectDialogComponent, { + const dialogRef = this._dialog.open(AddEditProjectDialogComponent, { width: '400px', maxWidth: '90vw', data: project }); - } - - public openDeleteProjectDialog($event: MouseEvent, project: Project) { - $event.stopPropagation(); - const dialogRef = this._dialog.open(ConfirmationDialogComponent, { - width: '400px', - maxWidth: '90vw' - }); dialogRef.afterClosed().subscribe(result => { if (result) { - this.appStateService.deleteProject(project); + this._calculateData(); } }); } + public openDeleteProjectDialog($event: MouseEvent, project: Project) { + this._dialogService.openDeleteProjectDialog($event, project, () => { + this._calculateData(); + }); + } + public openDetailsDialog($event: MouseEvent, project: ProjectWrapper) { $event.stopPropagation(); this._dialog.open(ProjectDetailsDialogComponent, { diff --git a/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.ts b/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.ts index 2ab6e3f71..a2e021953 100644 --- a/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.ts +++ b/apps/red-ui/src/app/screens/project-overview-screen/project-overview-screen.component.ts @@ -23,6 +23,7 @@ import { SortingOption } from '../../utils/types'; import { DoughnutChartConfig } from '../../components/simple-doughnut-chart/simple-doughnut-chart.component'; import { groupBy } from '../../utils/functions'; import { AssignProjectMembersDialogComponent } from '../../dialogs/assign-project-members-dialog/assign-project-members-dialog.component'; +import { DialogService } from '../../dialogs/dialog.service'; @Component({ @@ -49,6 +50,7 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy { private readonly _translateService: TranslateService, private readonly _notificationService: NotificationService, private readonly _dialog: MatDialog, + private readonly _dialogService: DialogService, private readonly _fileUploadService: FileUploadService, private readonly _uploadStatusOverlayService: UploadStatusOverlayService, private readonly _reanalysisControllerService: ReanalysisControllerService, @@ -109,22 +111,9 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy { } public openDeleteFileDialog($event: MouseEvent, fileStatus: FileStatus) { - $event.stopPropagation(); - const dialogRef = this._dialog.open(ConfirmationDialogComponent, { - width: '400px', - maxWidth: '90vw', - autoFocus: false - }); - - dialogRef.afterClosed().subscribe(result => { - if (result) { - this._fileUploadControllerService.deleteFile(fileStatus.projectId, fileStatus.fileId).subscribe(() => { - this._getFileStatus(); - }, () => { - this._notificationService.showToastNotification(this._translateService.instant('project-overview.delete-file-error.label', fileStatus), null, NotificationType.ERROR); - }); - } - }); + this._dialogService.openDeleteFileDialog($event, fileStatus.projectId, fileStatus.fileId, () => { + this._calculateChartConfig(); + }) } public openDetailsDialog($event: MouseEvent) { @@ -137,28 +126,13 @@ export class ProjectOverviewScreenComponent implements OnInit, OnDestroy { } public openEditProjectDialog($event: MouseEvent) { - $event.stopPropagation(); - this._dialog.open(AddEditProjectDialogComponent, { - width: '400px', - maxWidth: '90vw', - data: this.appStateService.activeProject.project - }); + this._dialogService.openEditProjectDialog($event, this.appStateService.activeProject.project); } public openDeleteProjectDialog($event: MouseEvent) { - $event.stopPropagation(); - const dialogRef = this._dialog.open(ConfirmationDialogComponent, { - width: '400px', - maxWidth: '90vw' - }); - - dialogRef.afterClosed().subscribe(result => { - if (result) { - this.appStateService.deleteProject(this.appStateService.activeProject.project); - this.ngOnDestroy(); - this._router.navigate(['/ui/projects']); - } - }); + this._dialogService.openDeleteProjectDialog($event, this.appStateService.activeProject.project, () => { + this._router.navigate(['/ui/projects']); + }) } public openAssignProjectMembersDialog() { diff --git a/apps/red-ui/src/app/state/app-state.service.ts b/apps/red-ui/src/app/state/app-state.service.ts index 4727a3028..8038dab87 100644 --- a/apps/red-ui/src/app/state/app-state.service.ts +++ b/apps/red-ui/src/app/state/app-state.service.ts @@ -109,6 +109,10 @@ export class AppStateService { return this.allProjects.find(project => project.project.projectId === id); } + public getFileById(projectId: string, fileId: string) { + return this.getProjectById(projectId).files.find(file => file.fileId === fileId); + } + async loadAllProjects() { const projects = await this._projectControllerService.getProjects().toPromise(); if (projects) { @@ -124,7 +128,7 @@ export class AppStateService { async getFiles(projectId: string) { const files = await this._statusControllerService.getProjectStatus(projectId).toPromise(); - const project = this._appState.projects.find(p => p.project.projectId === projectId); + const project = this.getProjectById(projectId); project.files = files; this._computeStats(); return files; @@ -152,7 +156,7 @@ export class AppStateService { } deleteProject(project: Project) { - this._projectControllerService.deleteProject(project.projectId).subscribe(() => { + return this._projectControllerService.deleteProject(project.projectId).toPromise().then(() => { const index = this._appState.projects.findIndex(p => p.project.projectId === project.projectId); this._appState.projects.splice(index, 1); this._appState.projects = [...this._appState.projects]; diff --git a/apps/red-ui/src/assets/icons/general/info.svg b/apps/red-ui/src/assets/icons/general/info.svg index 2a5ae4e0a..731218b6a 100644 --- a/apps/red-ui/src/assets/icons/general/info.svg +++ b/apps/red-ui/src/assets/icons/general/info.svg @@ -1,14 +1,7 @@ - - - - - - - - - + + + info + + + + \ No newline at end of file diff --git a/apps/red-ui/src/assets/styles/red-page-layout.scss b/apps/red-ui/src/assets/styles/red-page-layout.scss index c95cad404..56b3d5d08 100644 --- a/apps/red-ui/src/assets/styles/red-page-layout.scss +++ b/apps/red-ui/src/assets/styles/red-page-layout.scss @@ -119,12 +119,6 @@ html, body { display: block; } -.details-button { - position: fixed !important; - bottom: 20px; - right: 20px; -} - .detail-row { opacity: 1; font-family: Inconsolata, monospace, monospace;