import { Component, Input, OnInit } from '@angular/core'; import { Validators } from '@angular/forms'; import { SpinnerService } from '@core/services/spinner.service'; import { StatusService } from '@core/services/status.service'; import { ChangeStatusPayload } from '@core/typings/application.typing'; import { ApplicationStatuses } from '@core/typings/status.typing'; import { WorkflowLevel } from '@core/typings/workflow.typing'; import { AwardService } from '@features/awards/award.service'; import { EmailNotificationType } from '@features/system-emails/email.typing'; import { WorkflowService } from '@features/workflow/workflow.service'; import { DuplicateCheckValidator, EmailValidator, TypeaheadSelectOption, TypeSafeFormBuilder, TypeSafeFormGroup } from '@yourcause/common'; import { AnalyticsService, EventType } from '@yourcause/common/analytics'; import { I18nService } from '@yourcause/common/i18n'; import { YCModalComponent } from '@yourcause/common/modals'; interface UpdateFormGroup { statusId: ApplicationStatuses; workflowLevelId: number; comment: string; sendEmail: boolean; includeCommentInEmail: boolean; disregardWorkflowAutomationRules: boolean; clientEmailTemplateId: number; cc: string[]; bcc: string[]; } @Component({ selector: 'gc-update-status-modal', templateUrl: './update-status-modal.component.html', styleUrls: ['./update-status-modal.component.scss'] }) export class UpdateStatusModalComponent extends YCModalComponent implements OnInit { @Input() id: number; @Input() workflowId: number; @Input() currentWorkflowLevelId: number; @Input() isNomination = false; @Input() currentStatusId: ApplicationStatuses; modalHeader = this.i18n.translate('GLOBAL:textUpdateStatus'); formGroup: TypeSafeFormGroup; primaryButtonText = this.i18n.translate( 'APPLY:textUpdateStatus', {}, 'Update status' ); appStatusMap = this.statusService.applicationStatusMap; statusOptions: TypeaheadSelectOption[] = []; workflowOptions: TypeaheadSelectOption[] = []; hasAwards: boolean; // Cannot update status if has awards constructor ( private i18n: I18nService, private formBuilder: TypeSafeFormBuilder, private statusService: StatusService, private spinnerService: SpinnerService, private workflowService: WorkflowService, private analyticsService: AnalyticsService, private awardService: AwardService ) { super(); } get emailType () { return this.isNomination ? EmailNotificationType.NominationStatusWithCustomMsgForApplicant : EmailNotificationType.ApplicationStatusWithCustomMsgForApplicant; } async ngOnInit () { this.spinnerService.startSpinner(); if (this.isNomination) { this.primaryButtonText = this.i18n.translate( 'GLOBAL:textUpdate', {}, 'Update' ); } const numberOfNonVoidedPayments = await this.awardService.getNumberOfNonVoidedPaymentsByAppId( this.id ); const hasAwards = numberOfNonVoidedPayments > 0; if (hasAwards) { this.hasAwards = true; this.primaryButtonText = this.i18n.translate( 'common:textClose', {}, 'Close' ); } else { this.setStatusOptions(); await this.setWorkflowOptions(); this.setFormGroup(); } this.spinnerService.stopSpinner(); } async setWorkflowOptions () { const workflow = await this.workflowService.getAndSetWorkflowMap(this.workflowId); const options: TypeaheadSelectOption[] = []; workflow.levels.forEach((level) => { this.addLevelToOptionsArray(level, options); level.subLevels.forEach((sub) => { this.addLevelToOptionsArray(sub, options); }); }); this.workflowOptions = [ ...options ]; } addLevelToOptionsArray ( level: WorkflowLevel, options: TypeaheadSelectOption[] ) { const label = this.getWorkflowLevelLabel(level); options.push({ label, value: level.id }); } getWorkflowLevelLabel (level: WorkflowLevel) { return +level.id === this.currentWorkflowLevelId ? level.name + ' (' + this.i18n.translate('GLOBAL:textCurrent') + ')' : level.name; } setStatusOptions () { this.statusOptions = Object.keys(this.appStatusMap).map((key) => { return { label: this.appStatusMap[key].translated, value: key }; }).filter((item) => { return (+item.value !== this.currentStatusId) && (+item.value !== ApplicationStatuses.Draft) && (+item.value !== ApplicationStatuses.AwaitingReview); }); } setFormGroup () { this.formGroup = this.formBuilder.group({ statusId: [this.statusOptions[0].value, Validators.required], workflowLevelId: [this.currentWorkflowLevelId, Validators.required], comment: ['', Validators.required], sendEmail: true, includeCommentInEmail: true, disregardWorkflowAutomationRules: false, clientEmailTemplateId: 0, cc: [ [], EmailValidator() ], bcc: [ [], EmailValidator() ] }, { validator: [ DuplicateCheckValidator( 'cc', 'bcc' ) ] }); } onSave () { this.closeModal.emit({ statusId: this.formGroup.value.statusId, workflowLevelId: this.formGroup.value.workflowLevelId, comment: this.formGroup.value.comment, sendEmail: this.formGroup.value.sendEmail, includeCommentInEmail: this.formGroup.value.includeCommentInEmail, disregardWorkflowAutomationRules: this.formGroup.value.disregardWorkflowAutomationRules, clientEmailTemplateId: this.formGroup.value.clientEmailTemplateId, emailOptionsModel: { ccEmails: this.formGroup.value.cc, bccEmails: this.formGroup.value.bcc, attachments: [] } }); this.analyticsService.emitEvent({ eventName: 'Update status modal submit', eventType: EventType.Click, extras: null }); } }