import { Component, Input, OnInit } from '@angular/core'; import { CurrencyService } from '@core/services/currency.service'; import { SpinnerService } from '@core/services/spinner.service'; import { ReferenceFieldsUI } from '@core/typings/ui/reference-fields.typing'; import { ClientSettingsService } from '@features/client-settings/client-settings.service'; import { FormComponentValidChange, FormDefinitionComponent, FormioChanges } from '@features/configure-forms/form.typing'; import { CustomDataTablesService } from '@features/custom-data-tables/custom-data-table.service'; import { ComponentHelperService } from '@features/formio/services/component-helper/component-helper.service'; import { FormHelperService } from '@features/formio/services/form-helper/form-helper.service'; import { ReferenceFieldsService, REF_COMPONENT_TYPE_PREFIX } from '@features/reference-fields/services/reference-fields.service'; import { SimpleStringMap, TypeaheadSelectOption } from '@yourcause/common'; import { I18nService } from '@yourcause/common/i18n'; import { CurrencyRadioOptions } from '@yourcause/common/masking'; import { YCModalComponent } from '@yourcause/common/modals'; @Component({ selector: 'gc-table-field-crud-modal', templateUrl: './table-field-crud-modal.component.html', styleUrls: ['./table-field-crud-modal.component.scss'] }) export class TableFieldCrudModalComponent extends YCModalComponent< { row: ReferenceFieldsUI.TableResponseRowForUi; addAnother: boolean; openNext: boolean; openPrevious: boolean; } > implements OnInit { @Input() currentRow: ReferenceFieldsUI.TableResponseRowForUiMapped; @Input() tableReferenceFieldId: number; @Input() tableLabel: string; @Input() formId: number; @Input() isView = false; @Input() disableNextBtn: boolean; @Input() disablePreviousBtn: boolean; @Input() applicationId: number; @Input() applicationFormId: number; @Input() notAutoSave: boolean; @Input() translations: SimpleStringMap; modalHeader: string; primaryButtonText: string; secondaryButtonText: string; primaryDisabled: boolean; secondaryDisabled: boolean; FieldTypes = ReferenceFieldsUI.ReferenceFieldTypes; cdtItemsMap: Record = {}; responseMap: ReferenceFieldsUI.RefResponseMap = {}; defaultCurrency = this.clientSettingsService.defaultCurrency; formattingData = this.currencyService.formattingData; currencyIcon = this.formattingData[this.defaultCurrency].symbol; ready = false; errorString: string; tableColumns: ReferenceFieldsUI.TableFieldForCrudUi[]; validityMap: Record = {}; saving: boolean; constructor ( private i18n: I18nService, private referenceFieldService: ReferenceFieldsService, private customDataTableService: CustomDataTablesService, private clientSettingsService: ClientSettingsService, private currencyService: CurrencyService, private componentHelper: ComponentHelperService, private spinnerService: SpinnerService, private formHelperService: FormHelperService ) { super(); } get customDataTableOptionsMap () { return this.customDataTableService.customDataTableOptionsMap; } async ngOnInit () { this.setModalAttrs(); this.setResponseMap(); this.setTableColumns(); this.prepareCdtItemsMap(); this.ready = true; } setModalAttrs () { if (this.currentRow) { this.modalHeader = this.i18n.translate( this.isView ? 'common:textView' : 'common:textEdit', {}, this.isView ? 'View' : 'Edit' ); this.primaryButtonText = this.i18n.translate( this.isView ? 'common:btnNext' : 'common:btnSave', {}, this.isView ? 'Next' : 'Save' ); if (this.isView) { this.secondaryButtonText = this.i18n.translate( 'common:textPrevious', {}, 'Previous' ); } } else { this.modalHeader = this.i18n.translate( 'GLOBAL:hdrAddNew', {}, 'Add New' ); this.primaryButtonText = this.i18n.translate( 'common:btnSave', {}, 'Save' ); this.secondaryButtonText = this.i18n.translate( 'GLOBAL:btnSaveAndAddAnother', {}, 'Save and add another' ); } } setTableColumns () { const tableColumns = this.referenceFieldService.tableColumnsMap[ this.tableReferenceFieldId ]; this.tableColumns = tableColumns .map((col) => { return { ...col, component: this.componentHelper.getComponentFromTableColumn( col ) }; }); } setResponseMap () { const tableColumns = this.referenceFieldService.tableColumnsMap[ this.tableReferenceFieldId ]; this.responseMap = tableColumns.reduce((acc, column) => { const foundResponse = this.currentRow?.columns.find((col) => { return col.referenceFieldId === column.referenceFieldId; }); let value = foundResponse?.value; if (!value) { const component = { type: `${REF_COMPONENT_TYPE_PREFIX}${column.referenceField.key}`, useCustomCurrency: CurrencyRadioOptions.USE_ONE_CURRENCY, customCurrency: this.clientSettingsService.defaultCurrency } as FormDefinitionComponent; value = this.formHelperService.getValueFromComponent( component, { referenceFields: {} }, true ); } return { ...acc, [column.referenceField.key]: value }; }, {}); } prepareCdtItemsMap () { this.cdtItemsMap = this.customDataTableService.getCdtItemsMapForRow( this.tableColumns, this.currentRow ); } adaptTableRows (): ReferenceFieldsUI.TableResponseRowForUi { return { rowId: this.currentRow?.rowId ?? null, columns: this.tableColumns.map((column) => { return { referenceFieldId: column.referenceFieldId, referenceFieldKey: column.referenceField.key, value: this.responseMap[column.referenceField.key], dateValue: '', currencyValue: '', numericValue: null, file: null, files: [], applicationFormId: this.applicationFormId, applicationId: this.applicationId }; }) }; } onValueChange ( changes: FormioChanges, referenceFieldKey: string ) { this.responseMap[referenceFieldKey] = changes.value; } onValidChange ( validChanges: FormComponentValidChange, referenceFieldId: number ) { this.validityMap[referenceFieldId] = validChanges.isValid; this.setDisabledAttrs(); } setDisabledAttrs () { if (this.isView) { this.primaryDisabled = this.disableNextBtn; this.secondaryDisabled = this.disablePreviousBtn; } else { const allFieldsValid = this.tableColumns.every((column) => { return this.validityMap[column.referenceFieldId]; }); this.primaryDisabled = !allFieldsValid; this.secondaryDisabled = !allFieldsValid; } } async handleFileUploads () { const result = await this.referenceFieldService.handleTableFileUploads( this.tableColumns, this.responseMap, this.applicationId, this.applicationFormId ); if (!!result) { this.responseMap = result; } return !!result; } async onPrimaryClick () { if (this.isView) { /* Open Next Record */ this.closeModal.emit({ row: this.adaptTableRows(), addAnother: false, openNext: true, openPrevious: false }); } else { this.handleFilesAndCloseModal(false); } } async handleFilesAndCloseModal (addAnother: boolean) { let passed = true; if (!this.notAutoSave) { this.spinnerService.startSpinner(); this.saving = true; passed = await this.handleFileUploads(); this.saving = false; this.spinnerService.stopSpinner(); } if (passed) { /* Save and Exit */ this.closeModal.emit({ row: this.adaptTableRows(), addAnother, openNext: false, openPrevious: false }); } } onSecondaryClick () { if (this.isView) { /* Open Previous Record */ this.closeModal.emit({ row: this.adaptTableRows(), addAnother: false, openNext: false, openPrevious: true }); } else { this.handleFilesAndCloseModal(true); } } }