import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core'; import { BaseApplicationForLogic, FormDefinitionComponent, FormioAnswerValues } from '@features/configure-forms/form.typing'; import { FormBuilderService } from '@features/formio/form-builder/services/form-builder/form-builder.service'; import { ComponentHelperService } from '@features/formio/services/component-helper/component-helper.service'; import { FormLogicService } from '@features/formio/services/form-logic/form-logic.service'; import { FormulaBuilderModalComponent } from '@features/formula-builder/formula-builder-modal/formula-builder-modal.component'; import { FormulaBuilderService } from '@features/formula-builder/formula-builder.service'; import { RootFormula } from '@features/formula-builder/formula-builder.typing'; import { GlobalValueLogicGroup, LogicColumnDisplay, LogicValueFormatType } from '@features/logic-builder/logic-builder.typing'; import { ArrayHelpersService, SelectOption, TypeaheadSelectOption } from '@yourcause/common'; import { I18nService } from '@yourcause/common/i18n'; import { ModalFactory } from '@yourcause/common/modals'; @Component({ selector: 'gc-formula-builder-manager', templateUrl: './formula-builder-manager.component.html', styleUrls: ['./formula-builder-manager.component.scss'] }) export class FormulaBuilderManagerComponent implements OnInit, OnChanges { @Input() formula: RootFormula; @Input() component: FormDefinitionComponent; @Input() conditionalValue: GlobalValueLogicGroup[]; @Output() onModalOpenOrClose = new EventEmitter(); @Output() onChange = new EventEmitter>(); availableColumns: LogicColumnDisplay[]; noFormulaAlertMessage = this.i18n.translate( 'common:textNoValueFormulaRulesHelp', {}, `Click "Manage calculated value formula" below to manage calculated value logic to assign this component a value.` ); alertMessage: string; options: (TypeaheadSelectOption|SelectOption)[] = []; logicValueFormatType: LogicValueFormatType; columns: TypeaheadSelectOption[]; logicEnabled: boolean; constructor ( private i18n: I18nService, private modalFactory: ModalFactory, private formulaBuilderService: FormulaBuilderService, private formLogicService: FormLogicService, private componentHelper: ComponentHelperService, private formBuilderService: FormBuilderService, private arrayHelper: ArrayHelpersService ) { } ngOnInit () { this.setColumns(); } ngOnChanges (changes: SimpleChanges) { if (changes.conditionalValue) { this.logicEnabled = (this.conditionalValue?.length ?? 0) === 0; this.determineAlertText(); if (!this.logicEnabled) { this.alertMessage = this.i18n.translate( 'common:textFormulaBuilderUnavailable', {}, '"Calculated Value" and "Set Value" cannot be used together, please clear any rules from the "Set Value" tab to continue.' ); } } } setColumns () { const { availableColumns } = this.formLogicService.getAvailableLogicColumnsForComponent( this.component, false, this.formBuilderService.currentFormBuilderDefinition, this.formBuilderService.currentFormBuilderIndex, this.formBuilderService.currentFormBuilderFormAudience, false ); this.columns = this.arrayHelper.sort(availableColumns.filter(column => { return column.type === 'number' || column.type === 'currency'; }).map(column => { return { label: column.label, value: column.column.join('.') as string }; }), 'label'); } private determineAlertText () { if (this.logicEnabled) { if (this.formula?.step) { if (!this.columns) { this.setColumns(); } this.alertMessage = this.formulaBuilderService.generateFormulaString(this.formula, this.columns); } else { this.alertMessage = this.noFormulaAlertMessage; } } } async openLogicBuilderModal () { this.onModalOpenOrClose.emit(true); const otherFormulas: RootFormula[] = this.formBuilderService.currentFormBuilderDefinition.reduce((acc, def) => { this.componentHelper.eachComponent(def.components, (comp) => { if (comp.formula && (comp.key !== this.component.key)) { acc.push(comp.formula); } }); return [ ...acc ]; }, []); const formula: RootFormula = this.formula; const rootProperty = this.component.type.split('-').join('.') as string; const response = await this.modalFactory.open>( FormulaBuilderModalComponent as any, { columns: this.columns, formula, rootProperty, otherFormulas } ); this.onModalOpenOrClose.emit(false); if (response) { this.formula = response.step ? response : { step: null, property: rootProperty }; this.onChange.emit(this.formula); } this.determineAlertText(); } }