possibility to edit approver, code refactor

This commit is contained in:
Timo 2021-05-14 11:07:38 +03:00
parent 4b5b97c69f
commit b52ce1499f
10 changed files with 214 additions and 91 deletions

View File

@ -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';
}

View File

@ -7,15 +7,10 @@
type="dark-bg"
></redaction-circle-button>
<redaction-circle-button
(action)="assign()"
*ngIf="canAssign"
icon="red:assign"
tooltip="project-overview.bulk.assign"
type="dark-bg"
></redaction-circle-button>
<redaction-circle-button (action)="assign()" *ngIf="canAssign" icon="red:assign" [tooltip]="assignTooltip" type="dark-bg"></redaction-circle-button>
<redaction-file-download-btn [file]="selectedFiles" [project]="project"></redaction-file-download-btn>
<redaction-circle-button (action)="assignToMe()" *ngIf="canAssignToSelf" icon="red:assign-me" tooltip="project-overview.assign-me" type="dark-bg">
</redaction-circle-button>
<redaction-circle-button
(action)="setToUnderApproval()"
@ -29,6 +24,8 @@
<redaction-circle-button (action)="setToUnderReview()" *ngIf="canSetToUnderReview" icon="red:undo" tooltip="project-overview.under-review" type="dark-bg">
</redaction-circle-button>
<redaction-file-download-btn [file]="selectedFiles" [project]="project"></redaction-file-download-btn>
<!-- Approved-->
<redaction-circle-button
(action)="approveDocuments()"

View File

@ -50,12 +50,32 @@ export class ProjectOverviewBulkActionsComponent {
return this.selectedFileIds.length > 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() {}
}

View File

@ -19,7 +19,7 @@
<div class="file-actions">
<!-- delete-->
<redaction-circle-button
(action)="openDeleteFileDialog($event, fileStatus)"
(action)="openDeleteFileDialog($event)"
*ngIf="permissionsService.canDeleteFile(fileStatus)"
[tooltipPosition]="tooltipPosition"
[type]="buttonType"
@ -28,13 +28,21 @@
>
</redaction-circle-button>
<!-- assign-->
<redaction-circle-button
(action)="assignReviewer($event, fileStatus)"
*ngIf="permissionsService.canAssignReviewer(fileStatus) && screen === 'project-overview'"
[icon]="permissionsService.isOwner() ? 'red:assign' : 'red:assign-me'"
(action)="assign($event)"
*ngIf="canAssign"
icon="red:assign"
[tooltip]="assignTooltip"
[tooltipPosition]="tooltipPosition"
[type]="buttonType"
></redaction-circle-button>
<redaction-circle-button
(action)="assignToMe($event)"
*ngIf="canAssignToSelf"
icon="red:assign-me"
tooltip="project-overview.assign-me"
[tooltipPosition]="tooltipPosition"
[tooltip]="permissionsService.isApprover() ? 'project-overview.assign' : 'project-overview.assign-me'"
[type]="buttonType"
>
</redaction-circle-button>
@ -60,8 +68,8 @@
<!-- Ready for approval-->
<redaction-circle-button
(action)="setFileUnderApproval($event, fileStatus)"
*ngIf="permissionsService.canSetUnderApproval(fileStatus)"
(action)="setFileUnderApproval($event)"
*ngIf="canSetToUnderApproval"
[tooltipPosition]="tooltipPosition"
[type]="buttonType"
icon="red:ready-for-approval"
@ -71,8 +79,8 @@
<!-- Back to review -->
<redaction-circle-button
(action)="setFileUnderReview($event, fileStatus, true)"
*ngIf="permissionsService.canUndoUnderApproval(fileStatus)"
(action)="setFileUnderReview($event, true)"
*ngIf="canUndoApproval"
[tooltipPosition]="tooltipPosition"
[type]="buttonType"
icon="red:undo"
@ -82,7 +90,7 @@
<!-- Approved-->
<redaction-circle-button
(action)="setFileApproved($event, fileStatus)"
(action)="setFileApproved($event)"
*ngIf="permissionsService.isReadyForApproval(fileStatus)"
[disabled]="!permissionsService.canApprove(fileStatus)"
[tooltipPosition]="tooltipPosition"
@ -94,8 +102,8 @@
<!-- Back to approval -->
<redaction-circle-button
(action)="setFileUnderApproval($event, fileStatus)"
*ngIf="permissionsService.canUndoApproval(fileStatus)"
(action)="setFileUnderApproval($event)"
*ngIf="canUndoApproval"
[tooltipPosition]="tooltipPosition"
[type]="buttonType"
icon="red:undo"
@ -104,8 +112,8 @@
</redaction-circle-button>
<redaction-circle-button
(action)="ocrFile($event, fileStatus)"
*ngIf="permissionsService.canOcrFile(fileStatus)"
(action)="ocrFile($event)"
*ngIf="canOcr"
[tooltipPosition]="tooltipPosition"
[type]="buttonType"
icon="red:ocr"
@ -115,8 +123,8 @@
<!-- reanalyse file preview -->
<redaction-circle-button
(action)="reanalyseFile($event, fileStatus, 100)"
*ngIf="permissionsService.canReanalyseFile(fileStatus) && screen === 'file-preview'"
(action)="reanalyseFile($event, 100)"
*ngIf="canReanalyse && screen === 'file-preview'"
icon="red:refresh"
tooltip="file-preview.reanalyse-notification"
tooltipClass="warn small"
@ -127,8 +135,8 @@
<!-- reanalyse file listing -->
<redaction-circle-button
(action)="reanalyseFile($event, fileStatus)"
*ngIf="permissionsService.canReanalyseFile(fileStatus) && screen === 'project-overview'"
(action)="reanalyseFile($event)"
*ngIf="canReanalyse && screen === 'project-overview'"
[tooltipPosition]="tooltipPosition"
icon="red:refresh"
tooltip="project-overview.reanalyse.action"

