tuain-ng-forms-lib 17.2.21 → 17.2.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/.browserslistrc +16 -0
  2. package/.yarn/cache/nanoid-npm-4.0.0-924f5c6312-7d5946df5c.zip +0 -0
  3. package/.yarn/cache/tslib-npm-2.4.1-36f0ed04db-19480d6e03.zip +0 -0
  4. package/.yarn/cache/yn-npm-5.0.0-b001dab23c-f0ec7710d3.zip +0 -0
  5. package/.yarn/install-state.gz +0 -0
  6. package/karma.conf.js +44 -0
  7. package/ng-package.json +11 -0
  8. package/package.json +2 -16
  9. package/src/lib/classes/forms/action.ts +117 -0
  10. package/src/lib/classes/forms/element.ts +26 -0
  11. package/src/lib/classes/forms/field.ts +522 -0
  12. package/src/lib/classes/forms/form.constants.ts +28 -0
  13. package/src/lib/classes/forms/form.ts +692 -0
  14. package/src/lib/classes/forms/piece-propagate.ts +47 -0
  15. package/src/lib/classes/forms/piece.ts +164 -0
  16. package/src/lib/classes/forms/section.ts +165 -0
  17. package/src/lib/classes/forms/subsection.ts +109 -0
  18. package/src/lib/classes/forms/table/action.ts +41 -0
  19. package/src/lib/classes/forms/table/column.ts +94 -0
  20. package/src/lib/classes/forms/table/row-data.ts +121 -0
  21. package/src/lib/classes/forms/table/table.ts +582 -0
  22. package/src/lib/components/elements/action.component.ts +70 -0
  23. package/src/lib/components/elements/field.component.ts +115 -0
  24. package/src/lib/components/elements/layout/element.component.ts +14 -0
  25. package/src/lib/components/elements/layout/form-error.component.ts +11 -0
  26. package/src/lib/components/elements/layout/form-header.component.ts +14 -0
  27. package/src/lib/components/elements/layout/piece.component.ts +60 -0
  28. package/src/lib/components/elements/layout/section.component.ts +52 -0
  29. package/src/lib/components/elements/layout/sub-section.component.ts +52 -0
  30. package/src/lib/components/elements/tables/table-record-action.component.ts +66 -0
  31. package/src/lib/components/elements/tables/table-record-field.component.ts +20 -0
  32. package/src/lib/components/elements/tables/table.component.ts +112 -0
  33. package/src/lib/components/forms/basic-form.ts +1464 -0
  34. package/src/lib/services/event-manager.service.ts +45 -0
  35. package/src/lib/services/file-manager.service.ts +7 -0
  36. package/src/lib/services/form-manager.service.ts +89 -0
  37. package/src/lib/services/icon-dictionary.service.ts +159 -0
  38. package/src/lib/tuain-ng-forms-lib.module.ts +40 -0
  39. package/{public-api.d.ts → src/public-api.ts} +5 -0
  40. package/src/test.ts +27 -0
  41. package/tsconfig.lib.json +15 -0
  42. package/tsconfig.lib.prod.json +10 -0
  43. package/tsconfig.spec.json +17 -0
  44. package/esm2022/lib/classes/forms/action.mjs +0 -106
  45. package/esm2022/lib/classes/forms/element.mjs +0 -25
  46. package/esm2022/lib/classes/forms/field.mjs +0 -474
  47. package/esm2022/lib/classes/forms/form.constants.mjs +0 -26
  48. package/esm2022/lib/classes/forms/form.mjs +0 -608
  49. package/esm2022/lib/classes/forms/piece-propagate.mjs +0 -39
  50. package/esm2022/lib/classes/forms/piece.mjs +0 -134
  51. package/esm2022/lib/classes/forms/section.mjs +0 -151
  52. package/esm2022/lib/classes/forms/subsection.mjs +0 -99
  53. package/esm2022/lib/classes/forms/table/action.mjs +0 -38
  54. package/esm2022/lib/classes/forms/table/column.mjs +0 -74
  55. package/esm2022/lib/classes/forms/table/row-data.mjs +0 -116
  56. package/esm2022/lib/classes/forms/table/table.mjs +0 -535
  57. package/esm2022/lib/components/elements/action.component.mjs +0 -70
  58. package/esm2022/lib/components/elements/field.component.mjs +0 -115
  59. package/esm2022/lib/components/elements/layout/element.component.mjs +0 -21
  60. package/esm2022/lib/components/elements/layout/form-error.component.mjs +0 -23
  61. package/esm2022/lib/components/elements/layout/form-header.component.mjs +0 -23
  62. package/esm2022/lib/components/elements/layout/piece.component.mjs +0 -64
  63. package/esm2022/lib/components/elements/layout/section.component.mjs +0 -56
  64. package/esm2022/lib/components/elements/layout/sub-section.component.mjs +0 -56
  65. package/esm2022/lib/components/elements/tables/table-record-action.component.mjs +0 -72
  66. package/esm2022/lib/components/elements/tables/table-record-field.component.mjs +0 -31
  67. package/esm2022/lib/components/elements/tables/table.component.mjs +0 -109
  68. package/esm2022/lib/components/forms/basic-form.mjs +0 -1399
  69. package/esm2022/lib/services/event-manager.service.mjs +0 -43
  70. package/esm2022/lib/services/file-manager.service.mjs +0 -7
  71. package/esm2022/lib/services/form-manager.service.mjs +0 -81
  72. package/esm2022/lib/tuain-ng-forms-lib.module.mjs +0 -71
  73. package/esm2022/public-api.mjs +0 -19
  74. package/esm2022/tuain-ng-forms-lib.mjs +0 -5
  75. package/fesm2022/tuain-ng-forms-lib.mjs +0 -4593
  76. package/fesm2022/tuain-ng-forms-lib.mjs.map +0 -1
  77. package/index.d.ts +0 -5
  78. package/lib/classes/forms/action.d.ts +0 -40
  79. package/lib/classes/forms/element.d.ts +0 -9
  80. package/lib/classes/forms/field.d.ts +0 -206
  81. package/lib/classes/forms/form.constants.d.ts +0 -25
  82. package/lib/classes/forms/form.d.ts +0 -232
  83. package/lib/classes/forms/piece-propagate.d.ts +0 -13
  84. package/lib/classes/forms/piece.d.ts +0 -51
  85. package/lib/classes/forms/section.d.ts +0 -43
  86. package/lib/classes/forms/subsection.d.ts +0 -42
  87. package/lib/classes/forms/table/action.d.ts +0 -16
  88. package/lib/classes/forms/table/column.d.ts +0 -33
  89. package/lib/classes/forms/table/row-data.d.ts +0 -14
  90. package/lib/classes/forms/table/table.d.ts +0 -145
  91. package/lib/components/elements/action.component.d.ts +0 -22
  92. package/lib/components/elements/field.component.d.ts +0 -47
  93. package/lib/components/elements/layout/element.component.d.ts +0 -8
  94. package/lib/components/elements/layout/form-error.component.d.ts +0 -8
  95. package/lib/components/elements/layout/form-header.component.d.ts +0 -9
  96. package/lib/components/elements/layout/piece.component.d.ts +0 -18
  97. package/lib/components/elements/layout/section.component.d.ts +0 -13
  98. package/lib/components/elements/layout/sub-section.component.d.ts +0 -13
  99. package/lib/components/elements/tables/table-record-action.component.d.ts +0 -18
  100. package/lib/components/elements/tables/table-record-field.component.d.ts +0 -12
  101. package/lib/components/elements/tables/table.component.d.ts +0 -44
  102. package/lib/components/forms/basic-form.d.ts +0 -256
  103. package/lib/services/event-manager.service.d.ts +0 -11
  104. package/lib/services/file-manager.service.d.ts +0 -6
  105. package/lib/services/form-manager.service.d.ts +0 -28
  106. package/lib/tuain-ng-forms-lib.module.d.ts +0 -20
