From b52ce1499f127dc489b5b594577cd6146b53ad61 Mon Sep 17 00:00:00 2001 From: Timo Date: Fri, 14 May 2021 11:07:38 +0300 Subject: [PATCH] possibility to edit approver, code refactor --- .../app/models/file/file-status.wrapper.ts | 8 ++ ...oject-overview-bulk-actions.component.html | 13 ++- ...project-overview-bulk-actions.component.ts | 68 ++++++++++---- .../file-actions/file-actions.component.html | 46 ++++++---- .../file-actions/file-actions.component.ts | 90 +++++++++++++++---- .../file-preview-screen.component.html | 10 +-- .../projects/services/file-action.service.ts | 5 ++ .../src/app/services/permissions.service.ts | 54 ++++++----- .../src/app/state/model/project.wrapper.ts | 8 ++ apps/red-ui/src/assets/i18n/en.json | 3 +- 10 files changed, 214 insertions(+), 91 deletions(-) diff --git a/apps/red-ui/src/app/models/file/file-status.wrapper.ts b/apps/red-ui/src/app/models/file/file-status.wrapper.ts index 5296eee52..31fe3319e 100644 --- a/apps/red-ui/src/app/models/file/file-status.wrapper.ts +++ b/apps/red-ui/src/app/models/file/file-status.wrapper.ts @@ -180,6 +180,14 @@ export class FileStatusWrapper { return !this.currentReviewer; } + get isUnderReview() { + return this.fileStatus.status === 'UNDER_REVIEW'; + } + + get isUnderApproval() { + return this.fileStatus.status === 'UNDER_APPROVAL'; + } + get canApprove() { return this.status === 'UNDER_REVIEW' || this.status === 'UNDER_APPROVAL'; } diff --git a/apps/red-ui/src/app/modules/projects/components/bulk-actions/project-overview-bulk-actions.component.html b/apps/red-ui/src/app/modules/projects/components/bulk-actions/project-overview-bulk-actions.component.html index 20c695b5b..f607bf22d 100644 --- a/apps/red-ui/src/app/modules/projects/components/bulk-actions/project-overview-bulk-actions.component.html +++ b/apps/red-ui/src/app/modules/projects/components/bulk-actions/project-overview-bulk-actions.component.html @@ -7,15 +7,10 @@ type="dark-bg" > - + - + + + + 0; } - get canDelete() { - return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canDeleteFile(file), true); + get allSelectedFilesCanBeAssignedIntoSameState() { + if (this.areSomeFilesSelected) { + const selectedFiles = this.selectedFiles; + const allFilesAreUnderReviewOrUnassigned = selectedFiles.reduce((acc, file) => acc && (file.isUnderReview || file.isUnassigned), true); + const allFilesAreUnderApproval = selectedFiles.reduce((acc, file) => acc && file.isUnderApproval, true); + return allFilesAreUnderReviewOrUnassigned || allFilesAreUnderApproval; + } + return false; + } + + get canAssignToSelf() { + return ( + this.allSelectedFilesCanBeAssignedIntoSameState && + this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canAssignToSelf(file), true) + ); } get canAssign() { - return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canAssignReviewer(file), true); + return ( + this.allSelectedFilesCanBeAssignedIntoSameState && + this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canAssignUser(file), true) + ); + } + + get canDelete() { + return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canDeleteFile(file), true); } get canReanalyse() { @@ -94,6 +114,11 @@ export class ProjectOverviewBulkActionsComponent { return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canUndoApproval(file), true); } + get assignTooltip() { + const allFilesAreUnderApproval = this.selectedFiles.reduce((acc, file) => acc && file.isUnderApproval, true); + return allFilesAreUnderApproval ? 'project-overview.assign-approver' : 'project-overview.assign-reviewer'; + } + delete() { this.loading = true; this._dialogService.openDeleteFilesDialog(null, this._appStateService.activeProjectId, this.selectedFileIds, () => { @@ -103,26 +128,21 @@ export class ProjectOverviewBulkActionsComponent { }); } - assign() { - this.loading = true; - const files = this.selectedFileIds.map((fileId) => this._appStateService.getFileById(this._appStateService.activeProjectId, fileId)); - - this._dialogService.openAssignFileToUserDialog(files, 'reviewer', () => { - this.reload.emit(); - this.loading = false; - }); - } - setToUnderApproval() { // If more than 1 approver - show dialog and ask who to assign if (this._appStateService.activeProject.approverIds.length > 1) { this.loading = true; const files = this.selectedFileIds.map((fileId) => this._appStateService.getFileById(this._appStateService.activeProjectId, fileId)); - this._dialogService.openAssignFileToUserDialog(files, 'approver', () => { - this.reload.emit(); - this.loading = false; - }); + this._dialogService.openAssignFileToUserDialog( + files, + 'approver', + () => { + this.reload.emit(); + this.loading = false; + }, + true + ); } else { this._performBulkAction(this._fileActionService.setFileUnderApproval(this.selectedFiles, this._appStateService.activeProject.approverIds[0])); } @@ -152,4 +172,18 @@ export class ProjectOverviewBulkActionsComponent { this.loading = false; }); } + + assign() { + this.loading = true; + const files = this.selectedFileIds.map((fileId) => this._appStateService.getFileById(this._appStateService.activeProjectId, fileId)); + + const mode = files[0].isUnderApproval ? 'approver' : 'reviewer'; + + this._dialogService.openAssignFileToUserDialog(files, mode, () => { + this.reload.emit(); + this.loading = false; + }); + } + + assignToMe() {} } diff --git a/apps/red-ui/src/app/modules/projects/components/file-actions/file-actions.component.html b/apps/red-ui/src/app/modules/projects/components/file-actions/file-actions.component.html index 4d10597f0..75a7b8604 100644 --- a/apps/red-ui/src/app/modules/projects/components/file-actions/file-actions.component.html +++ b/apps/red-ui/src/app/modules/projects/components/file-actions/file-actions.component.html @@ -19,7 +19,7 @@
- + + @@ -60,8 +68,8 @@ { + openDeleteFileDialog($event: MouseEvent) { + this._dialogService.openDeleteFilesDialog($event, this.fileStatus.projectId, [this.fileStatus.fileId], () => { this.actionPerformed.emit('delete'); }); } - async assignReviewer($event: MouseEvent, file: FileStatusWrapper) { + assign($event: MouseEvent) { $event.stopPropagation(); - await this._fileActionService.assignProjectReviewerFromOverview(file, () => this.actionPerformed.emit('assign-reviewer')); + + const mode = this.fileStatus.isUnderApproval ? 'approver' : 'reviewer'; + + this._dialogService.openAssignFileToUserDialog([this.fileStatus], mode, () => { + this.actionPerformed.emit('assign-reviewer'); + }); } - reanalyseFile($event: MouseEvent, fileStatusWrapper: FileStatusWrapper, priority = -1) { + assignToMe($event: MouseEvent) { $event.stopPropagation(); - this._fileActionService.reanalyseFile(fileStatusWrapper, priority).subscribe(() => { + } + + reanalyseFile($event: MouseEvent, priority = -1) { + $event.stopPropagation(); + this._fileActionService.reanalyseFile(this.fileStatus, priority).subscribe(() => { this.reloadProjects('reanalyse'); }); } - setFileUnderApproval($event: MouseEvent, fileStatus: FileStatusWrapper) { + setFileUnderApproval($event: MouseEvent) { $event.stopPropagation(); if (this.appStateService.activeProject.approverIds.length > 1) { - this._fileActionService.assignProjectApprover(fileStatus, () => this.actionPerformed.emit('assign-reviewer')); + this._fileActionService.assignProjectApprover(this.fileStatus, () => this.actionPerformed.emit('assign-reviewer'), true); } else { - this._fileActionService.setFileUnderApproval(fileStatus).subscribe(() => { + this._fileActionService.setFileUnderApproval(this.fileStatus).subscribe(() => { this.reloadProjects('set-under-approval'); }); } } - setFileApproved($event: MouseEvent, fileStatus: FileStatusWrapper) { + setFileApproved($event: MouseEvent) { $event.stopPropagation(); - this._fileActionService.setFileApproved(fileStatus).subscribe(() => { + this._fileActionService.setFileApproved(this.fileStatus).subscribe(() => { this.reloadProjects('set-approved'); }); } - ocrFile($event: MouseEvent, fileStatus: FileStatusWrapper) { + ocrFile($event: MouseEvent) { $event.stopPropagation(); - this._fileActionService.ocrFile(fileStatus).subscribe(() => { + this._fileActionService.ocrFile(this.fileStatus).subscribe(() => { this.reloadProjects('ocr-file'); }); } - setFileUnderReview($event: MouseEvent, fileStatus: FileStatusWrapper, ignoreDialogChanges = false) { + setFileUnderReview($event: MouseEvent, ignoreDialogChanges = false) { $event.stopPropagation(); - // this._fileActionService.setFileUnderReview(fileStatus).subscribe(() => { - // this.reloadProjects('set-review'); - // }); - this._fileActionService.assignProjectReviewer(fileStatus, () => this.actionPerformed.emit('assign-reviewer'), ignoreDialogChanges); + this._fileActionService.assignProjectReviewer(this.fileStatus, () => this.actionPerformed.emit('assign-reviewer'), ignoreDialogChanges); } reloadProjects(action: string) { diff --git a/apps/red-ui/src/app/modules/projects/screens/file-preview-screen/file-preview-screen.component.html b/apps/red-ui/src/app/modules/projects/screens/file-preview-screen/file-preview-screen.component.html index 322bd99b5..6fbad582e 100644 --- a/apps/red-ui/src/app/modules/projects/screens/file-preview-screen/file-preview-screen.component.html +++ b/apps/red-ui/src/app/modules/projects/screens/file-preview-screen/file-preview-screen.component.html @@ -61,9 +61,7 @@ >
@@ -89,10 +87,10 @@ -
+
f.fileId), this._appStateService.activeProjectId, diff --git a/apps/red-ui/src/app/services/permissions.service.ts b/apps/red-ui/src/app/services/permissions.service.ts index 618743c65..ecaa1eb35 100644 --- a/apps/red-ui/src/app/services/permissions.service.ts +++ b/apps/red-ui/src/app/services/permissions.service.ts @@ -94,17 +94,44 @@ export class PermissionsService { if (!fileStatus) { return false; } - return fileStatus.status === 'APPROVED' || fileStatus.status === 'UNDER_APPROVAL'; + return fileStatus.isApprovedOrUnderApproval; } - isApproved(fileStatus?: FileStatusWrapper) { + canAssignToSelf(fileStatus?: FileStatusWrapper) { if (!fileStatus) { fileStatus = this._appStateService.activeFile; } if (!fileStatus) { return false; } - return fileStatus.status === 'APPROVED'; + + const precondition = this.isProjectMember() && !fileStatus.isProcessing && !fileStatus.isError && !fileStatus.isExcluded && !fileStatus.isApproved; + if (precondition) { + if (fileStatus.isUnassigned && !this.isApprover()) { + return true; + } + } + return false; + } + + canAssignUser(fileStatus?: FileStatusWrapper) { + if (!fileStatus) { + fileStatus = this._appStateService.activeFile; + } + if (!fileStatus) { + return false; + } + + const precondition = this.isProjectMember() && !fileStatus.isProcessing && !fileStatus.isError && !fileStatus.isExcluded && !fileStatus.isApproved; + if (precondition) { + if ((fileStatus.isUnassigned || fileStatus.isUnderReview) && this._appStateService.activeProject.hasMoreThanOneReviewer) { + return true; + } + if (fileStatus.isUnderApproval && this.isApprover() && this._appStateService.activeProject.hasMoreThanOneApprover) { + return true; + } + } + return false; } canSetUnderReview(fileStatus?: FileStatusWrapper) { @@ -114,7 +141,7 @@ export class PermissionsService { if (!fileStatus) { return false; } - return fileStatus.status === 'UNDER_APPROVAL' && this.isApprover(); + return fileStatus.isUnderApproval && this.isApprover(); } isReadyForApproval(fileStatus?: FileStatusWrapper) { @@ -144,7 +171,7 @@ export class PermissionsService { if (!fileStatus) { return false; } - return fileStatus.status === 'UNDER_REVIEW' && this.isReviewerOrApprover(fileStatus); + return fileStatus.isUnderReview && this.isReviewerOrApprover(fileStatus); } isOwner(project?: ProjectWrapper, user?: UserWrapper) { @@ -206,23 +233,6 @@ export class PermissionsService { return !fileStatus.isError && !fileStatus.isProcessing && !fileStatus.isPending; //&& this.isReviewerOrOwner(fileStatus); } - canAssignReviewer(fileStatus?: FileStatusWrapper) { - if (!fileStatus) { - fileStatus = this._appStateService.activeFile; - } - if (!fileStatus) { - return false; - } - return ( - this.isProjectMember() && - !fileStatus.isProcessing && - !fileStatus.isError && - !fileStatus.isExcluded && - !fileStatus.isApprovedOrUnderApproval && - (this.isApprover() || !this.isFileReviewer(fileStatus)) - ); - } - canUndoApproval(fileStatus: FileStatusWrapper) { if (!fileStatus) { fileStatus = this._appStateService.activeFile; diff --git a/apps/red-ui/src/app/state/model/project.wrapper.ts b/apps/red-ui/src/app/state/model/project.wrapper.ts index f2827c1d0..d78aa96a5 100644 --- a/apps/red-ui/src/app/state/model/project.wrapper.ts +++ b/apps/red-ui/src/app/state/model/project.wrapper.ts @@ -22,6 +22,14 @@ export class ProjectWrapper { private _files: FileStatusWrapper[]; + get hasMoreThanOneApprover() { + return this.approverIds.length > 1; + } + + get hasMoreThanOneReviewer() { + return this.memberIds.length > 1; + } + get files() { return this._files; } diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json index 13e816b89..c29ff9beb 100644 --- a/apps/red-ui/src/assets/i18n/en.json +++ b/apps/red-ui/src/assets/i18n/en.json @@ -231,7 +231,8 @@ "report": { "action": "Download redaction report" }, - "assign": "Assign Reviewer", + "assign-reviewer": "Assign Reviewer", + "assign-approver": "Assign Approver", "assign-me": "Assign To Me", "table-header": { "title": "{{length}} documents",