import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { BaseApplicationForLogic, FormDefinitionComponent } from '@features/configure-forms/form.typing'; import { FormBuilderService } from '@features/formio/form-builder/services/form-builder/form-builder.service'; import { FormLogicService } from '@features/formio/services/form-logic/form-logic.service'; import { ConditionalLogicBuilderModalComponent } from '@features/logic-builder/conditional-logic-builder-modal/conditional-logic-builder-modal.component'; import { LogicBuilderService } from '@features/logic-builder/logic-builder.service'; import { ConditionalLogicResultType, EvaluationType, GlobalLogicGroup, GlobalValueLogicGroup, LogicColumnDisplay } from '@features/logic-builder/logic-builder.typing'; import { FormError } from '@yourcause/common/core-forms'; import { I18nService } from '@yourcause/common/i18n'; import { ModalFactory } from '@yourcause/common/modals'; @Component({ selector: 'gc-validation-builder-manager', templateUrl: './validation-builder-manager.component.html', styleUrls: ['./validation-builder-manager.component.scss'] }) export class ValidationBuilderManagerComponent implements OnInit { @Input() component: FormDefinitionComponent; @Input() customValidation: GlobalValueLogicGroup; @Input() label: string; @Output() onModalOpenOrClose = new EventEmitter(); @Output() isValidChange = new EventEmitter(); @Output() onChange = new EventEmitter>(); showInvalidConditionsMessage = false; requiredError: FormError = { i18nKey: 'common:textThisInputIsRequired', defaultValue: 'This input is required', value: null, errorMessage: '' }; availableColumns: LogicColumnDisplay[] = []; dataWithoutResult: GlobalValueLogicGroup; instructions = this.i18n.translate( 'common:textClickManageCustomValidationAlert', {}, 'Click "Manage custom validation" below to create custom rules to define when this component is valid.' ); evaluationTypeOptions = this.logicBuilderService.getEvaluationTypeOptionsForValidity(); constructor ( private logicBuilderService: LogicBuilderService, private i18n: I18nService, private modalFactory: ModalFactory, private formLogicService: FormLogicService, private formBuilderService: FormBuilderService ) { } get errorMessage () { return this.customValidation?.result; } ngOnInit () { if (!this.customValidation) { this.setInitialLogic(); } else { this.setData(this.customValidation, this.customValidation.result); } this.setAvailableColumns(); this.emitValidity(); } setAvailableColumns () { const { availableColumns } = this.formLogicService.getAvailableLogicColumnsForComponent( this.component, false, this.formBuilderService.currentFormBuilderDefinition, this.formBuilderService.currentFormBuilderIndex, this.formBuilderService.currentFormBuilderFormAudience, false ); this.availableColumns = availableColumns; } setInitialLogic () { this.customValidation = { ...this.logicBuilderService.getDefaultConditionalLogic(), result: '', resultType: ConditionalLogicResultType.STATIC_VALUE }; this.emitConditionalLogic(); } getHasValidConditions () { return this.logicBuilderService.getHasValidConditions(this.customValidation); } async openLogicBuilderModal () { this.onModalOpenOrClose.emit(true); if (!this.customValidation) { this.setInitialLogic(); } const validationMessage = this.customValidation.result; const logic = { ...this.customValidation }; logic.evaluationType = EvaluationType.ConditionallyTrue; delete logic.result; const response = await this.modalFactory.open< ConditionalLogicBuilderModalComponent >( ConditionalLogicBuilderModalComponent, { builderName: this.i18n.translate( 'FORMS:hdrManageCustomValidity', {}, 'Manage Custom Validity' ), evaluationTypeOptions: null, currentColumnName: this.label, availableColumns: this.availableColumns, logic } ); this.onModalOpenOrClose.emit(false); if (response) { this.customValidation = { ...response, result: validationMessage, resultType: ConditionalLogicResultType.VALIDATION_MESSAGE }; this.emitConditionalLogic(); } } private setData ( response: GlobalLogicGroup, validationMessage: string ) { this.customValidation = { ...(response as GlobalValueLogicGroup), result: validationMessage }; this.dataWithoutResult = { ...this.customValidation }; delete this.dataWithoutResult.result; } handleEvaluationTypeChange (evaluationType: EvaluationType) { this.customValidation = { ...this.customValidation, evaluationType }; this.emitConditionalLogic(); } handleResultChange (newValue: string) { this.customValidation = { ...this.customValidation, result: newValue }; this.emitConditionalLogic(); } emitConditionalLogic () { this.onChange.emit(this.customValidation); this.setData(this.customValidation, this.customValidation.result); this.emitValidity(); } emitValidity () { const hasConditionalLogic = this.logicBuilderService.getHasConditionalLogic( this.customValidation?.evaluationType ); const hasValidConditions = this.getHasValidConditions(); let isValid = true; if (hasConditionalLogic) { isValid = hasValidConditions && !!this.customValidation?.result; this.showInvalidConditionsMessage = !hasValidConditions; } else { this.showInvalidConditionsMessage = false; } this.isValidChange.emit(isValid); } }