tuain-ng-forms-lib
Version:
Componentes y Clases Angular para la gestión de formularios TUAIN
1,210 lines • 194 kB
JavaScript
import { Component, signal } from '@angular/core';
import { Subject, takeUntil } from 'rxjs';
import { FormStructureAndData } from '../../classes/forms/form';
import { formActions, NO_ERROR } from '../../classes/forms/form.constants';
import * as i0 from "@angular/core";
import * as i1 from "../../services/form-manager.service";
import * as i2 from "../../services/event-manager.service";
import * as i3 from "../../services/file-manager.service";
const PAYLOAD_VERSION = 'TUAINEXCHANGE_1.0';
const INLINE_ACTION = 'INLINE';
const GLOBAL_ACTION = 'GLOBAL';
const GET_DATA_ACTION = 'GETDATA';
const SUBJECT = 'subject';
const TOKEN = 'token';
export class BasicFormComponent extends FormStructureAndData {
formManagerService;
_eventManager;
fileMgmtServices;
destroy$ = new Subject();
_controlToken = null;
_originToken = null;
_formRoute = null;
_definitionObtained = false;
_notifyFormActivity = true;
// Eventos de acciones y campos
_formChangeState = [];
_formSectionsCanDeactivate = {};
_formSectionsActivate = {};
_formSectionsInactivate = {};
_formActionsStart = {};
_formActionsFinish = {};
_fieldCustomeEvent = {};
_fieldInputValidation = {};
_fieldValidationsStart = {};
_fieldValidationsFinish = {};
// Callback de acciones de tablas
_tableSelectionsStart = {};
_tableSelectionsFinish = {};
_tableActionsStart = {};
_tableActionsFinish = {};
_tableGetDataStart = {};
_tableGetDataFinish = {};
// Errores en procesos
_actionServerError = [];
_fieldServerError = [];
_tableServerError = [];
// Datos complementarios del formulario
inputDataFields = {};
extraData = {};
_eventEmiter;
enabledSections = [];
// Gestión de error
_errorType = '';
errorCode = '';
errorFullCode = '';
errorName = '';
errorMessage = '';
errorDetail = '';
// Control de estado
visible = false;
busy = signal(false);
constructor(formManagerService, _eventManager, fileMgmtServices) {
super();
this.formManagerService = formManagerService;
this._eventManager = _eventManager;
this.fileMgmtServices = fileMgmtServices;
this._eventEmiter = this._eventManager;
this.cleanStart();
this.preStart();
this.customPreProcessing();
}
cleanStart() {
this._errorType = '';
this.errorCode = '';
this.errorFullCode = '';
this.errorName = '';
this.errorMessage = '';
this.errorDetail = '';
this.cleanForm();
this._controlToken = null;
this.inputDataFields = {};
this._definitionObtained = false;
// Se limpian los manejadores de eventos
this.visible = false;
this.busy.set(false);
this._formChangeState = [];
this._formSectionsCanDeactivate = {};
this._formSectionsActivate = {};
this._formSectionsInactivate = {};
this._formActionsStart = {};
this._formActionsFinish = {};
this._fieldCustomeEvent = {};
this._fieldInputValidation = {};
this._fieldValidationsStart = {};
this._fieldValidationsFinish = {};
this._tableSelectionsStart = {};
this._tableSelectionsFinish = {};
this._tableActionsStart = {};
this._tableActionsFinish = {};
this._tableGetDataStart = {};
this._tableGetDataFinish = {};
this._actionServerError = [];
this._fieldServerError = [];
this._tableServerError = [];
this.onActionServerError(() => this.displayActionServerError());
this.onValidationServerError(() => this.displayValidationServerError());
this.onTableServerError(() => this.displayTableServerError());
}
get formVisible() { return this.visible; }
get form() { return this; }
// Métodos virtuales
preStart() { }
start() { }
/**
* @deprecated Use preStart
*/
customPreProcessing() { }
/**
* @deprecated Overload start
*/
customFormStart() { }
displayActionServerError() { }
displayValidationServerError() { }
displayTableServerError() { }
showFieldInfo(code, detail) { }
showModalDialog(title, body, options, callback, params) { }
openUploadDialog(title, body, options, callback, params) { }
subscribeAppEvent(eventName, callback) {
this._eventEmiter.subscribe(eventName, callback);
}
openForm(name, data = null, backData = null, cleanStack = false) {
let origin = null;
if (!cleanStack) {
origin = { ...backData, name: this.name, url: this._formRoute, token: this._controlToken };
origin.subject = origin?.subject ?? this.subject;
origin.state = origin?.state ?? this.state;
origin.fields = origin?.fields ?? {};
origin.extra = origin?.extra ?? {};
}
const target = { ...data, name };
target.subject = target?.subject ?? null;
target.state = target?.state ?? null;
target.fields = target?.fields ?? {};
target.extra = target?.extra ?? {};
this.formManagerService.openForm(origin, target);
}
enableActivityNotification() { this._notifyFormActivity = true; }
disableActivityNotification() { this._notifyFormActivity = false; }
canGoBack() { return this._originToken !== null; }
goBack() { return this.formManagerService.backTo(); }
goBackForm() { return this.goBack(); }
getOriginDetail() { return this.formManagerService?.getFormInfo(this._originToken ?? ''); }
setError(errorType, errorMessage, errorDetail) {
this._errorType = errorType || '';
this.errorMessage = errorMessage || '';
this.errorDetail = errorDetail || '';
}
resetError() {
this.errorCode = NO_ERROR;
this.errorFullCode = '';
this.errorName = '';
this.errorMessage = '';
this.errorDetail = '';
}
getErrorType() { return this._errorType; }
getErrorMessage() { return this.errorMessage; }
getErrorDetail() { return this.errorDetail; }
getErrorName() { return this.errorName; }
getErrorFullCode() { return this.errorFullCode; }
getErrorCode() { return this.errorCode; }
getFormParameter(name) {
return (name) ? (this.extraData?.[name] ?? null) : null;
}
preocessInputParams(params) {
this._controlToken = params?.[TOKEN] ?? null;
this.subject = params?.[SUBJECT] ?? null;
const tokenInfo = (this._controlToken) ? this.formManagerService.getFormInfo(this._controlToken) : {};
const { token, subject, state, fields, extra, originToken } = tokenInfo;
if (token && this._controlToken === token) {
this.subject = this.subject ?? subject ?? null;
this.inputDataFields = fields;
this.extraData = extra;
this._originToken = originToken;
return state;
}
return null;
}
subscribeSectionActivation() {
const formSections = this.sections;
const sectionNames = Object.keys(formSections);
for (let index = 0; index < sectionNames.length; index++) {
const sectionName = sectionNames[index];
const section = formSections[sectionName];
section.activation
.pipe(takeUntil(this.destroy$))
.subscribe((code) => this.launchSectionActivation(code));
section.inactivation
.pipe(takeUntil(this.destroy$))
.subscribe((code) => this.launchSectionInactivation(code));
// Adicionalmente se le pide a la sección se subscriba al cambio de estado del formulario
section.connectWithParentForm(this, this.stateChange);
}
}
subscribeFieldsSubjects() {
const formFields = this.getFields();
if (Array.isArray(formFields)) {
formFields.forEach(field => {
field.customEvent
.pipe(takeUntil(this.destroy$))
.subscribe(event => {
const { code, eventName, eventData } = event;
this.startFieldCustomEvent(code, eventName, eventData);
});
field.editionFinish
.pipe(takeUntil(this.destroy$))
.subscribe(event => {
const { code, intrinsicValidation } = event;
this.startFieldValidation(code, intrinsicValidation);
});
field.editionPartial
.pipe(takeUntil(this.destroy$))
.subscribe(event => {
const { code, intrinsicValidation } = event;
this.startFieldInputValidation(code, intrinsicValidation);
});
field.detailRequest
.pipe(takeUntil(this.destroy$))
.subscribe(event => this.showFieldInfo(event.code, event.detail));
// Adicionalmente se le pide al campo se subscriba al cambio de estado del formulario
field.connectWithParentForm(this, this.stateChange);
});
}
}
subscribeActionSubjects() {
const formActions = this.getActions();
if (Array.isArray(formActions)) {
formActions.forEach(action => {
action.actionActivated
.pipe(takeUntil(this.destroy$))
.subscribe(code => this.startAction(code));
// Adicionalmente se le pide a la acción se subscriba al cambio de estado del formulario
action.connectWithParentForm(this, this.stateChange);
});
}
}
subscribeTableSubjects() {
const formTables = this.getTables();
if (Array.isArray(formTables)) {
formTables.forEach(table => {
table.inlineActionTrigger
.pipe(takeUntil(this.destroy$))
.subscribe(event => this.startTableAction(event));
table.globalActionTrigger
.pipe(takeUntil(this.destroy$))
.subscribe(event => this.startTableGlobalAction(event));
table.recordSelectionTrigger
.pipe(takeUntil(this.destroy$))
.subscribe(event => this.startTableRecordSelection(event));
table.selectionActionTrigger
.pipe(takeUntil(this.destroy$))
.subscribe(event => this.startTableSelectionAction(event));
table.getDataTrigger
.pipe(takeUntil(this.destroy$))
.subscribe(event => this.startTableGetData(event));
// Adicionalmente se le pide a la tabla se subscriba al cambio de estado del formulario
table.connectWithParentForm(this, this.stateChange);
});
}
}
async formInit(params, forceReload = false) {
let initialState = this.preocessInputParams(params);
if (!this.name) {
return;
}
if (forceReload || !this._definitionObtained) {
this.busy.set(true);
const formDefinition = await this.formManagerService.getFormDefinition(this.name);
this.busy.set(false);
this.loadDefinition(formDefinition);
this._definitionObtained = true;
}
else {
this.cleanData();
}
if (!this.supportState(initialState ?? '')) {
initialState = this.defaultState ?? null;
}
const inputFieldNames = Object.keys(this.inputDataFields);
for (let index = 0; index < inputFieldNames.length; index++) {
const code = inputFieldNames[index];
const fieldValue = this.inputDataFields[code];
this.setFieldValue(code, fieldValue);
}
this.subscribeSectionActivation();
this.subscribeFieldsSubjects();
this.subscribeActionSubjects();
this.subscribeTableSubjects();
// Se define el estado inicial y se solicita la acción inicial
this.changeState(initialState || this.defaultState);
if (this.loadInitialData) {
const recordResponse = await this.requestFormAction(formActions.getData);
this.checkErrorRecordReceived(recordResponse);
}
this.visible = true;
this.enabledSections = this.visibleSections ?? [];
this.start();
this.customFormStart();
}
changeState(state) {
const stateChanged = super.changeState(state ?? '') ?? false;
if (stateChanged) {
const clientActionMethods = this._formChangeState;
if (clientActionMethods && clientActionMethods.length > 0) {
for (const callback of clientActionMethods) {
callback(state);
}
}
}
return stateChanged;
}
checkErrorRecordReceived(recordResponse) {
const { error } = recordResponse ?? {};
if (!error) {
return false;
}
this.errorCode = recordResponse.errorCode;
this.errorFullCode = recordResponse.errorFullCode;
this.errorName = recordResponse.errorName;
this.errorMessage = recordResponse.errorMessage;
this.errorDetail = recordResponse.errorDetail;
return true;
}
errorOccured() {
return (this.errorCode !== NO_ERROR);
}
/**
* Soporte manejo de eventos de formulario
*/
async requestFormAction(actionCode, actionSubject = {}) {
const actionDetail = {
formCode: this.name,
formSubject: this.subject,
currentMode: this.state,
actionCode,
actionSubject,
version: PAYLOAD_VERSION,
formData: this.getPayload(),
immutableData: this.immutableData,
};
this.errorCode = NO_ERROR;
this.errorFullCode = '';
this.errorName = '';
this.errorMessage = '';
this.errorDetail = '';
this.busy.set(true);
const formActionResponse = await this.formManagerService.execServerAction(actionDetail);
if (!formActionResponse) {
return null;
}
this.busy.set(false);
if (formActionResponse.hasError()) {
const error = formActionResponse.error;
this.errorCode = error.errorCode;
this.errorFullCode = error.errorFullCode;
this.errorName = error.errorName;
this.errorMessage = error.errorMessage;
this.errorDetail = error.errorDetail;
}
const formResponseData = formActionResponse.getData();
this.updateFormWithServerData(formResponseData);
return formResponseData;
}
updateFormWithServerData(formContent) {
const { currentMode, formSubject, actions, fields, recordTables, returnedFile, immutableData, extraInfo, } = formContent;
currentMode && this.changeState(currentMode);
if (formSubject) {
this.subject = formSubject;
}
if (actions && actions.length > 0) {
for (const changedAction of actions) {
const actionObject = this.getAction(changedAction.actionCode);
if (actionObject) {
actionObject.updateFromServer(changedAction);
}
}
}
if (fields && fields.length > 0) {
for (const changedField of fields) {
const fieldObject = this.getField(changedField.fieldCode);
if (fieldObject) {
fieldObject.updateFromServer(changedField);
}
}
}
if (recordTables && recordTables.length > 0) {
for (const changedTable of recordTables) {
const tableObject = this.getTable(changedTable.tableCode);
if (tableObject) {
tableObject.updateFromServer(changedTable);
}
}
}
if (returnedFile && returnedFile.file) {
this.fileMgmtServices.saveFile(returnedFile.file, returnedFile.name, returnedFile.type);
}
this.immutableData = immutableData;
this.extraInfo = extraInfo;
}
/**
* Manejo de event handlers para errores Server del formulario
*/
cleanActionServerError() { this._actionServerError = []; }
cleanFieldServerError() { this._fieldServerError = []; }
cleanTableServerError() { this._tableServerError = []; }
onActionServerError(callback, properties = null) { this._actionServerError.push({ callback, properties }); }
onValidationServerError(callback, properties = null) { this._fieldServerError.push({ callback, properties }); }
onTableServerError(callback, properties = null) { this._tableServerError.push({ callback, properties }); }
/**
* Manejo de event handlers para acciones sobre el formulario
*/
onFormChange(callback) {
this._formChangeState.push(callback);
}
onSectionCanDeactivate(codes, callback, properties = null) {
const sectionSet = (Array.isArray(codes)) ? codes : (codes ? [codes] : []);
sectionSet.forEach((sectionName) => {
if (!this._formSectionsCanDeactivate[sectionName]) {
this._formSectionsCanDeactivate[sectionName] = [];
}
this._formSectionsCanDeactivate[sectionName].push({ callback, properties });
});
}
onSectionActivation(codes, callback, properties = null) {
const sectionSet = (Array.isArray(codes)) ? codes : (codes ? [codes] : []);
sectionSet.forEach((sectionName) => {
if (!this._formSectionsActivate[sectionName]) {
this._formSectionsActivate[sectionName] = [];
}
this._formSectionsActivate[sectionName].push({ callback, properties });
});
}
onSectionInactivation(codes, callback, properties = null) {
const sectionSet = (Array.isArray(codes)) ? codes : (codes ? [codes] : []);
sectionSet.forEach((sectionName) => {
if (!this._formSectionsInactivate[sectionName]) {
this._formSectionsInactivate[sectionName] = [];
}
this._formSectionsInactivate[sectionName].push({ callback, properties });
});
}
onActionStart(codes, callback, properties = null) {
const actionSet = (Array.isArray(codes)) ? codes : (codes ? [codes] : []);
actionSet.forEach((actionName) => {
if (!this._formActionsStart[actionName]) {
this._formActionsStart[actionName] = [];
}
this._formActionsStart[actionName].push({ callback, properties });
});
}
onActionFinish(codes, callback, properties = null) {
const actionSet = (Array.isArray(codes)) ? codes : (codes ? [codes] : []);
actionSet.forEach((actionName) => {
if (!this._formActionsFinish[actionName]) {
this._formActionsFinish[actionName] = [];
}
this._formActionsFinish[actionName].push({ callback, properties });
});
}
async verifySectionActivation(code) {
const sectionObject = this.getSection(code);
if (!sectionObject) {
return false;
}
const clientSectionMethods = this._formSectionsCanDeactivate[code];
if (clientSectionMethods) {
for (const clientSectionMethod of clientSectionMethods) {
const { callback, properties } = clientSectionMethod;
const canActivate = callback(sectionObject);
if (canActivate === false) {
return false;
}
}
}
return true;
}
async launchSectionActivation(code) {
this.notifyFormActivity();
const sectionObject = this.getSection(code);
if (!sectionObject) {
return;
}
const clientSectionMethods = this._formSectionsActivate[code];
if (clientSectionMethods) {
for (const clientSectionMethod of clientSectionMethods) {
const { callback, properties } = clientSectionMethod;
callback(sectionObject);
}
}
}
async launchSectionInactivation(code) {
this.notifyFormActivity();
const sectionObject = this.getSection(code);
if (!sectionObject) {
return;
}
const clientSectionMethods = this._formSectionsInactivate[code];
if (clientSectionMethods) {
for (const clientSectionMethod of clientSectionMethods) {
const { callback, properties } = clientSectionMethod;
callback(sectionObject);
}
}
}
async startAction(code) {
this.notifyFormActivity();
const actionObject = this.getAction(code);
if (!actionObject) {
return;
}
this.resetError();
actionObject.start();
const clientActionMethods = this._formActionsStart[code];
if (clientActionMethods) {
const clientActionPromises = [];
for (const clientActionMethod of clientActionMethods) {
const { callback, properties } = clientActionMethod;
const continueActionPromise = callback(actionObject);
clientActionPromises.push(continueActionPromise);
}
const clientActionResults = await Promise.all(clientActionPromises);
const continueAction = clientActionResults.reduce((total, curr) => (total && (curr !== false)), true);
if (!continueAction) {
actionObject.stop();
return;
}
}
this.startServerAction(actionObject);
}
async startServerAction(actionInput) {
const action = (typeof actionInput === 'string')
? this.getAction(actionInput) : actionInput;
if (!action) {
return;
}
let serverError = false;
let actionResult = null;
if (action.backend) {
actionResult = await this.requestFormAction(action.actionCode);
}
await this.finishAction(action, actionResult, serverError);
serverError = !!this.errorOccured();
if (!serverError) {
action.newState && this.changeState(action.newState);
}
else {
for (let index = 0; index < this._actionServerError.length; index++) {
const { callback, properties } = this._actionServerError[index];
callback(action);
}
}
action.stop();
}
async finishAction(action, actionResult, serverError = false) {
const finishActionMethods = this._formActionsFinish[action.actionCode];
if (finishActionMethods) {
const clientActionPromises = [];
for (const clientActionMethod of finishActionMethods) {
const { callback, properties } = clientActionMethod;
const continueOnError = properties?.continueOnError ?? false;
if (callback && (!serverError || continueOnError)) {
clientActionPromises.push(callback(action, actionResult));
}
}
await Promise.all(clientActionPromises);
}
}
completeGlobalAction(action) {
return this.startServerAction(action);
}
/**
* Manejadores de eventos para validaciones sobre campos
*/
onFieldInput(codes, callback, properties = null) {
const fieldSet = (Array.isArray(codes)) ? codes : (codes ? [codes] : []);
fieldSet.forEach((code) => {
if (!this._fieldInputValidation[code]) {
this._fieldInputValidation[code] = [];
}
this._fieldInputValidation[code].push({ callback, properties });
});
}
onFieldCustomEvent(codes, callback, properties = null) {
const fieldSet = (Array.isArray(codes)) ? codes : (codes ? [codes] : []);
fieldSet.forEach((code) => {
if (!this._fieldCustomeEvent[code]) {
this._fieldCustomeEvent[code] = [];
}
this._fieldCustomeEvent[code].push({ callback, properties });
});
}
onFieldValidationStart(codes, callback, properties = null) {
const fieldSet = (Array.isArray(codes)) ? codes : (codes ? [codes] : []);
fieldSet.forEach((code) => {
if (!this._fieldValidationsStart[code]) {
this._fieldValidationsStart[code] = [];
}
this._fieldValidationsStart[code].push({ callback, properties });
});
}
onFieldValidationFinish(codes, callback, properties = null) {
const fieldSet = (Array.isArray(codes)) ? codes : (codes ? [codes] : []);
fieldSet.forEach((code) => {
if (!this._fieldValidationsFinish[code]) {
this._fieldValidationsFinish[code] = [];
}
this._fieldValidationsFinish[code].push({ callback, properties });
});
}
async startFieldInputValidation(code, intrinsicValidation = true) {
this.notifyFormActivity();
const fieldToValidate = this.getField(code);
if (!fieldToValidate) {
return false;
}
const validationCallbacks = this._fieldInputValidation[code];
if (validationCallbacks) {
const clientValidationPromises = [];
for (const validationMethod of validationCallbacks) {
const { callback, properties } = validationMethod;
const continueValidationPromise = callback(fieldToValidate);
clientValidationPromises.push(continueValidationPromise);
}
await Promise.all(clientValidationPromises);
}
return true;
}
async startFieldCustomEvent(code, eventName, eventData) {
this.notifyFormActivity();
const fieldToTrigger = this.getField(code);
if (!fieldToTrigger) {
return;
}
const eventHandlerCallbacks = this._fieldCustomeEvent[code];
if (eventHandlerCallbacks) {
const clientEventPromises = [];
for (const eventHandlerMethod of eventHandlerCallbacks) {
const { callback, properties } = eventHandlerMethod;
const clientEventPromise = callback(eventName, eventData, fieldToTrigger);
clientEventPromises.push(clientEventPromise);
}
}
}
async startFieldValidation(code, intrinsicValidation = true) {
this.notifyFormActivity();
const fieldToValidate = this.getField(code);
if (!fieldToValidate) {
return;
}
const validationCallbacks = this._fieldValidationsStart[code];
if (validationCallbacks) {
const clientValidationPromises = [];
for (const validationMethod of validationCallbacks) {
const { callback, properties } = validationMethod;
const clientValidationPromise = callback(fieldToValidate);
clientValidationPromises.push(clientValidationPromise);
}
const clientValidationResults = await Promise.all(clientValidationPromises);
const continueValidation = clientValidationResults.reduce((total, curr) => (total && (curr !== false)), true);
if (!continueValidation) {
return;
}
}
if (intrinsicValidation) {
this.startServerFieldValidation(fieldToValidate);
}
}
async startServerFieldValidation(inputField) {
const fieldObj = (typeof inputField === 'string')
? this.getField(inputField) : inputField;
let serverError = false;
let validationResult = true;
if (!fieldObj) {
return;
}
if (fieldObj.backend) {
fieldObj.validating = true;
validationResult = await this
.requestFormAction(formActions.validate, fieldObj.code);
serverError = !!this.errorOccured();
}
if (serverError) {
fieldObj?.setErrorCode(this.errorCode);
fieldObj?.setErrorMessage(this.errorMessage);
for (let index = 0; index < this._fieldServerError.length; index++) {
const { callback, properties } = this._fieldServerError[index];
callback(fieldObj);
}
}
await this.finishFieldValidation(fieldObj, validationResult, serverError);
fieldObj.validating = false;
}
async finishFieldValidation(fieldObject, validationResult, serverError = false) {
const validationCallbacks = this._fieldValidationsFinish[fieldObject.code];
if (validationCallbacks) {
const clientActionPromises = [];
for (const validationMethod of validationCallbacks) {
const { callback, properties } = validationMethod;
const continueOnError = properties?.continueOnError ?? false;
if (!serverError || continueOnError) {
clientActionPromises.push(callback(fieldObject, validationResult));
}
}
await Promise.all(clientActionPromises);
}
}
async continueFieldValidation(code) {
return this.startServerFieldValidation(code);
}
/**
* Manejadores de eventos para acciones sobre Tablas
*/
onTableActionStart(code, actionCode, callback, properties = null) {
const tableObject = this.getTable(code);
if (!tableObject) {
return;
}
const inlineActionObject = tableObject.getAction(actionCode);
if (!inlineActionObject) {
return;
}
let tableEventHandlers;
if (this._tableActionsStart[code]) {
tableEventHandlers = this._tableActionsStart[code];
}
else {
tableEventHandlers = {};
this._tableActionsStart[code] = tableEventHandlers;
}
if (!tableEventHandlers[actionCode]) {
tableEventHandlers[actionCode] = [];
}
tableEventHandlers[actionCode].push({ callback, properties });
}
onTableActionFinish(code, actionCode, callback, properties = null) {
const tableObject = this.getTable(code);
if (!tableObject) {
return;
}
const inlineActionObject = tableObject.getAction(actionCode);
if (!inlineActionObject) {
return;
}
let tableEventHandlers;
if (this._tableActionsFinish[code]) {
tableEventHandlers = this._tableActionsFinish[code];
}
else {
tableEventHandlers = {};
this._tableActionsFinish[code] = tableEventHandlers;
}
if (!tableEventHandlers[actionCode]) {
tableEventHandlers[actionCode] = [];
}
tableEventHandlers[actionCode].push({ callback, properties });
}
onTableSelectionStart(code, callback, properties = null) {
const tableObject = this.getTable(code);
if (!tableObject) {
return;
}
let tableEventHandlers;
if (this._tableSelectionsStart[code]) {
tableEventHandlers = this._tableSelectionsStart[code];
}
else {
tableEventHandlers = [];
this._tableSelectionsStart[code] = tableEventHandlers;
}
tableEventHandlers.push({ callback, properties });
}
onTableSelectionFinish(code, callback, properties = null) {
const tableObject = this.getTable(code);
if (!tableObject) {
return;
}
let tableEventHandlers;
if (this._tableSelectionsFinish[code]) {
tableEventHandlers = this._tableSelectionsFinish[code];
}
else {
tableEventHandlers = [];
this._tableSelectionsFinish[code] = tableEventHandlers;
}
tableEventHandlers.push({ callback, properties });
}
onTableGetDataStart(code, callback, properties = null) {
const tableObject = this.getTable(code);
if (!tableObject) {
return;
}
let tableEventHandlers;
if (this._tableGetDataStart[code]) {
tableEventHandlers = this._tableGetDataStart[code];
}
else {
tableEventHandlers = [];
this._tableGetDataStart[code] = tableEventHandlers;
}
tableEventHandlers.push({ callback, properties });
}
onTableGetDataFinish(code, callback, properties = null) {
const tableObject = this.getTable(code);
if (!tableObject) {
return;
}
let tableEventHandlers;
if (this._tableGetDataFinish[code]) {
tableEventHandlers = this._tableGetDataFinish[code];
}
else {
tableEventHandlers = {};
this._tableGetDataFinish[code] = tableEventHandlers;
}
tableEventHandlers[GET_DATA_ACTION] = { callback, properties };
}
async startTableGlobalAction(tableActionEvent) {
this.notifyFormActivity();
const { tableCode, actionCode } = tableActionEvent;
const tableObject = this.getTable(tableCode);
if (!tableObject || !actionCode) {
return;
}
this.resetError();
const action = tableObject.getAction(actionCode);
if (!action) {
return;
}
const tableActionDetail = {
tableObject,
action,
tableCode,
actionCode,
};
const tableEventHandlers = this._tableActionsStart[tableCode];
const tableActionMethods = (tableEventHandlers) ? tableEventHandlers[actionCode] : null;
if (tableActionMethods) {
const clientActionPromises = [];
for (const tableActionMethod of tableActionMethods) {
const { callback, properties } = tableActionMethod;
const clientActionPromise = callback(tableActionDetail);
clientActionPromises.push(clientActionPromise);
}
const clientActionResults = await Promise.all(clientActionPromises);
const continueAction = clientActionResults.reduce((total, curr) => (total && (curr !== false)), true);
if (!continueAction) {
return;
}
}
this.startTableServerGlobalAction(tableActionDetail);
}
async startTableServerGlobalAction(tableActionDetail) {
const { tableObject, action, tableCode, actionCode } = tableActionDetail;
if (!tableObject || !action) {
return;
}
tableObject.putOnWait();
let serverError = false;
let actionResult = null;
if (action.backend) {
const actionSubject = {
tableCode,
actionType: GLOBAL_ACTION,
actionCode
};
actionResult = await this
.requestFormAction(formActions.tableAction, actionSubject);
serverError = !!this.errorOccured();
}
await this.finishTableGlobalAction(tableActionDetail, actionResult, serverError);
if (!serverError) {
action.newState && this.changeState(action.newState);
}
else {
for (let index = 0; index < this._tableServerError.length; index++) {
const { callback, properties } = this._tableServerError[index];
callback(tableObject);
}
}
tableObject.freeWaiting();
}
async finishTableGlobalAction(tableActionDetail, actionResult, serverError = false) {
const { tableCode, actionCode } = tableActionDetail;
const tableEventHandlers = this._tableActionsFinish[tableCode];
const tableActionMethods = (tableEventHandlers) ? tableEventHandlers[actionCode] : null;
if (tableActionMethods) {
const clientActionPromises = [];
for (const tableActionMethod of tableActionMethods) {
const { callback, properties } = tableActionMethod;
const continueOnError = properties?.continueOnError ?? false;
if (!serverError || continueOnError) {
clientActionPromises.push(callback(tableActionDetail, actionResult));
}
}
await Promise.all(clientActionPromises);
}
}
async startTableAction(tableActionEvent) {
this.notifyFormActivity();
const { tableCode, actionCode, actionDetail } = tableActionEvent;
const tableObject = this.getTable(tableCode);
if (!tableObject || !actionCode) {
return;
}
this.resetError();
const { recordId, recordData } = actionDetail;
const action = tableObject.getAction(actionCode);
if (!action) {
return;
}
const tableActionDetail = {
tableObject,
action,
tableCode,
actionCode,
recordId,
recordData
};
const tableEventHandlers = this._tableActionsStart[tableCode];
const tableActionMethods = (tableEventHandlers) ? tableEventHandlers[actionCode] : null;
if (tableActionMethods) {
const clientActionPromises = [];
for (const tableActionMethod of tableActionMethods) {
const { callback, properties } = tableActionMethod;
const clientActionPromise = callback(tableActionDetail);
clientActionPromises.push(clientActionPromise);
}
const clientActionResults = await Promise.all(clientActionPromises);
const continueAction = clientActionResults.reduce((total, curr) => (total && (curr !== false)), true);
if (!continueAction) {
return;
}
}
this.startTableServerAction(tableActionDetail);
}
async startTableServerAction(tableActionDetail) {
const { tableObject, action, tableCode, actionCode, recordId, recordData } = tableActionDetail;
if (!tableObject || !action) {
return;
}
tableObject.putOnWait();
let serverError = false;
let actionResult = null;
if (action.backend) {
const actionSubject = {
tableCode,
actionType: this.formConfig?.tableActions.inline,
actionCode,
tableRecordId: recordId,
tableRecordData: recordData
};
actionResult = await this
.requestFormAction(formActions.tableAction, actionSubject);
serverError = !!this.errorOccured();
}
await this.finishTableAction(tableActionDetail, actionResult, serverError);
if (!serverError) {
action.newState && this.changeState(action.newState);
}
else {
this.displayTableServerError();
}
tableObject.freeWaiting();
}
completeInlineAction(tableAction) {
return this.startTableServerAction(tableAction);
}
async finishTableAction(tableActionDetail, actionResult, serverError = false) {
const { tableCode, actionCode } = tableActionDetail;
const tableEventHandlers = this._tableActionsFinish[tableCode];
const tableActionMethods = (tableEventHandlers) ? tableEventHandlers[actionCode] : null;
if (tableActionMethods) {
const clientActionPromises = [];
for (const tableActionMethod of tableActionMethods) {
const { callback, properties } = tableActionMethod;
const continueOnError = properties?.continueOnError ?? false;
if (!serverError || continueOnError) {
clientActionPromises.push(callback(tableActionDetail, actionResult));
}
}
await Promise.all(clientActionPromises);
}
}
async startTableRecordSelection(tableActionEvent) {
this.notifyFormActivity();
const { tableCode, actionDetail } = tableActionEvent;
const tableObject = this.getTable(tableCode);
if (!tableObject) {
return;
}
this.resetError();
const { recordId, recordData } = actionDetail;
const tableSelectionDetail = {
tableObject,
tableCode,
recordId,
recordData
};
const tableEventHandlers = this._tableSelectionsStart[tableCode];
if (tableEventHandlers) {
const clientActionPromises = [];
for (const tableSelectionMethod of tableEventHandlers) {
const { callback, properties } = tableSelectionMethod;
const clientActionPromise = callback(tableSelectionDetail);
clientActionPromises.push(clientActionPromise);
}
const clientActionResults = await Promise.all(clientActionPromises);
const continueAction = clientActionResults.reduce((total, curr) => (total && (curr !== false)), true);
if (!continueAction) {
return;
}
}
this.startTableServerRecordSelection(tableSelectionDetail);
}
async startTableServerRecordSelection(tableSelectionDetail) {
const { tableObject, tableCode, recordId, recordData } = tableSelectionDetail;
if (!tableObject) {
return;
}
tableObject.putOnWait();
let serverError = false;
let actionResult = null;
if (tableObject.selectionBackend) {
const actionSubject = {
tableCode,
actionType: this.formConfig?.tableActions.rowSelection,
actionCode: null,
tableRecordId: recordId,
tableRecordData: recordData
};
actionResult = await this
.requestFormAction(formActions.tableAction, actionSubject);
serverError = !!this.errorOccured();
}
await this.finishTableRecordSelection(tableSelectionDetail, actionResult, serverError);
if (serverError) {
this.displayTableServerError();
}
tableObject.freeWaiting();
}
async finishTableRecordSelection(tableSelectionDetail, actionResult, serverError = false) {
const { tableCode } = tableSelectionDetail;
const tableEventHandlers = this._tableSelectionsFinish[tableCode];
if (tableEventHandlers) {
const clientActionPromises = [];
for (const tableSelectionMethod of tableEventHandlers) {
const { callback, properties } = tableSelectionMethod;
const continueOnError = properties?.continueOnError ?? false;
if (!serverError || continueOnError) {
clientActionPromises.push(callback(tableSelectionDetail, actionResult));
}
}
await Promise.all(clientActionPromises);
}
}
async startTableSelectionAction(tableActionEvent) {
this.notifyFormActivity();
const { tableCode, actionCode, actionDetail } = tableActionEvent;
const tableObject = this.getTable(tableCode);
if (!tableObject || !actionCode) {
return;
}
this.resetError();
const { selectedRecords } = actionDetail;
const action = tableObject.getAction(actionCode);
if (!action) {
return;
}
const tableActionDetail = {
tableObject,
action,
tableCode,
actionCode,
selectedRecords
};
const tableEventHandlers = this._tableActionsStart[tableCode];
const tableActionMethods = (tableEventHandlers) ? tableEventHandlers[actionCode] : null;
if (tableActionMethods) {
const clientActionPromises = [];
for (const tableActionMethod of tableActionMethods) {
const { callback, properties } = tableActionMethod;
const clientActionPromise = callback(tableActionDetail);
clientActionPromises.push(clientActionPromise);
}
const clientActionResults = await Promise.all(clientActionPromises);
const continueAction = clientActionResults.reduce((total, curr) => (total && (curr !== false)), true);
if (!continueAction) {
return;
}
}
this.startTableServerSelectionAction(tableActionDetail);
}
async startTableServerSelectionAction(tableActionDetail) {
const { tableObject, action, tableCode, actionCode, selectedRecords } = tableActionDetail;
if (!tableObject || !action) {
return;
}
tableObject.putOnWait();
let serverError = false;
let actionResult = null;
if (action.backend) {
const actionSubject = {
tableCode,
actionType: this.formConfig?.tableActions.selection,
actionCode,
selectedRecords
};
actionResult = await this
.requestFormAction(formActions.tableAction, actionSubject);
serverError = !!this.errorOccured();
}
await this.finishTableSelectionAction(tableActionDetail, actionResult, serverError);
if (!serverError) {
action.newState && this.changeState(action.newState);
}
else {
this.displayTableServerError();
}
tableObject.freeWaiting();
}
async finishTableSelectionAction(tableActionDetail, actionResult, serverError = false) {
const { tableCode, actionCode } = tableActionDetail;
const tableEventHandlers = this._tableActionsFinish[tableCode];
const tableActionMethods = (tableEventHandlers) ? tableEventHandlers[actionCode] : null;
if (tableActionMethods) {
const clientActionPromises = [];
for (const tableActionMethod of tableActionMethods) {
const { callback, properties } = tableActionMethod;
const continueOnError = properties?.continueOnError ?? false;
if (!serverError || continueOnError) {
clientActionPromises.push(callback(tableActionDetail, actionResult));
}
}
await Promise.all(clientActionPromises);
}
}
async startTableGetData(tableActionEvent) {
this.notifyFormActivity();
const { tableCode } = tableActionEvent;
const tableObject = this.getTable(tableCode);
const tableActionDetail = {
tableObject,
tableCode
};
this.resetError();
const tableEventHandlers = this._tableGetDataStart[tableCode];
if (tableEventHandlers) {
const clientActionPromises = [];
for (const tableActionMethod of tableEventHandlers) {
const { callback, properties } = tableActionMethod;
const clientActionPromise = callback(tableActionDetail);
clientActionPromises.push(clientActionPromise);
}
const clientActionResults = await Promise.all(clientActionPromises);
const continueAction = clientActionResults.reduce((total, curr) => (total && (curr !== false)), true);
if (!continueAction) {
return;
}
}
this.startTableServerGetData(tableActionDetail);
}
async startTableServerGetData(tableActionDetail) {
const { tableObject, tableCode } = tableActionDetail;
tableObject.putOnWait();
let serverError = false;
const actionSubject = { tableCode };
const actionResult = await this
.requestFormAction(formActions.getTableData, actionSubject);
serverError = !!this.errorOccured();
await this.finishTableGetData(tableActionDetail, actionResult, serverError);
if (serverError) {
this.displayTableServerError();
}
tableObject.freeWaiting();
}
async finishTableGetData(tableActionDetail, actionResult, serverError = false) {
const { tableCode, tableActionCode } = tableActionDetail;
const tableEventHandlers = this._tableActionsFinish[tableCode];
const tableActionMethods = (tableEventHandlers) ? tableEventHandlers[tableActionCode] : null;
if (tableActionMethods) {
const clientActionPromises = [];
for (const tableActionMethod of tableActionMethods) {
const { callback, properties } = tableActionMethod;
const continueOnError = properties?.continueOnError ?? false;
if (!serverError || continueOnError) {
clientActionPromises.push(callback(tableActionDetail, actionResult));
}
}
await Promise.all(clientActionPromises);
}
}
checkSectionRequiredFields(sectionCode, reqFieldMessage) {
this.cleanErrorFields(null, sectionCode);
const requiredFieldMessage = reqFieldMessage ?? this.formConfig?.formStandardErrors.requiredField;
const numErrors = this.tagFieldsWithError(requiredFieldMessage, this.getRequiredEmptyFields(null, sectionCode));
return (numErrors === 0);
}
validateSectionConsistency(sectionCode, reqFieldMessage) {
this.resetError();
const completeFields = this.checkSectionRequiredFields(sectionCode, reqFieldMessage);
if (!completeFiel