red-ui/apps/red-ui/src/app/services/permissions.service.ts

196 lines
7.4 KiB
TypeScript

import { Injectable } from '@angular/core';
import { UserService } from './user.service';
import { Dossier, File, IComment } from '@red/domain';
import { DossiersService } from './entity-services/dossiers.service';
@Injectable({
providedIn: 'root',
})
export class PermissionsService {
constructor(private readonly _userService: UserService, private readonly _dossiersService: DossiersService) {}
isReviewerOrApprover(file: File): boolean {
const dossier = this._getDossier(file);
return this.isFileAssignee(file) || this.isApprover(dossier);
}
displayReanalyseBtn(dossier: Dossier): boolean {
return this.isApprover(dossier);
}
canToggleAnalysis(file: File): boolean {
return this.isReviewerOrApprover(file) && (file.isNew || file.isUnderReview || file.isUnderApproval);
}
canReanalyseFile(file: File | File[]): boolean {
const files = file instanceof File ? [file] : file;
return files.reduce((acc, _file) => this._canReanalyseFile(_file) && acc, true);
}
isFileAssignee(file: File): boolean {
return file.assignee === this._userService.currentUser.id;
}
canDeleteFile(file: File | File[]): boolean {
const files = file instanceof File ? [file] : file;
const dossier = this._getDossier(files[0]);
return files.reduce((acc, _file) => this._canDeleteFile(_file, dossier) && acc, true);
}
canAssignToSelf(file: File | File[]): boolean {
const files = file instanceof File ? [file] : file;
const dossier = this._getDossier(files[0]);
return files.reduce((acc, _file) => this._canAssignToSelf(_file, dossier) && acc, true);
}
canAssignUser(file: File | File[]): boolean {
const files = file instanceof File ? [file] : file;
const dossier = this._getDossier(files[0]);
return files.reduce((acc, _file) => this._canAssignUser(_file, dossier) && acc, true);
}
canUnassignUser(file: File | File[]): boolean {
const files = file instanceof File ? [file] : file;
const dossier = this._getDossier(files[0]);
return files.reduce((acc, _file) => this._canUnassignUser(_file, dossier) && acc, true);
}
canSetUnderReview(file: File | File[]): boolean {
const files = file instanceof File ? [file] : file;
const dossier = this._getDossier(files[0]);
return this.isApprover(dossier) && files.reduce((acc, _file) => this._canSetUnderReview(_file) && acc, true);
}
canBeApproved(file: File | File[]): boolean {
const files = file instanceof File ? [file] : file;
return files.reduce((acc, _file) => this._canBeApproved(_file) && acc, true);
}
isReadyForApproval(files: File | File[]): boolean {
return this.canSetUnderReview(files);
}
canSetUnderApproval(file: File | File[]): boolean {
const files = file instanceof File ? [file] : file;
return files.reduce((acc, _file) => this._canSetUnderApproval(_file) && acc, true);
}
isOwner(dossier: Dossier, user = this._userService.currentUser): boolean {
return dossier.ownerId === user.id;
}
isApprover(dossier: Dossier, user = this._userService.currentUser): boolean {
return dossier.approverIds.indexOf(user.id) >= 0;
}
isDossierReviewer(dossier: Dossier, user = this._userService.currentUser): boolean {
return this.isDossierMember(dossier, user) && !this.isApprover(dossier, user);
}
isDossierMember(dossier: Dossier, user = this._userService.currentUser): boolean {
return dossier.memberIds.includes(user.id);
}
// TODO: Remove '?', after we make sure file is loaded before page
canPerformAnnotationActions(file: File): boolean {
return (file?.isUnderReview || file?.isUnderApproval) && this.isFileAssignee(file);
}
canUndoApproval(file: File | File[]): boolean {
const files = file instanceof File ? [file] : file;
const dossier = this._getDossier(files[0]);
return files.reduce((acc, _file) => this._canUndoApproval(_file, dossier) && acc, true);
}
canMarkPagesAsViewed(file: File): boolean {
return (file.isUnderReview || file.isUnderApproval) && this.isFileAssignee(file);
}
canDownloadFiles(files: File[]): boolean {
if (files.length === 0) {
return false;
}
const dossier = this._getDossier(files[0]);
return this.isApprover(dossier) && files.reduce((prev, file) => prev && file.isApproved, true);
}
canDeleteDossier(dossier: Dossier): boolean {
return dossier.ownerId === this._userService.currentUser.id;
}
isAdmin(user = this._userService.currentUser): boolean {
return user.isAdmin;
}
canAddComment(file: File): boolean {
return (this.isFileAssignee(file) || this.isApprover(this._getDossier(file))) && !file.isApproved;
}
canExcludePages(file: File): boolean {
const dossier = this._getDossier(file);
return (file.isUnderReview || file.isUnderApproval) && (this.isFileAssignee(file) || this.isApprover(dossier));
}
canDeleteComment(comment: IComment, file: File) {
const dossier = this._getDossier(file);
return (comment.user === this._userService.currentUser.id || this.isApprover(dossier)) && !file.isApproved;
}
// https://jira.iqser.com/browse/RED-2787
private _canDeleteFile(file: File, dossier: Dossier): boolean {
return (
file.isNew ||
(file.isUnderReview && !file.assignee && this.isDossierMember(dossier)) ||
(file.isUnderApproval && !file.assignee && this.isApprover(dossier)) ||
(file.assignee && !file.isApproved && (this.isFileAssignee(file) || this.isOwner(dossier)))
);
}
private _canReanalyseFile(file: File): boolean {
return this.isReviewerOrApprover(file) || file.isNew || (file.isError && file.isNew);
}
private _canAssignToSelf(file: File, dossier: Dossier): boolean {
const precondition = this.isDossierMember(dossier) && !this.isFileAssignee(file) && !file.isError && !file.isProcessing;
return precondition && (file.isNew || file.isUnderReview || (file.isUnderApproval && this.isApprover(dossier)));
}
private _canSetUnderApproval(file: File): boolean {
return file.isUnderReview && this.isReviewerOrApprover(file);
}
private _canUndoApproval(file: File, dossier: Dossier): boolean {
return file.isApproved && this.isApprover(dossier);
}
private _canBeApproved(file: File): boolean {
return file.canBeApproved;
}
private _canAssignUser(file: File, dossier: Dossier) {
const precondition = !file.isProcessing && !file.isError && !file.isApproved && this.isApprover(dossier);
if (precondition) {
if ((file.isNew || file.isUnderReview) && dossier.hasReviewers) {
return true;
}
if (file.isUnderApproval && dossier.approverIds.length > 1) {
return true;
}
}
return false;
}
private _canUnassignUser(file: File, dossier: Dossier) {
return (file.isUnderReview || file.isUnderApproval) && (this.isFileAssignee(file) || this.isApprover(dossier));
}
private _canSetUnderReview(file: File): boolean {
return file.isUnderApproval;
}
private _getDossier(file: File): Dossier {
return this._dossiersService.find(file.dossierId);
}
}