commons-shared-web-ui 0.0.62 → 0.0.63

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 (222) hide show
  1. package/fesm2022/commons-shared-web-ui.mjs +16153 -0
  2. package/fesm2022/commons-shared-web-ui.mjs.map +1 -0
  3. package/index.d.ts +5033 -0
  4. package/package.json +34 -53
  5. package/.claude/settings.local.json +0 -10
  6. package/documentation/alert.md +0 -123
  7. package/documentation/button-dropdown.md +0 -126
  8. package/documentation/button.md +0 -184
  9. package/documentation/cards-usage-guidelines.md +0 -131
  10. package/documentation/configurable-form.md +0 -605
  11. package/documentation/confirmation-modal.md +0 -250
  12. package/documentation/filter-sidebar.md +0 -178
  13. package/documentation/filter-table-selector.md +0 -228
  14. package/documentation/form-builder.md +0 -599
  15. package/documentation/form-components.md +0 -384
  16. package/documentation/form-field-configuration.md +0 -250
  17. package/documentation/nav.md +0 -427
  18. package/documentation/pagination.md +0 -181
  19. package/documentation/side-nav-documentation.md +0 -169
  20. package/documentation/smart-form.md +0 -2819
  21. package/documentation/smart-table.md +0 -1297
  22. package/documentation/snackbar.md +0 -118
  23. package/documentation/style-externalization.md +0 -88
  24. package/documentation/summary-card.md +0 -279
  25. package/documentation/table-column-configuration.md +0 -221
  26. package/documentation/time-picker.md +0 -274
  27. package/ng-package.json +0 -30
  28. package/src/lib/modules/alert/alert.models.ts +0 -6
  29. package/src/lib/modules/alert/alert.module.ts +0 -16
  30. package/src/lib/modules/alert/components/alert/alert.component.html +0 -27
  31. package/src/lib/modules/alert/components/alert/alert.component.scss +0 -92
  32. package/src/lib/modules/alert/components/alert/alert.component.ts +0 -81
  33. package/src/lib/modules/button/button.models.ts +0 -13
  34. package/src/lib/modules/button/button.module.ts +0 -16
  35. package/src/lib/modules/button/components/button/button.component.html +0 -22
  36. package/src/lib/modules/button/components/button/button.component.scss +0 -92
  37. package/src/lib/modules/button/components/button/button.component.ts +0 -67
  38. package/src/lib/modules/button-dropdown/button-dropdown.models.ts +0 -26
  39. package/src/lib/modules/button-dropdown/button-dropdown.module.ts +0 -22
  40. package/src/lib/modules/button-dropdown/components/button-dropdown/button-dropdown.component.html +0 -41
  41. package/src/lib/modules/button-dropdown/components/button-dropdown/button-dropdown.component.scss +0 -135
  42. package/src/lib/modules/button-dropdown/components/button-dropdown/button-dropdown.component.ts +0 -160
  43. package/src/lib/modules/configurable-form/component/configurable-form.component.html +0 -294
  44. package/src/lib/modules/configurable-form/component/configurable-form.component.scss +0 -503
  45. package/src/lib/modules/configurable-form/component/configurable-form.component.ts +0 -628
  46. package/src/lib/modules/configurable-form/configurable-form.examples.ts +0 -154
  47. package/src/lib/modules/configurable-form/configurable-form.model.ts +0 -131
  48. package/src/lib/modules/configurable-form/configurable-form.module.ts +0 -19
  49. package/src/lib/modules/confirmation-modal/components/confirmation-modal/confirmation-modal.component.html +0 -77
  50. package/src/lib/modules/confirmation-modal/components/confirmation-modal/confirmation-modal.component.scss +0 -395
  51. package/src/lib/modules/confirmation-modal/components/confirmation-modal/confirmation-modal.component.ts +0 -266
  52. package/src/lib/modules/confirmation-modal/confirmation-modal.models.ts +0 -71
  53. package/src/lib/modules/confirmation-modal/confirmation-modal.module.ts +0 -20
  54. package/src/lib/modules/filter/components/filter/filter.component.html +0 -131
  55. package/src/lib/modules/filter/components/filter/filter.component.scss +0 -245
  56. package/src/lib/modules/filter/components/filter/filter.component.ts +0 -216
  57. package/src/lib/modules/filter/filter.models.ts +0 -88
  58. package/src/lib/modules/filter/filter.module.ts +0 -24
  59. package/src/lib/modules/filter-sidebar/components/filter-sidebar/filter-sidebar.component.html +0 -112
  60. package/src/lib/modules/filter-sidebar/components/filter-sidebar/filter-sidebar.component.scss +0 -186
  61. package/src/lib/modules/filter-sidebar/components/filter-sidebar/filter-sidebar.component.ts +0 -163
  62. package/src/lib/modules/filter-sidebar/filter-sidebar.models.ts +0 -95
  63. package/src/lib/modules/filter-sidebar/filter-sidebar.module.ts +0 -24
  64. package/src/lib/modules/filter-table-selector/components/filter-table-selector/filter-table-selector.component.html +0 -73
  65. package/src/lib/modules/filter-table-selector/components/filter-table-selector/filter-table-selector.component.scss +0 -321
  66. package/src/lib/modules/filter-table-selector/components/filter-table-selector/filter-table-selector.component.ts +0 -361
  67. package/src/lib/modules/filter-table-selector/filter-table-selector.models.ts +0 -91
  68. package/src/lib/modules/filter-table-selector/filter-table-selector.module.ts +0 -22
  69. package/src/lib/modules/form-builder/components/field-configurator/configurator-config-panel/configurator-config-panel.component.html +0 -63
  70. package/src/lib/modules/form-builder/components/field-configurator/configurator-config-panel/configurator-config-panel.component.scss +0 -496
  71. package/src/lib/modules/form-builder/components/field-configurator/configurator-config-panel/configurator-config-panel.component.ts +0 -445
  72. package/src/lib/modules/form-builder/components/field-configurator/configurator-tree/configurator-tree.component.html +0 -75
  73. package/src/lib/modules/form-builder/components/field-configurator/configurator-tree/configurator-tree.component.scss +0 -210
  74. package/src/lib/modules/form-builder/components/field-configurator/configurator-tree/configurator-tree.component.ts +0 -55
  75. package/src/lib/modules/form-builder/components/field-configurator/field-configurator.component.html +0 -25
  76. package/src/lib/modules/form-builder/components/field-configurator/field-configurator.component.scss +0 -82
  77. package/src/lib/modules/form-builder/components/field-configurator/field-configurator.component.ts +0 -95
  78. package/src/lib/modules/form-builder/components/field-selection/field-selection.component.html +0 -20
  79. package/src/lib/modules/form-builder/components/field-selection/field-selection.component.scss +0 -37
  80. package/src/lib/modules/form-builder/components/field-selection/field-selection.component.ts +0 -94
  81. package/src/lib/modules/form-builder/components/field-selection/group-node/group-node.component.html +0 -46
  82. package/src/lib/modules/form-builder/components/field-selection/group-node/group-node.component.scss +0 -102
  83. package/src/lib/modules/form-builder/components/field-selection/group-node/group-node.component.ts +0 -50
  84. package/src/lib/modules/form-builder/components/field-selection/selection-field-node/selection-field-node.component.html +0 -35
  85. package/src/lib/modules/form-builder/components/field-selection/selection-field-node/selection-field-node.component.scss +0 -67
  86. package/src/lib/modules/form-builder/components/field-selection/selection-field-node/selection-field-node.component.ts +0 -34
  87. package/src/lib/modules/form-builder/components/field-selection/selection-section-node/selection-section-node.component.html +0 -68
  88. package/src/lib/modules/form-builder/components/field-selection/selection-section-node/selection-section-node.component.scss +0 -113
  89. package/src/lib/modules/form-builder/components/field-selection/selection-section-node/selection-section-node.component.ts +0 -74
  90. package/src/lib/modules/form-builder/configs/field-type-schema.map.ts +0 -533
  91. package/src/lib/modules/form-builder/form-builder.module.ts +0 -36
  92. package/src/lib/modules/form-builder/index.ts +0 -9
  93. package/src/lib/modules/form-builder/models/builder.models.ts +0 -7
  94. package/src/lib/modules/form-builder/models/field-configurator.models.ts +0 -38
  95. package/src/lib/modules/form-builder/models/field-selection.models.ts +0 -51
  96. package/src/lib/modules/form-builder/services/field-configurator.service.ts +0 -258
  97. package/src/lib/modules/form-builder/services/field-selection.service.ts +0 -299
  98. package/src/lib/modules/form-builder/services/form-schema-tree.service.ts +0 -670
  99. package/src/lib/modules/form-builder/tokens/builder.tokens.ts +0 -10
  100. package/src/lib/modules/form-builder/utils/constants.ts +0 -43
  101. package/src/lib/modules/form-components/components/checkbox/checkbox.component.html +0 -29
  102. package/src/lib/modules/form-components/components/checkbox/checkbox.component.scss +0 -111
  103. package/src/lib/modules/form-components/components/checkbox/checkbox.component.ts +0 -207
  104. package/src/lib/modules/form-components/components/checkbox/checkbox.models.ts +0 -35
  105. package/src/lib/modules/form-components/components/datepicker/datepicker.component.html +0 -42
  106. package/src/lib/modules/form-components/components/datepicker/datepicker.component.scss +0 -115
  107. package/src/lib/modules/form-components/components/datepicker/datepicker.component.ts +0 -267
  108. package/src/lib/modules/form-components/components/datepicker/datepicker.models.ts +0 -45
  109. package/src/lib/modules/form-components/components/dropdown/dropdown.component.html +0 -74
  110. package/src/lib/modules/form-components/components/dropdown/dropdown.component.scss +0 -252
  111. package/src/lib/modules/form-components/components/dropdown/dropdown.component.ts +0 -377
  112. package/src/lib/modules/form-components/components/dropdown/dropdown.models.ts +0 -53
  113. package/src/lib/modules/form-components/components/input/input.component.html +0 -51
  114. package/src/lib/modules/form-components/components/input/input.component.scss +0 -128
  115. package/src/lib/modules/form-components/components/input/input.component.ts +0 -250
  116. package/src/lib/modules/form-components/components/input/input.models.ts +0 -55
  117. package/src/lib/modules/form-components/components/radio/radio.component.html +0 -22
  118. package/src/lib/modules/form-components/components/radio/radio.component.scss +0 -107
  119. package/src/lib/modules/form-components/components/radio/radio.component.ts +0 -181
  120. package/src/lib/modules/form-components/components/radio/radio.models.ts +0 -39
  121. package/src/lib/modules/form-components/components/search/search.component.html +0 -15
  122. package/src/lib/modules/form-components/components/search/search.component.scss +0 -87
  123. package/src/lib/modules/form-components/components/search/search.component.ts +0 -213
  124. package/src/lib/modules/form-components/components/search/search.models.ts +0 -40
  125. package/src/lib/modules/form-components/components/toggle/toggle.component.html +0 -15
  126. package/src/lib/modules/form-components/components/toggle/toggle.component.scss +0 -81
  127. package/src/lib/modules/form-components/components/toggle/toggle.component.ts +0 -166
  128. package/src/lib/modules/form-components/components/toggle/toggle.models.ts +0 -27
  129. package/src/lib/modules/form-components/directives/click-outside.directive.ts +0 -22
  130. package/src/lib/modules/form-components/form-components.module.ts +0 -42
  131. package/src/lib/modules/form-field-configuration/components/_ffc-controls.scss +0 -89
  132. package/src/lib/modules/form-field-configuration/components/config-field-node/config-field-node.component.html +0 -68
  133. package/src/lib/modules/form-field-configuration/components/config-field-node/config-field-node.component.scss +0 -73
  134. package/src/lib/modules/form-field-configuration/components/config-field-node/config-field-node.component.ts +0 -34
  135. package/src/lib/modules/form-field-configuration/components/config-section-node/config-section-node.component.html +0 -78
  136. package/src/lib/modules/form-field-configuration/components/config-section-node/config-section-node.component.scss +0 -83
  137. package/src/lib/modules/form-field-configuration/components/config-section-node/config-section-node.component.ts +0 -94
  138. package/src/lib/modules/form-field-configuration/components/form-field-configuration/form-field-configuration.component.html +0 -38
  139. package/src/lib/modules/form-field-configuration/components/form-field-configuration/form-field-configuration.component.scss +0 -42
  140. package/src/lib/modules/form-field-configuration/components/form-field-configuration/form-field-configuration.component.ts +0 -92
  141. package/src/lib/modules/form-field-configuration/form-field-configuration.module.ts +0 -23
  142. package/src/lib/modules/form-field-configuration/index.ts +0 -7
  143. package/src/lib/modules/form-field-configuration/models/field-configuration.models.ts +0 -62
  144. package/src/lib/modules/form-field-configuration/services/config-schema-tree.service.ts +0 -159
  145. package/src/lib/modules/form-field-configuration/services/field-configuration.service.ts +0 -228
  146. package/src/lib/modules/material/material.module.ts +0 -94
  147. package/src/lib/modules/nav/components/nav/nav.component.html +0 -34
  148. package/src/lib/modules/nav/components/nav/nav.component.scss +0 -171
  149. package/src/lib/modules/nav/components/nav/nav.component.ts +0 -82
  150. package/src/lib/modules/nav/nav.models.ts +0 -31
  151. package/src/lib/modules/nav/nav.module.ts +0 -17
  152. package/src/lib/modules/pagination/components/pagination/pagination.component.html +0 -52
  153. package/src/lib/modules/pagination/components/pagination/pagination.component.scss +0 -155
  154. package/src/lib/modules/pagination/components/pagination/pagination.component.ts +0 -109
  155. package/src/lib/modules/pagination/pagination.module.ts +0 -17
  156. package/src/lib/modules/side-nav/components/side-nav/side-nav.component.html +0 -56
  157. package/src/lib/modules/side-nav/components/side-nav/side-nav.component.scss +0 -342
  158. package/src/lib/modules/side-nav/components/side-nav/side-nav.component.ts +0 -135
  159. package/src/lib/modules/side-nav/side-nav.models.ts +0 -38
  160. package/src/lib/modules/side-nav/side-nav.module.ts +0 -16
  161. package/src/lib/modules/smart-form/components/form-field/form-field.component.html +0 -1379
  162. package/src/lib/modules/smart-form/components/form-field/form-field.component.scss +0 -2255
  163. package/src/lib/modules/smart-form/components/form-field/form-field.component.ts +0 -3174
  164. package/src/lib/modules/smart-form/components/form-section/form-section.component.html +0 -67
  165. package/src/lib/modules/smart-form/components/form-section/form-section.component.scss +0 -209
  166. package/src/lib/modules/smart-form/components/form-section/form-section.component.ts +0 -142
  167. package/src/lib/modules/smart-form/components/smart-form/smart-form.component.html +0 -253
  168. package/src/lib/modules/smart-form/components/smart-form/smart-form.component.scss +0 -689
  169. package/src/lib/modules/smart-form/components/smart-form/smart-form.component.ts +0 -1134
  170. package/src/lib/modules/smart-form/index.ts +0 -10
  171. package/src/lib/modules/smart-form/models/form-schema.model.ts +0 -803
  172. package/src/lib/modules/smart-form/models/hierarchy-config.model.ts +0 -22
  173. package/src/lib/modules/smart-form/services/expression.service.ts +0 -75
  174. package/src/lib/modules/smart-form/services/smart-form-controller.service.ts +0 -67
  175. package/src/lib/modules/smart-form/smart-form.examples.ts +0 -1324
  176. package/src/lib/modules/smart-form/smart-form.module.ts +0 -40
  177. package/src/lib/modules/smart-form/utils/translation.utils.ts +0 -82
  178. package/src/lib/modules/smart-form/utils/trusted-url.pipe.ts +0 -25
  179. package/src/lib/modules/smart-form/utils/validation.utils.ts +0 -98
  180. package/src/lib/modules/smart-table/components/smart-table/smart-table.component.html +0 -283
  181. package/src/lib/modules/smart-table/components/smart-table/smart-table.component.scss +0 -685
  182. package/src/lib/modules/smart-table/components/smart-table/smart-table.component.ts +0 -1219
  183. package/src/lib/modules/smart-table/models/table-config.model.ts +0 -247
  184. package/src/lib/modules/smart-table/smart-table.module.ts +0 -30
  185. package/src/lib/modules/smart-table/utils/safe-html.pipe.ts +0 -28
  186. package/src/lib/modules/smart-table/utils/smart-table.utils.ts +0 -18
  187. package/src/lib/modules/snackbar/components/snackbar.component.html +0 -41
  188. package/src/lib/modules/snackbar/components/snackbar.component.scss +0 -99
  189. package/src/lib/modules/snackbar/components/snackbar.component.ts +0 -18
  190. package/src/lib/modules/snackbar/models/snackbar.models.ts +0 -10
  191. package/src/lib/modules/snackbar/services/snackbar.service.ts +0 -40
  192. package/src/lib/modules/snackbar/snackbar.module.ts +0 -11
  193. package/src/lib/modules/summary-card/components/summary-card/summary-card.component.html +0 -47
  194. package/src/lib/modules/summary-card/components/summary-card/summary-card.component.scss +0 -199
  195. package/src/lib/modules/summary-card/components/summary-card/summary-card.component.ts +0 -126
  196. package/src/lib/modules/summary-card/summary-card.module.ts +0 -18
  197. package/src/lib/modules/table-column-configuration/components/_tcc-controls.scss +0 -53
  198. package/src/lib/modules/table-column-configuration/components/config-column-node/config-column-node.component.html +0 -47
  199. package/src/lib/modules/table-column-configuration/components/config-column-node/config-column-node.component.scss +0 -50
  200. package/src/lib/modules/table-column-configuration/components/config-column-node/config-column-node.component.ts +0 -33
  201. package/src/lib/modules/table-column-configuration/components/table-column-configuration/table-column-configuration.component.html +0 -30
  202. package/src/lib/modules/table-column-configuration/components/table-column-configuration/table-column-configuration.component.scss +0 -36
  203. package/src/lib/modules/table-column-configuration/components/table-column-configuration/table-column-configuration.component.ts +0 -78
  204. package/src/lib/modules/table-column-configuration/index.ts +0 -5
  205. package/src/lib/modules/table-column-configuration/models/table-column-configuration.models.ts +0 -20
  206. package/src/lib/modules/table-column-configuration/services/table-column-configuration.service.ts +0 -77
  207. package/src/lib/modules/table-column-configuration/table-column-configuration.module.ts +0 -21
  208. package/src/lib/modules/time-picker/components/time-picker/time-picker.component.html +0 -37
  209. package/src/lib/modules/time-picker/components/time-picker/time-picker.component.scss +0 -102
  210. package/src/lib/modules/time-picker/components/time-picker/time-picker.component.ts +0 -178
  211. package/src/lib/modules/time-picker/components/time-wheel-panel/time-wheel-panel.component.html +0 -78
  212. package/src/lib/modules/time-picker/components/time-wheel-panel/time-wheel-panel.component.scss +0 -226
  213. package/src/lib/modules/time-picker/components/time-wheel-panel/time-wheel-panel.component.ts +0 -595
  214. package/src/lib/modules/time-picker/models/time-picker.models.ts +0 -49
  215. package/src/lib/modules/time-picker/time-picker.module.ts +0 -23
  216. package/src/lib/shared-ui.module.ts +0 -55
  217. package/src/lib/utils/constants.ts +0 -11
  218. package/src/lib/utils/storage.utils.ts +0 -37
  219. package/src/lib/utils/string.utils.ts +0 -23
  220. package/src/lib/utils/translation.utils.ts +0 -87
  221. package/src/public-api.ts +0 -127
  222. package/tsconfig.lib.json +0 -15
