import { CdkDragDrop } from '@angular/cdk/drag-drop'; import { Component, EventEmitter, HostListener, Input, OnChanges, OnInit, Optional, Output, SimpleChanges } from '@angular/core'; import { CurrencyService } from '@core/services/currency.service'; import { BaseApplication } from '@core/typings/application.typing'; import { ReferenceFieldsUI } from '@core/typings/ui/reference-fields.typing'; import { BaseApplicationForLogic, FormComponentValidChange, FormDecisionTypes, FormDefinitionComponent, FormioAnswerValues, FormioChangesWithCompKey, FormioComponentType, FormValueChange } from '@features/configure-forms/form.typing'; import { FormBuilderActionEvent } from '@features/formio/form-builder/form-builder.typing'; import { FormBuilderComponent } from '@features/formio/form-builder/form-builder/form-builder.component'; import { ComponentHelperService } from '@features/formio/services/component-helper/component-helper.service'; import { FormHelperService } from '@features/formio/services/form-helper/form-helper.service'; import { FormLogicService } from '@features/formio/services/form-logic/form-logic.service'; import { InKindRequestedItem } from '@features/in-kind/in-kind.typing'; import { LogicState } from '@features/logic-builder/logic-builder.typing'; import { ReferenceFieldsService } from '@features/reference-fields/services/reference-fields.service'; import { SimpleStringMap, TypeaheadSelectOption, TypeToken } from '@yourcause/common'; import { CurrencyValue } from '@yourcause/common/masking'; import { isEqual } from 'lodash'; import { SpecialHandling } from '../standard-formio-components/gc-special-handling/gc-special-handling.component'; @Component({ selector: 'gc-formio-component-display', templateUrl: './formio-component-display.component.html', styleUrls: ['./formio-component-display.component.scss'] }) export class FormioComponentDisplayComponent implements OnInit, OnChanges { @Input() depth: number; // used to organize drop containers for the builder @Input() formId: number; @Input() editable: boolean; @Input() component: FormDefinitionComponent; @Input() masked: boolean; @Input() disabledOverride: boolean; @Input() showErrorSummary: boolean; @Input() value: FormioAnswerValues; @Input() parentFields: Partial; @Input() isManagerEditingApplicantForm: boolean; @Input() isManagerForm: boolean; @Input() translations: SimpleStringMap; @Input() validityState: LogicState; @Input() errorOverride: string; @Input() isForSetValue: boolean; // pass true if this input is used to capture default value @Input() lastCompOnPage: boolean; @Input() notAutoSave: boolean; @Input() uploadRequestStatusText: string; @Input() inConfigModal: boolean; @Input() emitInitialValidity = false; @Output() onValueChange = new EventEmitter(); @Output() onValidChange = new EventEmitter(); @Output() componentDropped = new EventEmitter>(); @Output() componentActionClick = new EventEmitter(); hovered = false; type: FormioComponentType; valueForField: FormioAnswerValues; currency: string; forceDefaultCurrency: boolean; currencyOptions: TypeaheadSelectOption[] = []; canToggleCurrency = false; afterInit = false; $number = new TypeToken(); $string = new TypeToken(); $decisionType = new TypeToken(); $specialHandling = new TypeToken(); $inKindItems = new TypeToken(); $currencyValue = new TypeToken(); @HostListener('mouseenter') handleMouseEnter () { this.hovered = true; } @HostListener('mouseleave') handleMouseLeave () { this.hovered = false; } constructor ( @Optional() private formBuilder: FormBuilderComponent, private formHelperService: FormHelperService, private formLogicService: FormLogicService, private componentHelper: ComponentHelperService, private referenceFieldService: ReferenceFieldsService, private currencyService: CurrencyService ) { } get isHidden () { return this.component.isHidden; } get toolboxOpen () { return this.formBuilder?.toolboxOpen; } ngOnInit () { this.type = this.componentHelper.getAdaptedTypeFromComponentType( this.component.type ); this.handleCurrencies(); this.setValueForField(); this.afterInit = true; } ngOnChanges (changes: SimpleChanges) { if (changes.value && this.afterInit) { if (!isEqual(changes.value.previousValue, changes.value.currentValue)) { this.setValueForField(); } } } handleCurrencies () { const refField = this.referenceFieldService.getReferenceFieldFromCompType(this.component.type); const isCurrencyField = this.type === 'amountRequested' || refField?.type === ReferenceFieldsUI.ReferenceFieldTypes.Currency; if (isCurrencyField) { if (this.type === 'amountRequested') { if (!this.isForSetValue) { this.forceDefaultCurrency = this.formHelperService.shouldForceDefaultCurrencyInAmountRequested( this.isManagerForm, this.isManagerEditingApplicantForm ); } } const currency = (this.value as CurrencyValue)?.currency; this.currencyOptions = this.currencyService.getCurrencyOptionsForComponent( currency, this.component.useCustomCurrency, this.component.customCurrency ); this.canToggleCurrency = this.formHelperService.canToggleCurrency( currency, this.disabledOverride, this.isForSetValue ); } } handleComponentDropped (drop: CdkDragDrop) { this.componentDropped.emit(drop); } setValueForField () { this.valueForField = this.value; } valueChanged (change: FormValueChange) { this.formLogicService.setValueForComp(this.component, change.value); const changes = this.componentHelper.adaptToFormChanges( this.component, change.value, change.updateFormGroup ); this.onValueChange.emit(changes); } }