commons-shared-web-ui 0.0.53 → 0.0.54

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 (214) hide show
  1. package/fesm2022/commons-shared-web-ui.mjs +14823 -0
  2. package/fesm2022/commons-shared-web-ui.mjs.map +1 -0
  3. package/index.d.ts +4679 -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 -2532
  21. package/documentation/smart-table.md +0 -1221
  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/ng-package.json +0 -28
  27. package/src/lib/modules/alert/alert.models.ts +0 -6
  28. package/src/lib/modules/alert/alert.module.ts +0 -16
  29. package/src/lib/modules/alert/components/alert/alert.component.html +0 -27
  30. package/src/lib/modules/alert/components/alert/alert.component.scss +0 -92
  31. package/src/lib/modules/alert/components/alert/alert.component.ts +0 -81
  32. package/src/lib/modules/button/button.models.ts +0 -13
  33. package/src/lib/modules/button/button.module.ts +0 -16
  34. package/src/lib/modules/button/components/button/button.component.html +0 -22
  35. package/src/lib/modules/button/components/button/button.component.scss +0 -88
  36. package/src/lib/modules/button/components/button/button.component.ts +0 -67
  37. package/src/lib/modules/button-dropdown/button-dropdown.models.ts +0 -26
  38. package/src/lib/modules/button-dropdown/button-dropdown.module.ts +0 -22
  39. package/src/lib/modules/button-dropdown/button-dropdown.theme.scss +0 -87
  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 -41
  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 -148
  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 -1196
  162. package/src/lib/modules/smart-form/components/form-field/form-field.component.scss +0 -2014
  163. package/src/lib/modules/smart-form/components/form-field/form-field.component.ts +0 -2782
  164. package/src/lib/modules/smart-form/components/form-section/form-section.component.html +0 -65
  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 -131
  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 -1131
  170. package/src/lib/modules/smart-form/index.ts +0 -10
  171. package/src/lib/modules/smart-form/models/form-schema.model.ts +0 -749
  172. package/src/lib/modules/smart-form/models/hierarchy-config.model.ts +0 -21
  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 -36
  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 -1128
  183. package/src/lib/modules/smart-table/models/table-config.model.ts +0 -213
  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/shared-ui.module.ts +0 -50
  209. package/src/lib/utils/constants.ts +0 -11
  210. package/src/lib/utils/storage.utils.ts +0 -37
  211. package/src/lib/utils/string.utils.ts +0 -23
  212. package/src/lib/utils/translation.utils.ts +0 -87
  213. package/src/public-api.ts +0 -121
  214. package/tsconfig.lib.json +0 -15
