| /******************************************************************************** |
| * Copyright (c) 2020 Contributors to the Eclipse Foundation |
| * |
| * See the NOTICE file(s) distributed with this work for additional |
| * information regarding copyright ownership. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0 |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| ********************************************************************************/ |
| |
| import {Component, EventEmitter, Input, OnChanges, Output, SimpleChanges} from "@angular/core"; |
| import {Action} from "@ngrx/store"; |
| import { |
| ALL_NON_TRIVIAL_USER_ROLES, |
| EAPIProcessTaskDefinitionKey, |
| EAPIUserRoles, |
| IAPIProcessTask, |
| TCompleteTaskVariable |
| } from "../../../../core"; |
| import {claimAndCompleteTask, claimTaskAction, EErrorCode, sendStatementViaMailAction} from "../../../../store"; |
| import {arrayJoin, filterDistinctValues} from "../../../../util/store"; |
| |
| export interface IStatementDetailsSideMenuActionButton { |
| |
| emit?: (task?: IAPIProcessTask) => void; |
| |
| task?: IAPIProcessTask; |
| |
| action?: Action; |
| |
| label?: string; |
| |
| icon?: string; |
| |
| cssClass?: string; |
| |
| } |
| |
| interface ITaskUserLayoutMap<T> { |
| |
| [taskKey: string]: { |
| [role: string]: T[] |
| }; |
| |
| } |
| |
| @Component({ |
| selector: "app-statement-details-side-menu", |
| templateUrl: "./statement-details-side-menu.component.html", |
| styleUrls: ["./statement-details-side-menu.component.scss"] |
| }) |
| export class StatementDetailsSideMenuComponent implements OnChanges { |
| |
| @Input() |
| appLoading: boolean; |
| |
| @Input() |
| public appUserName: string; |
| |
| @Input() |
| public appUserRoles: EAPIUserRoles[]; |
| |
| @Input() |
| public appTasks: IAPIProcessTask[]; |
| |
| @Input() |
| public appErrorMessage: string; |
| |
| @Output() |
| public appDispatch = new EventEmitter<Action>(); |
| |
| public buttonLayout: IStatementDetailsSideMenuActionButton[] = []; |
| |
| public infoMessage: string; |
| |
| private taskUserLayoutMap: ITaskUserLayoutMap<IStatementDetailsSideMenuActionButton> = { |
| [EAPIUserRoles.SPA_OFFICIAL_IN_CHARGE]: { |
| [EAPIProcessTaskDefinitionKey.ADD_BASIC_INFO_DATA]: [ |
| { |
| emit: this.emitClaimAndCompleteFactory( |
| {responsible: {type: "Boolean", value: false}}, |
| EAPIProcessTaskDefinitionKey.CREATE_NEGATIVE_RESPONSE |
| ), |
| label: "details.sideMenu.createNegativeStatement", |
| icon: "edit", |
| cssClass: "openk-danger" |
| }, |
| { |
| emit: this.emitClaimTaskFactory(), |
| label: "details.sideMenu.editInfoData", |
| icon: "subject", |
| cssClass: "openk-success" |
| } |
| ], |
| [EAPIProcessTaskDefinitionKey.CREATE_NEGATIVE_RESPONSE]: [ |
| { |
| emit: this.emitClaimAndCompleteFactory( |
| {response_created: {type: "Boolean", value: false}}, |
| EAPIProcessTaskDefinitionKey.ADD_BASIC_INFO_DATA |
| ), |
| label: "details.sideMenu.backToInfoData", |
| icon: "subject", |
| cssClass: "openk-info" |
| }, |
| { |
| emit: this.emitClaimTaskFactory(), |
| label: "details.sideMenu.createNegativeStatement", |
| icon: "edit", |
| cssClass: "openk-info" |
| } |
| ], |
| [EAPIProcessTaskDefinitionKey.ADD_WORK_FLOW_DATA]: [ |
| { |
| emit: this.emitClaimTaskFactory(), |
| label: "details.sideMenu.editWorkflowData", |
| icon: "subject", |
| cssClass: "openk-info" |
| } |
| ], |
| [EAPIProcessTaskDefinitionKey.CREATE_DRAFT]: [ |
| { |
| emit: this.emitClaimTaskFactory(), |
| label: "details.sideMenu.createDraft", |
| icon: "edit", |
| cssClass: "openk-info" |
| } |
| ], |
| [EAPIProcessTaskDefinitionKey.ENRICH_DRAFT]: [ |
| { |
| emit: this.emitClaimAndCompleteFactory({}, EAPIProcessTaskDefinitionKey.CHECK_AND_FORMULATE_RESPONSE), |
| label: "details.sideMenu.checkDraft", |
| icon: "description", |
| cssClass: "openk-success" |
| } |
| ], |
| [EAPIProcessTaskDefinitionKey.CHECK_AND_FORMULATE_RESPONSE]: [ |
| { |
| emit: this.emitClaimTaskFactory(), |
| label: "details.sideMenu.completeDraft", |
| icon: "description", |
| cssClass: "openk-info" |
| } |
| ], |
| [EAPIProcessTaskDefinitionKey.SEND_STATEMENT]: [ |
| { |
| emit: (task) => this.appDispatch.emit(sendStatementViaMailAction({ |
| statementId: task?.statementId, |
| taskId: task?.taskId |
| })), |
| label: "details.sideMenu.sendEmail", |
| icon: "send", |
| cssClass: "openk-success" |
| }, |
| { |
| emit: this.emitClaimAndCompleteFactory({}), |
| label: "details.sideMenu.completeIssue", |
| icon: "done", |
| cssClass: "openk-success" |
| } |
| ] |
| }, |
| [EAPIUserRoles.DIVISION_MEMBER]: { |
| [EAPIProcessTaskDefinitionKey.ENRICH_DRAFT]: [ |
| { |
| emit: this.emitClaimTaskFactory(), |
| label: "details.sideMenu.editDraft", |
| icon: "description", |
| cssClass: "openk-info" |
| } |
| ] |
| }, |
| [EAPIUserRoles.SPA_APPROVER]: { |
| [EAPIProcessTaskDefinitionKey.APPROVE_STATEMENT]: [ |
| { |
| emit: this.emitClaimAndCompleteFactory({approved_statement: {type: "Boolean", value: false}}), |
| label: "details.sideMenu.disapprove", |
| icon: "replay", |
| cssClass: "openk-danger" |
| }, |
| { |
| emit: this.emitClaimAndCompleteFactory({approved_statement: {type: "Boolean", value: true}}), |
| label: "details.sideMenu.approve", |
| icon: "send", |
| cssClass: "openk-success" |
| } |
| ] |
| } |
| }; |
| |
| public ngOnChanges(changes: SimpleChanges) { |
| const keys: Array<keyof StatementDetailsSideMenuComponent> = ["appUserRoles", "appTasks", "appUserName"]; |
| if (keys.some((_) => changes[_] != null)) { |
| this.update(); |
| } |
| } |
| |
| public update() { |
| let roles = filterDistinctValues(this.appUserRoles); |
| roles = ALL_NON_TRIVIAL_USER_ROLES.filter((_) => roles.indexOf(_) > -1); |
| const tasks = filterDistinctValues(this.appTasks); |
| const actionsForRoles = filterDistinctValues(roles).map((role) => { |
| return tasks |
| .filter((task) => task.authorized) |
| .map((task) => this.getLayoutForRoleAndTask(role, task)); |
| }); |
| this.buttonLayout = arrayJoin(...arrayJoin(...actionsForRoles)); |
| this.infoMessage = this.getInfoMessage(); |
| } |
| |
| private emitClaimAndCompleteFactory(variables: TCompleteTaskVariable, claimNext?: EAPIProcessTaskDefinitionKey) { |
| return (task: IAPIProcessTask) => this.appDispatch.emit(claimAndCompleteTask({ |
| statementId: task?.statementId, |
| taskId: task?.taskId, |
| variables, |
| claimNext |
| })); |
| } |
| |
| private emitClaimTaskFactory() { |
| return (task: IAPIProcessTask) => this.appDispatch.emit(claimTaskAction({ |
| statementId: task?.statementId, |
| taskId: task?.taskId |
| })); |
| } |
| |
| private getLayoutForRoleAndTask(role: EAPIUserRoles, task: IAPIProcessTask): IStatementDetailsSideMenuActionButton[] { |
| const userActions = this.taskUserLayoutMap[role]; |
| return userActions == null ? [] : arrayJoin(userActions[task.taskDefinitionKey]).map((_) => ({..._, task})); |
| } |
| |
| private getInfoMessage(): string { |
| const isTaskClaimedByOtherUser = arrayJoin(this.appTasks) |
| .map((task) => task.assignee) |
| .some((assignee) => assignee != null && assignee !== this.appUserName); |
| |
| if (isTaskClaimedByOtherUser) { |
| return EErrorCode.CLAIMED_BY_OTHER_USER; |
| } |
| |
| return; |
| } |
| |
| } |