View File

@ -41,6 +41,54 @@ export class FileActionsComponent implements OnInit {
return this.fileStatus?.isExcluded ? 'file-preview.toggle-analysis.enable' : 'file-preview.toggle-analysis.disable';
}
get canAssignToSelf() {
return this.permissionsService.canAssignToSelf(this.fileStatus);
}
get canAssign() {
return this.permissionsService.canAssignUser(this.fileStatus);
}
get canDelete() {
return this.permissionsService.canDeleteFile(this.fileStatus);
}
get canReanalyse() {
return this.permissionsService.canReanalyseFile(this.fileStatus);
}
get canOcr() {
return this.permissionsService.canOcrFile(this.fileStatus);
}
// Under review
get canSetToUnderReview() {
return this.permissionsService.canSetUnderReview(this.fileStatus);
}
// Under approval
get canSetToUnderApproval() {
return this.permissionsService.canSetUnderApproval(this.fileStatus);
}
// Approve
get isReadyForApproval() {
return this.permissionsService.isReadyForApproval(this.fileStatus);
}
get canApprove() {
return this.permissionsService.canApprove(this.fileStatus);
}
// Undo approval
get canUndoApproval() {
return this.permissionsService.canUndoApproval(this.fileStatus);
}
get assignTooltip() {
return this.fileStatus.isUnderApproval ? 'project-overview.assign-approver' : 'project-overview.assign-reviewer';
}
ngOnInit(): void {
if (!this.fileStatus) {
this.fileStatus = this.appStateService.activeFile;
@ -59,55 +107,61 @@ export class FileActionsComponent implements OnInit {
this.actionPerformed.emit('view-document-info');
}
openDeleteFileDialog($event: MouseEvent, fileStatusWrapper: FileStatusWrapper) {
this._dialogService.openDeleteFilesDialog($event, fileStatusWrapper.projectId, [fileStatusWrapper.fileId], () => {
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) {

View File

@ -61,9 +61,7 @@
></redaction-initials-avatar>
<div
(click)="editingReviewer = true"
*ngIf="
!editingReviewer && !appStateService.activeFile.currentReviewer && permissionsService.canAssignReviewer(appStateService.activeFile)
"
*ngIf="!editingReviewer && !appStateService.activeFile.currentReviewer && permissionsService.canAssignUser()"
class="assign-reviewer pointer"
translate="file-preview.assign-reviewer"
></div>
@ -89,10 +87,10 @@
</form>
</ng-container>
<div *ngIf="permissionsService.canAssignReviewer(appStateService.activeFile)" class="assign-actions-wrapper">
<div *ngIf="permissionsService.canAssignUser()" class="assign-actions-wrapper">
<redaction-circle-button
(action)="editingReviewer = true"
*ngIf="!editingReviewer && permissionsService.canAssignReviewer(appStateService.activeFile) && appStateService.activeFile.currentReviewer"
*ngIf="!editingReviewer && permissionsService.canAssignUser() && appStateService.activeFile.currentReviewer"
icon="red:edit"
tooltip="file-preview.assign-reviewer"
tooltipPosition="below"
@ -119,7 +117,7 @@
<redaction-circle-button
(action)="assignToMe()"
*ngIf="!editingReviewer && permissionsService.canAssignReviewer(appStateService.activeFile) && !permissionsService.isFileReviewer()"
*ngIf="!editingReviewer && permissionsService.canAssignToSelf() && !permissionsService.isFileReviewer()"
icon="red:assign-me"
tooltip="file-preview.assign-me"
tooltipPosition="below"

View File

@ -82,6 +82,11 @@ export class FileActionService {
if (!isArray(fileStatus)) {
fileStatus = [fileStatus];
}
if (!approverId) {
approverId = this._appStateService.activeProject.approverIds[0];
}
return this._statusControllerService.setStatusUnderApprovalForList(
fileStatus.map((f) => f.fileId),
this._appStateService.activeProjectId,

View File

@ -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;

View File

@ -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;
}

View File

@ -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",