@@ -1,92 +0,0 @@
1
- import {
2
- Component,
3
- ChangeDetectionStrategy,
4
- Input,
5
- OnChanges,
6
- SimpleChanges,
7
- inject,
8
- } from '@angular/core';
9
- import { FormSchema } from '../../../smart-form/models/form-schema.model';
10
- import { FieldConfigurationService } from '../../services/field-configuration.service';
11
- import { FieldEventPayload } from '../config-section-node/config-section-node.component';
12
-
13
- /**
14
- * Form Field Configuration
15
- * ------------------------
16
- * Renders a compact tree of a form schema's sections and fields, each with a
17
- * **visibility** toggle and a **mandatory** control. Intended to be embedded
18
- * inside a `cc-confirmation-modal` on a host page ("Configure fields").
19
- *
20
- * Pass a `FormSchema` via `[schema]`. The input is deep-cloned, so it is never
21
- * mutated. When the user confirms, call `getUpdatedSchema()` to read back the
22
- * modified schema (visible/isEnabled/disabled and required flags updated).
23
- *
24
- * Fields/sections carrying `lockVisibility: true` cannot be hidden, and
25
- * `lockMandatory: true` freezes their required state.
26
- *
27
- * @example
28
- * ```html
29
- * <cc-confirmation-modal [isOpen]="open" (confirm)="save()" (cancel)="open = false">
30
- * <lib-form-field-configuration #cfg [schema]="schema" [translate]="translateFn" />
31
- * </cc-confirmation-modal>
32
- * ```
33
- * ```ts
34
- * @ViewChild('cfg') cfg!: FormFieldConfigurationComponent;
35
- * save() { this.updatedSchema = this.cfg.getUpdatedSchema(); }
36
- * ```
37
- */
38
- @Component({
39
- selector: 'lib-form-field-configuration',
40
- standalone: false,
41
- providers: [FieldConfigurationService],
42
- templateUrl: './form-field-configuration.component.html',
43
- styleUrls: ['./form-field-configuration.component.scss'],
44
- changeDetection: ChangeDetectionStrategy.OnPush,
45
- })
46
- export class FormFieldConfigurationComponent implements OnChanges {
47
- /** The form schema to configure. Deep-cloned internally; never mutated. */
48
- @Input({ required: true }) schema!: FormSchema;
49
-
50
- /** Optional label translator, e.g. an ngx-translate `instant` function. */
51
- @Input() translate?: (key: string) => string;
52
-
53
- /** Show the "Visible / Mandatory (only if visible)" legend row. Default true. */
54
- @Input() showLegend = true;
55
-
56
- protected readonly store = inject(FieldConfigurationService);
57
-
58
- ngOnChanges(changes: SimpleChanges): void {
59
- if (changes['schema'] && this.schema) {
60
- this.store.loadSchema(this.schema);
61
- }
62
- }
63
-
64
- /**
65
- * Returns a fresh, modified copy of the schema with the current
66
- * visibility/mandatory selections applied. Returns null if no schema loaded.
67
- */
68
- getUpdatedSchema(): FormSchema | null {
69
- return this.store.buildUpdatedSchema();
70
- }
71
-
72
- // ── Event wiring (prefix top-level section index → store) ───────
73
- onToggleVisible(sectionIndex: number, subPath: number[]): void {
74
- this.store.toggleSectionVisible([sectionIndex, ...subPath]);
75
- }
76
-
77
- onToggleExpanded(sectionIndex: number, subPath: number[]): void {
78
- this.store.toggleSectionExpanded([sectionIndex, ...subPath]);
79
- }
80
-
81
- onFieldToggleVisible(sectionIndex: number, payload: FieldEventPayload): void {
82
- this.store.toggleFieldVisible([sectionIndex, ...payload.sectionPath], payload.fieldIndex);
83
- }
84
-
85
- onFieldToggleMandatory(sectionIndex: number, payload: FieldEventPayload): void {
86
- this.store.toggleFieldMandatory([sectionIndex, ...payload.sectionPath], payload.fieldIndex);
87
- }
88
-
89
- trackByIndex(index: number): number {
90
- return index;
91
- }
92
- }
@@ -1,23 +0,0 @@
1
- import { NgModule } from '@angular/core';
2
- import { CommonModule } from '@angular/common';
3
-
4
- import { FormFieldConfigurationComponent } from './components/form-field-configuration/form-field-configuration.component';
5
- import { ConfigSectionNodeComponent } from './components/config-section-node/config-section-node.component';
6
- import { ConfigFieldNodeComponent } from './components/config-field-node/config-field-node.component';
7
-
8
- const COMPONENTS = [
9
- FormFieldConfigurationComponent,
10
- ConfigSectionNodeComponent,
11
- ConfigFieldNodeComponent,
12
- ];
13
-
14
- @NgModule({
15
- declarations: [...COMPONENTS],
16
- imports: [
17
- CommonModule,
18
- ],
19
- exports: [
20
- FormFieldConfigurationComponent,
21
- ],
22
- })
23
- export class FormFieldConfigurationModule {}
@@ -1,7 +0,0 @@
1
- export * from './form-field-configuration.module';
2
- export * from './components/form-field-configuration/form-field-configuration.component';
3
- export * from './components/config-section-node/config-section-node.component';
4
- export * from './components/config-field-node/config-field-node.component';
5
- export * from './models/field-configuration.models';
6
- export * from './services/field-configuration.service';
7
- export * from './services/config-schema-tree.service';
@@ -1,62 +0,0 @@
1
- import { FieldConfig, SectionConfig } from '../../smart-form/models/form-schema.model';
2
-
3
- /**
4
- * A single editable field row in the configurator.
5
- * Wraps a leaf FieldConfig with visibility + mandatory state.
6
- *
7
- * `fieldConfig` is a live reference into the module's working (cloned) schema,
8
- * so writing the node state back onto it is all that's needed to produce the
9
- * updated schema — no fragile index re-matching required.
10
- */
11
- export interface ConfigFieldNode {
12
- /** Live reference to the FieldConfig inside the working schema clone. */
13
- fieldConfig: FieldConfig;
14
- /** Display label (resolved through the optional translate fn at render time uses fieldConfig directly). */
15
- label: string;
16
- /** Raw field type (e.g. 'TEXT_INPUT', 'DROPDOWN'). */
17
- type: string;
18
- /** Whether the field is shown to end users. */
19
- visible: boolean;
20
- /** Whether the field is mandatory (required). Only meaningful when `visible` is true. */
21
- mandatory: boolean;
22
- /** When true, the visibility toggle is locked ON (cannot be hidden). */
23
- lockVisibility: boolean;
24
- /** When true, the mandatory control is locked (cannot be changed). */
25
- lockMandatory: boolean;
26
- /**
27
- * Name of the field this one depends on, read from
28
- * `optionConfig.dependencies.parentDataCode` (e.g. a `state` dropdown depends
29
- * on `country`). When the parent is hidden, this field must be hidden too.
30
- */
31
- parentName?: string;
32
- /**
33
- * Derived: true when this field's dependency parent is currently hidden.
34
- * While true the field is force-hidden and its visibility toggle is disabled —
35
- * the user must show the parent field before this one can be shown.
36
- */
37
- visibilityLockedByParent: boolean;
38
- }
39
-
40
- /**
41
- * A section / group in the configurator tree. Sections can nest recursively.
42
- * A section with `fieldConfig === null` is a synthetic bundle of stray
43
- * top-level leaf fields and has no visibility toggle of its own.
44
- */
45
- export interface ConfigSectionNode {
46
- /** Section label. */
47
- label: string;
48
- /** Live reference to the GROUP/SUBFIELDS FieldConfig, or null for a synthetic bundle / root. */
49
- fieldConfig: FieldConfig | null;
50
- /** Live reference to the backing SectionConfig, when present. */
51
- sectionConfig: SectionConfig | null;
52
- /** Whether the whole section is shown to end users. */
53
- visible: boolean;
54
- /** When true, the section visibility toggle is locked ON. */
55
- lockVisibility: boolean;
56
- /** Whether the section is expanded in the UI tree. */
57
- expanded: boolean;
58
- /** Leaf fields directly inside this section. */
59
- fields: ConfigFieldNode[];
60
- /** Recursively nested child sections. */
61
- subsections: ConfigSectionNode[];
62
- }
@@ -1,148 +0,0 @@
1
- import { Injectable } from '@angular/core';
2
- import {
3
- FormSchema,
4
- FieldConfig,
5
- } from '../../smart-form/models/form-schema.model';
6
- import {
7
- ConfigSectionNode,
8
- ConfigFieldNode,
9
- } from '../models/field-configuration.models';
10
-
11
- /**
12
- * Parses a FormSchema into a configurator tree (sections + fields, each carrying
13
- * visibility/mandatory state) and writes that tree back onto a schema.
14
- *
15
- * Nodes hold LIVE references to the FieldConfig objects inside the working schema
16
- * clone, so `applyTreeToSchema` simply walks the tree and assigns the node state
17
- * onto those references — there is no positional re-matching, which keeps it robust
18
- * against ROWs, nested groups, and mixed leaf/section children.
19
- */
20
- @Injectable({ providedIn: 'root' })
21
- export class ConfigSchemaTreeService {
22
- // ── Parsing ─────────────────────────────────────────────────────────────────
23
-
24
- /**
25
- * Build the configurator section tree from a schema.
26
- * The passed schema is treated as the working copy — nodes reference its objects.
27
- */
28
- parseSchema(schema: FormSchema): ConfigSectionNode[] {
29
- const topChildren =
30
- schema.formType === 'STEPPER'
31
- ? (schema.stepperConfig?.children ?? []).filter(c => c.type === 'GROUP')
32
- : schema.sectionConfig?.children ?? [];
33
- return this._buildSections(topChildren);
34
- }
35
-
36
- /**
37
- * Write the current tree state back onto the schema the nodes reference.
38
- * Sets isEnabled/visible/disabled for visibility and required for mandatory.
39
- * Hidden fields always emit required: false ("mandatory only if visible").
40
- */
41
- applyTreeToSchema(sections: ConfigSectionNode[]): void {
42
- for (const section of sections) {
43
- this._applySection(section);
44
- }
45
- }
46
-
47
- // ── Private: parsing ──────────────────────────────────────────────────────────
48
-
49
- private _buildSections(children: FieldConfig[]): ConfigSectionNode[] {
50
- const sections: ConfigSectionNode[] = [];
51
- let leafBundle: ConfigFieldNode[] = [];
52
-
53
- for (const child of children) {
54
- if (this._isSection(child)) {
55
- if (leafBundle.length) {
56
- sections.push(this._createBundleSection(leafBundle));
57
- leafBundle = [];
58
- }
59
- sections.push(this._buildSection(child));
60
- } else if (child.type === 'ROW' && child.children?.length) {
61
- for (const rowChild of child.children) leafBundle.push(this._buildField(rowChild));
62
- } else {
63
- leafBundle.push(this._buildField(child));
64
- }
65
- }
66
-
67
- if (leafBundle.length) sections.push(this._createBundleSection(leafBundle));
68
- return sections;
69
- }
70
-
71
- private _buildSection(field: FieldConfig): ConfigSectionNode {
72
- const children = field.sectionConfig?.children ?? field.children ?? [];
73
- const fields: ConfigFieldNode[] = [];
74
- const subsections: ConfigSectionNode[] = [];
75
-
76
- for (const child of children) {
77
- if (this._isSection(child)) {
78
- subsections.push(this._buildSection(child));
79
- } else if (child.type === 'ROW' && child.children?.length) {
80
- for (const rowChild of child.children) fields.push(this._buildField(rowChild));
81
- } else {
82
- fields.push(this._buildField(child));
83
- }
84
- }
85
-
86
- const visible = (field.isEnabled ?? field.visible ?? true) && field.disabled !== true;
87
- return {
88
- label: field.sectionConfig?.label || field.label || field.name || 'Section',
89
- fieldConfig: field,
90
- sectionConfig: field.sectionConfig ?? null,
91
- visible,
92
- lockVisibility: field.lockVisibility === true,
93
- expanded: true,
94
- fields,
95
- subsections,
96
- };
97
- }
98
-
99
- private _createBundleSection(fields: ConfigFieldNode[]): ConfigSectionNode {
100
- return {
101
- label: 'Fields',
102
- fieldConfig: null,
103
- sectionConfig: null,
104
- visible: true,
105
- lockVisibility: false,
106
- expanded: true,
107
- fields,
108
- subsections: [],
109
- };
110
- }
111
-
112
- private _buildField(field: FieldConfig): ConfigFieldNode {
113
- const visible = field.isEnabled ?? field.visible ?? true;
114
- return {
115
- fieldConfig: field,
116
- label: field.label || field.name || 'Field',
117
- type: field.type,
118
- visible,
119
- mandatory: visible ? field.required === true : false,
120
- lockVisibility: field.lockVisibility === true,
121
- lockMandatory: field.lockMandatory === true,
122
- parentName: field.optionConfig?.dependencies?.['parentDataCode'],
123
- visibilityLockedByParent: false,
124
- };
125
- }
126
-
127
- private _isSection(field: FieldConfig): boolean {
128
- return field.type === 'GROUP' || field.type === 'SUBFIELDS' || !!field.sectionConfig;
129
- }
130
-
131
- // ── Private: applying ─────────────────────────────────────────────────────────
132
-
133
- private _applySection(section: ConfigSectionNode): void {
134
- if (section.fieldConfig) {
135
- section.fieldConfig.isEnabled = section.visible;
136
- section.fieldConfig.visible = section.visible; // backward compatibility
137
- section.fieldConfig.disabled = !section.visible;
138
- }
139
- for (const field of section.fields) this._applyField(field);
140
- for (const sub of section.subsections) this._applySection(sub);
141
- }
142
-
143
- private _applyField(field: ConfigFieldNode): void {
144
- field.fieldConfig.isEnabled = field.visible;
145
- field.fieldConfig.visible = field.visible; // backward compatibility
146
- field.fieldConfig.required = field.visible ? field.mandatory : false;
147
- }
148
- }
@@ -1,228 +0,0 @@
1
- import { Injectable, computed, inject, signal } from '@angular/core';
2
- import { FormSchema } from '../../smart-form/models/form-schema.model';
3
- import { ConfigSectionNode, ConfigFieldNode } from '../models/field-configuration.models';
4
- import { ConfigSchemaTreeService } from './config-schema-tree.service';
5
-
6
- interface FieldConfigurationState {
7
- sections: ConfigSectionNode[];
8
- /** Deep clone of the input schema; node references point into this object. */
9
- workingSchema: FormSchema | null;
10
- }
11
-
12
- /**
13
- * Signal-based store for the form-field-configuration component.
14
- * Owns the section/field tree and the visibility + mandatory toggle logic.
15
- * Provided at the component level (one store instance per configurator).
16
- */
17
- @Injectable()
18
- export class FieldConfigurationService {
19
- private readonly tree = inject(ConfigSchemaTreeService);
20
-
21
- private readonly _state = signal<FieldConfigurationState>({
22
- sections: [],
23
- workingSchema: null,
24
- });
25
-
26
- readonly sections = computed(() => this._state().sections);
27
-
28
- // ── Load ────────────────────────────────────────────────────────────────────
29
-
30
- /**
31
- * Initialise from an input schema. The schema is deep-cloned so the caller's
32
- * object is never mutated; the tree references the clone.
33
- */
34
- loadSchema(schema: FormSchema): void {
35
- const workingSchema: FormSchema = JSON.parse(JSON.stringify(schema));
36
- const parsed = this.tree.parseSchema(workingSchema);
37
- // Apply dependency rules up-front so a schema that ships with a hidden parent
38
- // (e.g. country off) starts with its dependents hidden + locked.
39
- const sections = this._applyDependencyRules(parsed);
40
- this._state.set({ sections, workingSchema });
41
- }
42
-
43
- // ── Mutations ─────────────────────────────────────────────────────────────────
44
-
45
- /** Expand/collapse a section. Purely visual — does not change the schema. */
46
- toggleSectionExpanded(path: number[]): void {
47
- this._updateSectionAtPath(path, s => ({ ...s, expanded: !s.expanded }));
48
- }
49
-
50
- /**
51
- * Toggle a section's visibility. Locked sections are ignored.
52
- * Cascades: hiding disables every descendant field/subsection; showing
53
- * re-enables all non-locked descendants.
54
- */
55
- toggleSectionVisible(path: number[]): void {
56
- this._updateSectionAtPath(path, s => {
57
- if (s.lockVisibility || !s.fieldConfig) return s;
58
- const visible = !s.visible;
59
- return this._cascadeVisibility(s, visible);
60
- });
61
- this._normalizeDependencies();
62
- }
63
-
64
- /**
65
- * Toggle a field's visibility. Ignored for locked fields and for fields whose
66
- * dependency parent is currently hidden (their toggle is disabled in the UI).
67
- * Hiding a field also hides every field that depends on it (transitively).
68
- */
69
- toggleFieldVisible(path: number[], fieldIndex: number): void {
70
- this._updateFieldAtPath(path, fieldIndex, f => {
71
- if (f.lockVisibility || f.visibilityLockedByParent) return f;
72
- const visible = !f.visible;
73
- // "Mandatory only if visible" — drop the mandatory flag when hiding.
74
- return { ...f, visible, mandatory: visible ? f.mandatory : false };
75
- });
76
- this._normalizeDependencies();
77
- }
78
-
79
- /** Toggle a field's mandatory flag. Ignored when locked or hidden. */
80
- toggleFieldMandatory(path: number[], fieldIndex: number): void {
81
- this._updateFieldAtPath(path, fieldIndex, f => {
82
- if (f.lockMandatory || !f.visible) return f;
83
- return { ...f, mandatory: !f.mandatory };
84
- });
85
- }
86
-
87
- // ── Output ──────────────────────────────────────────────────────────────────
88
-
89
- /**
90
- * Produce the updated schema. Writes the current tree state onto the working
91
- * clone and returns a fresh deep clone (safe to hand to the host / submit).
92
- * Returns null if no schema has been loaded.
93
- */
94
- buildUpdatedSchema(): FormSchema | null {
95
- const { sections, workingSchema } = this._state();
96
- if (!workingSchema) return null;
97
- this.tree.applyTreeToSchema(sections);
98
- return JSON.parse(JSON.stringify(workingSchema));
99
- }
100
-
101
- // ── Private helpers ─────────────────────────────────────────────────────────
102
-
103
- private _updateSectionAtPath(
104
- path: number[],
105
- updater: (section: ConfigSectionNode) => ConfigSectionNode,
106
- ): void {
107
- this._state.update(state => ({
108
- ...state,
109
- sections: this._mapSectionAtPath(state.sections, path, 0, updater),
110
- }));
111
- }
112
-
113
- private _updateFieldAtPath(
114
- path: number[],
115
- fieldIndex: number,
116
- updater: (field: ConfigFieldNode) => ConfigFieldNode,
117
- ): void {
118
- this._updateSectionAtPath(path, section => ({
119
- ...section,
120
- fields: section.fields.map((f, i) => (i === fieldIndex ? updater(f) : f)),
121
- }));
122
- }
123
-
124
- private _mapSectionAtPath(
125
- sections: ConfigSectionNode[],
126
- path: number[],
127
- depth: number,
128
- updater: (section: ConfigSectionNode) => ConfigSectionNode,
129
- ): ConfigSectionNode[] {
130
- return sections.map((section, i) => {
131
- if (i !== path[depth]) return section;
132
- if (depth === path.length - 1) return updater(section);
133
- return {
134
- ...section,
135
- subsections: this._mapSectionAtPath(section.subsections, path, depth + 1, updater),
136
- };
137
- });
138
- }
139
-
140
- /** Re-apply field dependency rules to the current tree and commit the result. */
141
- private _normalizeDependencies(): void {
142
- this._state.update(state => ({
143
- ...state,
144
- sections: this._applyDependencyRules(state.sections),
145
- }));
146
- }
147
-
148
- /**
149
- * Enforce field dependencies expressed via `optionConfig.dependencies.parentDataCode`.
150
- * A field can only be visible when its dependency parent is visible; hiding a
151
- * parent cascades (transitively) to every dependent field. Locked-visible fields
152
- * are never force-hidden.
153
- *
154
- * Returns a new tree with each field's `visible` / `mandatory` adjusted and its
155
- * derived `visibilityLockedByParent` flag set (drives the disabled toggle in the UI).
156
- */
157
- private _applyDependencyRules(sections: ConfigSectionNode[]): ConfigSectionNode[] {
158
- // 1. Gather every named field.
159
- const allFields: ConfigFieldNode[] = [];
160
- const collect = (secs: ConfigSectionNode[]): void => {
161
- for (const s of secs) {
162
- allFields.push(...s.fields);
163
- collect(s.subsections);
164
- }
165
- };
166
- collect(sections);
167
-
168
- // 2. Resolve effective visibility to a fixed point over the parent chain.
169
- const effective = new Map<string, boolean>();
170
- for (const f of allFields) {
171
- const name = f.fieldConfig.name;
172
- if (name) effective.set(name, f.visible);
173
- }
174
- let changed = true;
175
- let guard = 0;
176
- const maxIterations = allFields.length + 2;
177
- while (changed && guard++ < maxIterations) {
178
- changed = false;
179
- for (const f of allFields) {
180
- const name = f.fieldConfig.name;
181
- if (!name || f.lockVisibility || !f.parentName) continue;
182
- // Parent hidden (and known) → this field must be hidden.
183
- if (effective.get(f.parentName) === false && effective.get(name) !== false) {
184
- effective.set(name, false);
185
- changed = true;
186
- }
187
- }
188
- }
189
-
190
- // 3. Rebuild the tree applying the resolved visibility + lock flag.
191
- const rebuildFields = (fields: ConfigFieldNode[]): ConfigFieldNode[] =>
192
- fields.map(f => {
193
- const name = f.fieldConfig.name;
194
- const resolved = name && effective.has(name) ? effective.get(name)! : f.visible;
195
- const newVisible = f.lockVisibility ? f.visible : resolved;
196
- const parentHidden = !!f.parentName && effective.get(f.parentName) === false;
197
- return {
198
- ...f,
199
- visible: newVisible,
200
- mandatory: newVisible ? f.mandatory : false,
201
- visibilityLockedByParent: parentHidden && !f.lockVisibility,
202
- };
203
- });
204
- const rebuildSections = (secs: ConfigSectionNode[]): ConfigSectionNode[] =>
205
- secs.map(s => ({
206
- ...s,
207
- fields: rebuildFields(s.fields),
208
- subsections: rebuildSections(s.subsections),
209
- }));
210
- return rebuildSections(sections);
211
- }
212
-
213
- /** Recursively set visibility on a section and all its descendants (respecting locks). */
214
- private _cascadeVisibility(section: ConfigSectionNode, visible: boolean): ConfigSectionNode {
215
- return {
216
- ...section,
217
- visible,
218
- fields: section.fields.map(f =>
219
- f.lockVisibility
220
- ? f
221
- : { ...f, visible, mandatory: visible ? f.mandatory : false },
222
- ),
223
- subsections: section.subsections.map(sub =>
224
- sub.lockVisibility ? sub : this._cascadeVisibility(sub, visible),
225
- ),
226
- };
227
- }
228
- }
@@ -1,94 +0,0 @@
1
- import { NgModule } from "@angular/core";
2
- import { MatCardModule } from '@angular/material/card';
3
- import { MatSnackBarModule } from "@angular/material/snack-bar";
4
- import { MatCheckboxModule } from '@angular/material/checkbox'
5
- import { MatDividerModule } from '@angular/material/divider';
6
- import { MatRadioModule } from '@angular/material/radio';
7
- import { MatDialogModule } from "@angular/material/dialog";
8
- import { MatFormFieldModule } from '@angular/material/form-field';
9
- import { MatIconModule } from '@angular/material/icon';
10
- import { MatButtonModule } from "@angular/material/button";
11
- import { MatMenuModule } from '@angular/material/menu';
12
- import { MatDatepickerModule } from '@angular/material/datepicker';
13
- import { MatTabsModule } from '@angular/material/tabs';
14
- import { MatNativeDateModule } from "@angular/material/core";
15
- import { MatInputModule } from '@angular/material/input';
16
- import { MatProgressBarModule } from '@angular/material/progress-bar';
17
- import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
18
- import { MatSelectModule } from '@angular/material/select';
19
- import { MatTooltipModule } from '@angular/material/tooltip';
20
- import {MatSliderModule} from '@angular/material/slider';
21
- import {MatListModule} from '@angular/material/list';
22
- import {MatChipsModule} from '@angular/material/chips';
23
- import {MatPaginatorModule} from '@angular/material/paginator';
24
- import {MatTableModule} from '@angular/material/table';
25
- import {MatExpansionModule} from '@angular/material/expansion';
26
- import {CdkAccordionModule} from '@angular/cdk/accordion';
27
- import { MatSortModule } from "@angular/material/sort";
28
- import {MatAutocompleteModule} from '@angular/material/autocomplete';
29
- import {MatSlideToggleModule} from '@angular/material/slide-toggle';
30
- import {MatButtonToggleModule} from '@angular/material/button-toggle';
31
-
32
- @NgModule({
33
- imports: [
34
- MatCardModule,
35
- MatSnackBarModule,
36
- MatCheckboxModule,
37
- MatDividerModule,
38
- MatSelectModule,
39
- MatRadioModule,
40
- MatDialogModule,
41
- MatFormFieldModule,
42
- MatDatepickerModule,
43
- MatNativeDateModule,
44
- MatInputModule,
45
- MatIconModule,
46
- MatProgressSpinnerModule,
47
- MatTabsModule,
48
- MatButtonModule,
49
- MatMenuModule,
50
- MatTabsModule,
51
- MatProgressBarModule,
52
- MatTooltipModule,
53
- MatSliderModule,
54
- MatListModule,
55
- MatChipsModule,
56
- MatSortModule,
57
- MatAutocompleteModule,
58
- MatSlideToggleModule,
59
- MatButtonToggleModule
60
- ],
61
- exports: [
62
- MatCardModule,
63
- MatSnackBarModule,
64
- MatCheckboxModule,
65
- MatDividerModule,
66
- MatSelectModule,
67
- MatRadioModule,
68
- MatDialogModule,
69
- MatFormFieldModule,
70
- MatDatepickerModule,
71
- MatNativeDateModule,
72
- MatInputModule,
73
- MatIconModule,
74
- MatProgressSpinnerModule,
75
- MatTabsModule,
76
- MatButtonModule,
77
- MatMenuModule,
78
- MatTabsModule,
79
- MatProgressBarModule,
80
- MatTooltipModule,
81
- MatSliderModule,
82
- MatListModule,
83
- MatChipsModule,
84
- MatPaginatorModule,
85
- MatTableModule,
86
- MatExpansionModule,
87
- CdkAccordionModule,
88
- MatSortModule,
89
- MatAutocompleteModule,
90
- MatSlideToggleModule,
91
- MatButtonToggleModule
92
- ]
93
- })
94
- export class MaterialModule { }