import { Component, OnInit } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { SpinnerService } from '@core/services/spinner.service'; import { AddEditLevelResponse, Sublevel, WorkflowLevel, WorkflowLevelOptions } from '@core/typings/workflow.typing'; import { ArrayHelpersService, PanelTypes, SimpleStringMap } from '@yourcause/common'; import { I18nService } from '@yourcause/common/i18n'; import { ConfirmationModalComponent, ModalFactory } from '@yourcause/common/modals'; import { Subscription } from 'rxjs'; import { AddEditLevelModalComponent } from '../add-edit-level-modal/add-edit-level-modal.component'; import { ToggleWorkflowLevelModalComponent } from '../toggle-workflow-level-modal/toggle-workflow-level-modal.component'; import { WorkflowService } from '../workflow.service'; @Component({ selector: 'gc-workflow-structure', templateUrl: './workflow-structure.component.html', styleUrls: ['./workflow-structure.component.scss'] }) export class WorkflowStructureComponent implements OnInit { PanelTypes = PanelTypes; id = this.activatedRoute.snapshot.parent.params.id; isNew = this.id === 'new'; allLevels: WorkflowLevel[] = []; levelHiddenMap: SimpleStringMap = {}; sub = new Subscription(); constructor ( private activatedRoute: ActivatedRoute, private i18n: I18nService, private modalFactory: ModalFactory, private spinnerService: SpinnerService, private workflowService: WorkflowService, private arrayHelper: ArrayHelpersService, private router: Router ) { this.sub.add(this.activatedRoute.parent.params.subscribe((params) => { if (params) { this.id = params.id; this.isNew = this.id === 'new'; this.ngOnInit(); } })); } get workflowMap () { return this.workflowService.get('workflowMap'); } get workflow () { return this.workflowMap[this.id]; } ngOnInit () { if (!this.isNew) { this.setAllLevels(); } } setAllLevels () { this.allLevels = [ ...this.workflow.levels ]; this.sortLevels(); } toggleLevelHiddenMap (id: number) { this.levelHiddenMap[id] = !this.levelHiddenMap[id]; } async levelModal ( level?: WorkflowLevel, levelIndex?: number, isSubAdding?: boolean, subLevel?: WorkflowLevel, subIndex?: number ) { const levelForModal = this.isNew ? null : (isSubAdding ? null : subLevel || level); const response = await this.modalFactory.open( AddEditLevelModalComponent, { level: levelForModal, isSubExisting: !!subLevel, isSubAdding } ); if (response) { this.handleLevelChanges( response, level, levelIndex, isSubAdding, subLevel, subIndex ); await this.save(); } } handleLevelChanges ( response: AddEditLevelResponse, level?: WorkflowLevel, levelIndex?: number, isSubAdding?: boolean, subLevel?: WorkflowLevel, subIndex?: number ) { if (!level) { const updated: WorkflowLevel = this.getUpdatedLevel(response, null); updated.subLevels = []; this.allLevels.push(updated); } else { if (isSubAdding) { const updatedSub = this.getUpdatedLevel(response, null); const subLevels = [ ...(level.subLevels || []), updatedSub ]; this.allLevels = [ ...this.allLevels.slice(0, levelIndex), { ...level, subLevels }, ...this.allLevels.slice(levelIndex + 1) ]; } else if (subLevel) { const updatedSub: Sublevel = this.getUpdatedLevel(response, subLevel.id); this.allLevels = [ ...this.allLevels.slice(0, levelIndex), { ...level, subLevels: [ ...level.subLevels.slice(0, subIndex), updatedSub, ...level.subLevels.slice(subIndex + 1) ] }, ...this.allLevels.slice(levelIndex + 1) ]; } else { const updated: WorkflowLevel = this.getUpdatedLevel(response, level.id); updated.subLevels = [ ...level.subLevels ]; this.allLevels = [ ...this.allLevels.slice(0, levelIndex), updated, ...this.allLevels.slice(levelIndex + 1) ]; } } } getUpdatedLevel ( response: AddEditLevelResponse, id: number ): WorkflowLevel|Sublevel { const updated: WorkflowLevel|Sublevel = { id, name: response.name, description: response.description, allowDeclination: response.levelActions.includes( WorkflowLevelOptions.ALLOW_DECLINE ), allowApproval: response.levelActions.includes( WorkflowLevelOptions.ALLOW_APPROVAL ), allowUserToArchiveAndUnarchive: response.levelActions.includes( WorkflowLevelOptions.ALLOW_ARCHIVE_APPLICATIONS ), allowAward: response.levelActions.includes( WorkflowLevelOptions.ALLOW_AWARD_ACTIONS ), allowUserToRequestRevision: response.levelActions.includes( WorkflowLevelOptions.ALLOW_REQUEST_REVISION ), allowRecommendedFunding: response.levelActions.includes( WorkflowLevelOptions.ALLOW_RECOMMEND_FUNDING ), allowUserToViewAwardsAndPayments: response.allowUserToViewAwardsAndPayments, showMaskedApplicantInfo: response.showMaskedApplicantInfo, allowFormDueDateExtension: response.allowFormDueDateExtension, showBudgetSummaryInfo: response.showBudgetSummaryInfo }; return updated; } sortLevels () { this.allLevels = this.arrayHelper.sort(this.allLevels, 'sortOrder'); this.allLevels.forEach((level, index) => { level.sortOrder = index + 1; if (level.subLevels && level.subLevels.length > 0) { level.subLevels = this.arrayHelper.sort(level.subLevels, 'sortOrder'); level.subLevels.forEach((subLevel, subIndex) => { subLevel.sortOrder = subIndex + 1; }); } }); } moveLevelUp ( level: WorkflowLevel, index: number, subIndex?: number ) { if (subIndex) { const subLevel = level.subLevels[subIndex]; const otherSubLevel = level.subLevels[subIndex - 1]; subLevel.sortOrder = subIndex; otherSubLevel.sortOrder = subIndex + 1; } else { const thisLevel = this.allLevels[index]; const otherLevel = this.allLevels[index - 1]; thisLevel.sortOrder = index - 1; otherLevel.sortOrder = index; } this.save(); } moveLevelDown ( level: WorkflowLevel, index: number, subIndex?: number ) { if (subIndex >= 0) { const subLevel = level.subLevels[subIndex]; const otherSubLevel = level.subLevels[subIndex + 1]; subLevel.sortOrder = subIndex + 1; otherSubLevel.sortOrder = subIndex; } else { const thisLevel = this.allLevels[index]; const otherLevel = this.allLevels[index + 1]; thisLevel.sortOrder = index + 1; otherLevel.sortOrder = index; } this.save(); } async deleteLevelModal ( level: WorkflowLevel, levelIndex: number, subLevel?: Sublevel, subIndex?: number ) { const response = await this.modalFactory.open( ConfirmationModalComponent, { confirmText: this.i18n.translate( 'WORKFLOW:textAreSureYouWantToRemoveThisLevel', {}, 'Are you sure you want to remove this level?' ), modalHeader: `${this.i18n.translate( 'WORKFLOW:textRemoveWorkflowLevel', {}, 'Remove Workflow Level' )}: ${subLevel ? subLevel.name : level.name}`, confirmButtonText: this.i18n.translate( 'common:textRemove', {}, 'Remove' ) } ); if (response) { if (subLevel) { this.allLevels = [ ...this.allLevels.slice(0, levelIndex), { ...level, subLevels: [ ...level.subLevels.slice(0, subIndex), ...level.subLevels.slice(subIndex + 1) ] }, ...this.allLevels.slice(levelIndex + 1) ]; } else { this.allLevels = [ ...this.allLevels.slice(0, levelIndex), ...this.allLevels.slice(levelIndex + 1) ]; } await this.save(); } } async disableEnableLevelModal ( level: WorkflowLevel, subLevel?: Sublevel ) { const response = await this.modalFactory.open( ToggleWorkflowLevelModalComponent, { level, subLevel } ); if (response) { this.spinnerService.startSpinner(); await this.workflowService.handleDisableEnableWorkflowLevel(response); await this.save(); this.spinnerService.stopSpinner(); } } async save () { this.spinnerService.startSpinner(); this.sortLevels(); const id = await this.workflowService.handleSaveWorkflowLevels({ id: this.isNew ? null : this.id, name: this.workflow.name, description: this.workflow.description, levels: this.allLevels }); this.setAllLevels(); if (this.isNew) { if (id) { this.router.navigate([ `/management/program-setup/workflows/detail/${id}/structure` ]); } } this.spinnerService.stopSpinner(); } }