import { Component, Input, OnInit } from '@angular/core'; import { FormMaskingService } from '@core/services/form-masking.service'; import { SpinnerService } from '@core/services/spinner.service'; import { StatusService } from '@core/services/status.service'; import { TranslationService } from '@core/services/translation.service'; import { ApplicationViewPage, Nominee } from '@core/typings/application.typing'; import { ApplicationInfoForPDF, FormInfoForPDF, OrgInfoForPDF } from '@core/typings/pdf.typing'; import { ApplicationDownloadService } from '@features/application-download/application-download.service'; import { ApplicationFormService } from '@features/application-forms/services/application-forms.service'; import { ClientSettingsService } from '@features/client-settings/client-settings.service'; import { CollaborationService } from '@features/collaboration/collaboration.service'; import { FormStatuses, FormTypes, ViewFormResponse } from '@features/configure-forms/form.typing'; import { FormsResolver } from '@features/configure-forms/resolvers/forms.resolver'; import { FormsService } from '@features/configure-forms/services/forms/forms.service'; import { EmployeeSSOFieldsResolver } from '@features/employee-sso-fields/resolvers/employee-sso-fields.resolver'; import { FormHelperService } from '@features/formio/services/form-helper/form-helper.service'; import { ReportFieldService } from '@features/formio/services/report-field/report-field.service'; import { NonprofitService } from '@features/nonprofit/nonprofit.service'; import { ProgramService } from '@features/programs/program.service'; import { ReferenceFieldsResolver } from '@features/reference-fields/reference-fields.resolver'; import { ReferenceFieldsService } from '@features/reference-fields/services/reference-fields.service'; import { SignatureService } from '@features/signature/signature.service'; import { EmailService } from '@features/system-emails/email.service'; import { SystemTagsService } from '@features/system-tags/system-tags.service'; import { SimpleStringMap } from '@yourcause/common'; import { ModalFactory, YCModalComponent } from '@yourcause/common/modals'; import { BehaviorSubject } from 'rxjs'; import { FormReminderModalComponent } from '../form-reminder-modal/form-reminder-modal.component'; import { ApplicationManagerService } from '../services/application-manager/application-manager.service'; @Component({ selector: 'gc-view-form-modal', templateUrl: './view-form-modal.component.html', styleUrls: ['./view-form-modal.component.scss'] }) export class ViewFormModalComponent extends YCModalComponent implements OnInit { @Input() isNomination = false; @Input() applicationId: number; @Input() form: ViewFormResponse; @Input() forOrg: boolean; @Input() isManagerForm = false; application: ApplicationViewPage; nominee?: Nominee; showNominationHeader = false; showModal = false; viewTranslations = this.translationService.viewTranslations; formTranslationMap = this.viewTranslations.FormTranslation; showSendReminderAction = false; showMaskToggle = false; masked$ = new BehaviorSubject(true); masked = true; FormTypes = FormTypes; showComments = true; translations: SimpleStringMap = {}; richTextTranslations: SimpleStringMap = {}; constructor ( private statusService: StatusService, private applicationDownloadService: ApplicationDownloadService, private formService: FormsService, private applicationManagerService: ApplicationManagerService, private spinnerService: SpinnerService, private clientSettingsService: ClientSettingsService, private translationService: TranslationService, private modalFactory: ModalFactory, private employeeSSOFieldsResolver: EmployeeSSOFieldsResolver, private referenceFieldsResolver: ReferenceFieldsResolver, private emailService: EmailService, private collaborationService: CollaborationService, private systemTagsService: SystemTagsService, private formHelperService: FormHelperService, private referenceFieldsService: ReferenceFieldsService, private programService: ProgramService, private reportFieldService: ReportFieldService, private formMaskingService: FormMaskingService, private formsResolver: FormsResolver, private nonprofitService: NonprofitService, private signatureService: SignatureService, private applicationFormService: ApplicationFormService ) { super(); } get clientBranding () { return this.clientSettingsService.get('clientBranding'); } async ngOnInit () { this.spinnerService.startSpinner(); const [ nominee ] = await Promise.all([ this.applicationManagerService.getNomineeInfo(this.applicationId), this.employeeSSOFieldsResolver.resolve(), this.referenceFieldsResolver.resolve(), this.formsResolver.resolve() ]); this.nominee = nominee; this.application = await this.applicationManagerService.getApplicationForViewFormModal( this.applicationId, this.form.applicationFormId, this.form.formDefinition, this.form.formTypeId === FormTypes.ELIGIBILITY ? this.form.formData : null ); this.showSendReminderAction = !this.isManagerForm && [ FormStatuses.Sent, FormStatuses.DraftSaved ].includes(this.form.formStatus); const formType = this.formService.getFormTypeFromFormId(this.form.formId); this.showNominationHeader = !!this.nominee && formType === FormTypes.NOMINATION; this.showModal = true; this.setShowMaskToggle(); this.spinnerService.stopSpinner(); } private setShowMaskToggle () { const maskResult = this.formMaskingService.checkShouldShowMaskToggleForFormView( this.form.formDefinition ); this.showMaskToggle = maskResult.shouldShow; this.masked = maskResult.defaultSetting; } toggleMask (newMaskValue = !this.masked) { this.masked = newMaskValue; this.masked$.next(newMaskValue); } async formReminderModal () { this.showModal = false; const response = await this.modalFactory.open( FormReminderModalComponent, { isNomination: this.isNomination, formName: this.form.formName, programId: this.application.programId } ); this.showModal = true; if (response) { this.spinnerService.startSpinner(); const attachments = await this.emailService.returnIdsFromMixedAttachments( response.emailOptionsModel.attachments, this.applicationId ); const emailOptionsModel = { ...response.emailOptionsModel, attachments }; this.spinnerService.stopSpinner(); await this.applicationFormService.sendFormReminder({ ...response, applicationId: this.application.applicationId, formId: this.form.formId, emailOptionsModel }); } } toggleComments () { this.showComments = !this.showComments; } async downloadPDF () { this.spinnerService.startSpinner(); const guid = this.application.nonprofitGuid; let orgPhone = ''; if (guid) { const org = await this.nonprofitService.getNonprofitAdditionalDataByGuid( this.application.nonprofitGuid ); if (org.nonprofitDetail) { orgPhone = org.nonprofitDetail.displayNumber; } } const [ referenceFields, reportFieldResponse, signature, tags ] = await Promise.all([ // reference fields this.referenceFieldsService.getReferenceFieldResponses( this.applicationId, this.form.applicationFormId, this.form.formDefinition, this.formHelperService.getTableAndSubsetIdsFromFormDefinition( [this.form.formDefinition] ), null, true, false, undefined, this.form.formTypeId === FormTypes.ELIGIBILITY ? this.form.formData : null ), // report field response this.reportFieldService.handleReportFieldData( this.form.formDefinition, this.applicationId ), // signature this.signatureService.setFormSignature( this.applicationId, this.form.applicationFormId, true ), // tags this.systemTagsService.getCurrentTagsForPDF( this.applicationId ) ]); const application: ApplicationInfoForPDF = { appId: this.application.applicationId, programName: this.application.programName, isMasked: this.application.isMasked, amountRequested: this.application.amountRequested, currencyRequested: this.application.currencyRequested, currencyRequestedAmountEquivalent: this.application.currencyRequestedAmountEquivalent, inKindItems: this.application.inKindItems, specialHandling: this.application.specialHandling, cycleName: this.translationService.viewTranslations?.Grant_Program_Cycle?.[this.application.grantProgramCycle.id]?.Name ?? this.application.grantProgramCycle.name, workflowLevelName: this.application.currentWorkFlowLevelName, workflowName: this.application.currentWorkflowName, careOf: this.application.careOf, status: this.statusService.applicationStatusMap?.[this.application.applicationStatus]?.translated ?? '', submittedDate: this.application.submittedDate, tags, reportFieldResponse, employeeInfo: this.application.employeeInfo, designation: this.application.designation }; const orgInfo: OrgInfoForPDF = { name: this.application.organizationName, addressString: this.application.organizationAddress, registrationId: this.application.organizationIdentification, phone: orgPhone }; const formInfo: FormInfoForPDF = { formName: this.form.formName, formSubmittedOn: this.form.formSubmittedOn, formSubmittedBy: this.form.formSubmittedBy, formDefinition: this.form.formDefinition, formData: this.form.formData, formId: this.form.formId, formStatus: this.form.formStatus, applicationFormId: this.form.applicationFormId, referenceFields, decision: this.form.decision, specialHandling: this.application.specialHandling, reviewerRecommendedFundingAmount: this.form.reviewerRecommendedFundingAmount, signature, translations: this.translations, richTextTranslations: this.richTextTranslations }; await this.formHelperService.prepareComponentsForRenderForm( [this.form.formDefinition], [this.form.formId] ); const { fileUploads, tableCsvs } = this.formHelperService.extractFilesAndTablesForPdf([formInfo]); await this.applicationDownloadService.buildApplicationPDF( await this.collaborationService.getApplicantsForPDF( this.applicationId, this.application.isMasked && !this.application.canViewMaskedApplicantInfo ), application, this.nominee, orgInfo, this.isNomination, [formInfo], fileUploads, tableCsvs, null, null, this.masked, this.clientBranding.name, await this.programService.getProgramLogo( this.application.programId ), null, null, null, this.application.isArchived, false ); this.spinnerService.stopSpinner(); } }