@@ -0,0 +1,1464 @@
1
+ import { Component, signal, OnInit, OnDestroy } from '@angular/core';
2
+ import { Subject, takeUntil } from 'rxjs';
3
+ import { FormStructureAndData } from '../../classes/forms/form';
4
+ import { LibFormManagerService } from '../../services/form-manager.service';
5
+ import { LibEventManagerService } from '../../services/event-manager.service';
6
+ import { LibFileManagementService } from '../../services/file-manager.service';
7
+ import { formActions, NO_ERROR } from '../../classes/forms/form.constants';
8
+ import { FieldDescriptor } from '../../classes/forms/field';
9
+ import { RecordFormSection } from '../../classes/forms/section';
10
+
11
+ const PAYLOAD_VERSION = 'TUAINEXCHANGE_1.0';
12
+ const INLINE_ACTION = 'INLINE';
13
+ const GLOBAL_ACTION = 'GLOBAL';
14
+ const GET_DATA_ACTION = 'GETDATA';
15
+
16
+ const SUBJECT = 'subject';
17
+ const TOKEN = 'token';
18
+
19
+ @Component({
20
+ template: `<ng-content></ng-content>`
21
+ })
22
+ export class BasicFormComponent extends FormStructureAndData implements OnInit, OnDestroy {
23
+ private destroy$ = new Subject<void>();
24
+
25
+ private _controlToken: string | null = null;
26
+ private _originToken: string | null = null;
27
+ private _formRoute: string | null = null;
28
+ private _definitionObtained: boolean = false;
29
+ private _notifyFormActivity: boolean = true;
30
+ // Eventos de acciones y campos
31
+ private _formChangeState: any[] = [];
32
+ private _formSectionsCanDeactivate: any = {};
33
+ private _formSectionsActivate: any = {};
34
+ private _formSectionsInactivate: any = {};
35
+ private _formActionsStart: any = {};
36
+ private _formActionsFinish: any = {};
37
+ private _fieldCustomeEvent: any = {};
38
+ private _fieldInputValidation: any = {};
39
+ private _fieldValidationsStart: any = {};
40
+ private _fieldValidationsFinish: any = {};
41
+ // Callback de acciones de tablas
42
+ private _tableSelectionsStart: any = {};
43
+ private _tableSelectionsFinish: any = {};
44
+ private _tableActionsStart: any = {};
45
+ private _tableActionsFinish: any = {};
46
+ private _tableGetDataStart: any = {};
47
+ private _tableGetDataFinish: any = {};
48
+ // Errores en procesos
49
+ private _actionServerError: any[] = [];
50
+ private _fieldServerError: any[] = [];
51
+ private _tableServerError: any[] = [];
52
+ // Acciones en curso dentro del formulario
53
+ private _actionsInProgress: any = {};
54
+ private _serverActionsInProgress: any = {};
55
+ // Datos complementarios del formulario
56
+ protected inputDataFields: any = {};
57
+ protected extraData: any = {};
58
+ protected _eventEmiter: LibEventManagerService;
59
+ protected enabledSections: RecordFormSection[] = [];
60
+ // Gestión de error
61
+ _errorType: string = '';
62
+ errorCode: string = '';
63
+ errorFullCode: string = '';
64
+ errorName: string = '';
65
+ errorMessage: string = '';
66
+ errorDetail: string = '';
67
+
68
+ // Control de estado
69
+ visible: boolean = false;
70
+ busy = signal<boolean>(false);
71
+
72
+ constructor(
73
+ protected formManagerService: LibFormManagerService,
74
+ protected _eventManager: LibEventManagerService,
75
+ protected fileMgmtServices: LibFileManagementService) {
76
+ super();
77
+ this._eventEmiter = this._eventManager;
78
+ this.cleanStart();
79
+ }
80
+
81
+ cleanStart() {
82
+ this._errorType = '';
83
+ this.errorCode = '';
84
+ this.errorFullCode = '';
85
+ this.errorName = '';
86
+ this.errorMessage = '';
87
+ this.errorDetail = '';
88
+ this.cleanForm();
89
+ this._controlToken = null;
90
+ this.inputDataFields = {};
91
+ this._definitionObtained = false;
92
+ // Se limpian los manejadores de eventos
93
+ this.visible = false;
94
+ this.busy.set(false);
95
+ this._formChangeState = [];
96
+ this._formSectionsCanDeactivate = {};
97
+ this._formSectionsActivate = {};
98
+ this._formSectionsInactivate = {};
99
+ this._formActionsStart = {};
100
+ this._formActionsFinish = {};
101
+ this._fieldCustomeEvent = {};
102
+ this._fieldInputValidation = {};
103
+ this._fieldValidationsStart = {};
104
+ this._fieldValidationsFinish = {};
105
+ this._tableSelectionsStart = {};
106
+ this._tableSelectionsFinish = {};
107
+ this._tableActionsStart = {};
108
+ this._tableActionsFinish = {};
109
+ this._tableGetDataStart = {};
110
+ this._tableGetDataFinish = {};
111
+
112
+ this._actionServerError = [];
113
+ this._fieldServerError = [];
114
+ this._tableServerError = [];
115
+
116
+ this.onActionServerError(() => this.displayActionServerError());
117
+ this.onValidationServerError(() => this.displayValidationServerError());
118
+ this.onTableServerError(() => this.displayTableServerError());
119
+ }
120
+
121
+ get formVisible(): boolean { return this.visible; }
122
+ get form() { return this; }
123
+
124
+ ngOnInit() {
125
+ this.preStart();
126
+ this.customPreProcessing();
127
+ }
128
+
129
+ // Métodos virtuales
130
+ preStart() { }
131
+ start() { }
132
+
133
+ /**
134
+ * @deprecated Use preStart
135
+ */
136
+ customPreProcessing() { }
137
+
138
+ /**
139
+ * @deprecated Overload start
140
+ */
141
+ customFormStart() { }
142
+
143
+ displayActionServerError() { }
144
+ displayValidationServerError() { }
145
+ displayTableServerError() { }
146
+ showFieldInfo(code?: string, detail?: any) { }
147
+ showModalDialog(title, body, options, callback?, params?) { }
148
+ openUploadDialog(title, body, options, callback?, params?) { }
149
+
150
+ subscribeAppEvent(eventName: string, callback): void {
151
+ this._eventEmiter.subscribe(eventName, callback);
152
+ }
153
+
154
+ openForm(name: string, data: any = null, backData: any = null, cleanStack = false): void {
155
+ let origin: any = null;
156
+ if (!cleanStack) {
157
+ origin = { ...backData, name: this.name, url: this._formRoute, token: this._controlToken };
158
+ origin.subject = origin?.subject ?? this.subject;
159
+ origin.state = origin?.state ?? this.state;
160
+ origin.fields = origin?.fields ?? {};
161
+ origin.extra = origin?.extra ?? {};
162
+ }
163
+ const target = { ...data, name };
164
+ target.subject = target?.subject ?? null;
165
+ target.state = target?.state ?? null;
166
+ target.fields = target?.fields ?? {};
167
+ target.extra = target?.extra ?? {};
168
+ this.formManagerService.openForm(origin, target);
169
+ }
170
+
171
+ enableActivityNotification() { this._notifyFormActivity = true; }
172
+ disableActivityNotification() { this._notifyFormActivity = false; }
173
+ canGoBack(): boolean { return this._originToken !== null }
174
+ goBack(): void { return this.formManagerService.backTo(); }
175
+ goBackForm(): void { return this.goBack(); }
176
+ getOriginDetail(): any { return this.formManagerService?.getFormInfo(this._originToken ?? ''); }
177
+
178
+ setError(errorType: string | null, errorMessage: string | null, errorDetail: string | null): void {
179
+ this._errorType = errorType || '';
180
+ this.errorMessage = errorMessage || '';
181
+ this.errorDetail = errorDetail || '';
182
+ }
183
+
184
+ resetError(): void {
185
+ this.errorCode = NO_ERROR;
186
+ this.errorFullCode = '';
187
+ this.errorName = '';
188
+ this.errorMessage = '';
189
+ this.errorDetail = '';
190
+ }
191
+
192
+ getErrorType(): string { return this._errorType; }
193
+ getErrorMessage(): string { return this.errorMessage; }
194
+ getErrorDetail(): string { return this.errorDetail; }
195
+ getErrorName(): string { return this.errorName; }
196
+ getErrorFullCode(): string { return this.errorFullCode; }
197
+ getErrorCode(): string { return this.errorCode; }
198
+
199
+ getFormParameter(name: string): string {
200
+ return (name) ? (this.extraData?.[name] ?? null) : null;
201
+ }
202
+
203
+ preocessInputParams(params: any): string | null {
204
+ this._controlToken = params?.[TOKEN] ?? null;
205
+ this.subject = params?.[SUBJECT] ?? null;
206
+ const tokenInfo: any = (this._controlToken) ? this.formManagerService.getFormInfo(this._controlToken) : {};
207
+ const { token, subject, state, fields, extra, originToken } = tokenInfo;
208
+ if (token && this._controlToken === token) {
209
+ this.subject = this.subject ?? subject ?? null;
210
+ this.inputDataFields = fields;
211
+ this.extraData = extra;
212
+ this._originToken = originToken;
213
+ return state;
214
+ }
215
+ return null;
216
+ }
217
+
218
+ subscribeSectionActivation(): void {
219
+ const formSections = this.sections;
220
+ const sectionNames = Object.keys(formSections);
221
+ for (let index = 0; index < sectionNames.length; index++) {
222
+ const sectionName = sectionNames[index];
223
+ const section = formSections[sectionName];
224
+ section.activation
225
+ .pipe(takeUntil(this.destroy$))
226
+ .subscribe((code: string) => this.launchSectionActivation(code));
227
+ section.inactivation
228
+ .pipe(takeUntil(this.destroy$))
229
+ .subscribe((code: string) => this.launchSectionInactivation(code));
230
+ // Adicionalmente se le pide a la sección se subscriba al cambio de estado del formulario
231
+ section.connectWithParentForm(this, this.stateChange);
232
+ }
233
+ }
234
+
235
+ subscribeFieldsSubjects(): void {
236
+ const formFields = this.getFields();
237
+ if (Array.isArray(formFields)) {
238
+ formFields.forEach(field => {
239
+ field.customEvent
240
+ .pipe(takeUntil(this.destroy$))
241
+ .subscribe(event => {
242
+ const { code, eventName, eventData } = event;
243
+ this.startFieldCustomEvent(code, eventName, eventData);
244
+ });
245
+ field.editionFinish
246
+ .pipe(takeUntil(this.destroy$))
247
+ .subscribe(event => {
248
+ const { code, intrinsicValidation } = event;
249
+ this.startFieldValidation(code, intrinsicValidation);
250
+ });
251
+ field.editionPartial
252
+ .pipe(takeUntil(this.destroy$))
253
+ .subscribe(event => {
254
+ const { code, intrinsicValidation } = event;
255
+ this.startFieldInputValidation(code, intrinsicValidation);
256
+ });
257
+ field.detailRequest
258
+ .pipe(takeUntil(this.destroy$))
259
+ .subscribe(event => this.showFieldInfo(event.code, event.detail));
260
+ // Adicionalmente se le pide al campo se subscriba al cambio de estado del formulario
261
+ field.connectWithParentForm(this, this.stateChange);
262
+ });
263
+ }
264
+ }
265
+
266
+ subscribeActionSubjects(): void {
267
+ const formActions = this.getActions();
268
+ if (Array.isArray(formActions)) {
269
+ formActions.forEach(action => {
270
+ action.actionActivated
271
+ .pipe(takeUntil(this.destroy$))
272
+ .subscribe(code => this.startAction(code));
273
+ // Adicionalmente se le pide a la acción se subscriba al cambio de estado del formulario
274
+ action.connectWithParentForm(this, this.stateChange);
275
+ });
276
+ }
277
+ }
278
+
279
+ subscribeTableSubjects(): void {
280
+ const formTables = this.getTables();
281
+ if (Array.isArray(formTables)) {
282
+ formTables.forEach(table => {
283
+ table.inlineActionTrigger
284
+ .pipe(takeUntil(this.destroy$))
285
+ .subscribe(event => this.startTableAction(event));
286
+ table.globalActionTrigger
287
+ .pipe(takeUntil(this.destroy$))
288
+ .subscribe(event => this.startTableGlobalAction(event));
289
+ table.recordSelectionTrigger
290
+ .pipe(takeUntil(this.destroy$))
291
+ .subscribe(event => this.startTableRecordSelection(event));
292
+ table.selectionActionTrigger
293
+ .pipe(takeUntil(this.destroy$))
294
+ .subscribe(event => this.startTableSelectionAction(event));
295
+ table.getDataTrigger
296
+ .pipe(takeUntil(this.destroy$))
297
+ .subscribe(event => this.startTableGetData(event));
298
+ // Adicionalmente se le pide a la tabla se subscriba al cambio de estado del formulario
299
+ table.connectWithParentForm(this, this.stateChange);
300
+ });
301
+ }
302
+ }
303
+
304
+ async formInit(params, forceReload = false): Promise<void> {
305
+ let initialState: string | null = this.preocessInputParams(params);
306
+ if (!this.name) { return; }
307
+ if (forceReload || !this._definitionObtained) {
308
+ this.busy.set(true);
309
+ const formDefinition = await this.formManagerService.getFormDefinition(this.name);
310
+ this.busy.set(false);
311
+ this.loadDefinition(formDefinition)
312
+ this._definitionObtained = true;
313
+ } else {
314
+ this.cleanData();
315
+ }
316
+ if (!this.supportState(initialState ?? '')) {
317
+ initialState = this.defaultState ?? null;
318
+ }
319
+ const inputFieldNames = Object.keys(this.inputDataFields);
320
+ for (let index = 0; index < inputFieldNames.length; index++) {
321
+ const code = inputFieldNames[index];
322
+ const fieldValue = this.inputDataFields[code];
323
+ this.setFieldValue(code, fieldValue);
324
+ }
325
+ this.subscribeSectionActivation();
326
+ this.subscribeFieldsSubjects();
327
+ this.subscribeActionSubjects();
328
+ this.subscribeTableSubjects();
329
+ // Se define el estado inicial y se solicita la acción inicial
330
+ this.changeState(initialState || this.defaultState);
331
+ if (this.loadInitialData) {
332
+ const recordResponse = await this.requestFormAction(formActions.getData);
333
+ this.checkErrorRecordReceived(recordResponse);
334
+ }
335
+ this.visible = true;
336
+ this.enabledSections = this.visibleSections ?? [];
337
+
338
+ this.start();
339
+ this.customFormStart();
340
+ }
341
+
342
+ override changeState(state: string | undefined): boolean {
343
+ const stateChanged = super.changeState(state ?? '') ?? false;
344
+ if (stateChanged) {
345
+ const clientActionMethods = this._formChangeState;
346
+ if (clientActionMethods && clientActionMethods.length > 0) {
347
+ for (const callback of clientActionMethods) {
348
+ callback(state);
349
+ }
350
+ }
351
+ }
352
+ return stateChanged;
353
+ }
354
+
355
+ checkErrorRecordReceived(recordResponse: any): boolean {
356
+ const { error } = recordResponse ?? {};
357
+ if (!error) { return false; }
358
+ this.errorCode = recordResponse.errorCode;
359
+ this.errorFullCode = recordResponse.errorFullCode;
360
+ this.errorName = recordResponse.errorName;
361
+ this.errorMessage = recordResponse.errorMessage;
362
+ this.errorDetail = recordResponse.errorDetail;
363
+ return true;
364
+ }
365
+
366
+ errorOccured(): boolean {
367
+ return (this.errorCode !== NO_ERROR);
368
+ }
369
+
370
+ /**
371
+ * Soporte manejo de eventos de formulario
372
+ */
373
+
374
+ async requestFormAction(actionCode: string, actionSubject: any = {}): Promise<any> {
375
+ const actionDetail = {
376
+ formCode: this.name,
377
+ formSubject: this.subject,
378
+ currentMode: this.state,
379
+ actionCode,
380
+ actionSubject,
381
+ version: PAYLOAD_VERSION,
382
+ formData: this.getPayload(),
383
+ immutableData: this.immutableData,
384
+ };
385
+ this.errorCode = NO_ERROR;
386
+ this.errorFullCode = '';
387
+ this.errorName = '';
388
+ this.errorMessage = '';
389
+ this.errorDetail = '';
390
+ this.busy.set(true);
391
+ const formActionResponse: any = await this.formManagerService.execServerAction(actionDetail);
392
+ if (!formActionResponse) {
393
+ return null;
394
+ }
395
+ this.busy.set(false);
396
+ if (formActionResponse.hasError()) {
397
+ const error = formActionResponse.error;
398
+ this.errorCode = error.errorCode;
399
+ this.errorFullCode = error.errorFullCode;
400
+ this.errorName = error.errorName;
401
+ this.errorMessage = error.errorMessage;
402
+ this.errorDetail = error.errorDetail;
403
+ }
404
+ const formResponseData = formActionResponse.getData();
405
+ this.updateFormWithServerData(formResponseData);
406
+ return formResponseData;
407
+ }
408
+
409
+ updateFormWithServerData(formContent: any) {
410
+ const {
411
+ currentMode, formSubject, actions, fields, recordTables,
412
+ returnedFile, immutableData, extraInfo,
413
+ } = formContent;
414
+ currentMode && this.changeState(currentMode);
415
+ if (formSubject) { this.subject = formSubject; }
416
+ if (actions && actions.length > 0) {
417
+ for (const changedAction of actions) {
418
+ const actionObject = this.getAction(changedAction.actionCode);
419
+ if (actionObject) { actionObject.updateFromServer(changedAction); }
420
+ }
421
+ }
422
+ if (fields && fields.length > 0) {
423
+ for (const changedField of fields) {
424
+ const fieldObject = this.getField(changedField.fieldCode);
425
+ if (fieldObject) {
426
+ fieldObject.updateFromServer(changedField);
427
+ }
428
+ }
429
+ }
430
+ if (recordTables && recordTables.length > 0) {
431
+ for (const changedTable of recordTables) {
432
+ const tableObject = this.getTable(changedTable.tableCode);
433
+ if (tableObject) {
434
+ tableObject.updateFromServer(changedTable);
435
+ }
436
+ }
437
+ }
438
+ if (returnedFile && returnedFile.file) {
439
+ this.fileMgmtServices.saveFile(returnedFile.file, returnedFile.name, returnedFile.type);
440
+ }
441
+ this.immutableData = immutableData;
442
+ this.extraInfo = extraInfo;
443
+ }
444
+
445
+ /**
446
+ * Manejo de event handlers para errores Server del formulario
447
+ */
448
+
449
+ cleanActionServerError() { this._actionServerError = []; }
450
+ cleanFieldServerError() { this._fieldServerError = []; }
451
+ cleanTableServerError() { this._tableServerError = []; }
452
+ onActionServerError(callback, properties = null) { this._actionServerError.push({ callback, properties }); }
453
+ onValidationServerError(callback, properties = null) { this._fieldServerError.push({ callback, properties }); }
454
+ onTableServerError(callback, properties = null) { this._tableServerError.push({ callback, properties }); }
455
+
456
+ /**
457
+ * Manejo de event handlers para acciones sobre el formulario
458
+ */
459
+
460
+ onFormChange(callback) {
461
+ this._formChangeState.push(callback);
462
+ }
463
+
464
+ onSectionCanDeactivate(codes: string[] | string | null, callback, properties = null) {
465
+ const sectionSet = (Array.isArray(codes)) ? codes : (codes ? [codes] : []);
466
+ sectionSet.forEach((sectionName) => {
467
+ if (!this._formSectionsCanDeactivate[sectionName]) {
468
+ this._formSectionsCanDeactivate[sectionName] = [];
469
+ }
470
+ this._formSectionsCanDeactivate[sectionName].push({ callback, properties });
471
+ });
472
+ }
473
+
474
+ onSectionActivation(codes: string[] | string | null, callback, properties = null) {
475
+ const sectionSet = (Array.isArray(codes)) ? codes : (codes ? [codes] : []);
476
+ sectionSet.forEach((sectionName) => {
477
+ if (!this._formSectionsActivate[sectionName]) {
478
+ this._formSectionsActivate[sectionName] = [];
479
+ }
480
+ this._formSectionsActivate[sectionName].push({ callback, properties });
481
+ });
482
+ }
483
+
484
+ onSectionInactivation(codes: string[] | string | null, callback, properties = null) {
485
+ const sectionSet = (Array.isArray(codes)) ? codes : (codes ? [codes] : []);
486
+ sectionSet.forEach((sectionName) => {
487
+ if (!this._formSectionsInactivate[sectionName]) {
488
+ this._formSectionsInactivate[sectionName] = [];
489
+ }
490
+ this._formSectionsInactivate[sectionName].push({ callback, properties });
491
+ });
492
+ }
493
+
494
+ onActionStart(codes: string[] | string | null, callback, properties = null) {
495
+ const actionSet = (Array.isArray(codes)) ? codes : (codes ? [codes] : []);
496
+ actionSet.forEach((actionName) => {
497
+ if (!this._formActionsStart[actionName]) {
498
+ this._formActionsStart[actionName] = [];
499
+ }
500
+ this._formActionsStart[actionName].push({ callback, properties });
501
+ });
502
+ }
503
+
504
+ onActionFinish(codes: string[] | string | null, callback, properties = null) {
505
+ const actionSet = (Array.isArray(codes)) ? codes : (codes ? [codes] : []);
506
+ actionSet.forEach((actionName) => {
507
+ if (!this._formActionsFinish[actionName]) {
508
+ this._formActionsFinish[actionName] = [];
509
+ }
510
+ this._formActionsFinish[actionName].push({ callback, properties });
511
+ });
512
+ }
513
+
514
+ async verifySectionActivation(code: string): Promise<boolean> {
515
+ const sectionObject = this.getSection(code);
516
+ if (!sectionObject) { return false; }
517
+ const clientSectionMethods = this._formSectionsCanDeactivate[code];
518
+ if (clientSectionMethods) {
519
+ for (const clientSectionMethod of clientSectionMethods) {
520
+ const { callback, properties } = clientSectionMethod;
521
+ const canActivate = callback(sectionObject);
522
+ if (canActivate === false) {
523
+ return false;
524
+ }
525
+ }
526
+ }
527
+ return true;
528
+ }
529
+
530
+ async launchSectionActivation(code: string) {
531
+ this.notifyFormActivity();
532
+ const sectionObject = this.getSection(code);
533
+ if (!sectionObject) { return; }
534
+ const clientSectionMethods = this._formSectionsActivate[code];
535
+ if (clientSectionMethods) {
536
+ for (const clientSectionMethod of clientSectionMethods) {
537
+ const { callback, properties } = clientSectionMethod;
538
+ callback(sectionObject);
539
+ }
540
+ }
541
+ }
542
+
543
+ async launchSectionInactivation(code: string) {
544
+ this.notifyFormActivity();
545
+ const sectionObject = this.getSection(code);
546
+ if (!sectionObject) { return; }
547
+ const clientSectionMethods = this._formSectionsInactivate[code];
548
+ if (clientSectionMethods) {
549
+ for (const clientSectionMethod of clientSectionMethods) {
550
+ const { callback, properties } = clientSectionMethod;
551
+ callback(sectionObject);
552
+ }
553
+ }
554
+ }
555
+
556
+ async startAction(code: string) {
557
+ this.notifyFormActivity();
558
+ const actionObject = this.getAction(code);
559
+ if (!actionObject) { return; }
560
+ if (this._actionsInProgress[code]) {
561
+ const { sent } = this._actionsInProgress[code];
562
+ console.log(`Reingreso sobre acción ${code} con ejecución previa ${sent}`);
563
+ return;
564
+ }
565
+ this._actionsInProgress[code] = { sent: new Date() };
566
+ this.resetError();
567
+ actionObject.start();
568
+ const clientActionMethods = this._formActionsStart[code];
569
+ if (clientActionMethods) {
570
+ const clientActionPromises: any[] = [];
571
+ for (const clientActionMethod of clientActionMethods) {
572
+ const { callback, properties } = clientActionMethod;
573
+ const continueActionPromise = callback(actionObject);
574
+ clientActionPromises.push(continueActionPromise);
575
+ }
576
+ const clientActionResults = await Promise.all(clientActionPromises);
577
+ const continueAction = clientActionResults.reduce((total, curr) => (total && (curr !== false)), true);
578
+ if (!continueAction) {
579
+ actionObject.stop();
580
+ this._actionsInProgress[code] = null;
581
+ delete this._actionsInProgress[code];
582
+ return;
583
+ }
584
+ }
585
+ this.startServerAction(actionObject);
586
+ this._actionsInProgress[code] = null;
587
+ delete this._actionsInProgress[code];
588
+ }
589
+
590
+ async startServerAction(actionInput) {
591
+ const action = (typeof actionInput === 'string')
592
+ ? this.getAction(actionInput) : actionInput;
593
+ if (!action) {
594
+ return;
595
+ }
596
+ let serverError = false;
597
+ let actionResult = null;
598
+ if (!action.backend) {
599
+ return;
600
+ }
601
+ if (this._serverActionsInProgress[action.actionCode]) {
602
+ const { sent } = this._serverActionsInProgress[action.actionCode];
603
+ console.log(`Reingreso server sobre acción ${action.actionCode} con ejecución previa ${sent}`);
604
+ return;
605
+ }
606
+ this._serverActionsInProgress[action.actionCode] = { sent: new Date() };
607
+ // Se inicia la parte server de la acción
608
+ actionResult = await this.requestFormAction(action.actionCode);
609
+ await this.finishAction(action, actionResult, serverError);
610
+ serverError = !!this.errorOccured();
611
+ if (!serverError) {
612
+ action.newState && this.changeState(action.newState);
613
+ } else {
614
+ for (let index = 0; index < this._actionServerError.length; index++) {
615
+ const { callback, properties } = this._actionServerError[index];
616
+ callback(action);
617
+ }
618
+ }
619
+ this._serverActionsInProgress[action.actionCode] = null;
620
+ delete this._serverActionsInProgress[action.actionCode];
621
+ action.stop();
622
+ }
623
+
624
+ async finishAction(action, actionResult, serverError = false) {
625
+ const finishActionMethods = this._formActionsFinish[action.actionCode];
626
+ if (finishActionMethods) {
627
+ const clientActionPromises: any[] = [];
628
+ for (const clientActionMethod of finishActionMethods) {
629
+ const { callback, properties } = clientActionMethod;
630
+ const continueOnError = properties?.continueOnError ?? false;
631
+ if (callback && (!serverError || continueOnError)) {
632
+ clientActionPromises.push(callback(action, actionResult));
633
+ }
634
+ }
635
+ await Promise.all(clientActionPromises);
636
+ }
637
+ }
638
+
639
+ completeGlobalAction(action: any) {
640
+ return this.startServerAction(action);
641
+ }
642
+
643
+ /**
644
+ * Manejadores de eventos para validaciones sobre campos
645
+ */
646
+
647
+ onFieldInput(codes: string[] | string | null, callback, properties = null) {
648
+ const fieldSet = (Array.isArray(codes)) ? codes : (codes ? [codes] : []);
649
+ fieldSet.forEach((code) => {
650
+ if (!this._fieldInputValidation[code]) {
651
+ this._fieldInputValidation[code] = [];
652
+ }
653
+ this._fieldInputValidation[code].push({ callback, properties });
654
+ });
655
+ }
656
+
657
+ onFieldCustomEvent(codes: string[] | string | null, callback, properties = null) {
658
+ const fieldSet = (Array.isArray(codes)) ? codes : (codes ? [codes] : []);
659
+ fieldSet.forEach((code) => {
660
+ if (!this._fieldCustomeEvent[code]) {
661
+ this._fieldCustomeEvent[code] = [];
662
+ }
663
+ this._fieldCustomeEvent[code].push({ callback, properties });
664
+ });
665
+ }
666
+
667
+ onFieldValidationStart(codes: string[] | string | null, callback, properties = null) {
668
+ const fieldSet = (Array.isArray(codes)) ? codes : (codes ? [codes] : []);
669
+ fieldSet.forEach((code) => {
670
+ if (!this._fieldValidationsStart[code]) {
671
+ this._fieldValidationsStart[code] = [];
672
+ }
673
+ this._fieldValidationsStart[code].push({ callback, properties });
674
+ });
675
+ }
676
+
677
+ onFieldValidationFinish(codes: string[] | string | null, callback, properties = null) {
678
+ const fieldSet = (Array.isArray(codes)) ? codes : (codes ? [codes] : []);
679
+ fieldSet.forEach((code) => {
680
+ if (!this._fieldValidationsFinish[code]) {
681
+ this._fieldValidationsFinish[code] = [];
682
+ }
683
+ this._fieldValidationsFinish[code].push({ callback, properties });
684
+ });
685
+ }
686
+
687
+ async startFieldInputValidation(code: string, intrinsicValidation: boolean = true) {
688
+ this.notifyFormActivity();
689
+ const fieldToValidate = this.getField(code);
690
+ if (!fieldToValidate) { return false; }
691
+ const validationCallbacks = this._fieldInputValidation[code];
692
+ if (validationCallbacks) {
693
+ const clientValidationPromises: any[] = [];
694
+ for (const validationMethod of validationCallbacks) {
695
+ const { callback, properties } = validationMethod;
696
+ const continueValidationPromise = callback(fieldToValidate);
697
+ clientValidationPromises.push(continueValidationPromise);
698
+ }
699
+ await Promise.all(clientValidationPromises);
700
+ }
701
+ return true;
702
+ }
703
+
704
+ async startFieldCustomEvent(code: string, eventName: string, eventData: any) {
705
+ this.notifyFormActivity();
706
+ const fieldToTrigger = this.getField(code);
707
+ if (!fieldToTrigger) { return; }
708
+ const eventHandlerCallbacks = this._fieldCustomeEvent[code];
709
+ if (eventHandlerCallbacks) {
710
+ const clientEventPromises: any[] = [];
711
+ for (const eventHandlerMethod of eventHandlerCallbacks) {
712
+ const { callback, properties } = eventHandlerMethod;
713
+ const clientEventPromise = callback(eventName, eventData, fieldToTrigger);
714
+ clientEventPromises.push(clientEventPromise);
715
+ }
716
+ }
717
+ }
718
+
719
+ async startFieldValidation(code: string, intrinsicValidation: boolean = true) {
720
+ this.notifyFormActivity();
721
+ const fieldToValidate = this.getField(code);
722
+ if (!fieldToValidate) { return; }
723
+ const validationCallbacks = this._fieldValidationsStart[code];
724
+ if (validationCallbacks) {
725
+ const clientValidationPromises: any[] = [];
726
+ for (const validationMethod of validationCallbacks) {
727
+ const { callback, properties } = validationMethod;
728
+ const clientValidationPromise = callback(fieldToValidate);
729
+ clientValidationPromises.push(clientValidationPromise);
730
+ }
731
+ const clientValidationResults = await Promise.all(clientValidationPromises);
732
+ const continueValidation = clientValidationResults.reduce((total, curr) => (total && (curr !== false)), true);
733
+ if (!continueValidation) {
734
+ return;
735
+ }
736
+ }
737
+ if (intrinsicValidation) {
738
+ this.startServerFieldValidation(fieldToValidate);
739
+ }
740
+ }
741
+
742
+ async startServerFieldValidation(inputField: string | FieldDescriptor) {
743
+ const fieldObj: FieldDescriptor | null = (typeof inputField === 'string')
744
+ ? this.getField(inputField) : inputField;
745
+ let serverError = false;
746
+ let validationResult: boolean = true;
747
+ if (!fieldObj) {
748
+ return;
749
+ }
750
+ if (fieldObj.backend) {
751
+ fieldObj.validating = true;
752
+ validationResult = await this
753
+ .requestFormAction(formActions.validate, fieldObj.code);
754
+ serverError = !!this.errorOccured();
755
+ }
756
+ if (serverError) {
757
+ fieldObj?.setErrorCode(this.errorCode);
758
+ fieldObj?.setErrorMessage(this.errorMessage);
759
+ for (let index = 0; index < this._fieldServerError.length; index++) {
760
+ const { callback, properties } = this._fieldServerError[index];
761
+ callback(fieldObj);
762
+ }
763
+ }
764
+ await this.finishFieldValidation(fieldObj, validationResult, serverError);
765
+ fieldObj.validating = false;
766
+ }
767
+
768
+ async finishFieldValidation(fieldObject: any, validationResult: boolean, serverError = false) {
769
+ const validationCallbacks = this._fieldValidationsFinish[fieldObject.code];
770
+ if (validationCallbacks) {
771
+ const clientActionPromises: any[] = [];
772
+ for (const validationMethod of validationCallbacks) {
773
+ const { callback, properties } = validationMethod;
774
+ const continueOnError = properties?.continueOnError ?? false;
775
+ if (!serverError || continueOnError) {
776
+ clientActionPromises.push(callback(fieldObject, validationResult));
777
+ }
778
+ }
779
+ await Promise.all(clientActionPromises);
780
+ }
781
+ }
782
+
783
+ async continueFieldValidation(code: string) {
784
+ return this.startServerFieldValidation(code);
785
+ }
786
+
787
+ /**
788
+ * Manejadores de eventos para acciones sobre Tablas
789
+ */
790
+
791
+ onTableActionStart(code: string, actionCode: string, callback, properties = null) {
792
+ const tableObject = this.getTable(code);
793
+ if (!tableObject) {
794
+ return;
795
+ }
796
+ const inlineActionObject = tableObject.getAction(actionCode);
797
+ if (!inlineActionObject) {
798
+ return;
799
+ }
800
+ let tableEventHandlers: any;
801
+ if (this._tableActionsStart[code]) {
802
+ tableEventHandlers = this._tableActionsStart[code];
803
+ } else {
804
+ tableEventHandlers = {};
805
+ this._tableActionsStart[code] = tableEventHandlers;
806
+ }
807
+ if (!tableEventHandlers[actionCode]) {
808
+ tableEventHandlers[actionCode] = [];
809
+ }
810
+ tableEventHandlers[actionCode].push({ callback, properties });
811
+ }
812
+
813
+ onTableActionFinish(code: string, actionCode: string, callback, properties = null) {
814
+ const tableObject = this.getTable(code);
815
+ if (!tableObject) {
816
+ return;
817
+ }
818
+ const inlineActionObject = tableObject.getAction(actionCode);
819
+ if (!inlineActionObject) {
820
+ return;
821
+ }
822
+ let tableEventHandlers: any;
823
+ if (this._tableActionsFinish[code]) {
824
+ tableEventHandlers = this._tableActionsFinish[code];
825
+ } else {
826
+ tableEventHandlers = {};
827
+ this._tableActionsFinish[code] = tableEventHandlers;
828
+ }
829
+ if (!tableEventHandlers[actionCode]) {
830
+ tableEventHandlers[actionCode] = [];
831
+ }
832
+ tableEventHandlers[actionCode].push({ callback, properties });
833
+ }
834
+
835
+ onTableSelectionStart(code: string, callback, properties = null) {
836
+ const tableObject = this.getTable(code);
837
+ if (!tableObject) { return; }
838
+ let tableEventHandlers: any[];
839
+ if (this._tableSelectionsStart[code]) {
840
+ tableEventHandlers = this._tableSelectionsStart[code];
841
+ } else {
842
+ tableEventHandlers = [];
843
+ this._tableSelectionsStart[code] = tableEventHandlers;
844
+ }
845
+ tableEventHandlers.push({ callback, properties });
846
+ }
847
+
848
+ onTableSelectionFinish(code: string, callback, properties = null) {
849
+ const tableObject = this.getTable(code);
850
+ if (!tableObject) { return; }
851
+ let tableEventHandlers: any[];
852
+ if (this._tableSelectionsFinish[code]) {
853
+ tableEventHandlers = this._tableSelectionsFinish[code];
854
+ } else {
855
+ tableEventHandlers = [];
856
+ this._tableSelectionsFinish[code] = tableEventHandlers;
857
+ }
858
+ tableEventHandlers.push({ callback, properties });
859
+ }
860
+
861
+ onTableGetDataStart(code: string, callback, properties = null) {
862
+ const tableObject = this.getTable(code);
863
+ if (!tableObject) {
864
+ return;
865
+ }
866
+ let tableEventHandlers: any[];
867
+ if (this._tableGetDataStart[code]) {
868
+ tableEventHandlers = this._tableGetDataStart[code];
869
+ } else {
870
+ tableEventHandlers = [];
871
+ this._tableGetDataStart[code] = tableEventHandlers;
872
+ }
873
+ tableEventHandlers.push({ callback, properties });
874
+ }
875
+
876
+ onTableGetDataFinish(code: string, callback, properties = null) {
877
+ const tableObject = this.getTable(code);
878
+ if (!tableObject) {
879
+ return;
880
+ }
881
+ let tableEventHandlers: any;
882
+ if (this._tableGetDataFinish[code]) {
883
+ tableEventHandlers = this._tableGetDataFinish[code];
884
+ } else {
885
+ tableEventHandlers = {};
886
+ this._tableGetDataFinish[code] = tableEventHandlers;
887
+ }
888
+ tableEventHandlers[GET_DATA_ACTION] = { callback, properties };
889
+ }
890
+
891
+ async startTableGlobalAction(tableActionEvent: any) {
892
+ this.notifyFormActivity();
893
+ const { tableCode, actionCode } = tableActionEvent;
894
+ const tableObject = this.getTable(tableCode);
895
+ if (!tableObject || !actionCode) { return; }
896
+ this.resetError();
897
+ const action = tableObject.getAction(actionCode);
898
+ if (!action) { return; }
899
+ const tableActionDetail = {
900
+ tableObject,
901
+ action,
902
+ tableCode,
903
+ actionCode,
904
+ };
905
+ const tableEventHandlers = this._tableActionsStart[tableCode];
906
+ const tableActionMethods = (tableEventHandlers) ? tableEventHandlers[actionCode] : null;
907
+ if (tableActionMethods) {
908
+ const clientActionPromises: any[] = [];
909
+ for (const tableActionMethod of tableActionMethods) {
910
+ const { callback, properties } = tableActionMethod;
911
+ const clientActionPromise = callback(tableActionDetail);
912
+ clientActionPromises.push(clientActionPromise);
913
+ }
914
+ const clientActionResults = await Promise.all(clientActionPromises);
915
+ const continueAction = clientActionResults.reduce((total, curr) => (total && (curr !== false)), true);
916
+ if (!continueAction) {
917
+ return;
918
+ }
919
+ }
920
+ this.startTableServerGlobalAction(tableActionDetail);
921
+ }
922
+
923
+ async startTableServerGlobalAction(tableActionDetail: any) {
924
+ const { tableObject, action, tableCode, actionCode } = tableActionDetail;
925
+ if (!tableObject || !action) { return; }
926
+ tableObject.putOnWait();
927
+ let serverError = false;
928
+ let actionResult = null;
929
+ if (action.backend) {
930
+ const actionSubject = {
931
+ tableCode,
932
+ actionType: GLOBAL_ACTION,
933
+ actionCode
934
+ };
935
+ actionResult = await this
936
+ .requestFormAction(formActions.tableAction, actionSubject);
937
+ serverError = !!this.errorOccured();
938
+ }
939
+ await this.finishTableGlobalAction(tableActionDetail, actionResult, serverError);
940
+ if (!serverError) {
941
+ action.newState && this.changeState(action.newState);
942
+ } else {
943
+ for (let index = 0; index < this._tableServerError.length; index++) {
944
+ const { callback, properties } = this._tableServerError[index];
945
+ callback(tableObject);
946
+ }
947
+ }
948
+ tableObject.freeWaiting();
949
+ }
950
+
951
+ async finishTableGlobalAction(tableActionDetail: any, actionResult, serverError = false) {
952
+ const { tableCode, actionCode } = tableActionDetail;
953
+ const tableEventHandlers = this._tableActionsFinish[tableCode];
954
+ const tableActionMethods = (tableEventHandlers) ? tableEventHandlers[actionCode] : null;
955
+ if (tableActionMethods) {
956
+ const clientActionPromises: any[] = [];
957
+ for (const tableActionMethod of tableActionMethods) {
958
+ const { callback, properties } = tableActionMethod;
959
+ const continueOnError = properties?.continueOnError ?? false;
960
+ if (!serverError || continueOnError) {
961
+ clientActionPromises.push(callback(tableActionDetail, actionResult));
962
+ }
963
+ }
964
+ await Promise.all(clientActionPromises);
965
+ }
966
+ }
967
+
968
+ async startTableAction(tableActionEvent: any) {
969
+ this.notifyFormActivity();
970
+ const { tableCode, actionCode, actionDetail } = tableActionEvent;
971
+ const tableObject = this.getTable(tableCode);
972
+ if (!tableObject || !actionCode) { return; }
973
+ this.resetError();
974
+ const { recordId, recordData } = actionDetail;
975
+ const action = tableObject.getAction(actionCode);
976
+ if (!action) { return; }
977
+ const tableActionDetail = {
978
+ tableObject,
979
+ action,
980
+ tableCode,
981
+ actionCode,
982
+ recordId,
983
+ recordData
984
+ };
985
+ const tableEventHandlers = this._tableActionsStart[tableCode];
986
+ const tableActionMethods = (tableEventHandlers) ? tableEventHandlers[actionCode] : null;
987
+ if (tableActionMethods) {
988
+ const clientActionPromises: any[] = [];
989
+ for (const tableActionMethod of tableActionMethods) {
990
+ const { callback, properties } = tableActionMethod;
991
+ const clientActionPromise = callback(tableActionDetail);
992
+ clientActionPromises.push(clientActionPromise);
993
+ }
994
+ const clientActionResults = await Promise.all(clientActionPromises);
995
+ const continueAction = clientActionResults.reduce((total, curr) => (total && (curr !== false)), true);
996
+ if (!continueAction) {
997
+ return;
998
+ }
999
+ }
1000
+ this.startTableServerAction(tableActionDetail);
1001
+ }
1002
+
1003
+ async startTableServerAction(tableActionDetail: any) {
1004
+ const { tableObject, action, tableCode, actionCode, recordId, recordData } = tableActionDetail;
1005
+ if (!tableObject || !action) { return; }
1006
+ tableObject.putOnWait();
1007
+ let serverError = false;
1008
+ let actionResult = null;
1009
+ if (action.backend) {
1010
+ const actionSubject = {
1011
+ tableCode,
1012
+ actionType: this.formConfig?.tableActions.inline,
1013
+ actionCode,
1014
+ tableRecordId: recordId,
1015
+ tableRecordData: recordData
1016
+ };
1017
+ actionResult = await this
1018
+ .requestFormAction(formActions.tableAction, actionSubject);
1019
+ serverError = !!this.errorOccured();
1020
+ }
1021
+ await this.finishTableAction(tableActionDetail, actionResult, serverError);
1022
+ if (!serverError) {
1023
+ action.newState && this.changeState(action.newState);
1024
+ } else {
1025
+ this.displayTableServerError();
1026
+ }
1027
+ tableObject.freeWaiting();
1028
+ }
1029
+
1030
+ completeInlineAction(tableAction: any) {
1031
+ return this.startTableServerAction(tableAction);
1032
+ }
1033
+
1034
+ async finishTableAction(tableActionDetail: any, actionResult, serverError = false) {
1035
+ const { tableCode, actionCode } = tableActionDetail;
1036
+ const tableEventHandlers = this._tableActionsFinish[tableCode];
1037
+ const tableActionMethods = (tableEventHandlers) ? tableEventHandlers[actionCode] : null;
1038
+ if (tableActionMethods) {
1039
+ const clientActionPromises: any[] = [];
1040
+ for (const tableActionMethod of tableActionMethods) {
1041
+ const { callback, properties } = tableActionMethod;
1042
+ const continueOnError = properties?.continueOnError ?? false;
1043
+ if (!serverError || continueOnError) {
1044
+ clientActionPromises.push(callback(tableActionDetail, actionResult));
1045
+ }
1046
+ }
1047
+ await Promise.all(clientActionPromises);
1048
+ }
1049
+ }
1050
+
1051
+ async startTableRecordSelection(tableActionEvent: any) {
1052
+ this.notifyFormActivity();
1053
+ const { tableCode, actionDetail } = tableActionEvent;
1054
+ const tableObject = this.getTable(tableCode);
1055
+ if (!tableObject) { return; }
1056
+ this.resetError();
1057
+ const { recordId, recordData } = actionDetail;
1058
+ const tableSelectionDetail = {
1059
+ tableObject,
1060
+ tableCode,
1061
+ recordId,
1062
+ recordData
1063
+ };
1064
+ const tableEventHandlers = this._tableSelectionsStart[tableCode];
1065
+ if (tableEventHandlers) {
1066
+ const clientActionPromises: any[] = [];
1067
+ for (const tableSelectionMethod of tableEventHandlers) {
1068
+ const { callback, properties } = tableSelectionMethod;
1069
+ const clientActionPromise = callback(tableSelectionDetail);
1070
+ clientActionPromises.push(clientActionPromise);
1071
+ }
1072
+ const clientActionResults = await Promise.all(clientActionPromises);
1073
+ const continueAction = clientActionResults.reduce((total, curr) => (total && (curr !== false)), true);
1074
+ if (!continueAction) {
1075
+ return;
1076
+ }
1077
+ }
1078
+ this.startTableServerRecordSelection(tableSelectionDetail);
1079
+ }
1080
+
1081
+ async startTableServerRecordSelection(tableSelectionDetail: any) {
1082
+ const { tableObject, tableCode, recordId, recordData } = tableSelectionDetail;
1083
+ if (!tableObject) { return; }
1084
+ tableObject.putOnWait();
1085
+ let serverError = false;
1086
+ let actionResult = null;
1087
+ if (tableObject.selectionBackend) {
1088
+ const actionSubject: any = {
1089
+ tableCode,
1090
+ actionType: this.formConfig?.tableActions.rowSelection,
1091
+ actionCode: null,
1092
+ tableRecordId: recordId,
1093
+ tableRecordData: recordData
1094
+ };
1095
+ actionResult = await this
1096
+ .requestFormAction(formActions.tableAction, actionSubject);
1097
+ serverError = !!this.errorOccured();
1098
+ }
1099
+ await this.finishTableRecordSelection(tableSelectionDetail, actionResult, serverError);
1100
+ if (serverError) {
1101
+ this.displayTableServerError();
1102
+ }
1103
+ tableObject.freeWaiting();
1104
+ }
1105
+
1106
+ async finishTableRecordSelection(tableSelectionDetail: any, actionResult, serverError = false) {
1107
+ const { tableCode } = tableSelectionDetail;
1108
+ const tableEventHandlers = this._tableSelectionsFinish[tableCode];
1109
+ if (tableEventHandlers) {
1110
+ const clientActionPromises: any[] = [];
1111
+ for (const tableSelectionMethod of tableEventHandlers) {
1112
+ const { callback, properties } = tableSelectionMethod;
1113
+ const continueOnError = properties?.continueOnError ?? false;
1114
+ if (!serverError || continueOnError) {
1115
+ clientActionPromises.push(callback(tableSelectionDetail, actionResult));
1116
+ }
1117
+ }
1118
+ await Promise.all(clientActionPromises);
1119
+ }
1120
+ }
1121
+
1122
+ async startTableSelectionAction(tableActionEvent: any) {
1123
+ this.notifyFormActivity();
1124
+ const { tableCode, actionCode, actionDetail } = tableActionEvent;
1125
+ const tableObject = this.getTable(tableCode);
1126
+ if (!tableObject || !actionCode) { return; }
1127
+ this.resetError();
1128
+ const { selectedRecords } = actionDetail;
1129
+ const action = tableObject.getAction(actionCode);
1130
+ if (!action) { return; }
1131
+ const tableActionDetail = {
1132
+ tableObject,
1133
+ action,
1134
+ tableCode,
1135
+ actionCode,
1136
+ selectedRecords
1137
+ };
1138
+ const tableEventHandlers = this._tableActionsStart[tableCode];
1139
+ const tableActionMethods = (tableEventHandlers) ? tableEventHandlers[actionCode] : null;
1140
+ if (tableActionMethods) {
1141
+ const clientActionPromises: any[] = [];
1142
+ for (const tableActionMethod of tableActionMethods) {
1143
+ const { callback, properties } = tableActionMethod;
1144
+ const clientActionPromise = callback(tableActionDetail);
1145
+ clientActionPromises.push(clientActionPromise);
1146
+ }
1147
+ const clientActionResults = await Promise.all(clientActionPromises);
1148
+ const continueAction = clientActionResults.reduce((total, curr) => (total && (curr !== false)), true);
1149
+ if (!continueAction) {
1150
+ return;
1151
+ }
1152
+ }
1153
+ this.startTableServerSelectionAction(tableActionDetail);
1154
+ }
1155
+
1156
+ async startTableServerSelectionAction(tableActionDetail: any) {
1157
+ const { tableObject, action, tableCode, actionCode, selectedRecords } = tableActionDetail;
1158
+ if (!tableObject || !action) { return; }
1159
+ tableObject.putOnWait();
1160
+ let serverError = false;
1161
+ let actionResult = null;
1162
+ if (action.backend) {
1163
+ const actionSubject = {
1164
+ tableCode,
1165
+ actionType: this.formConfig?.tableActions.selection,
1166
+ actionCode,
1167
+ selectedRecords
1168
+ };
1169
+ actionResult = await this
1170
+ .requestFormAction(formActions.tableAction, actionSubject);
1171
+ serverError = !!this.errorOccured();
1172
+ }
1173
+ await this.finishTableSelectionAction(tableActionDetail, actionResult, serverError);
1174
+ if (!serverError) {
1175
+ action.newState && this.changeState(action.newState);
1176
+ } else {
1177
+ this.displayTableServerError();
1178
+ }
1179
+ tableObject.freeWaiting();
1180
+ }
1181
+
1182
+ async finishTableSelectionAction(tableActionDetail: any, actionResult, serverError = false) {
1183
+ const { tableCode, actionCode } = tableActionDetail;
1184
+ const tableEventHandlers = this._tableActionsFinish[tableCode];
1185
+ const tableActionMethods = (tableEventHandlers) ? tableEventHandlers[actionCode] : null;
1186
+ if (tableActionMethods) {
1187
+ const clientActionPromises: any[] = [];
1188
+ for (const tableActionMethod of tableActionMethods) {
1189
+ const { callback, properties } = tableActionMethod;
1190
+ const continueOnError = properties?.continueOnError ?? false;
1191
+ if (!serverError || continueOnError) {
1192
+ clientActionPromises.push(callback(tableActionDetail, actionResult));
1193
+ }
1194
+ }
1195
+ await Promise.all(clientActionPromises);
1196
+ }
1197
+ }
1198
+
1199
+ async startTableGetData(tableActionEvent: any) {
1200
+ this.notifyFormActivity();
1201
+ const { tableCode } = tableActionEvent;
1202
+ const tableObject = this.getTable(tableCode);
1203
+ const tableActionDetail = {
1204
+ tableObject,
1205
+ tableCode
1206
+ };
1207
+ this.resetError();
1208
+ const tableEventHandlers = this._tableGetDataStart[tableCode];
1209
+ if (tableEventHandlers) {
1210
+ const clientActionPromises: any[] = [];
1211
+ for (const tableActionMethod of tableEventHandlers) {
1212
+ const { callback, properties } = tableActionMethod;
1213
+ const clientActionPromise = callback(tableActionDetail);
1214
+ clientActionPromises.push(clientActionPromise);
1215
+ }
1216
+ const clientActionResults = await Promise.all(clientActionPromises);
1217
+ const continueAction = clientActionResults.reduce((total, curr) => (total && (curr !== false)), true);
1218
+ if (!continueAction) {
1219
+ return;
1220
+ }
1221
+ }
1222
+ this.startTableServerGetData(tableActionDetail);
1223
+ }
1224
+
1225
+ async startTableServerGetData(tableActionDetail: any) {
1226
+ const { tableObject, tableCode } = tableActionDetail;
1227
+ tableObject.putOnWait();
1228
+ let serverError = false;
1229
+ const actionSubject = { tableCode };
1230
+ const actionResult = await this
1231
+ .requestFormAction(formActions.getTableData, actionSubject);
1232
+ serverError = !!this.errorOccured();
1233
+ await this.finishTableGetData(tableActionDetail, actionResult, serverError);
1234
+ if (serverError) {
1235
+ this.displayTableServerError();
1236
+ }
1237
+ tableObject.freeWaiting();
1238
+ }
1239
+
1240
+ async finishTableGetData(tableActionDetail: any, actionResult, serverError = false) {
1241
+ const { tableCode, tableActionCode } = tableActionDetail;
1242
+ const tableEventHandlers = this._tableActionsFinish[tableCode];
1243
+ const tableActionMethods = (tableEventHandlers) ? tableEventHandlers[tableActionCode] : null;
1244
+ if (tableActionMethods) {
1245
+ const clientActionPromises: any[] = [];
1246
+ for (const tableActionMethod of tableActionMethods) {
1247
+ const { callback, properties } = tableActionMethod;
1248
+ const continueOnError = properties?.continueOnError ?? false;
1249
+ if (!serverError || continueOnError) {
1250
+ clientActionPromises.push(callback(tableActionDetail, actionResult));
1251
+ }
1252
+ }
1253
+ await Promise.all(clientActionPromises);
1254
+ }
1255
+ }
1256
+
1257
+ checkSectionRequiredFields(sectionCode: string, reqFieldMessage?: string) {
1258
+ this.cleanErrorFields(null, sectionCode);
1259
+ const requiredFieldMessage = reqFieldMessage ?? this.formConfig?.formStandardErrors.requiredField
1260
+ const numErrors = this.tagFieldsWithError(requiredFieldMessage, this.getRequiredEmptyFields(null, sectionCode));
1261
+ return (numErrors === 0);
1262
+ }
1263
+
1264
+ validateSectionConsistency(sectionCode: string, reqFieldMessage?: string) {
1265
+ this.resetError();
1266
+ const completeFields = this.checkSectionRequiredFields(sectionCode, reqFieldMessage);
1267
+ if (!completeFields) {
1268
+ this.setError(this.formConfig?.formStandardErrors.typeWarning,
1269
+ this.formConfig?.formStandardErrors.validationTitle,
1270
+ this.formConfig?.formStandardErrors.requiredFields);
1271
+ return false;
1272
+ }
1273
+ let validationError = false;
1274
+ const requiredEmptyFields: any[] = this.getRequiredEmptyFields(null, sectionCode) ?? [];
1275
+ if (requiredEmptyFields?.length > 0) {
1276
+ validationError = true;
1277
+ this.setError(this.formConfig?.formStandardErrors.typeWarning,
1278
+ this.formConfig?.formStandardErrors.validationTitle,
1279
+ this.formConfig?.formStandardErrors.requiredFields);
1280
+ this.tagFieldsWithError(this.formConfig?.formStandardErrors.requiredField, requiredEmptyFields);
1281
+ for (const code of requiredEmptyFields) {
1282
+ const requiredEmptyField = this.getField(code);
1283
+ requiredEmptyField?.focus();
1284
+ break;
1285
+ }
1286
+ }
1287
+ const validationIssueFields: any[] = this.getFieldsWithValidationIssues(null,
1288
+ sectionCode) ?? [];
1289
+ if (!validationError && validationIssueFields.length > 0) {
1290
+ validationError = true;
1291
+ this.setError(this.formConfig?.formStandardErrors.typeWarning,
1292
+ this.formConfig?.formStandardErrors.validationTitle,
1293
+ this.formConfig?.formStandardErrors.validationFields);
1294
+ for (const code of validationIssueFields) {
1295
+ const validationIssueField = this.getField(code);
1296
+ if (validationIssueField) {
1297
+ validationIssueField.focus();
1298
+ }
1299
+ break;
1300
+ }
1301
+ }
1302
+ return validationError;
1303
+ }
1304
+
1305
+ copyTableRecordToFields(tableObj: any, mappingTable: any = null) {
1306
+ const tableObject = this.getTable(tableObj.tableCode);
1307
+ const tableRecord = tableObject?.getTableRecord(tableObj.recordId);
1308
+ const columnNames = tableObject?.columnNames;
1309
+ if (tableRecord && columnNames) {
1310
+ for (const columnName of columnNames) {
1311
+ const columnValue = tableRecord.getFieldValue(columnName) ?? '';
1312
+ const code = mappingTable?.[columnName] ?? columnName;
1313
+ const field = code ? this.getField(code) : null;
1314
+ if (field) {
1315
+ field.setValue(columnValue);
1316
+ field.hasChanged = false;
1317
+ }
1318
+ }
1319
+ return true;
1320
+ }
1321
+ return false;
1322
+ }
1323
+
1324
+ notifyFormActivity() {
1325
+ if (this._notifyFormActivity) {
1326
+ this._eventEmiter.next('formActivity', { code: this.formCode });
1327
+ }
1328
+ }
1329
+
1330
+ /**
1331
+ * Métodos Legacy de compatibilidad hacia atrás
1332
+ */
1333
+
1334
+ /**
1335
+ * @deprecated Use name
1336
+ */
1337
+ get formCode(): string { return this.name ?? ''; }
1338
+
1339
+ /**
1340
+ * @deprecated Use name
1341
+ */
1342
+ set formCode(name: string) { this.name = name; }
1343
+
1344
+ /**
1345
+ * @deprecated Use busy signal
1346
+ */
1347
+ get inServerProcess() { return this.busy(); }
1348
+
1349
+ /**
1350
+ * @deprecated Use state
1351
+ */
1352
+ get currentState(): string { return this.state ?? ''; }
1353
+
1354
+ /**
1355
+ * @deprecated Use changeState
1356
+ */
1357
+ set currentState(state: string) { this?.changeState(state); }
1358
+
1359
+ /**
1360
+ * @deprecated Use onSectionActivation
1361
+ */
1362
+ get formRoute(): string { return this._formRoute ?? ''; }
1363
+
1364
+ /**
1365
+ * @deprecated Use onSectionActivation
1366
+ */
1367
+ set formRoute(route: string) { this._formRoute = route; }
1368
+
1369
+ /**
1370
+ * @deprecated Use onSectionActivation
1371
+ */
1372
+ addSectionActivation(codes: string[] | string | null, callback, properties = null) {
1373
+ return this.onSectionActivation(codes, callback, properties);
1374
+ }
1375
+
1376
+ /**
1377
+ * @deprecated Use onSectionInactivation
1378
+ */
1379
+ addSectionInactivation(codes: string[] | string | null, callback, properties = null) {
1380
+ return this.onSectionInactivation(codes, callback, properties);
1381
+ }
1382
+
1383
+ /**
1384
+ * @deprecated Use onActionStart
1385
+ */
1386
+ addActionMethodStart(codes: string[] | string | null, callback, properties = null) {
1387
+ return this.onActionStart(codes, callback, properties);
1388
+ }
1389
+
1390
+ /**
1391
+ * @deprecated Use onActionFinish
1392
+ */
1393
+ addActionMethodFinish(codes: string[] | string | null, callback, properties = null) {
1394
+ return this.onActionFinish(codes, callback, properties);
1395
+ }
1396
+
1397
+ /**
1398
+ * @deprecated Use onFieldInput
1399
+ */
1400
+ addFieldInputValidation(codes: string[] | string | null, callback, properties = null) {
1401
+ return this.onFieldInput(codes, callback, properties);
1402
+ }
1403
+
1404
+ /**
1405
+ * @deprecated Use onFieldValidationStart
1406
+ */
1407
+ addFieldValidationStart(codes: string[] | string | null, callback, properties = null) {
1408
+ return this.onFieldValidationStart(codes, callback, properties);
1409
+ }
1410
+
1411
+ /**
1412
+ * @deprecated Use onFieldValidationFinish
1413
+ */
1414
+ addFieldValidationFinish(codes: string[] | string | null, callback, properties = null) {
1415
+ return this.onFieldValidationFinish(codes, callback, properties);
1416
+ }
1417
+
1418
+ /**
1419
+ * @deprecated Use onTableActionStart
1420
+ */
1421
+ addTableActionStart(code: string, actionCode: string, callback, properties = null) {
1422
+ return this.onTableActionStart(code, actionCode, callback, properties);
1423
+ }
1424
+
1425
+ /**
1426
+ * @deprecated Use onTableActionFinish
1427
+ */
1428
+ addTableActionFinish(code: string, actionCode: string, callback, properties = null) {
1429
+ return this.onTableActionFinish(code, actionCode, callback, properties);
1430
+ }
1431
+
1432
+ /**
1433
+ * @deprecated Use onTableSelectionStart
1434
+ */
1435
+ addTableSelectionStart(code: string, callback, properties = null) {
1436
+ return this.onTableSelectionStart(code, callback, properties);
1437
+ }
1438
+
1439
+ /**
1440
+ * @deprecated Use onTableSelectionFinish
1441
+ */
1442
+ addTableSelectionFinish(code: string, callback, properties = null) {
1443
+ return this.onTableSelectionFinish(code, callback, properties);
1444
+ }
1445
+
1446
+ /**
1447
+ * @deprecated Use onTableGetDataStart
1448
+ */
1449
+ addTableGetDataStart(code: string, callback, properties = null) {
1450
+ return this.onTableGetDataStart(code, callback, properties);
1451
+ }
1452
+
1453
+ /**
1454
+ * @deprecated Use onTableGetDataFinish
1455
+ */
1456
+ addTableGetDataFinish(code: string, callback, properties = null) {
1457
+ return this.onTableGetDataFinish(code, callback, properties);
1458
+ }
1459
+
1460
+ ngOnDestroy() {
1461
+ this.destroy$.next();
1462
+ this.destroy$.complete();
1463
+ }
1464
+ }