@@ -1,628 +0,0 @@
1
- import { Component, EventEmitter, Input, OnInit, Output, OnChanges, SimpleChanges } from '@angular/core';
2
- import { FormBuilder, FormGroup, FormControl, FormArray, Validators, AbstractControl, ReactiveFormsModule } from '@angular/forms';
3
- import { MatSnackBar } from '@angular/material/snack-bar';
4
- import { HttpClient } from '@angular/common/http';
5
- import {
6
- FormConfig,
7
- FormField,
8
- FormSection,
9
- FormOption,
10
- JsonFormConfig,
11
- JsonFieldConfig,
12
- FieldType,
13
- UISubType
14
- } from '../configurable-form.model';
15
- import { CommonModule } from '@angular/common';
16
- import { MaterialModule } from '../../material/material.module';
17
- import { translateConfig } from '../../../utils/translation.utils';
18
-
19
- @Component({
20
- selector: 'lib-configurable-form',
21
- templateUrl: './configurable-form.component.html',
22
- styleUrls: ['./configurable-form.component.scss'],
23
- standalone: true,
24
- imports: [CommonModule, ReactiveFormsModule, MaterialModule],
25
- })
26
- export class ConfigurableFormComponent implements OnInit, OnChanges {
27
- @Input() config!: FormConfig;
28
- @Input() jsonConfig!: JsonFormConfig;
29
- @Input() data: any = {};
30
- @Input() baseApiUrl: string = '';
31
- @Input() labels: any;
32
- @Output() optionsLoad = new EventEmitter<any>();
33
-
34
- form!: FormGroup;
35
- processedConfig!: FormConfig;
36
- fieldVisibilityMap: Map<string, boolean> = new Map();
37
- passwordFieldState: Map<string, boolean> = new Map();
38
-
39
- constructor(
40
- private fb: FormBuilder,
41
- private snackBar: MatSnackBar,
42
- private http: HttpClient
43
- ) { }
44
-
45
- ngOnInit(): void {
46
- this.initializeForm();
47
- }
48
-
49
- ngOnChanges(changes: SimpleChanges): void {
50
- if (changes['config'] || changes['jsonConfig']) {
51
- this.initializeForm();
52
- }
53
- if (changes['data'] && this.form) {
54
- this.form.patchValue(this.data);
55
- }
56
- }
57
-
58
- initializeForm() {
59
- // Transform JSON config if provided, otherwise use config directly
60
- if (this.jsonConfig) {
61
- this.processedConfig = this.transformJsonConfig(this.jsonConfig);
62
- } else if (this.config) {
63
- this.processedConfig = JSON.parse(JSON.stringify(this.config));
64
- } else {
65
- return;
66
- }
67
-
68
- // Apply translations if labels and labelsObject are provided
69
- if (this.labels && this.labels.labelsObject) {
70
- translateConfig(this.processedConfig, this.labels.labelsObject);
71
- }
72
-
73
-
74
- this.normalizeFields();
75
- this.initializeFieldVisibility();
76
- this.buildForm();
77
- this.setupDependencies();
78
-
79
- // Patch initial data if provided
80
- if (this.data && Object.keys(this.data).length > 0) {
81
- this.form.patchValue(this.data);
82
- }
83
- }
84
-
85
- // Transform JSON config format to internal FormConfig format
86
- transformJsonConfig(jsonConfig: JsonFormConfig): FormConfig {
87
- const fields = jsonConfig.jsonConfig
88
- .sort((a, b) => a.sequence - b.sequence)
89
- .map(field => this.transformJsonField(field));
90
-
91
- return {
92
- sections: [{
93
- sectionTitle: jsonConfig.label,
94
- fields: fields
95
- }],
96
- entityType: jsonConfig.entityType
97
- };
98
- }
99
-
100
- // Transform individual JSON field to FormField
101
- transformJsonField(jsonField: JsonFieldConfig): FormField {
102
- const fieldType = this.mapUISubTypeToFieldType(jsonField.uiConfig.subType);
103
-
104
- return {
105
- name: jsonField.jsonKey,
106
- jsonKey: jsonField.jsonKey,
107
- label: jsonField.label,
108
- type: fieldType,
109
- sequence: jsonField.sequence,
110
- keyType: jsonField.keyType,
111
- uiConfig: jsonField.uiConfig,
112
- validationRules: jsonField.validationRules,
113
- required: jsonField.validationRules?.isMandatory || jsonField.validationRules?.isRequired,
114
- mandatory: jsonField.validationRules?.isMandatory,
115
- dependsOn: undefined, // Will be set based on dependent array
116
- dependent: jsonField.uiConfig.dependent,
117
- optionConfigs: jsonField.uiConfig.optionConfigs,
118
- class: 'col-12'
119
- };
120
- }
121
-
122
- // Map UI subtype to field type
123
- mapUISubTypeToFieldType(subType?: string): FieldType {
124
- switch (subType) {
125
- case 'UI_SUBTYPE.SHORT_TEXT':
126
- return 'text';
127
- case 'UI_SUBTYPE.LONG_TEXT':
128
- return 'textarea';
129
- case 'UI_SUBTYPE.NUMBER':
130
- return 'number';
131
- case 'UI_SUBTYPE.EMAIL':
132
- return 'email';
133
- case 'UI_SUBTYPE.PHONE':
134
- return 'tel';
135
- case 'UI_SUBTYPE.URL':
136
- return 'url';
137
- default:
138
- return 'text';
139
- }
140
- }
141
-
142
- // Normalize fields to ensure all required properties exist
143
- normalizeFields() {
144
- this.processedConfig.sections.forEach(section => {
145
- section.fields.forEach(field => {
146
- // Set default type if not specified
147
- if (!field.type) {
148
- field.type = 'text';
149
- }
150
-
151
- // Merge uiConfig with field-level properties
152
- if (field.uiConfig) {
153
- if (field.uiConfig.type === 'UI_TYPE.DROP_DOWN') {
154
- field.type = 'dropdown';
155
- }
156
- if (field.uiConfig.optionConfigs) {
157
- field.optionConfigs = field.uiConfig.optionConfigs;
158
- }
159
- if (field.uiConfig.dependent) {
160
- field.dependent = field.uiConfig.dependent;
161
- }
162
- }
163
-
164
- // Initialize visibility
165
- if (field.visible === undefined) {
166
- field.visible = true;
167
- }
168
-
169
- // Load options for dropdowns
170
- if ((field.type === 'dropdown' || field.type === 'select') && field.optionConfigs) {
171
- this.loadFieldOptions(field);
172
- }
173
- });
174
- });
175
- }
176
-
177
- // Initialize field visibility map
178
- initializeFieldVisibility() {
179
- this.processedConfig.sections.forEach(section => {
180
- section.fields.forEach(field => {
181
- this.fieldVisibilityMap.set(field.name, field.visible !== false);
182
- });
183
- });
184
- }
185
-
186
- buildForm() {
187
- const formGroupConfig: any = {};
188
-
189
- this.processedConfig.sections.forEach(section => {
190
- if (section.isRepeater) {
191
- // Create FormArray for repeater sections
192
- const arrayName = section.formArrayName || 'items';
193
- const minItems = section.minItems || 1;
194
- const initialItems = [];
195
-
196
- for (let i = 0; i < minItems; i++) {
197
- initialItems.push(this.createGroup(section.fields));
198
- }
199
-
200
- formGroupConfig[arrayName] = this.fb.array(initialItems);
201
- } else {
202
- // Add regular fields to form group
203
- section.fields.forEach(field => {
204
- if (field.subFields) {
205
- // Composite field - add all sub-fields
206
- field.subFields.forEach(subField => {
207
- if (field.required || field.mandatory) {
208
- subField.required = true;
209
- }
210
- formGroupConfig[subField.name] = this.createControl(subField);
211
- });
212
- } else {
213
- formGroupConfig[field.name] = this.createControl(field);
214
- }
215
- });
216
- }
217
- });
218
-
219
- this.form = this.fb.group(formGroupConfig);
220
-
221
- // Apply composite validators to the root form group
222
- this.processedConfig.sections.forEach(section => {
223
- if (!section.isRepeater) {
224
- section.fields.forEach(field => {
225
- if (field.type === 'composite' && field.compositeValidationRule && field.subFields) {
226
- this.form.addValidators(this.createCompositeValidator(field));
227
- }
228
- });
229
- }
230
- });
231
- this.form.updateValueAndValidity();
232
- }
233
-
234
- createCompositeValidator(field: FormField) {
235
- return (control: AbstractControl) => {
236
- const group = control as FormGroup;
237
- if (!field.subFields || field.subFields.length < 2) return null;
238
-
239
- if (field.compositeValidationRule === 'minMax') {
240
- const minControl = group.get(field.subFields[0].name);
241
- const maxControl = group.get(field.subFields[1].name);
242
-
243
- if (minControl && maxControl && minControl.value !== null && maxControl.value !== null) {
244
- if (Number(minControl.value) > Number(maxControl.value)) {
245
- return { [`invalid_minMax_${field.name}`]: true };
246
- }
247
- }
248
- }
249
-
250
- if (field.compositeValidationRule === 'percentageTotal') {
251
- let total = 0;
252
- let allPresent = true;
253
-
254
- field.subFields.forEach(sub => {
255
- const ctrl = group.get(sub.name);
256
- if (ctrl && ctrl.value !== null && ctrl.value !== '') {
257
- total += Number(ctrl.value);
258
- } else {
259
- allPresent = false;
260
- }
261
- });
262
-
263
- if (allPresent && total !== 100) {
264
- return { [`invalid_percentageTotal_${field.name}`]: true };
265
- }
266
- }
267
-
268
- return null;
269
- };
270
- }
271
-
272
- createControl(field: FormField): FormControl {
273
- const validators = [];
274
-
275
- // Add validators based on field configuration
276
- if (field.required || field.mandatory || field.validationRules?.isMandatory || field.validationRules?.isRequired) {
277
- validators.push(Validators.required);
278
- }
279
-
280
- if (field.validationRules?.minLength) {
281
- validators.push(Validators.minLength(field.validationRules.minLength));
282
- }
283
-
284
- if (field.validationRules?.maxLength) {
285
- validators.push(Validators.maxLength(field.validationRules.maxLength));
286
- }
287
-
288
- if (field.validationRules?.pattern) {
289
- validators.push(Validators.pattern(field.validationRules.pattern));
290
- }
291
-
292
- if (field.validationRules?.min !== undefined) {
293
- validators.push(Validators.min(field.validationRules.min));
294
- }
295
-
296
- if (field.validationRules?.max !== undefined) {
297
- validators.push(Validators.max(field.validationRules.max));
298
- }
299
-
300
- if (field.type === 'email') {
301
- validators.push(Validators.email);
302
- }
303
-
304
- const initialValue = field.value !== undefined ? field.value : '';
305
- return this.fb.control({ value: initialValue, disabled: field.disabled || false }, validators);
306
- }
307
-
308
- createGroup(fields: FormField[]): FormGroup {
309
- const groupConfig: any = {};
310
-
311
- fields.forEach(field => {
312
- if (field.subFields) {
313
- field.subFields.forEach(subField => {
314
- groupConfig[subField.name] = this.createControl(subField);
315
- });
316
- } else {
317
- groupConfig[field.name] = this.createControl(field);
318
- }
319
- });
320
-
321
- return this.fb.group(groupConfig);
322
- }
323
-
324
- getFormArray(name: string): FormArray {
325
- return this.form.get(name) as FormArray;
326
- }
327
-
328
- addRepeaterItem(section: FormSection) {
329
- const arrayName = section.formArrayName || 'items';
330
- const formArray = this.getFormArray(arrayName);
331
-
332
- // Check max items
333
- if (section.maxItems && formArray.length >= section.maxItems) {
334
- this.snackBar.open(this.labels.errorMaxItemsAllowed.replace('{0}', String(section.maxItems)), this.labels.closeSnackBar, { duration: 3000 });
335
- return;
336
- }
337
-
338
- formArray.push(this.createGroup(section.fields));
339
- }
340
-
341
- removeRepeaterItem(sectionName: string, index: number) {
342
- const formArray = this.getFormArray(sectionName);
343
- formArray.removeAt(index);
344
- }
345
-
346
- validate(): boolean {
347
- if (this.form.invalid) {
348
- this.form.markAllAsTouched();
349
- this.scrollToFirstInvalidControl();
350
- return false;
351
- }
352
- return true;
353
- }
354
-
355
- scrollToFirstInvalidControl() {
356
- const firstInvalidControl = document.querySelector('.is-invalid');
357
- if (firstInvalidControl) {
358
- firstInvalidControl.scrollIntoView({ behavior: 'smooth', block: 'center' });
359
- }
360
- }
361
-
362
- setupDependencies() {
363
- this.processedConfig.sections.forEach(section => {
364
- section.fields.forEach(field => {
365
-
366
-
367
- // Also setup for fields with dependent array
368
- if (field.dependent && field.dependent.length > 0) {
369
- const control = this.form.get(field.name);
370
- if (control) {
371
- control.valueChanges.subscribe(value => {
372
- this.onFieldValueChange(field, value);
373
- });
374
- }
375
- }
376
- });
377
- });
378
- }
379
-
380
- onFieldValueChange(field: FormField, value: any) {
381
- // Handle dependent fields
382
- if (field.dependent && field.dependent.length > 0) {
383
- field.dependent.forEach(dependentFieldName => {
384
- const dependentField = this.findFieldByName(dependentFieldName);
385
- if (dependentField) {
386
- // Clear the dependent field value
387
- const control = this.form.get(dependentFieldName);
388
- if (control) {
389
- control.setValue('');
390
- control.markAsUntouched();
391
- }
392
-
393
- // Load new options for the dependent field
394
- if (value) {
395
- this.loadFieldOptions(dependentField, { [field.name]: value });
396
- } else {
397
- // Clear options if parent value is cleared
398
- dependentField.loadedOptions = [];
399
- }
400
- }
401
- });
402
- }
403
- }
404
-
405
- // Load options for a dropdown field
406
- loadFieldOptions(field: FormField, parentValues?: any) {
407
- // Emit event for parent to notify about options load request
408
- // Allow parent to mark as handled to skip internal API call
409
- const event = { field, parentValue: parentValues, handled: false };
410
- this.optionsLoad.emit(event);
411
-
412
- if (event.handled) {
413
- return;
414
- }
415
-
416
- if (!field.optionConfigs) {
417
- return;
418
- }
419
-
420
- const config = field.optionConfigs;
421
-
422
- // Handle static options
423
- if (config.optionDTO === 'OPTION_DTO.STATIC' && config.staticOptions) {
424
- field.loadedOptions = config.staticOptions;
425
- return;
426
- }
427
-
428
- // Handle API-based options
429
- if (config.optionDTO === 'OPTION_DTO.REF_DATA' && config.url) {
430
- let url = config.url;
431
-
432
- // Replace placeholders in URL with parent values
433
- if (parentValues) {
434
- Object.keys(parentValues).forEach(key => {
435
- url = url.replace(`{${key}}`, parentValues[key]);
436
- });
437
- }
438
-
439
- // Prepend base API URL if provided
440
- if (this.baseApiUrl && !url.startsWith('http')) {
441
- url = `${this.baseApiUrl}/${url}`;
442
- }
443
-
444
- this.http.get<any>(url).subscribe({
445
- next: (response) => {
446
- // Extract data from response
447
- const data = response.data || response.content || response;
448
- field.loadedOptions = this.extractOptions(data, config);
449
- },
450
- error: (error) => {
451
- console.error('Error loading options:', error);
452
- field.loadedOptions = [];
453
- }
454
- });
455
- }
456
- }
457
-
458
- // Extract options from API response
459
- extractOptions(data: any[], config: any): FormOption[] {
460
- if (!Array.isArray(data)) {
461
- return [];
462
- }
463
-
464
- return data.map(item => ({
465
- label: item[config.labelKey || 'name'],
466
- value: item[config.requestKey || 'code'] || item[config.valueKey || 'id'],
467
- code: item.code,
468
- name: item.name
469
- }));
470
- }
471
-
472
- // Get options for a field (either static or loaded)
473
- getFieldOptions(field: FormField): FormOption[] {
474
- return field.loadedOptions || field.options || [];
475
- }
476
-
477
- // Check if field is visible
478
- isFieldVisible(field: FormField): boolean {
479
- return this.fieldVisibilityMap.get(field.name) !== false;
480
- }
481
-
482
- // Toggle field visibility
483
- toggleFieldVisibility(field: FormField, visible: boolean) {
484
- this.fieldVisibilityMap.set(field.name, visible);
485
-
486
- const control = this.form.get(field.name);
487
- if (control) {
488
- if (visible) {
489
- // Re-enable and restore validators
490
- control.enable();
491
- this.updateControlValidators(control, field);
492
- } else {
493
- // Disable and clear validators
494
- control.disable();
495
- control.clearValidators();
496
- control.updateValueAndValidity();
497
- }
498
- }
499
- }
500
-
501
- // Update control validators based on field config
502
- updateControlValidators(control: AbstractControl, field: FormField) {
503
- const validators = [];
504
-
505
- if (field.required || field.mandatory || field.validationRules?.isMandatory) {
506
- validators.push(Validators.required);
507
- }
508
-
509
- if (field.validationRules?.minLength) {
510
- validators.push(Validators.minLength(field.validationRules.minLength));
511
- }
512
-
513
- if (field.validationRules?.maxLength) {
514
- validators.push(Validators.maxLength(field.validationRules.maxLength));
515
- }
516
-
517
- if (field.validationRules?.pattern) {
518
- validators.push(Validators.pattern(field.validationRules.pattern));
519
- }
520
-
521
- control.setValidators(validators);
522
- control.updateValueAndValidity();
523
- }
524
-
525
- onFileChange(event: any, field: FormField) {
526
- const files: FileList = event.target.files;
527
-
528
- if (!files || files.length === 0) {
529
- return;
530
- }
531
-
532
- // Initialize uploadedFiles if not present
533
- // Initialize uploadedFiles if not present
534
- if (!field.uploadedFiles) {
535
- field.uploadedFiles = [];
536
- }
537
-
538
- const uploadedFiles: any[] = [];
539
- // Handle files
540
- for (let i = 0; i < files.length; i++) {
541
- const file = files[i];
542
-
543
- // Check file size (5MB limit)
544
- if (file.size > 5 * 1024 * 1024) {
545
- this.snackBar.open(this.labels.errorFileLimitExceeded.replace('{0}', file.name), this.labels.closeSnackBar, { duration: 3000 });
546
- continue;
547
- }
548
-
549
- uploadedFiles.push({
550
- name: file.name,
551
- size: file.size,
552
- type: file.type,
553
- file: file
554
- });
555
- }
556
-
557
- if (field.multiple) {
558
- field.uploadedFiles.push(...uploadedFiles);
559
- } else {
560
- field.uploadedFiles = uploadedFiles;
561
- }
562
-
563
- // Update form control value for validation
564
- this.updateFileControlValue(field);
565
-
566
- // Clear the input
567
- event.target.value = '';
568
- }
569
-
570
- // Remove uploaded file
571
- removeFile(field: FormField, index: number) {
572
- if (field.uploadedFiles) {
573
- field.uploadedFiles.splice(index, 1);
574
- this.updateFileControlValue(field);
575
- }
576
- }
577
-
578
- // Update file control value for validation
579
- updateFileControlValue(field: FormField) {
580
- const control = this.form.get(field.name);
581
- if (control) {
582
- const hasFiles = field.uploadedFiles && field.uploadedFiles.length > 0;
583
- control.setValue(hasFiles ? field.uploadedFiles : null);
584
- control.markAsTouched();
585
- }
586
- }
587
-
588
- // Get character count for text field
589
- getCharacterCount(fieldName: string): number {
590
- const control = this.form.get(fieldName);
591
- if (control && control.value) {
592
- return control.value.toString().length;
593
- }
594
- return 0;
595
- }
596
-
597
- // Toggle section collapse
598
- toggleSection(section: FormSection) {
599
- section.collapsed = !section.collapsed;
600
- }
601
-
602
-
603
-
604
- // Helper method to find field by name
605
- private findFieldByName(name: string): FormField | undefined {
606
- for (const section of this.processedConfig.sections) {
607
- const field = section.fields.find(f => f.name === name);
608
- if (field) {
609
- return field;
610
- }
611
- }
612
- return undefined;
613
- }
614
-
615
- // Get the processed config for template use
616
- get sections(): FormSection[] {
617
- return this.processedConfig?.sections || [];
618
- }
619
-
620
- togglePassword(fieldName: string) {
621
- this.passwordFieldState.set(fieldName, !this.passwordFieldState.get(fieldName));
622
- }
623
-
624
- isPasswordVisible(fieldName: string): boolean {
625
- return this.passwordFieldState.get(fieldName) || false;
626
- }
627
- }
628
-