UNPKG

tuain-ng-forms-lib

Version:

Componentes y Clases Angular para la gestión de formularios TUAIN

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