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,70 @@
1
+ import { Component, signal, Input, OnInit } from '@angular/core';
2
+ import { Subject, takeUntil } from 'rxjs';
3
+ import { FormAction } from '../../classes/forms/action';
4
+ import { ElementComponent } from './layout/element.component';
5
+
6
+ const CUSTOM_ATTRIBUTES = 'customAttributes';
7
+
8
+ const signaledAttributes = [
9
+ 'actionCode', 'actionName', 'iconName', 'inProgress', 'restrictedOnField', 'restrictedOnOperator',
10
+ 'restrictedOnValue', 'visible', 'disabled',
11
+ ];
12
+
13
+ @Component({
14
+ selector: 'lib-action',
15
+ template: `<ng-content></ng-content>`
16
+ })
17
+
18
+ export class ActionComponent extends ElementComponent implements OnInit {
19
+ private destroy$ = new Subject<void>();
20
+
21
+ actionCode: any = signal(null);
22
+ actionName: any = signal(null);
23
+ iconName: any = signal(null);
24
+ inProgress: any = signal(false);
25
+ restrictedOnField: any = signal(null);
26
+ restrictedOnOperator: any = signal(null);
27
+ restrictedOnValue: any = signal(null);
28
+
29
+ @Input() action: FormAction | null = null;
30
+
31
+ updatePropagatedAttributes() {
32
+ this.updatePieceAttributes(this.action, signaledAttributes)
33
+ }
34
+
35
+ ngOnInit() {
36
+ if (!this.action) { return; }
37
+ this.action.widget = this;
38
+ this.formConfig = this.action?._formConfig;
39
+ this.updatePropagatedAttributes();
40
+ this.replaceCustomAttributes(this.action?.customAttributes);
41
+ this.action?.attributeChange
42
+ .pipe(takeUntil(this.destroy$))
43
+ .subscribe(event => {
44
+ const { name: attribute, value = null } = event ?? {};
45
+ const attributeParts = attribute?.split('.') ?? [];
46
+ if (signaledAttributes.includes(attribute)) {
47
+ this.updatePieceAttribute(signaledAttributes, attribute, value);
48
+ } else if (attributeParts?.length > 1 && attributeParts?.[0] === CUSTOM_ATTRIBUTES) {
49
+ const subAttribute = attributeParts?.[1] ?? null;
50
+ this.updateCustomAttribute(subAttribute, value);
51
+ }
52
+ });
53
+ this.start();
54
+ }
55
+
56
+ override start() {
57
+ this.setForm(this.action?._form);
58
+ }
59
+
60
+ activate() {
61
+ if (this.action?.notifyActivation) {
62
+ this.action.notifyActivation();
63
+ }
64
+ }
65
+
66
+ ngOnDestroy() {
67
+ this.destroy$.next();
68
+ this.destroy$.complete();
69
+ }
70
+ }
@@ -0,0 +1,115 @@
1
+ import { Component, signal, Input, input, model, OnInit } from '@angular/core';
2
+ import { Subject, takeUntil } from 'rxjs';
3
+ import { FieldDescriptor } from '../../classes/forms/field';
4
+ import { ElementComponent } from './layout/element.component'
5
+
6
+ const CUSTOM_ATTRIBUTES = 'customAttributes';
7
+
8
+ const signaledAttributes = ['captureType', 'errorCode', 'errorMessage', 'errorType', 'defaultValue',
9
+ 'defaultEditable', 'alignment', 'code', 'info', 'required', 'title', 'type', 'format', 'options',
10
+ 'hasChanged', 'maxLength', 'maxValue', 'minLength', 'minValue', 'onValidation', 'outputOnly',
11
+ 'placeholder', 'tooltip', 'validateOnServer', 'visibleLabel', 'visible', 'disabled', 'value',
12
+ ];
13
+
14
+ const VALUE = 'value';
15
+ const FOCUS = 'focus';
16
+ @Component({
17
+ selector: 'lib-field',
18
+ template: `<ng-content></ng-content>`
19
+ })
20
+ export class FieldComponent extends ElementComponent implements OnInit {
21
+ private destroy$ = new Subject<void>();
22
+
23
+ // Atributos propagados desde el campo
24
+ captureType: any = signal<string>('');
25
+ errorCode: any = signal<string>('');
26
+ errorMessage: any = signal<string>('');
27
+ errorType: any = signal<string>('');
28
+ defaultValue: any = signal<any>(null);
29
+ defaultEditable: any = signal<boolean>(false);
30
+ alignment: any = signal<string>('');
31
+ code: any = signal<string>('');
32
+ info: any = signal<any>(null);
33
+ required: any = signal<boolean>(false);
34
+ title: any = signal<string>('');
35
+ type: any = signal<string>('');
36
+ format: any = signal<any>(null);
37
+ options: any = signal<any[]>([]);
38
+ hasChanged: any = signal<boolean>(false);
39
+ minLength: any = signal<number>(0);
40
+ maxLength: any = signal<number>(0);
41
+ minValue: any = signal<any>(null);
42
+ maxValue: any = signal<any>(null);
43
+ onValidation: any = signal<boolean>(false);
44
+ outputOnly: any = signal<boolean>(false);
45
+ placeholder: any = signal<string>('');
46
+ tooltip: any = signal<string>('');
47
+ validateOnServer: any = signal<boolean>(false);
48
+ visibleLabel: any = signal<boolean>(true);
49
+
50
+ // value: any; // Valor del componente relacionado con el campo (pueden diferir en formato y tipo)
51
+ value = model<any>(); // Valor del componente relacionado con el campo (pueden diferir en formato y tipo)
52
+ @Input() field: FieldDescriptor | null = null;
53
+ // field = input.required<FieldDescriptor>();
54
+
55
+ updatePropagatedAttributes() {
56
+ this.updatePieceAttributes(this.field, signaledAttributes)
57
+ }
58
+
59
+ ngOnInit() {
60
+ if (!this.field) { return; }
61
+ this.field.widget = this;
62
+ this.formConfig = this.field?._formConfig;
63
+ this.updatePropagatedAttributes();
64
+ this.updateValue();
65
+ this.replaceCustomAttributes(this.field?.customAttributes);
66
+ this.field?.attributeChange
67
+ .pipe(takeUntil(this.destroy$))
68
+ .subscribe(event => {
69
+ const { name: attribute, value = null } = event ?? {};
70
+ const attributeParts = attribute?.split('.') ?? [];
71
+ if (attribute === VALUE) {
72
+ this.updateValue();
73
+ } else if (attribute === FOCUS) {
74
+ this.focus();
75
+ } else if (signaledAttributes.includes(attribute)) {
76
+ this.updatePieceAttribute(signaledAttributes, attribute, value);
77
+ } else if (attributeParts?.length > 1 && attributeParts?.[0] === CUSTOM_ATTRIBUTES) {
78
+ const subAttribute = attributeParts?.[1] ?? null;
79
+ this.updateCustomAttribute(subAttribute, value);
80
+ }
81
+ });
82
+ this.start();
83
+ }
84
+
85
+ updateValue() {
86
+ try {
87
+ this.value.set(this.field?.value);
88
+ } catch (e) {
89
+ console.log(`Excepción en componente de campo ${e}`);
90
+ }
91
+ }
92
+
93
+ onInputChange() { setTimeout(() => this.field?.notifyEditionPartial(), 50); }
94
+ onChangeContent() { setTimeout(() => this.field?.notifyEditionFinish(), 50); }
95
+ onShowInfo(detail = null) { setTimeout(() => this.field?.notifyEditionDetailRequest(detail), 50); }
96
+
97
+ focus() { }
98
+
99
+ updateObject(widgetUpdate = true) { this.field?.setValue(this.value(), widgetUpdate); }
100
+
101
+ inputChanged() {
102
+ this.updateObject();
103
+ this.onChangeContent();
104
+ }
105
+
106
+ inputTyped() {
107
+ this.updateObject(false);
108
+ this.onInputChange();
109
+ }
110
+
111
+ ngOnDestroy() {
112
+ this.destroy$.next();
113
+ this.destroy$.complete();
114
+ }
115
+ }
@@ -0,0 +1,14 @@
1
+ import { Component, Input } from '@angular/core';
2
+ import { PieceComponent } from './piece.component';
3
+
4
+ @Component({
5
+ selector: 'lib-element',
6
+ template: `<ng-content></ng-content>`
7
+ })
8
+ export class ElementComponent extends PieceComponent {
9
+ @Input() element: any;
10
+
11
+ start() {
12
+ this.setForm(this.element?._form);
13
+ }
14
+ }
@@ -0,0 +1,11 @@
1
+ import { Component, Input } from '@angular/core';
2
+
3
+ @Component({
4
+ selector: 'lib-form-error',
5
+ template: `<ng-content></ng-content>`
6
+ })
7
+ export class FormErrorComponent {
8
+ @Input() errorTitle: any;
9
+ @Input() errorMessage: any;
10
+ @Input() errorType: any;
11
+ }
@@ -0,0 +1,14 @@
1
+ import { Component, Input, Output, EventEmitter } from '@angular/core';
2
+
3
+ @Component({
4
+ selector: 'lib-form-header',
5
+ template: `<ng-content></ng-content>`
6
+ })
7
+ export class FormHeaderComponent {
8
+ @Input() form: any;
9
+ @Output() goBackEvent: EventEmitter<void> = new EventEmitter<void>();
10
+
11
+ goBackForm() {
12
+ this.goBackEvent.emit();
13
+ }
14
+ }
@@ -0,0 +1,60 @@
1
+ import { Component, signal, computed } from '@angular/core';
2
+
3
+ const CUSTOM_ATTRIBUTES = 'customAttributes';
4
+ @Component({
5
+ selector: 'lib-piece',
6
+ template: `<ng-content></ng-content>`
7
+ })
8
+ export class PieceComponent {
9
+ form: any;
10
+ formConfig: any;
11
+ visible: any = signal(false);
12
+ disabled: any = signal(false);
13
+ enabled: any = computed(() => !this.disabled());
14
+ customAttributes: any = signal({});
15
+
16
+ setForm(form) { this.form = form; }
17
+
18
+ propagatedAttributeChange(attribute: string, value?: any) { }
19
+
20
+ updatePieceAttribute(signaledAttributes, signaledAttribute, value) {
21
+ if (!signaledAttributes.includes(signaledAttribute)) { return; }
22
+ this[signaledAttribute]?.set(value);
23
+ this.propagatedAttributeChange(signaledAttribute, value);
24
+ }
25
+
26
+ updatePieceAttributes(piece, signaledAttributes) {
27
+ if (!piece) { return; }
28
+ // Se recore el conjunto de los atributos propagados desde el piece y se asigna el valor respectivo
29
+ for (let index = 0; index < signaledAttributes.length; index++) {
30
+ const signaledAttribute = signaledAttributes[index];
31
+ try {
32
+ this[signaledAttribute]?.set(piece?.[signaledAttribute]);
33
+ this.propagatedAttributeChange(signaledAttribute, piece?.[signaledAttribute]);
34
+ } catch (e) {
35
+ console.log(`Señal ${signaledAttribute} invalida en el componente. ${e}`);
36
+ }
37
+ }
38
+ }
39
+
40
+ // Función que las subclases pueden sobrecargar para manejar un comportamiento específico
41
+ customAttributeChange(subAttribute: string, value?: any) { }
42
+
43
+ updateCustomAttribute(attrName, attrValue) {
44
+ this.customAttributes.update(oldCustomAttr => {
45
+ oldCustomAttr[attrName] = attrValue;
46
+ return oldCustomAttr;
47
+ });
48
+ // Ejecución de función personalizada ante un cambio de atributo personalizado
49
+ this.customAttributeChange(attrName, attrValue);
50
+ }
51
+
52
+ replaceCustomAttributes(customAttributes) {
53
+ this.customAttributes.set(customAttributes ?? {});
54
+ Object.keys(customAttributes).forEach(attrName => {
55
+ const attrValue = customAttributes[attrName];
56
+ // Ejecución de función personalizada ante un cambio de atributo personalizado
57
+ this.customAttributeChange(attrName, attrValue);
58
+ });
59
+ }
60
+ }
@@ -0,0 +1,52 @@
1
+ import { Component, Input, OnInit } from '@angular/core';
2
+ import { Subject, takeUntil } from 'rxjs';
3
+ import { PieceComponent } from './piece.component';
4
+
5
+ const CUSTOM_ATTRIBUTES = 'customAttributes';
6
+
7
+ const signaledAttributes = [
8
+ 'visible', 'disabled',
9
+ ];
10
+
11
+ @Component({
12
+ selector: 'lib-section',
13
+ template: `<ng-content></ng-content>`
14
+ })
15
+ export class SectionComponent extends PieceComponent implements OnInit {
16
+ private destroy$ = new Subject<void>();
17
+
18
+ @Input() section: any;
19
+
20
+ updatePropagatedAttributes() {
21
+ this.updatePieceAttributes(this.section, signaledAttributes)
22
+ }
23
+
24
+ ngOnInit() {
25
+ if (!this.section) { return; }
26
+ this.formConfig = this.section?._formConfig;
27
+ this.updatePropagatedAttributes();
28
+ this.replaceCustomAttributes(this.section?.customAttributes);
29
+ this.section?.attributeChange
30
+ .pipe(takeUntil(this.destroy$))
31
+ .subscribe(event => {
32
+ const { name: attribute, value = null } = event ?? {};
33
+ const attributeParts = attribute?.split('.') ?? [];
34
+ if (signaledAttributes.includes(attribute)) {
35
+ this.updatePieceAttribute(signaledAttributes, attribute, value);
36
+ } else if (attributeParts?.length > 1 && attributeParts?.[0] === CUSTOM_ATTRIBUTES) {
37
+ const subAttribute = attributeParts?.[1] ?? null;
38
+ this.updateCustomAttribute(subAttribute, value);
39
+ }
40
+ });
41
+ this.start();
42
+ }
43
+
44
+ start() {
45
+ this.setForm(this.section?._form);
46
+ }
47
+
48
+ ngOnDestroy() {
49
+ this.destroy$.next();
50
+ this.destroy$.complete();
51
+ }
52
+ }
@@ -0,0 +1,52 @@
1
+ import { Component, Input, OnInit } from '@angular/core';
2
+ import { Subject, takeUntil } from 'rxjs';
3
+ import { PieceComponent } from './piece.component';
4
+
5
+ const CUSTOM_ATTRIBUTES = 'customAttributes';
6
+
7
+ const signaledAttributes = [
8
+ 'visible', 'disabled',
9
+ ];
10
+
11
+ @Component({
12
+ selector: 'lib-subsection',
13
+ template: `<ng-content></ng-content>`
14
+ })
15
+ export class SubSectionComponent extends PieceComponent implements OnInit {
16
+ private destroy$ = new Subject<void>();
17
+
18
+ @Input() subSection: any;
19
+
20
+ updatePropagatedAttributes() {
21
+ this.updatePieceAttributes(this.subSection, signaledAttributes)
22
+ }
23
+
24
+ ngOnInit() {
25
+ if (!this.subSection) { return; }
26
+ this.formConfig = this.subSection?._formConfig;
27
+ this.updatePropagatedAttributes();
28
+ this.replaceCustomAttributes(this.subSection?.customAttributes);
29
+ this.subSection?.attributeChange
30
+ .pipe(takeUntil(this.destroy$))
31
+ .subscribe(event => {
32
+ const { name: attribute, value = null } = event ?? {};
33
+ const attributeParts = attribute?.split('.') ?? [];
34
+ if (signaledAttributes.includes(attribute)) {
35
+ this.updatePieceAttribute(signaledAttributes, attribute, value);
36
+ } else if (attributeParts?.length > 1 && attributeParts?.[0] === CUSTOM_ATTRIBUTES) {
37
+ const subAttribute = attributeParts?.[1] ?? null;
38
+ this.updateCustomAttribute(subAttribute, value);
39
+ }
40
+ });
41
+ this.start();
42
+ }
43
+
44
+ start() {
45
+ this.setForm(this.subSection?._form);
46
+ }
47
+
48
+ ngOnDestroy() {
49
+ this.destroy$.next();
50
+ this.destroy$.complete();
51
+ }
52
+ }
@@ -0,0 +1,66 @@
1
+ import { Component, Input, Output, OnInit, EventEmitter, ChangeDetectionStrategy } from '@angular/core';
2
+ import { PieceComponent } from '../layout/piece.component';
3
+ import { TableEvent, TableActionEvent } from '../../../classes/forms/table/table';
4
+ import { TableAction } from '../../../classes/forms/table/action';
5
+
6
+ const INLINE_ACTION = 'INLINE';
7
+ const CUSTOM_ATTRIBUTES = 'customAttributes';
8
+
9
+ const signaledAttributes = [
10
+ 'visible', 'disabled',
11
+ ];
12
+
13
+ @Component({
14
+ selector: 'lib-table-record-action',
15
+ template: `<ng-content></ng-content>`,
16
+ changeDetection: ChangeDetectionStrategy.OnPush
17
+ })
18
+
19
+ export class LibTableRecordActionComponent extends PieceComponent implements OnInit {
20
+ @Input() recordId: any;
21
+ @Input() recordData: any;
22
+ @Input() action: TableAction | undefined;
23
+
24
+ @Output() actionSelected: EventEmitter<TableActionEvent> = new EventEmitter<TableActionEvent>();
25
+
26
+ updatePropagatedAttributes() {
27
+ this.updatePieceAttributes(this.action, signaledAttributes)
28
+ }
29
+
30
+ ngOnInit() {
31
+ if (!this.action) { return; }
32
+ this.formConfig = this.action?._formConfig;
33
+ this.updatePropagatedAttributes();
34
+ this.replaceCustomAttributes(this.action?.customAttributes);
35
+ this.start();
36
+ }
37
+
38
+ start() {
39
+ if (this.action && this.action.restrictedOnField && this.recordData) {
40
+ const relatedField = this.action.restrictedOnField;
41
+ if (relatedField) {
42
+ const relatedFieldValue = this.recordData[relatedField];
43
+ const restrictionOper = this.action.restrictedOnOperator;
44
+ const restrictionValue = this.action.restrictedOnValue;
45
+ let visibility = false;
46
+ if ((restrictionOper === '==' || restrictionOper === '===') && relatedFieldValue === restrictionValue) {
47
+ visibility = true;
48
+ } else if ((restrictionOper === '!=' || restrictionOper === '!==') && relatedFieldValue !== restrictionValue) {
49
+ visibility = true;
50
+ }
51
+ this.visible.set(visibility);
52
+ }
53
+ }
54
+ }
55
+
56
+ onActivate() {
57
+ const tableEvent: TableActionEvent = {
58
+ actionCode: this.action?.actionCode ?? '',
59
+ recordId: this.recordId,
60
+ recordData: this.recordData,
61
+ };
62
+ this.actionSelected.emit(tableEvent);
63
+ }
64
+
65
+ class() { }
66
+ }
@@ -0,0 +1,20 @@
1
+ import { Component, Input, OnInit, ChangeDetectionStrategy } from '@angular/core';
2
+
3
+ @Component({
4
+ selector: 'lib-table-record-field',
5
+ template: `<ng-content></ng-content>`,
6
+ changeDetection: ChangeDetectionStrategy.OnPush
7
+ })
8
+
9
+ export class LibTableRecordFieldComponent implements OnInit {
10
+ @Input() fieldCode: any;
11
+ @Input() fieldType: any;
12
+ @Input() fieldValue: any;
13
+ @Input() column: any = null;
14
+
15
+ ngOnInit() {
16
+ this.start();
17
+ }
18
+
19
+ start() { }
20
+ }
@@ -0,0 +1,112 @@
1
+ import { Component, signal, OnInit, Input, ChangeDetectionStrategy } from '@angular/core';
2
+ import { Subject, takeUntil } from 'rxjs';
3
+ import { TableRecordData } from '../../../classes/forms/table/row-data';
4
+ import { TableActionEvent } from '../../../classes/forms/table/table';
5
+ import { RecordTable, TableEvent } from '../../../classes/forms/table/table';
6
+ import { ElementComponent } from '../layout/element.component';
7
+
8
+ const CUSTOM_ATTRIBUTES = 'customAttributes';
9
+
10
+ const signaledAttributes = [
11
+ 'allSelected', 'code', 'globalSearch', 'recordsPerPage', 'layout',
12
+ 'columns', 'selectedRecords', 'currentPage', 'totalRecordsNumber', 'visibleRecords',
13
+ 'waiting', 'visible', 'disabled',
14
+ ];
15
+
16
+ @Component({
17
+ selector: 'lib-table',
18
+ template: `<ng-content></ng-content>`,
19
+ changeDetection: ChangeDetectionStrategy.OnPush
20
+ })
21
+
22
+ export class LibTableComponent extends ElementComponent implements OnInit {
23
+ private destroy$ = new Subject<void>();
24
+
25
+ // Atributos sincronizados del objeto
26
+ allSelected: any = signal<any>(null);
27
+ code: any = signal<string>('');
28
+ globalSearch: any = signal<any>(null);
29
+ recordsPerPage: any = signal<any>(null);
30
+ layout: any = signal<any>(null);
31
+ columns: any = signal<any>(null);
32
+ selectedRecords: any = signal<any>(null);
33
+ currentPage: any = signal<any>(null);
34
+ totalRecordsNumber: any = signal<any>(null);
35
+ visibleRecords: any = signal<any[]>([]);
36
+ waiting: any = signal<boolean>(false);
37
+
38
+ globalFilterString: string = '';
39
+
40
+ tableFieldStyles: any;
41
+ loaded = false;
42
+ selectable = false;
43
+ hasActions = false;
44
+ inlineActions: any;
45
+ globalActions: any;
46
+ selectionActions: any;
47
+
48
+ @Input() table: RecordTable | null = null;
49
+
50
+ ngOnInit() {
51
+ if (!this.table) { return; }
52
+ this.table.setWidget(this);
53
+ this.formConfig = this.table?._formConfig;
54
+
55
+ this.tableFieldStyles = this.formConfig?.tableFieldStyles;
56
+ this.selectable = this.table?.selectable;
57
+ this.hasActions = this.table?.hasActions();
58
+ this.inlineActions = this.table?.getActions(this.formConfig?.tableActions.inline);
59
+ this.globalActions = this.table?.getActions(this.formConfig?.tableActions.global);
60
+ this.selectionActions = this.table?.getActions(this.formConfig?.tableActions.selection);
61
+ this.globalFilterString = this.table?.globalFilterString;
62
+ this.updatePropagatedAttributes();
63
+ this.replaceCustomAttributes(this.table?.customAttributes);
64
+
65
+ this.table?.attributeChange
66
+ .pipe(takeUntil(this.destroy$))
67
+ .subscribe(event => {
68
+ const { name: attribute, value = null } = event ?? {};
69
+ const attributeParts = attribute?.split('.') ?? [];
70
+ if (attribute === 'visibleRecords') {
71
+ this.visibleRecords.set(value ?? []);
72
+ this.updateTableData();
73
+ } else if (attribute === 'globalFilterString') {
74
+ this.globalFilterString = value;
75
+ } else if (signaledAttributes.includes(attribute)) {
76
+ this.updatePieceAttribute(signaledAttributes, attribute, value);
77
+ } else if (attributeParts?.length > 1 && attributeParts?.[0] === CUSTOM_ATTRIBUTES) {
78
+ const subAttribute = attributeParts?.[1] ?? null;
79
+ this.updateCustomAttribute(subAttribute, value);
80
+ }
81
+ });
82
+ this.start();
83
+ }
84
+
85
+ updatePropagatedAttributes() {
86
+ this.updatePieceAttributes(this.table, signaledAttributes)
87
+ }
88
+
89
+ updateTableData() { }
90
+ tableGlobalAction(actionCode: string) { this.table?.notifyGlobalAction(actionCode); }
91
+ tableSelectionAction(actionCode: string) { this.table?.notifySelectionAction(actionCode); }
92
+ tableActionSelected(actionEvent: TableActionEvent) { this.table?.notifyInlineAction(actionEvent); }
93
+ tableSelectionToggle(recordId: any) { this.table?.notifyRecordSelection(recordId); }
94
+ toggleSelectAll() { return (this.table?.allSelected) ? this.table?.unSelectAll() : this.table?.selectAll(); }
95
+ globalFilterCompleted() { this.changePage(1); }
96
+ changePage(requestedPage: number) { this.table?.changePage(requestedPage); }
97
+ tableColumnSort(columnName: string, direction = null) { this.table?.sort(columnName, direction ?? 'ascend'); }
98
+ globalFilterChanged() { this.table?.setGlobalFilterString(this.globalFilterString?.trim() ?? '', false); }
99
+
100
+ filterHasChanged(column, values) {
101
+ if (!values || values.length === 0) {
102
+ this.table?.removeColumnFilter(column.fieldCode);
103
+ } else {
104
+ this.table?.addColumnFilter(column.fieldCode, values);
105
+ }
106
+ }
107
+
108
+ ngOnDestroy() {
109
+ this.destroy$.next();
110
+ this.destroy$.complete();
111
+ }
112
+ }