tuain-ng-forms-lib
Version:
Componentes y Clases Angular para la gestión de formularios TUAIN
1 lines • 367 kB
Source Map (JSON)
{"version":3,"file":"tuain-ng-forms-lib.mjs","sources":["../../../projects/tuain-ng-forms-lib/src/lib/components/elements/layout/piece.component.ts","../../../projects/tuain-ng-forms-lib/src/lib/components/elements/layout/element.component.ts","../../../projects/tuain-ng-forms-lib/src/lib/components/elements/action.component.ts","../../../projects/tuain-ng-forms-lib/src/lib/components/elements/field.component.ts","../../../projects/tuain-ng-forms-lib/src/lib/components/elements/layout/form-error.component.ts","../../../projects/tuain-ng-forms-lib/src/lib/components/elements/layout/form-header.component.ts","../../../projects/tuain-ng-forms-lib/src/lib/components/elements/layout/section.component.ts","../../../projects/tuain-ng-forms-lib/src/lib/components/elements/layout/sub-section.component.ts","../../../projects/tuain-ng-forms-lib/src/lib/components/elements/tables/table-record-action.component.ts","../../../projects/tuain-ng-forms-lib/src/lib/components/elements/tables/table-record-field.component.ts","../../../projects/tuain-ng-forms-lib/src/lib/components/elements/tables/table.component.ts","../../../projects/tuain-ng-forms-lib/src/lib/classes/forms/form.constants.ts","../../../projects/tuain-ng-forms-lib/src/lib/classes/forms/piece.ts","../../../projects/tuain-ng-forms-lib/src/lib/classes/forms/piece-propagate.ts","../../../projects/tuain-ng-forms-lib/src/lib/classes/forms/element.ts","../../../projects/tuain-ng-forms-lib/src/lib/classes/forms/action.ts","../../../projects/tuain-ng-forms-lib/src/lib/classes/forms/field.ts","../../../projects/tuain-ng-forms-lib/src/lib/classes/forms/table/column.ts","../../../projects/tuain-ng-forms-lib/src/lib/classes/forms/table/action.ts","../../../projects/tuain-ng-forms-lib/src/lib/classes/forms/table/row-data.ts","../../../projects/tuain-ng-forms-lib/src/lib/classes/forms/table/table.ts","../../../projects/tuain-ng-forms-lib/src/lib/classes/forms/subsection.ts","../../../projects/tuain-ng-forms-lib/src/lib/classes/forms/section.ts","../../../projects/tuain-ng-forms-lib/src/lib/classes/forms/form.ts","../../../projects/tuain-ng-forms-lib/src/lib/services/form-manager.service.ts","../../../projects/tuain-ng-forms-lib/src/lib/services/event-manager.service.ts","../../../projects/tuain-ng-forms-lib/src/lib/services/file-manager.service.ts","../../../projects/tuain-ng-forms-lib/src/lib/components/forms/basic-form.ts","../../../projects/tuain-ng-forms-lib/src/lib/tuain-ng-forms-lib.module.ts","../../../projects/tuain-ng-forms-lib/src/public-api.ts","../../../projects/tuain-ng-forms-lib/src/tuain-ng-forms-lib.ts"],"sourcesContent":["import { Component, signal, computed } from '@angular/core';\n\nconst CUSTOM_ATTRIBUTES = 'customAttributes';\n@Component({\n selector: 'lib-piece',\n template: `<ng-content></ng-content>`\n})\nexport class PieceComponent {\n form: any;\n formConfig: any;\n visible: any = signal(false);\n disabled: any = signal(false);\n enabled: any = computed(() => !this.disabled());\n customAttributes: any = signal({});\n\n setForm(form) { this.form = form; }\n\n propagatedAttributeChange(attribute: string, value?: any) { }\n\n updatePieceAttribute(signaledAttributes, signaledAttribute, value) {\n if (!signaledAttributes.includes(signaledAttribute)) { return; }\n this[signaledAttribute]?.set(value);\n this.propagatedAttributeChange(signaledAttribute, value);\n }\n\n updatePieceAttributes(piece, signaledAttributes) {\n if (!piece) { return; }\n // Se recore el conjunto de los atributos propagados desde el piece y se asigna el valor respectivo\n for (let index = 0; index < signaledAttributes.length; index++) {\n const signaledAttribute = signaledAttributes[index];\n try {\n this[signaledAttribute]?.set(piece?.[signaledAttribute]);\n this.propagatedAttributeChange(signaledAttribute, piece?.[signaledAttribute]);\n } catch (e) {\n console.log(`Señal ${signaledAttribute} invalida en el componente. ${e}`);\n }\n }\n }\n\n // Función que las subclases pueden sobrecargar para manejar un comportamiento específico\n customAttributeChange(subAttribute: string, value?: any) { }\n\n updateCustomAttribute(attrName, attrValue) {\n this.customAttributes.update(oldCustomAttr => {\n oldCustomAttr[attrName] = attrValue;\n return oldCustomAttr;\n });\n // Ejecución de función personalizada ante un cambio de atributo personalizado\n this.customAttributeChange(attrName, attrValue);\n }\n\n replaceCustomAttributes(customAttributes) {\n this.customAttributes.set(customAttributes ?? {});\n Object.keys(customAttributes).forEach(attrName => {\n const attrValue = customAttributes[attrName];\n // Ejecución de función personalizada ante un cambio de atributo personalizado\n this.customAttributeChange(attrName, attrValue);\n });\n }\n}\n","import { Component, Input } from '@angular/core';\nimport { PieceComponent } from './piece.component';\n\n@Component({\n selector: 'lib-element',\n template: `<ng-content></ng-content>`\n})\nexport class ElementComponent extends PieceComponent {\n @Input() element: any;\n\n start() {\n this.setForm(this.element?._form);\n }\n}\n","import { Component, signal, Input, OnInit } from '@angular/core';\nimport { Subject, takeUntil } from 'rxjs';\nimport { FormAction } from '../../classes/forms/action';\nimport { ElementComponent } from './layout/element.component';\n\nconst CUSTOM_ATTRIBUTES = 'customAttributes';\n\nconst signaledAttributes = [\n 'actionCode', 'actionName', 'iconName', 'inProgress', 'restrictedOnField', 'restrictedOnOperator',\n 'restrictedOnValue', 'visible', 'disabled',\n];\n\n@Component({\n selector: 'lib-action',\n template: `<ng-content></ng-content>`\n})\n\nexport class ActionComponent extends ElementComponent implements OnInit {\n private destroy$ = new Subject<void>();\n\n actionCode: any = signal(null);\n actionName: any = signal(null);\n iconName: any = signal(null);\n inProgress: any = signal(false);\n restrictedOnField: any = signal(null);\n restrictedOnOperator: any = signal(null);\n restrictedOnValue: any = signal(null);\n\n @Input() action: FormAction | null = null;\n\n updatePropagatedAttributes() {\n this.updatePieceAttributes(this.action, signaledAttributes)\n }\n\n ngOnInit() {\n if (!this.action) { return; }\n this.action.widget = this;\n this.formConfig = this.action?._formConfig;\n this.updatePropagatedAttributes();\n this.replaceCustomAttributes(this.action?.customAttributes);\n this.action?.attributeChange\n .pipe(takeUntil(this.destroy$))\n .subscribe(event => {\n const { name: attribute, value = null } = event ?? {};\n const attributeParts = attribute?.split('.') ?? [];\n if (signaledAttributes.includes(attribute)) {\n this.updatePieceAttribute(signaledAttributes, attribute, value);\n } else if (attributeParts?.length > 1 && attributeParts?.[0] === CUSTOM_ATTRIBUTES) {\n const subAttribute = attributeParts?.[1] ?? null;\n this.updateCustomAttribute(subAttribute, value);\n }\n });\n this.start();\n }\n\n override start() {\n this.setForm(this.action?._form);\n }\n\n activate() {\n if (this.action?.notifyActivation) {\n this.action.notifyActivation();\n }\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n}","import { Component, signal, Input, input, model, OnInit } from '@angular/core';\nimport { Subject, takeUntil } from 'rxjs';\nimport { FieldDescriptor } from '../../classes/forms/field';\nimport { ElementComponent } from './layout/element.component'\n\nconst CUSTOM_ATTRIBUTES = 'customAttributes';\n\nconst signaledAttributes = ['captureType', 'errorCode', 'errorMessage', 'errorType', 'defaultValue',\n 'defaultEditable', 'alignment', 'code', 'info', 'required', 'title', 'type', 'format', 'options',\n 'hasChanged', 'maxLength', 'maxValue', 'minLength', 'minValue', 'onValidation', 'outputOnly',\n 'placeholder', 'tooltip', 'validateOnServer', 'visibleLabel', 'visible', 'disabled', 'value',\n];\n\nconst VALUE = 'value';\nconst FOCUS = 'focus';\n@Component({\n selector: 'lib-field',\n template: `<ng-content></ng-content>`\n})\nexport class FieldComponent extends ElementComponent implements OnInit {\n private destroy$ = new Subject<void>();\n\n // Atributos propagados desde el campo\n captureType: any = signal<string>('');\n errorCode: any = signal<string>('');\n errorMessage: any = signal<string>('');\n errorType: any = signal<string>('');\n defaultValue: any = signal<any>(null);\n defaultEditable: any = signal<boolean>(false);\n alignment: any = signal<string>('');\n code: any = signal<string>('');\n info: any = signal<any>(null);\n required: any = signal<boolean>(false);\n title: any = signal<string>('');\n type: any = signal<string>('');\n format: any = signal<any>(null);\n options: any = signal<any[]>([]);\n hasChanged: any = signal<boolean>(false);\n minLength: any = signal<number>(0);\n maxLength: any = signal<number>(0);\n minValue: any = signal<any>(null);\n maxValue: any = signal<any>(null);\n onValidation: any = signal<boolean>(false);\n outputOnly: any = signal<boolean>(false);\n placeholder: any = signal<string>('');\n tooltip: any = signal<string>('');\n validateOnServer: any = signal<boolean>(false);\n visibleLabel: any = signal<boolean>(true);\n\n // value: any; // Valor del componente relacionado con el campo (pueden diferir en formato y tipo)\n value = model<any>(); // Valor del componente relacionado con el campo (pueden diferir en formato y tipo)\n @Input() field: FieldDescriptor | null = null;\n // field = input.required<FieldDescriptor>();\n\n updatePropagatedAttributes() {\n this.updatePieceAttributes(this.field, signaledAttributes)\n }\n\n ngOnInit() {\n if (!this.field) { return; }\n this.field.widget = this;\n this.formConfig = this.field?._formConfig;\n this.updatePropagatedAttributes();\n this.updateValue();\n this.replaceCustomAttributes(this.field?.customAttributes);\n this.field?.attributeChange\n .pipe(takeUntil(this.destroy$))\n .subscribe(event => {\n const { name: attribute, value = null } = event ?? {};\n const attributeParts = attribute?.split('.') ?? [];\n if (attribute === VALUE) {\n this.updateValue();\n } else if (attribute === FOCUS) {\n this.focus();\n } else if (signaledAttributes.includes(attribute)) {\n this.updatePieceAttribute(signaledAttributes, attribute, value);\n } else if (attributeParts?.length > 1 && attributeParts?.[0] === CUSTOM_ATTRIBUTES) {\n const subAttribute = attributeParts?.[1] ?? null;\n this.updateCustomAttribute(subAttribute, value);\n }\n });\n this.start();\n }\n\n updateValue() {\n try {\n this.value.set(this.field?.value);\n } catch (e) {\n console.log(`Excepción en componente de campo ${e}`);\n }\n }\n\n onInputChange() { setTimeout(() => this.field?.notifyEditionPartial(), 50); }\n onChangeContent() { setTimeout(() => this.field?.notifyEditionFinish(), 50); }\n onShowInfo(detail = null) { setTimeout(() => this.field?.notifyEditionDetailRequest(detail), 50); }\n\n focus() { }\n\n updateObject(widgetUpdate = true) { this.field?.setValue(this.value(), widgetUpdate); }\n\n inputChanged() {\n this.updateObject();\n this.onChangeContent();\n }\n\n inputTyped() {\n this.updateObject(false);\n this.onInputChange();\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n}\n","import { Component, Input } from '@angular/core';\n\n@Component({\n selector: 'lib-form-error',\n template: `<ng-content></ng-content>`\n})\nexport class FormErrorComponent {\n @Input() errorTitle: any;\n @Input() errorMessage: any;\n @Input() errorType: any;\n}\n","import { Component, Input, Output, EventEmitter } from '@angular/core';\n\n@Component({\n selector: 'lib-form-header',\n template: `<ng-content></ng-content>`\n})\nexport class FormHeaderComponent {\n @Input() form: any;\n @Output() goBackEvent: EventEmitter<void> = new EventEmitter<void>();\n\n goBackForm() {\n this.goBackEvent.emit();\n }\n}\n","import { Component, Input, OnInit } from '@angular/core';\nimport { Subject, takeUntil } from 'rxjs';\nimport { PieceComponent } from './piece.component';\n\nconst CUSTOM_ATTRIBUTES = 'customAttributes';\n\nconst signaledAttributes = [\n 'visible', 'disabled',\n];\n\n@Component({\n selector: 'lib-section',\n template: `<ng-content></ng-content>`\n})\nexport class SectionComponent extends PieceComponent implements OnInit {\n private destroy$ = new Subject<void>();\n\n @Input() section: any;\n\n updatePropagatedAttributes() {\n this.updatePieceAttributes(this.section, signaledAttributes)\n }\n\n ngOnInit() {\n if (!this.section) { return; }\n this.formConfig = this.section?._formConfig;\n this.updatePropagatedAttributes();\n this.replaceCustomAttributes(this.section?.customAttributes);\n this.section?.attributeChange\n .pipe(takeUntil(this.destroy$))\n .subscribe(event => {\n const { name: attribute, value = null } = event ?? {};\n const attributeParts = attribute?.split('.') ?? [];\n if (signaledAttributes.includes(attribute)) {\n this.updatePieceAttribute(signaledAttributes, attribute, value);\n } else if (attributeParts?.length > 1 && attributeParts?.[0] === CUSTOM_ATTRIBUTES) {\n const subAttribute = attributeParts?.[1] ?? null;\n this.updateCustomAttribute(subAttribute, value);\n }\n });\n this.start();\n }\n\n start() {\n this.setForm(this.section?._form);\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n}\n","import { Component, Input, OnInit } from '@angular/core';\nimport { Subject, takeUntil } from 'rxjs';\nimport { PieceComponent } from './piece.component';\n\nconst CUSTOM_ATTRIBUTES = 'customAttributes';\n\nconst signaledAttributes = [\n 'visible', 'disabled',\n];\n\n@Component({\n selector: 'lib-subsection',\n template: `<ng-content></ng-content>`\n})\nexport class SubSectionComponent extends PieceComponent implements OnInit {\n private destroy$ = new Subject<void>();\n\n @Input() subSection: any;\n\n updatePropagatedAttributes() {\n this.updatePieceAttributes(this.subSection, signaledAttributes)\n }\n\n ngOnInit() {\n if (!this.subSection) { return; }\n this.formConfig = this.subSection?._formConfig;\n this.updatePropagatedAttributes();\n this.replaceCustomAttributes(this.subSection?.customAttributes);\n this.subSection?.attributeChange\n .pipe(takeUntil(this.destroy$))\n .subscribe(event => {\n const { name: attribute, value = null } = event ?? {};\n const attributeParts = attribute?.split('.') ?? [];\n if (signaledAttributes.includes(attribute)) {\n this.updatePieceAttribute(signaledAttributes, attribute, value);\n } else if (attributeParts?.length > 1 && attributeParts?.[0] === CUSTOM_ATTRIBUTES) {\n const subAttribute = attributeParts?.[1] ?? null;\n this.updateCustomAttribute(subAttribute, value);\n }\n });\n this.start();\n }\n\n start() {\n this.setForm(this.subSection?._form);\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n}\n","import { Component, Input, Output, OnInit, EventEmitter, ChangeDetectionStrategy } from '@angular/core';\nimport { PieceComponent } from '../layout/piece.component';\nimport { TableEvent, TableActionEvent } from '../../../classes/forms/table/table';\nimport { TableAction } from '../../../classes/forms/table/action';\n\nconst INLINE_ACTION = 'INLINE';\nconst CUSTOM_ATTRIBUTES = 'customAttributes';\n\nconst signaledAttributes = [\n 'visible', 'disabled',\n];\n\n@Component({\n selector: 'lib-table-record-action',\n template: `<ng-content></ng-content>`,\n changeDetection: ChangeDetectionStrategy.OnPush\n})\n\nexport class LibTableRecordActionComponent extends PieceComponent implements OnInit {\n @Input() recordId: any;\n @Input() recordData: any;\n @Input() action: TableAction | undefined;\n\n @Output() actionSelected: EventEmitter<TableActionEvent> = new EventEmitter<TableActionEvent>();\n\n updatePropagatedAttributes() {\n this.updatePieceAttributes(this.action, signaledAttributes)\n }\n\n ngOnInit() {\n if (!this.action) { return; }\n this.formConfig = this.action?._formConfig;\n this.updatePropagatedAttributes();\n this.replaceCustomAttributes(this.action?.customAttributes);\n this.start();\n }\n\n start() {\n if (this.action && this.action.restrictedOnField && this.recordData) {\n const relatedField = this.action.restrictedOnField;\n if (relatedField) {\n const relatedFieldValue = this.recordData[relatedField];\n const restrictionOper = this.action.restrictedOnOperator;\n const restrictionValue = this.action.restrictedOnValue\n if ((restrictionOper === '==' && relatedFieldValue !== restrictionValue)\n || (restrictionOper === '!=' && relatedFieldValue === restrictionValue)) {\n this.visible.set(false);\n } else {\n this.visible.set(true);\n }\n }\n }\n }\n\n onActivate() {\n const tableEvent: TableActionEvent = {\n actionCode: this.action?.actionCode ?? '',\n recordId: this.recordId,\n recordData: this.recordData,\n };\n this.actionSelected.emit(tableEvent);\n }\n\n class() { }\n}\n","import { Component, Input, OnInit, ChangeDetectionStrategy } from '@angular/core';\n\n@Component({\n selector: 'lib-table-record-field',\n template: `<ng-content></ng-content>`,\n changeDetection: ChangeDetectionStrategy.OnPush\n})\n\nexport class LibTableRecordFieldComponent implements OnInit {\n @Input() fieldCode: any;\n @Input() fieldType: any;\n @Input() fieldValue: any;\n @Input() column: any = null;\n\n ngOnInit() {\n this.start();\n }\n\n start() { }\n}\n","import { Component, signal, OnInit, Input, ChangeDetectionStrategy } from '@angular/core';\nimport { Subject, takeUntil } from 'rxjs';\nimport { TableRecordData } from '../../../classes/forms/table/row-data';\nimport { TableActionEvent } from '../../../classes/forms/table/table';\nimport { RecordTable, TableEvent } from '../../../classes/forms/table/table';\nimport { ElementComponent } from '../layout/element.component';\n\nconst CUSTOM_ATTRIBUTES = 'customAttributes';\n\nconst signaledAttributes = [\n 'allSelected', 'code', 'globalSearch', 'recordsPerPage', 'layout',\n 'columns', 'selectedRecords', 'currentPage', 'totalRecordsNumber', 'visibleRecords',\n 'waiting', 'visible', 'disabled',\n];\n\n@Component({\n selector: 'lib-table',\n template: `<ng-content></ng-content>`,\n changeDetection: ChangeDetectionStrategy.OnPush\n})\n\nexport class LibTableComponent extends ElementComponent implements OnInit {\n private destroy$ = new Subject<void>();\n\n // Atributos sincronizados del objeto\n allSelected: any = signal<any>(null);\n code: any = signal<string>('');\n globalSearch: any = signal<any>(null);\n recordsPerPage: any = signal<any>(null);\n layout: any = signal<any>(null);\n columns: any = signal<any>(null);\n selectedRecords: any = signal<any>(null);\n currentPage: any = signal<any>(null);\n totalRecordsNumber: any = signal<any>(null);\n visibleRecords: any = signal<any[]>([]);\n waiting: any = signal<boolean>(false);\n\n globalFilterString: string = '';\n\n tableFieldStyles: any;\n loaded = false;\n selectable = false;\n hasActions = false;\n inlineActions: any;\n globalActions: any;\n selectionActions: any;\n\n @Input() table: RecordTable | null = null;\n\n ngOnInit() {\n if (!this.table) { return; }\n this.table.setWidget(this);\n this.formConfig = this.table?._formConfig;\n\n this.tableFieldStyles = this.formConfig?.tableFieldStyles;\n this.selectable = this.table?.selectable;\n this.hasActions = this.table?.hasActions();\n this.inlineActions = this.table?.getActions(this.formConfig?.tableActions.inline);\n this.globalActions = this.table?.getActions(this.formConfig?.tableActions.global);\n this.selectionActions = this.table?.getActions(this.formConfig?.tableActions.selection);\n this.globalFilterString = this.table?.globalFilterString;\n this.updatePropagatedAttributes();\n this.replaceCustomAttributes(this.table?.customAttributes);\n\n this.table?.attributeChange\n .pipe(takeUntil(this.destroy$))\n .subscribe(event => {\n const { name: attribute, value = null } = event ?? {};\n const attributeParts = attribute?.split('.') ?? [];\n if (attribute === 'visibleRecords') {\n this.visibleRecords.set(value ?? []);\n this.updateTableData();\n } else if (attribute === 'globalFilterString') {\n this.globalFilterString = value;\n } else if (signaledAttributes.includes(attribute)) {\n this.updatePieceAttribute(signaledAttributes, attribute, value);\n } else if (attributeParts?.length > 1 && attributeParts?.[0] === CUSTOM_ATTRIBUTES) {\n const subAttribute = attributeParts?.[1] ?? null;\n this.updateCustomAttribute(subAttribute, value);\n }\n });\n this.start();\n }\n\n updatePropagatedAttributes() {\n this.updatePieceAttributes(this.table, signaledAttributes)\n }\n\n updateTableData() { }\n tableGlobalAction(actionCode: string) { this.table?.notifyGlobalAction(actionCode); }\n tableSelectionAction(actionCode: string) { this.table?.notifySelectionAction(actionCode); }\n tableActionSelected(actionEvent: TableActionEvent) { this.table?.notifyInlineAction(actionEvent); }\n tableSelectionToggle(recordId: any) { this.table?.notifyRecordSelection(recordId); }\n toggleSelectAll() { return (this.table?.allSelected) ? this.table?.unSelectAll() : this.table?.selectAll(); }\n globalFilterCompleted() { this.changePage(1); }\n changePage(requestedPage: number) { this.table?.changePage(requestedPage); }\n tableColumnSort(columnName: string, direction = null) { this.table?.sort(columnName, direction ?? 'ascend'); }\n globalFilterChanged() { this.table?.setGlobalFilterString(this.globalFilterString?.trim() ?? '', false); }\n\n filterHasChanged(column, values) {\n if (!values || values.length === 0) {\n this.table?.removeColumnFilter(column.fieldCode);\n } else {\n this.table?.addColumnFilter(column.fieldCode, values);\n }\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n}\n","export const NO_ERROR = '00';\nexport const HEADER = 'HEADER';\n\nexport const elementTypes = {\n action: 'ACTION',\n field: 'FIELD',\n table: 'TABLE',\n};\n\nexport const formActions = {\n tableAction: 'TABLEACTION',\n getData: 'GETDATA',\n getTableData: 'GETTABLEDATA',\n validate: 'VALIDATE',\n};\n\nexport const operators = {\n G: 'G',\n L: 'L',\n GE: 'GE',\n LE: 'LE',\n EQ: 'EQ',\n NEQ: 'NEQ',\n HAS: 'HAS',\n NOTHAS: 'NOTHAS',\n BETWEEN: 'BETWEEN',\n IN: 'IN',\n};\n","import { Subject, takeUntil } from 'rxjs';\n\nexport class FormPiece {\n private destroy$ = new Subject<void>();\n\n protected _formState: string = '';\n protected _visibleForced: boolean;\n protected _isForced: boolean;\n protected _absoluteVisible: boolean = true;\n protected _absoluteDisabled: boolean = false;\n protected _widget: any = null;\n\n protected visibleStates: string[] = [];\n protected enabledStates: string[] = [];\n\n public _form: any = null;\n public _formConfig: any;\n public _visible: boolean = true;\n public _disabled: boolean = false;\n public customAttributes: any = {};\n\n constructor(pieceDefinition: any, formConfig: any) {\n this._formConfig = formConfig;\n this._isForced = false;\n this._visibleForced = false;\n this.setVisibleStates(pieceDefinition.visibleStates);\n this.setEnabledStates(pieceDefinition.enabledStates);\n\n this.enabled = !pieceDefinition?.disabled ?? false;\n this.setVisibility(pieceDefinition?.visible ?? true);\n this.customAttributes = pieceDefinition?.customAttributes ?? {};\n if (pieceDefinition?.customAttributes) {\n Object.keys(pieceDefinition?.customAttributes)\n ?.forEach(attr => this.customAttributes[attr] = pieceDefinition?.customAttributes[attr])\n }\n }\n\n getCustomAttribute(name: string): any { return this.customAttributes?.[name] ?? null; }\n setCustomAttribute(name: string, value: any): void { if (name) { this.customAttributes[name] = value; } }\n\n setCustomAttributes(attributes: any): FormPiece {\n Object.entries(attributes).forEach(([name, value]) => {\n this.setCustomAttribute(name, value);\n });\n return this;\n }\n\n matchAttribute(name: string, value: string): boolean { return this.customAttributes?.[name] === value; }\n\n setVisibleStates(newStates: any): void {\n const visibleStates = (!Array.isArray(newStates) && typeof newStates === 'string')\n ? newStates.split(',').map(state => state.trim()).filter(state => state.length > 0)\n : newStates;\n this.visibleStates = (Array.isArray(visibleStates)) ? [...(new Set(visibleStates))] : [];\n }\n\n addVisibleState(state: string) {\n if (!this.visibleStates.includes(state)) {\n this.visibleStates.push(state);\n }\n }\n\n removeVisibleState(state: string) {\n const existStateIdx = this.visibleStates.findIndex(st => st === state);\n if (existStateIdx >= 0) {\n this.visibleStates.splice(existStateIdx, 1);\n }\n }\n\n setEnabledStates(newStates: any): void {\n const enabledStates = (!Array.isArray(newStates) && typeof newStates === 'string')\n ? newStates.split(',').map(state => state.trim()).filter(state => state.length > 0)\n : newStates;\n this.enabledStates = (Array.isArray(enabledStates)) ? [...(new Set(enabledStates))] : [];\n }\n\n addEnabledState(state: string) {\n if (!this.enabledStates.includes(state)) {\n this.enabledStates.push(state);\n }\n }\n\n removeEnabledState(state: string) {\n const existStateIdx = this.enabledStates.findIndex(st => st === state);\n if (existStateIdx >= 0) {\n this.enabledStates.splice(existStateIdx, 1);\n }\n }\n\n viewOnState(state: string): boolean { return (this.visibleStates && state) ? this.visibleStates.includes(state) : false; }\n enabledOnState(state: string): boolean { return (this.enabledStates && state) ? this.enabledStates.includes(state) : false; }\n\n get absoluteVisible(): boolean { return this._absoluteVisible; }\n get absoluteDisabled(): boolean { return this._absoluteDisabled; }\n\n get visible(): boolean { return this._visible; }\n set visible(visible: boolean) { this.setVisibility(visible); }\n\n visibleOn(state: string): boolean {\n return this._absoluteVisible && this.viewOnState(state);\n }\n\n enabledOn(state: string): boolean {\n return !this._absoluteDisabled && this.enabledOnState(state);\n }\n\n setVisibility(visible: boolean, forced: boolean | null = null): void {\n this._absoluteVisible = !!visible;\n if (forced !== null) {\n this._isForced = forced;\n this._visibleForced = visible;\n }\n this._visible = this._absoluteVisible && this.viewOnState(this._formState);\n }\n\n show(forced: boolean | null = null): void {\n this.setVisibility(true, forced);\n }\n\n hide(forced: boolean | null = null): void {\n this.setVisibility(false, forced);\n }\n\n get enabled(): boolean { return !this._disabled; }\n set enabled(enabled) {\n this._absoluteDisabled = !enabled;\n this._disabled = this._absoluteDisabled || !this.enabledOnState(this._formState);\n }\n\n get editable(): boolean { return !this._disabled; }\n\n get disabled(): boolean { return this._disabled; }\n\n set disabled(disabled) { this.enabled = !disabled; }\n\n enable(): void { this.enabled = true; }\n disable(): void { this.enabled = false; }\n\n formStateChangeCustomSubscribe(form, formChangeSubject) { }\n\n formStateChange(state) {\n if (state) {\n this._formState = state;\n this._visible = this._absoluteVisible && this.viewOnState(state);\n this._disabled = this._absoluteDisabled || !this.enabledOnState(state);\n }\n }\n\n connectWithParentForm(form, formChangeSubject) {\n this._form = form;\n this.formStateChangeCustomSubscribe(form, formChangeSubject);\n formChangeSubject\n .pipe(takeUntil(this.destroy$))\n .subscribe(event => this.formStateChange(event?.state));\n }\n\n set widget(widget) { this._widget = widget; }\n get widget() { return this._widget; }\n\n destroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n}\n","import { BehaviorSubject } from 'rxjs';\nimport { FormPiece } from './piece';\n\nconst VISIBLE = 'visible';\nconst DISABLED = 'disabled';\n\nexport class FormPiecePropagate extends FormPiece {\n protected propagationCustomAttributes: string[] = [];\n protected _attributeChange: BehaviorSubject<any>;\n\n constructor(pieceDefinition: any, formConfig: any) {\n super(pieceDefinition, formConfig);\n this._attributeChange = new BehaviorSubject<any>(null);\n }\n\n get attributeChange() { return this._attributeChange.asObservable(); }\n\n propagateAttribute(name, value) {\n this._attributeChange?.next({ name, value });\n }\n\n override setCustomAttribute(name: string, value: any): void {\n super.setCustomAttribute(name, value);\n if (this.propagationCustomAttributes?.includes(name)) {\n const fullName = `customAttributes.${name}`;\n this.propagateAttribute(fullName, value);\n }\n }\n\n override setVisibility(visible: boolean, forced: boolean | null = null): void {\n super.setVisibility(visible, forced);\n this.propagateAttribute(VISIBLE, this._visible);\n }\n\n override set enabled(enabled) {\n super.enabled = enabled;\n this.propagateAttribute(DISABLED, this._disabled);\n }\n\n override formStateChange(state) {\n super.formStateChange(state);\n if (state) {\n this.propagateAttribute(VISIBLE, this._visible);\n this.propagateAttribute(DISABLED, this._disabled);\n }\n }\n}\n","import { FormPiecePropagate } from './piece-propagate';\nimport { elementTypes } from './form.constants';\nexport class FormElement extends FormPiecePropagate {\n elementType: string | null = null;\n\n constructor(elementDefinition: any, formConfig: any) {\n super(elementDefinition, formConfig);\n }\n\n setAttr(attr: any, value: any) {\n const { name: attrName, propagate: name } = attr;\n try {\n const currentValue = this[attrName];\n if (currentValue !== value) {\n this[attrName] = value;\n name && this.propagateAttribute(name, value);\n }\n } catch (e) {\n console.log(`Atributo ${attrName} no presente o valor ${value} inconsistente. ${e}`);\n }\n }\n\n isField(): boolean { return this.elementType === elementTypes.field; }\n isAction(): boolean { return this.elementType === elementTypes.action; }\n isTable(): boolean { return this.elementType === elementTypes.table; }\n}\n","import { Subject } from 'rxjs';\nimport { elementTypes } from './form.constants';\nimport { FormElement } from './element';\n\nconst HEADER = 'HEADER';\n\nconst attrs = {\n actionCode: { name: '_actionCode', propagate: 'actionCode' },\n actionName: { name: '_actionName', propagate: 'actionName' },\n iconName: { name: '_iconName', propagate: 'iconName' },\n inProgress: { name: '_inProgress', propagate: 'inProgress' },\n restrictedOnField: { name: '_restrictedOnField', propagate: 'restrictedOnField' },\n restrictedOnOperator: { name: '_restrictedOnOperator', propagate: 'restrictedOnOperator' },\n restrictedOnValue: { name: '_restrictedOnValue', propagate: 'restrictedOnValue' },\n}\n\nexport class FormAction extends FormElement {\n private readonly _actionActivated = new Subject<string>();\n private _actionCode: string = '';\n private _actionName: string = '';\n private _iconName: string = '';\n private _inProgress = false;\n private _newState: string;\n private _backend: boolean;\n private _restrictedOnField: string | null = null;\n private _restrictedOnOperator: string | null = null;\n private _restrictedOnValue: string | null = null;\n\n constructor(actionDefinition, formConfig) {\n super(actionDefinition, formConfig);\n this.propagationCustomAttributes = this._formConfig?.propagationCustomAttributes?.actions ?? [];\n this.elementType = elementTypes.action;\n this.setAttr(attrs.actionCode, actionDefinition.actionCode ? actionDefinition.actionCode.toString() : '');\n this.setAttr(attrs.actionName, actionDefinition.actionTitle);\n this.setAttr(attrs.iconName, actionDefinition.iconName || this._actionCode);\n this.setAttr(attrs.restrictedOnField, actionDefinition.fieldRestrictedCode?.toString() ?? null);\n if (this._restrictedOnField) {\n this.setAttr(attrs.restrictedOnOperator, actionDefinition.operatorRestricted || '');\n this.setAttr(attrs.restrictedOnValue, actionDefinition.valueRestricted ?? '');\n }\n this._backend = actionDefinition?.serverAction ?? false;\n this._newState = actionDefinition?.newState;\n this.setCustomAttribute('location', actionDefinition.position || HEADER);\n }\n\n get actionCode() { return this._actionCode; }\n get actionName() { return this._actionName; }\n get iconName() { return this._iconName; }\n get inProgress() { return this._inProgress; }\n get newState() { return this._newState; }\n get backend() { return this._backend; }\n get restrictedOnField() { return this._restrictedOnField; }\n get restrictedOnOperator() { return this._restrictedOnOperator; }\n get restrictedOnValue() { return this._restrictedOnValue; }\n\n set actionCode(actionCode) { this.setAttr(attrs.actionCode, actionCode); }\n set actionName(actionName) { this.setAttr(attrs.actionName, actionName); }\n set iconName(iconName) { this.setAttr(attrs.iconName, iconName); }\n set inProgress(inProgress) { this.setAttr(attrs.inProgress, inProgress); }\n set newState(newState) { this._newState, newState; }\n set backend(backend) { this._backend, backend; }\n set restrictedOnField(restrictedOnField) { this.setAttr(attrs.restrictedOnField, restrictedOnField); }\n set restrictedOnOperator(restrictedOnOperator) { this.setAttr(attrs.restrictedOnOperator, restrictedOnOperator); }\n set restrictedOnValue(restrictedOnValue) { this.setAttr(attrs.restrictedOnValue, restrictedOnValue); }\n\n start() { this.inProgress = true; }\n stop() { this.inProgress = false; }\n\n override connectWithParentForm(form, formChangeSubject) {\n super.connectWithParentForm(form, formChangeSubject);\n if (this._restrictedOnField) {\n const relatedField = this._form.fields?.[this._restrictedOnField];\n if (relatedField) {\n relatedField.editionFinish\n\n .subscribe(event => this.updateRestrictedVisibility(event));\n relatedField.editionPartial\n\n .subscribe(event => this.updateRestrictedVisibility(event));\n }\n }\n }\n\n updateRestrictedVisibility(event) {\n const newVisible = this._absoluteVisible && this.viewOnState(this._formState);\n (this._visible !== newVisible) && this.setVisibility(newVisible);\n }\n\n override viewOnState(state: string): boolean {\n const actionVisible = (this.visibleStates && state) ? this.visibleStates.includes(state) : false;\n if (actionVisible && this._form && this._restrictedOnField) {\n const relatedField = this._form.fields?.[this._restrictedOnField];\n if (relatedField) {\n const fieldValue = relatedField.value;\n if ((this._restrictedOnOperator === '==' && fieldValue !== this._restrictedOnValue)\n || (this._restrictedOnOperator === '!=' && fieldValue === this._restrictedOnValue)) {\n return false;\n }\n }\n }\n return actionVisible;\n }\n\n get actionActivated() { return this._actionActivated.asObservable(); }\n\n notifyActivation() { this._actionActivated.next(this._actionCode); }\n\n updateFromServer(receivedAction) {\n for (const propertyName in receivedAction) {\n if (propertyName !== 'actionCode' && propertyName !== 'actionId') {\n try {\n this[propertyName] = receivedAction[propertyName];\n } catch (e) {\n console.log(`Error actualizando la propiedad ${propertyName} de la acción ${this.actionCode}. ${e}`);\n }\n }\n }\n }\n}\n","import { Subject } from 'rxjs';\nimport yn from 'yn';\nimport { elementTypes, NO_ERROR } from './form.constants';\nimport { FormElement } from './element';\n\nconst UNDEFINED = 'undefined';\n\nconst DEFAULT_ERROR_TYPE = 'error';\nconst DEFAULT_CAPTURE_TYPE = 'INPUT';\nconst DEFAULT_ALIGNMENT = 'left';\n\nconst STD_MAX_LENGTH = 50;\nconst BIG_MAX_LENGTH = 500;\n\nconst directChanges = [\n 'defaultEditable', 'defaultValue', 'alignment', 'required', 'errorCode', 'errorMessage', 'errorType',\n 'tooltip', 'info', 'format', 'intrinsicErrorMessage', 'outputOnly', 'captureType', 'title', 'type',\n 'maxLength', 'maxValue', 'minLength', 'minValue', 'validateOnServer', 'serverAction', 'visibleLabel',\n 'options', 'placeholder',\n];\n\nconst attrs = {\n captureType: { name: '_captureType', propagate: 'captureType' },\n errorCode: { name: '_errorCode', propagate: 'errorCode' },\n errorMessage: { name: '_errorMessage', propagate: 'errorMessage' },\n errorType: { name: '_errorType', propagate: 'errorType' },\n defaultValue: { name: '_defaultValue', propagate: 'defaultValue' },\n defaultEditable: { name: '_defaultEditable', propagate: 'defaultEditable' },\n fieldAlignment: { name: '_fieldAlignment', propagate: 'alignment' },\n fieldCode: { name: '_fieldCode', propagate: 'code' },\n fieldInfo: { name: '_fieldInfo', propagate: 'info' },\n fieldRequired: { name: '_fieldRequired', propagate: 'required' },\n fieldTitle: { name: '_fieldTitle', propagate: 'title' },\n fieldType: { name: '_fieldType', propagate: 'type' },\n fieldFormat: { name: '_fieldFormat', propagate: 'format' },\n fieldOptions: { name: '_fieldOptions', propagate: 'options' },\n focus: { name: '_focus', propagate: 'focus' },\n hasChanged: { name: '_hasChanged', propagate: 'hasChanged' },\n intrinsicErrorMessage: { name: '_intrinsicErrorMessage', propagate: null },\n maxLength: { name: '_maxLength', propagate: 'maxLength' },\n maxValue: { name: '_maxValue', propagate: 'maxValue' },\n minLength: { name: '_minLength', propagate: 'minLength' },\n minValue: { name: '_minValue', propagate: 'minValue' },\n onValidation: { name: '_onValidation', propagate: 'onValidation' },\n outputOnly: { name: '_outputOnly', propagate: 'outputOnly' },\n placeholder: { name: '_placeholder', propagate: 'placeholder' },\n tooltipText: { name: '_tooltipText', propagate: 'tooltip' },\n validateOnServer: { name: '_validateOnServer', propagate: 'validateOnServer' },\n value: { name: '_value', propagate: 'value' },\n visibleLabel: { name: '_visibleLabel', propagate: 'visibleLabel' },\n};\n\nexport interface DetailEvent {\n code: string;\n detail: any;\n}\n\nexport interface FieldOption {\n fieldOptionValue: string;\n fieldOptionId: string;\n}\n\nexport class FieldDescriptor extends FormElement {\n private readonly _customEvent = new Subject<any>();\n private readonly _editionFinish = new Subject<any>();\n private readonly _editionPartial = new Subject<any>();\n private readonly _detailRequest = new Subject<DetailEvent>();\n\n private _errorType: string = '';\n private _errorCode: string = '';\n private _errorMessage: string = '';\n private _intrinsicErrorMessage: string = '';\n private _minValue: any;\n private _maxValue: any;\n private _maxLength: number = 0;\n private _minLength: number = 0;\n private _focus: boolean = false;\n private _onValidation: boolean = false;\n private _validateOnServer: boolean = false;\n private _value: any;\n private _visibleLabel: boolean = false;\n private _captureType: string = '';\n private _defaultValue: any = '';\n private _defaultEditable: boolean = false;\n private _externalValue: any;\n private _fieldAlignment: string = '';\n private _fieldInfo: any = '';\n private _fieldRequired: boolean = false;\n private _fieldTitle: string = '';\n private _fieldType: string = '';\n private _fieldFormat: RegExp | null = null;\n private _hasChanged: boolean = false;\n private _outputOnly: boolean = false;\n private _tooltipText: string = '';\n private _placeholder: string = '';\n private _fieldCode: string = '';\n private _fieldOptions: FieldOption[] | null = null;\n\n constructor(inputFieldReceived, formConfig) {\n super(inputFieldReceived, formConfig);\n this.propagationCustomAttributes = this._formConfig?.propagationCustomAttributes?.fields ?? [];\n this.elementType = elementTypes.field;\n const fld = (inputFieldReceived) ? inputFieldReceived : {};\n this.setAttr(attrs.fieldCode, fld.fieldCode);\n this.title = fld.fieldTitle ?? this._fieldCode;\n this.placeholder = fld.placeholder ?? this.title;\n this.type = fld.fieldTypeCode;\n this.captureType = fld.captureType ?? DEFAULT_CAPTURE_TYPE;\n\n const defaultValue = fld.defaultValue ?? null;\n if (this._fieldType === this._formConfig.fieldTypes.boolean) {\n this.defaultValue = defaultValue ?? false;\n } else {\n this.defaultValue = defaultValue;\n }\n const defaultTypeAlignment = (this._formConfig.tableFieldStyles[this._fieldType] != null)\n ? this._formConfig.tableFieldStyles[this._fieldType]['text-align'] : DEFAULT_ALIGNMENT;\n const fieldAlignment = (fld.alignment != null) ? fld.alignment.toLowerCase() : defaultTypeAlignment;\n this.alignment = fieldAlignment;\n this.info = fld.info || '';\n let fieldFormat;\n try {\n if (fld.format && typeof fld.format === 'string') {\n fieldFormat = new RegExp(fld.format);\n } else if (fld.format?.regExp) {\n fieldFormat = new RegExp(fld.format?.regExp);\n }\n } catch (e) {\n fieldFormat = null;\n }\n this.format = fieldFormat;\n this.validateOnServer = fld.serverAction ?? false;\n this.tooltip = fld.tooltip || '';\n this.defaultEditable = this.enabled;\n this.required = fld.required ?? false;\n this.outputOnly = fld.outputOnly ?? false;\n this.minLength = fld.minLength ?? 0;\n this.maxLength = fld.maxLength || (this._captureType === 'TEXTAREA' ? BIG_MAX_LENGTH : STD_MAX_LENGTH);\n this.intrinsicErrorMessage = this._formConfig?.fieldValidations?.[this._fieldType]?.message\n ?? this._formConfig?.fieldValidations?.DEFAULT?.message ?? '';\n\n this.setError(fld.errorCode, fld.errorMessage, fld.errorType ?? DEFAULT_ERROR_TYPE);\n this.setEditable(fld.editable ?? true);\n this.visibleLabel = fld.visibleLabel ?? true;\n this.setVisibility(fld.visible);\n this.options = fld.fieldOptions;\n this._setValue(fld.fieldValue ?? this._defaultValue ?? '');\n }\n\n get alignment() { return this._fieldAlignment; }\n set alignment(alignment) { this.setAttr(attrs.fieldAlignment, alignment); }\n get backend() { return this._validateOnServer; }\n\n get captureType() { return this._captureType; }\n set captureType(captureType) { this.setAttr(attrs.captureType, captureType); }\n\n get placeholder() { return this._placeholder; }\n set placeholder(placeholder) { this.setAttr(attrs.placeholder, placeholder); }\n\n get code() { return this._fieldCode; }\n get defaultValue() { return this._defaultValue; }\n set defaultValue(defaultValue) { this.setAttr(attrs.defaultValue, defaultValue); }\n get defaultEditable() { return this._defaultEditable; }\n set defaultEditable(editable) { this.setAttr(attrs.defaultEditable, editable); }\n get detailRequest() { return this._detailRequest.asObservable(); }\n get customEvent() { return this._customEvent.asObservable(); }\n get editionFinish() { return this._editionFinish.asObservable(); }\n get editionPartial() { return this._editionPartial.asObservable(); }\n\n get empty(): boolean {\n const fieldCurrentValue = this.value;\n if (fieldCurrentValue === undefined || fieldCurrentValue === null) {\n return true;\n }\n if (this._fieldType === this._formConfig.fieldTypes.array\n && Array.isArray(fieldCurrentValue) && fieldCurrentValue.length === 0) {\n return true;\n };\n if (this._fieldType === this._formConfig.fieldTypes.phone) {\n if (!Array.isArray(fieldCurrentValue)) {\n return true;\n }\n if (fieldCurrentValue.length !== 2 || !fieldCurrentValue[0] || !fieldCurrentValue[1]) {\n return true;\n }\n return false;\n };\n const arrayFieldTypes = this._formConfig.arrayFieldTypes ?? null;\n if (arrayFieldTypes && Object.keys(arrayFieldTypes).includes(this._fieldType)) {\n let arraySize = arrayFieldTypes[this._fieldType];\n arraySize = !Number.isNaN(+arraySize) ? +arraySize : 0;\n if (arraySize === 0) {\n return (Array.isArray(fieldCurrentValue) && fieldCurrentValue.length === 0);\n }\n return (Array.isArray(fieldCurrentValue) && fieldCurrentValue.length < arraySize);\n };\n return fieldCurrentValue === '';\n }\n\n get error() { return { type: this._errorType, code: this._errorCode, message: this._errorMessage }; }\n set error(errorObj) { this.setError(errorObj.code, errorObj.message, errorObj.type ?? DEFAULT_ERROR_TYPE) }\n get errorCode() { return this._errorCode; }\n set errorCode(code) { this.setError(code, this._errorMessage); }\n get errorMessage() { return this._errorMessage; }\n set errorMessage(msg) { this.setError(this._errorCode, msg); }\n get errorType() { return this._errorType; }\n get externalValue() { return this._externalValue; }\n get format() { return this._fieldFormat; }\n set format(format) { this.setAttr(attrs.fieldFormat, format); }\n get hasChanged() { return this._hasChanged; }\n set hasChanged(hasChanged) { this.setAttr(attrs.hasChanged, hasChanged); }\n\n get info() { return this._fieldInfo; }\n set info(newInfo: string) { this.setAttr(attrs.fieldInfo, newInfo); }\n set intrinsicErrorMessage(message: string) { this.setAttr(attrs.intrinsicErrorMessage, message); }\n get maxLength() { return (this._maxLength > 0) ? this._maxLength.toString() : ''; }\n set maxLength(requiredMaxLength: any) { this.setAttr(attrs.maxLength, requiredMaxLength ? +requiredMaxLength : null); }\n get maxValue() { return this._maxValue; }\n\n set maxValue(inputMaxValue) {\n let maxValue = inputMaxValue;\n if (this._fieldType === this._formConfig.fieldTypes.date) {\n maxValue = new Date(maxValue);\n }\n this.setAttr(attrs.maxValue, maxValue);\n }\n\n get minLength() { return this._minLength; }\n set minLength(requiredMinLength: number) {\n this.setAttr(attrs.minLength, requiredMinLength ? +requiredMinLength : null);\n }\n get minValue() { return this._minValue; }\n\n set minValue(inputMinValue) {\n let minValue = inputMinValue;\n if (this._fieldType === this._formConfig.fieldTypes.date) {\n minValue = new Date(minValue);\n }\n this.setAttr(attrs.minValue, minValue);\n }\n\n get name() { return this._fieldCode; }\n\n get options(): FieldOption[] | null {\n return this._fieldOptions?.map(option => {\n const optionCopy: FieldOption = { ...option };\n return optionCopy;\n }) ?? [];\n }\n\n set options(newOptions) {\n if ((!this._formConfig.captureTypesWithOptions.includes(this._captureType))\n || typeof newOptions === UNDEFINED || !newOptions\n || !Array.isArray(newOptions)) {\n return;\n }\n let fieldOptions = newOptions.map((option: any) => {\n if (option.text !== undefined && option.text !== null\n && option.value !== undefined && option.value !== null) {\n return { fieldOptionValue: option.text, fieldOptionId: option.value };\n }\n return option;\n });\n fieldOptions = (fieldOptions && Array.isArray(fieldOptions)\n && fieldOptions.length > 0) ? fieldOptions : [];\n this.setAttr(attrs.fieldOptions, fieldOptions);\n if (this._value) {\n if (this._fieldType === this._formConfig.fieldTypes.array && Array.isArray(this._value)) {\n const fieldValue = this._value?.filter(item =>\n this._fieldOptions?.find(opt => opt.fieldOptionId === item)\n );\n this.setAttr(attrs.value, fieldValue);\n } else {\n const valInOptions = this._fieldOptions?.find(item => item.fieldOptionId === this._value);\n if (!valInOptions) {\n this._setValue('');\n }\n }\n }\n if (this._fieldRequired && this._fieldOptions?.length === 1 && this._value !== this._fieldOptions?.[0].fieldOptionId) {\n this._setValue(this._fieldOptions?.[0].fieldOptionId);\n this.notifyEditionFinish();\n }\n }\n\n get optionText() { return this._fieldOptions?.find(item => item.fieldOptionId === this._value)?.fieldOptionValue ?? null; }\n get outputOnly() { return this._outputOnly; }\n set outputOnly(outputOnly) { this.setAttr(attrs.outputOnly, outputOnly); }\n get required(): boolean { return this._fieldRequired; }\n set required(required: boolean) { this.setAttr(attrs.fieldRequired, required ?? false); }\n get title() { return this._fieldTitle; }\n set title(title) { this.setAttr(attrs.fieldTitle, title?.toString() ?? ''); }\n get tooltip() { return this._tooltipText; }\n set tooltip(tooltip) { this.setAttr(attrs.tooltipText, tooltip); }\n get type() { return this._fieldType; }\n set type(fieldType) { this.setAttr(attrs.fieldType, fieldType); }\n get onValidation() { return this._onValidation; }\n get valid