@hmcts/opal-frontend-common 0.0.32 → 0.0.34
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.
- package/components/abstract/abstract-form-base/index.d.ts +4 -0
- package/components/abstract/abstract-nested-form-base/README.md +89 -0
- package/components/abstract/abstract-nested-form-base/index.d.ts +78 -0
- package/fesm2022/hmcts-opal-frontend-common-components-abstract-abstract-form-alias-base.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-abstract-abstract-form-array-base.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-abstract-abstract-form-array-removal-base.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-abstract-abstract-form-base.mjs +12 -3
- package/fesm2022/hmcts-opal-frontend-common-components-abstract-abstract-form-base.mjs.map +1 -1
- package/fesm2022/hmcts-opal-frontend-common-components-abstract-abstract-nested-form-base.mjs +141 -0
- package/fesm2022/hmcts-opal-frontend-common-components-abstract-abstract-nested-form-base.mjs.map +1 -0
- package/fesm2022/hmcts-opal-frontend-common-components-abstract-abstract-sortable-table-pagination.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-abstract-abstract-sortable-table.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-abstract-abstract-table-filter.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-alphagov-alphagov-accessible-autocomplete.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-custom-custom-account-information-custom-account-information-item-custom-account-information-item-label.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-custom-custom-account-information-custom-account-information-item-custom-account-information-item-value.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-custom-custom-account-information-custom-account-information-item.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-custom-custom-account-information.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-custom-custom-action-links.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-custom-custom-horizontal-scroll-pane.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-custom-custom-page-header.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-custom-custom-scrollable-panes-custom-scrollable-panes-inner-pane.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-custom-custom-scrollable-panes.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-custom-custom-summary-metric-bar-custom-summary-metric-bar-item-custom-summary-metric-bar-item-label.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-custom-custom-summary-metric-bar-custom-summary-metric-bar-item-custom-summary-metric-bar-item-value.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-custom-custom-summary-metric-bar-custom-summary-metric-bar-item.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-custom-custom-summary-metric-bar.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-custom-custom-vertical-scroll-pane-custom-vertical-scroll-pane-inner-pane.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-custom-custom-vertical-scroll-pane-custom-vertical-scroll-pane-outer-pane.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-custom-custom-vertical-scroll-pane.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-accordion.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-back-link.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-button.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-cancel-link.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-checkboxes.mjs +12 -12
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-date-input.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-details.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-error-summary.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-footer.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-header.mjs +6 -6
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-heading-with-caption.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-inset-text.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-list-govuk-list-link.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-list.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-notification-banner.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-pagination.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-panel.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-radio.mjs +12 -12
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-select.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-summary-card-list.mjs +6 -6
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-summary-list.mjs +12 -12
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-table.mjs +12 -12
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-tabs-govuk-tabs-list-item.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-tabs-govuk-tabs-panel.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-tabs.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-tag.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-task-list.mjs +6 -6
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-text-area.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-text-input-prefix-suffix.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-govuk-govuk-text-input.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-hod-hod-loading-spinner.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-moj-moj-alert.mjs +21 -21
- package/fesm2022/hmcts-opal-frontend-common-components-moj-moj-badge.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-moj-moj-button-menu-moj-button-menu-item.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-moj-moj-button-menu.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-moj-moj-date-picker.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-moj-moj-filter-moj-filter-panel-moj-filter-panel-header.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-moj-moj-filter-moj-filter-panel-moj-filter-panel-option-moj-filter-panel-option-form-group-item.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-moj-moj-filter-moj-filter-panel-moj-filter-panel-option-moj-filter-panel-option-form-group-keyword.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-moj-moj-filter-moj-filter-panel-moj-filter-panel-option.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-moj-moj-filter-moj-filter-panel-moj-filter-panel-selected-moj-filter-panel-selected-tag.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-moj-moj-filter-moj-filter-panel-moj-filter-panel-selected.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-moj-moj-filter-moj-filter-panel.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-moj-moj-filter.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-moj-moj-header.mjs +6 -6
- package/fesm2022/hmcts-opal-frontend-common-components-moj-moj-notification-badge.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-moj-moj-page-header.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-moj-moj-pagination.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-moj-moj-primary-navigation.mjs +6 -6
- package/fesm2022/hmcts-opal-frontend-common-components-moj-moj-sortable-table.mjs +18 -18
- package/fesm2022/hmcts-opal-frontend-common-components-moj-moj-sub-navigation.mjs +6 -6
- package/fesm2022/hmcts-opal-frontend-common-components-moj-moj-ticket-panel.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-components-moj-moj-timeline.mjs +6 -6
- package/fesm2022/hmcts-opal-frontend-common-directives-capitalisation.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-directives-govuk-button.mjs +3 -3
- package/fesm2022/{hmcts-opal-frontend-common-pages-access-denied.component-DE61xF9w.mjs → hmcts-opal-frontend-common-pages-access-denied.component-CGl13lxV.mjs} +4 -4
- package/fesm2022/{hmcts-opal-frontend-common-pages-access-denied.component-DE61xF9w.mjs.map → hmcts-opal-frontend-common-pages-access-denied.component-CGl13lxV.mjs.map} +1 -1
- package/fesm2022/{hmcts-opal-frontend-common-pages-sign-in-stub.component-CGigL_1F.mjs → hmcts-opal-frontend-common-pages-sign-in-stub.component-BqKx-kQk.mjs} +4 -4
- package/fesm2022/{hmcts-opal-frontend-common-pages-sign-in-stub.component-CGigL_1F.mjs.map → hmcts-opal-frontend-common-pages-sign-in-stub.component-BqKx-kQk.mjs.map} +1 -1
- package/fesm2022/{hmcts-opal-frontend-common-pages-sign-in.component-cs_m2MgL.mjs → hmcts-opal-frontend-common-pages-sign-in.component-gSWZ7kxd.mjs} +4 -4
- package/fesm2022/{hmcts-opal-frontend-common-pages-sign-in.component-cs_m2MgL.mjs.map → hmcts-opal-frontend-common-pages-sign-in.component-gSWZ7kxd.mjs.map} +1 -1
- package/fesm2022/hmcts-opal-frontend-common-pages.mjs +2 -2
- package/fesm2022/hmcts-opal-frontend-common-pipes-date-format.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-pipes-days-ago.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-pipes-national-insurance.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-resolvers-title.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-services-app-initializer-service.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-services-app-insights-service.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-services-auth-service.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-services-date-service.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-services-launch-darkly-service.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-services-permissions-service.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-services-session-service.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-services-sort-service.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-services-transfer-state-service.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-services-transformation-service.mjs +3 -3
- package/fesm2022/hmcts-opal-frontend-common-services-utils-service.mjs +3 -3
- package/package.json +6 -1
|
@@ -213,6 +213,10 @@ declare abstract class AbstractFormBaseComponent implements OnInit, OnDestroy {
|
|
|
213
213
|
* @param controlName - The name of the control for which to remove the error message.
|
|
214
214
|
*/
|
|
215
215
|
protected removeControlErrors(controlName: string): void;
|
|
216
|
+
/**
|
|
217
|
+
* Clears all error messages from the form.
|
|
218
|
+
*/
|
|
219
|
+
protected clearAllErrorMessages(): void;
|
|
216
220
|
/**
|
|
217
221
|
* Clears the search form.
|
|
218
222
|
*/
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Abstract Nested Form Base Component
|
|
2
|
+
|
|
3
|
+
This Angular component extends the `AbstractFormBaseComponent` and is designed for **nested sub-form components** that contribute their own controls and field-error messages into a parent form. It provides helpers for installing/removing nested controls, managing conditional validation, and spreading error definitions into the parent’s error maps.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Installation](#installation)
|
|
8
|
+
- [Usage](#usage)
|
|
9
|
+
- [Responsibilities](#responsibilities)
|
|
10
|
+
- [Methods](#methods)
|
|
11
|
+
- [Error Handling](#error-handling)
|
|
12
|
+
- [Testing](#testing)
|
|
13
|
+
- [Contributing](#contributing)
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
To use the `AbstractNestedFormBaseComponent`, extend it in a nested sub-form component (e.g. Individuals, Companies, Creditors):
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { AbstractNestedFormBaseComponent } from '@hmcts/opal-frontend-common/components/abstract/abstract-nested-form-base/abstract-nested-form-base.component';
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
This component is intended to be extended by **child sub-forms** that plug into a parent form component. It ensures consistent handling of control installation, conditional validation, and error-message registration.
|
|
26
|
+
|
|
27
|
+
### Example Usage
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
@Component({
|
|
31
|
+
selector: 'app-child-sub-form',
|
|
32
|
+
templateUrl: './child-sub-form.component.html',
|
|
33
|
+
})
|
|
34
|
+
export class ChildSubFormComponent extends AbstractNestedFormBaseComponent implements OnInit, OnDestroy {
|
|
35
|
+
@Input({ required: true }) override form!: FormGroup;
|
|
36
|
+
|
|
37
|
+
public override ngOnInit(): void {
|
|
38
|
+
this.setupChildForm();
|
|
39
|
+
super.ngOnInit();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private setupChildForm(): void {
|
|
43
|
+
const controlsGroup = this.buildChildControls();
|
|
44
|
+
this.addControlsToNestedFormGroup(controlsGroup);
|
|
45
|
+
this.setupConditionalValidation();
|
|
46
|
+
this.rePopulateForm(/* values from store */);
|
|
47
|
+
this.handleConditionalValidation();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Responsibilities
|
|
53
|
+
|
|
54
|
+
- Install (and later remove) sub-form controls into an existing parent FormGroup.
|
|
55
|
+
- Provide ergonomic helpers for common validation flows:
|
|
56
|
+
- Toggle `required` validators.
|
|
57
|
+
- Reset and revalidate controls/groups.
|
|
58
|
+
- Subscribe to conditional validation with automatic teardown.
|
|
59
|
+
- Ensure proper cleanup on destroy (removes its own controls).
|
|
60
|
+
|
|
61
|
+
## Methods
|
|
62
|
+
|
|
63
|
+
| Method | Parameters | Description |
|
|
64
|
+
| ----------------------------------- | -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
|
|
65
|
+
| `addControlsToNestedFormGroup` | `source: FormGroup, target?: FormGroup` | Installs detached controls into target form (defaults to `this.form`). |
|
|
66
|
+
| `removeControlsFromNestedFormGroup` | `source: FormGroup, target?: FormGroup` | Removes controls from target whose names are in `source`. |
|
|
67
|
+
| `setValidatorPresence` | `control: AbstractControl, validators: ValidatorFn \| ValidatorFn[], present: boolean` | Adds or removes one or more validators and updates validity. |
|
|
68
|
+
| `hasValue` | `v: unknown` | Utility to check if a value is considered present (non-null; non-empty string; all non-strings are true). |
|
|
69
|
+
| `resetAndValidateControls` | `controls: (AbstractControl \| null)[]` | Resets given controls, clears errors, reapplies validators. |
|
|
70
|
+
| `resetAndValidateFormGroup` | `group: FormGroup` | Resets entire group, marks pristine/untouched, updates validity. |
|
|
71
|
+
| `subscribeValidation` | `handler: () => void, ...controls` | Subscribes a handler to `valueChanges` of controls with auto-unsubscribe. |
|
|
72
|
+
|
|
73
|
+
## Error Handling
|
|
74
|
+
|
|
75
|
+
- Each sub-form is responsible only for its own validators and error state.
|
|
76
|
+
- The parent remains the single source of truth for fieldErrors and merges child error templates as needed.
|
|
77
|
+
- The abstract ensures cleanup by removing its own controls on destroy.
|
|
78
|
+
|
|
79
|
+
## Testing
|
|
80
|
+
|
|
81
|
+
Unit tests should verify:
|
|
82
|
+
|
|
83
|
+
- Controls are installed and removed correctly.
|
|
84
|
+
- Conditional validators are toggled and errors appear/disappear as expected.
|
|
85
|
+
- Lifecycle (`ngOnInit`, `ngOnDestroy`) ensures no leaks.
|
|
86
|
+
|
|
87
|
+
## Contributing
|
|
88
|
+
|
|
89
|
+
Contributions should maintain consistency with the base form component and Angular best practices. Add unit tests for any new helpers or changes to validation/error-handling logic.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { FormGroup, AbstractControl, ValidatorFn } from '@angular/forms';
|
|
2
|
+
import { AbstractFormBaseComponent } from '@hmcts/opal-frontend-common/components/abstract/abstract-form-base';
|
|
3
|
+
import * as i0 from '@angular/core';
|
|
4
|
+
|
|
5
|
+
declare abstract class AbstractNestedFormBaseComponent extends AbstractFormBaseComponent {
|
|
6
|
+
/**
|
|
7
|
+
* Installs all controls from a **detached** builder group into a target FormGroup (defaults to `this.form`).
|
|
8
|
+
*
|
|
9
|
+
* @param source A FormGroup created locally (its controls must not already belong to another parent).
|
|
10
|
+
* @param target The FormGroup to install the controls into. Defaults to `this.form`.
|
|
11
|
+
*
|
|
12
|
+
* Notes:
|
|
13
|
+
* - This method **moves** the control instances from `source` into `target` (no cloning).
|
|
14
|
+
* - If a control already has a parent, Angular will throw when adding it to `target`.
|
|
15
|
+
*/
|
|
16
|
+
protected addControlsToNestedFormGroup(source: FormGroup, target?: FormGroup): void;
|
|
17
|
+
/**
|
|
18
|
+
* Removes controls from `target` whose names are present in `source` (defaults to `this.form`).
|
|
19
|
+
*
|
|
20
|
+
* @param source A FormGroup whose control names identify which controls to remove.
|
|
21
|
+
* @param target The FormGroup to remove controls from. Defaults to `this.form`.
|
|
22
|
+
*
|
|
23
|
+
* Use this with the same builder group you used to add controls so you only remove what you added.
|
|
24
|
+
*/
|
|
25
|
+
protected removeControlsFromNestedFormGroup(source: FormGroup, target?: FormGroup): void;
|
|
26
|
+
/**
|
|
27
|
+
* Adds or removes one or more validators on a control and updates validity without emitting events.
|
|
28
|
+
*
|
|
29
|
+
* @param control The control to modify. If null/undefined, the method no-ops and returns `false`.
|
|
30
|
+
* @param validators A single `ValidatorFn` or an array of `ValidatorFn`s to add/remove.
|
|
31
|
+
* @param present When `true`, validators are added; when `false`, the same validators are removed.
|
|
32
|
+
* @returns The `present` flag (for convenient inline use in conditionals).
|
|
33
|
+
*/
|
|
34
|
+
protected setValidatorPresence(control: AbstractControl | null, validators: ValidatorFn | ValidatorFn[], present: boolean): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Truthy-value helper used by multiple sub-forms.
|
|
37
|
+
*
|
|
38
|
+
* Returns `false` for `null`/`undefined`. For strings, trims whitespace and checks for non-zero length.
|
|
39
|
+
* For all other types, returns `true` (treat non-string values as present).
|
|
40
|
+
*/
|
|
41
|
+
protected hasValue(v: unknown): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Resets a list of controls and re-computes validity without emitting value-change events.
|
|
44
|
+
*
|
|
45
|
+
* For each control: clears errors, resets the value to `null`, and calls `updateValueAndValidity`.
|
|
46
|
+
* This means built-in validators (e.g. `required`) will be re-applied after reset.
|
|
47
|
+
*/
|
|
48
|
+
protected resetAndValidateControls(controls: (AbstractControl | null)[]): void;
|
|
49
|
+
/**
|
|
50
|
+
* Resets a FormGroup’s value/state and re-computes validity without emitting value-change events.
|
|
51
|
+
*
|
|
52
|
+
* Performs: `group.reset(undefined)`, marks pristine/untouched, then `updateValueAndValidity`.
|
|
53
|
+
*/
|
|
54
|
+
protected resetAndValidateFormGroup(group: FormGroup): void;
|
|
55
|
+
/**
|
|
56
|
+
* Subscribes a handler to the `valueChanges` of multiple controls, with auto-unsubscribe on destroy.
|
|
57
|
+
*
|
|
58
|
+
* @param handler Function invoked whenever **any** provided control emits a value change.
|
|
59
|
+
* @param controls One or more controls to observe; falsy entries are ignored.
|
|
60
|
+
*
|
|
61
|
+
* Implementation detail: merges the streams and unsubscribes via `takeUntil(this.ngUnsubscribe)`.
|
|
62
|
+
*/
|
|
63
|
+
protected subscribeValidation(handler: () => void, ...controls: (AbstractControl | null)[]): void;
|
|
64
|
+
/**
|
|
65
|
+
* @inheritdoc
|
|
66
|
+
*
|
|
67
|
+
* Handles cleanup logic when the component is destroyed.
|
|
68
|
+
*
|
|
69
|
+
* - Clears local child error definitions and emits an empty map to the parent.
|
|
70
|
+
* - Removes all controls added by this sub-form from the parent form, if nested.
|
|
71
|
+
* - Calls the base class's `ngOnDestroy` for additional teardown.
|
|
72
|
+
*/
|
|
73
|
+
ngOnDestroy(): void;
|
|
74
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AbstractNestedFormBaseComponent, never>;
|
|
75
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<AbstractNestedFormBaseComponent, "ng-component", never, {}, {}, never, never, true, never>;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export { AbstractNestedFormBaseComponent };
|
package/fesm2022/hmcts-opal-frontend-common-components-abstract-abstract-form-alias-base.mjs
CHANGED
|
@@ -190,10 +190,10 @@ class AbstractFormAliasBaseComponent extends AbstractFormBaseComponent {
|
|
|
190
190
|
this['ngUnsubscribe'].complete();
|
|
191
191
|
super.ngOnDestroy();
|
|
192
192
|
}
|
|
193
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
194
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.
|
|
193
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: AbstractFormAliasBaseComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
194
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.7", type: AbstractFormAliasBaseComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: '', isInline: true });
|
|
195
195
|
}
|
|
196
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
196
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: AbstractFormAliasBaseComponent, decorators: [{
|
|
197
197
|
type: Component,
|
|
198
198
|
args: [{
|
|
199
199
|
template: '',
|
package/fesm2022/hmcts-opal-frontend-common-components-abstract-abstract-form-array-base.mjs
CHANGED
|
@@ -234,10 +234,10 @@ class AbstractFormArrayBaseComponent extends AbstractFormBaseComponent {
|
|
|
234
234
|
this.ngUnsubscribe.complete();
|
|
235
235
|
super.ngOnDestroy();
|
|
236
236
|
}
|
|
237
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
238
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.
|
|
237
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: AbstractFormArrayBaseComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
238
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.7", type: AbstractFormArrayBaseComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: '', isInline: true });
|
|
239
239
|
}
|
|
240
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
240
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: AbstractFormArrayBaseComponent, decorators: [{
|
|
241
241
|
type: Component,
|
|
242
242
|
args: [{
|
|
243
243
|
template: '',
|
package/fesm2022/hmcts-opal-frontend-common-components-abstract-abstract-form-array-removal-base.mjs
CHANGED
|
@@ -77,10 +77,10 @@ class AbstractFormArrayRemovalComponent {
|
|
|
77
77
|
this.router.navigate([route], { relativeTo: this.activatedRoute.parent });
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
81
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.
|
|
80
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: AbstractFormArrayRemovalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
81
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.7", type: AbstractFormArrayRemovalComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: '', isInline: true });
|
|
82
82
|
}
|
|
83
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
83
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: AbstractFormArrayRemovalComponent, decorators: [{
|
|
84
84
|
type: Component,
|
|
85
85
|
args: [{
|
|
86
86
|
template: '',
|
|
@@ -405,6 +405,15 @@ class AbstractFormBaseComponent {
|
|
|
405
405
|
removeControlErrors(controlName) {
|
|
406
406
|
delete this.formControlErrorMessages[controlName];
|
|
407
407
|
}
|
|
408
|
+
/**
|
|
409
|
+
* Clears all error messages from the form.
|
|
410
|
+
*/
|
|
411
|
+
clearAllErrorMessages() {
|
|
412
|
+
this.formControlErrorMessages = {};
|
|
413
|
+
this.formErrorSummaryMessage = [];
|
|
414
|
+
this.formErrors = [];
|
|
415
|
+
this.form.updateValueAndValidity({ onlySelf: false, emitEvent: false });
|
|
416
|
+
}
|
|
408
417
|
/**
|
|
409
418
|
* Clears the search form.
|
|
410
419
|
*/
|
|
@@ -474,10 +483,10 @@ class AbstractFormBaseComponent {
|
|
|
474
483
|
this.ngUnsubscribe.next();
|
|
475
484
|
this.ngUnsubscribe.complete();
|
|
476
485
|
}
|
|
477
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
478
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.
|
|
486
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: AbstractFormBaseComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
487
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.7", type: AbstractFormBaseComponent, isStandalone: true, selector: "ng-component", outputs: { unsavedChanges: "unsavedChanges", formSubmit: "formSubmit" }, ngImport: i0, template: '', isInline: true });
|
|
479
488
|
}
|
|
480
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
489
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: AbstractFormBaseComponent, decorators: [{
|
|
481
490
|
type: Component,
|
|
482
491
|
args: [{
|
|
483
492
|
template: '',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hmcts-opal-frontend-common-components-abstract-abstract-form-base.mjs","sources":["../../../projects/opal-frontend-common/components/abstract/abstract-form-base/abstract-form-base.component.ts","../../../projects/opal-frontend-common/components/abstract/abstract-form-base/hmcts-opal-frontend-common-components-abstract-abstract-form-base.ts"],"sourcesContent":["import { ChangeDetectorRef, Component, EventEmitter, OnDestroy, OnInit, Output, inject } from '@angular/core';\nimport { FormArray, FormControl, FormGroup, ValidatorFn } from '@angular/forms';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { Subject, takeUntil } from 'rxjs';\nimport { IAbstractFormBaseFieldError } from './interfaces/abstract-form-base-field-error.interface';\nimport { IAbstractFormBaseFieldErrors } from './interfaces/abstract-form-base-field-errors.interface';\nimport { IAbstractFormBaseFormError } from './interfaces/abstract-form-base-form-error.interface';\nimport {\n IAbstractFormBaseFormErrorSummaryMessage,\n IAbstractFormControlErrorMessage,\n IAbstractFormArrayControlValidation,\n} from '@hmcts/opal-frontend-common/components/abstract/interfaces';\nimport { IAbstractFormBaseHighPriorityFormError } from './interfaces/abstract-form-base-high-priority-form-error.interface';\nimport { IAbstractFormBaseForm } from './interfaces/abstract-form-base-form.interface';\nimport { UtilsService } from '@hmcts/opal-frontend-common/services/utils-service';\n\n@Component({\n template: '',\n})\nexport abstract class AbstractFormBaseComponent implements OnInit, OnDestroy {\n private readonly changeDetectorRef = inject(ChangeDetectorRef);\n private readonly router = inject(Router);\n private readonly activatedRoute = inject(ActivatedRoute);\n\n @Output() protected unsavedChanges = new EventEmitter<boolean>();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n @Output() protected formSubmit = new EventEmitter<IAbstractFormBaseForm<any>>();\n protected readonly utilsService = inject(UtilsService);\n protected fieldErrors!: IAbstractFormBaseFieldErrors;\n protected formSubmitted = false;\n protected readonly ngUnsubscribe = new Subject<void>();\n\n public form!: FormGroup;\n public formControlErrorMessages!: IAbstractFormControlErrorMessage;\n public formErrorSummaryMessage!: IAbstractFormBaseFormErrorSummaryMessage[];\n public formErrors!: IAbstractFormBaseFormError[];\n\n constructor() {}\n\n /**\n * Scrolls to the label of the component and focuses on the field id\n *\n * @param fieldId - Field id of the component\n */\n private scroll(fieldId: string): void {\n let labelTarget;\n let fieldElement;\n\n const autocompleteLabel = document.querySelector(`label[for=${fieldId}-autocomplete]`);\n const regularLabel = document.querySelector(`label[for=${fieldId}]`);\n const fieldsetLegend = document.querySelector(`#${fieldId} .govuk-fieldset__legend`);\n\n if (autocompleteLabel) {\n labelTarget = autocompleteLabel;\n fieldElement = document.getElementById(`${fieldId}-autocomplete`);\n } else {\n labelTarget = regularLabel || fieldsetLegend;\n fieldElement = document.getElementById(fieldId);\n }\n\n if (fieldElement) {\n if (labelTarget) {\n labelTarget.scrollIntoView({ behavior: 'smooth' });\n }\n fieldElement.focus();\n }\n }\n\n /**\n * Returns the highest priority form error from the given error keys and field errors.\n * @param errorKeys - An array of error keys.\n * @param fieldErrors - An object containing field errors.\n * @returns The highest priority form error or null if no errors are found.\n */\n private getHighestPriorityError(\n errorKeys: string[] = [],\n fieldErrors: IAbstractFormBaseFieldError = {},\n ): IAbstractFormBaseHighPriorityFormError | null {\n if (errorKeys.length && Object.keys(fieldErrors).length) {\n const errors = errorKeys.map((errorType: string) => {\n return {\n ...fieldErrors[errorType],\n type: errorType,\n };\n });\n\n const sortedErrors = [...errors].sort((a, b) => a.priority - b.priority);\n\n return sortedErrors[0];\n }\n return null;\n }\n\n /**\n * Retrieves the details of the highest priority form error for a given control path.\n * @param controlPath - The path to the control in the form.\n * @returns The details of the highest priority form error, or null if there are no errors.\n */\n private getFieldErrorDetails(controlPath: (string | number)[]): IAbstractFormBaseHighPriorityFormError | null {\n // Get the control\n const control = this.form.get(controlPath);\n\n // If we have errors\n const controlErrors = control?.errors;\n\n if (controlErrors) {\n /// Get all the error keys\n const controlKey = controlPath[controlPath.length - 1];\n const errorKeys = Object.keys(controlErrors) || [];\n const fieldErrors = this.fieldErrors[controlKey] || {};\n\n if (errorKeys.length && Object.keys(fieldErrors).length) {\n return this.getHighestPriorityError(errorKeys, fieldErrors);\n }\n }\n return null;\n }\n\n /**\n * Retrieves all form errors from the provided form and its nested form groups.\n *\n * @param form - The form group to retrieve errors from.\n * @param controlPath - An optional array representing the path to the current control within the form group.\n * @returns An array of form errors, each containing the field ID, error message, priority, and type.\n */\n private getFormErrors(form: FormGroup, controlPath: (string | number)[] = []): IAbstractFormBaseFormError[] {\n // recursively get all errors from all controls in the form including nested form group controls\n const formControls = form.controls;\n\n const errorSummary = Object.keys(formControls)\n .filter((controlName) => formControls[controlName].invalid)\n .map((controlName) => {\n const control = formControls[controlName];\n\n if (control instanceof FormGroup) {\n return this.getFormErrors(control, [...controlPath, controlName]);\n }\n\n if (control instanceof FormArray) {\n return control.controls\n .map((controlItem, index) => {\n // We only support FormGroups in FormArrays\n if (controlItem instanceof FormGroup) {\n return this.getFormErrors(controlItem, [...controlPath, controlName, index]);\n }\n\n return [];\n })\n .flat();\n }\n\n const getFieldErrorDetails = this.getFieldErrorDetails([...controlPath, controlName]);\n\n // Return the error summary entry\n // If we don't have the error details, return a null message\n return {\n fieldId: controlName,\n message: getFieldErrorDetails?.message ?? null,\n priority: getFieldErrorDetails?.priority ?? 999999999,\n type: getFieldErrorDetails?.type ?? null,\n };\n })\n .flat();\n\n // Remove any null errors\n return errorSummary.filter((item) => item?.message !== null);\n }\n\n /**\n * Sets the error messages for the form controls and error summary based on the provided form errors.\n * @param formErrors - An array of form errors containing field IDs and error messages.\n */\n private setErrorMessages(formErrors: IAbstractFormBaseFormError[]) {\n // Reset the form error messages\n this.formControlErrorMessages = {};\n this.formErrorSummaryMessage = [];\n\n // Set the form error messages based on the error summary entries\n formErrors.forEach((entry) => {\n this.formControlErrorMessages[entry.fieldId] = entry.message;\n this.formErrorSummaryMessage.push({ fieldId: entry.fieldId, message: entry.message });\n });\n }\n\n /**\n * Gets the indexes of the date fields to remove based on the form error summary message.\n * @returns An array of indexes representing the date fields to remove.\n */\n private getDateFieldsToRemoveIndexes(): number[] {\n const indexesToRemove: number[] = [];\n // The order of the field ids is important\n // this is the order in which we want to remove them\n const foundIndexes = this.getFormErrorSummaryIndex(\n ['dayOfMonth', 'monthOfYear', 'year'],\n this.formErrorSummaryMessage,\n );\n\n // Determine which indexes to remove based on the found fields\n switch (foundIndexes.length) {\n case 3:\n // All three date fields are present\n indexesToRemove.push(foundIndexes[1], foundIndexes[2]);\n break;\n case 2:\n // Two date fields are present\n indexesToRemove.push(foundIndexes[1]);\n break;\n }\n\n return indexesToRemove;\n }\n\n /**\n * Returns an array of indices corresponding to the positions of the given field IDs in the form error summary message array.\n *\n * @param fieldIds - An array of field IDs to search for in the form error summary message array.\n * @param formErrorSummaryMessage - An array of form error summary messages.\n * @returns An array of indices corresponding to the positions of the field IDs in the form error summary message array.\n */\n private getFormErrorSummaryIndex(\n fieldIds: string[],\n formErrorSummaryMessage: IAbstractFormBaseFormErrorSummaryMessage[],\n ): number[] {\n return fieldIds.reduce((acc: number[], field) => {\n const index = formErrorSummaryMessage.findIndex((error) => error.fieldId === field);\n return index !== -1 ? [...acc, index] : acc;\n }, []);\n }\n\n /**\n * Removes error summary messages from the given array based on the specified indexes.\n *\n * @param formErrorSummaryMessage - The array of error summary messages.\n * @param indexes - The indexes of the error summary messages to be removed.\n * @returns The updated array of error summary messages.\n */\n private removeErrorSummaryMessages(\n formErrorSummaryMessage: IAbstractFormBaseFormErrorSummaryMessage[],\n indexes: number[],\n ): IAbstractFormBaseFormErrorSummaryMessage[] {\n return formErrorSummaryMessage.filter((_, index) => !indexes.includes(index));\n }\n\n /**\n * Splits the form errors into two arrays based on the provided field IDs.\n * Errors with field IDs included in the fieldIds array will be moved to the removedFormErrors array,\n * while the remaining errors will be moved to the cleanFormErrors array.\n *\n * @param fieldIds - An array of field IDs to filter the form errors.\n * @param formErrors - An array of form errors to be split.\n * @returns An array containing two arrays: cleanFormErrors and removedFormErrors.\n */\n private splitFormErrors(\n fieldIds: string[],\n formErrors: IAbstractFormBaseFormError[],\n ): IAbstractFormBaseFormError[][] {\n const cleanFormErrors: IAbstractFormBaseFormError[] = [];\n const removedFormErrors: IAbstractFormBaseFormError[] = [];\n\n formErrors.forEach((error) => {\n if (fieldIds.includes(error.fieldId)) {\n removedFormErrors.push(error);\n } else {\n cleanFormErrors.push(error);\n }\n });\n\n return [cleanFormErrors, removedFormErrors];\n }\n\n /**\n * Manipulates the error message for specific fields in the formErrors array.\n * @param fields - An array of field IDs to target for error message manipulation.\n * @param messageOverride - The new error message to be used for the targeted fields.\n * @param errorType - The type of error to match for the targeted fields.\n * @param formErrors - An array of IFormError objects representing the form errors.\n * @returns An array of IFormError objects with the manipulated error messages.\n */\n private manipulateFormErrorMessage(\n fields: string[],\n messageOverride: string,\n errorType: string,\n formErrors: IAbstractFormBaseFormError[],\n ): IAbstractFormBaseFormError[] {\n const manipulatedFields: IAbstractFormBaseFormError[] = [];\n formErrors.forEach((field) => {\n if (fields.includes(field.fieldId)) {\n if (field.type === errorType) {\n manipulatedFields.push({ ...field, message: messageOverride });\n } else {\n manipulatedFields.push(field);\n }\n } else {\n manipulatedFields.push(field);\n }\n });\n\n return manipulatedFields;\n }\n\n /**\n * Retrieves the form errors with the highest priority.\n *\n * @param formErrors - An array of form errors.\n * @returns An array of form errors with the highest priority.\n */\n private getHighPriorityFormErrors(formErrors: IAbstractFormBaseFormError[]): IAbstractFormBaseFormError[] {\n // Get the lowest priority (1 is the highest priority, 3 is the lowest priority)\n const lowestPriority = Math.min(...formErrors.map((item) => item.priority));\n return formErrors.filter((item) => item.priority === lowestPriority);\n }\n\n /**\n * Focuses on the error summary element and scrolls to the top of the page.\n *\n * This method first triggers change detection to ensure the view is up-to-date.\n * It then selects the error summary element with the class 'govuk-error-summary'.\n * If the error summary element is found, it sets focus on it without scrolling the page.\n * Finally, it calls a utility service to scroll to the top of the page.\n *\n * @private\n */\n private focusAndScrollToErrorSummary(): void {\n this.changeDetectorRef.detectChanges();\n\n const errorSummary = document.querySelector('.govuk-error-summary') as HTMLElement;\n if (errorSummary) {\n errorSummary.focus({ preventScroll: true });\n this.utilsService.scrollToTop();\n }\n }\n\n /**\n * Setup listener for the form value changes and to emit hasUnsavedChanges\n */\n private setupListener(): void {\n this.form.valueChanges.pipe(takeUntil(this.ngUnsubscribe)).subscribe(() => {\n this.unsavedChanges.emit(this.hasUnsavedChanges());\n });\n }\n\n /**\n * Adds controls to a form group.\n *\n * @param formGroup - The form group to add controls to.\n * @param controls - An array of form array control validations.\n * @param index - The index of the form array control.\n */\n protected addControlsToFormGroup(\n formGroup: FormGroup,\n controls: IAbstractFormArrayControlValidation[],\n index: number,\n ): void {\n controls.forEach(({ controlName, validators }) => {\n formGroup.addControl(`${controlName}_${index}`, new FormControl(null, validators));\n });\n }\n\n /**\n * Creates a form control with the specified validators and initial value.\n *\n * @param validators - An array of validator functions.\n * @param initialValue - The initial value for the form control. Defaults to null.\n * @returns The created form control.\n */\n protected createFormControl(validators: ValidatorFn[], initialValue: string | null = null): FormControl {\n return new FormControl(initialValue, { validators: [...validators] });\n }\n\n /**\n * Handles the error messages and populates the relevant variables\n */\n protected handleErrorMessages(): void {\n this.formErrors = this.getFormErrors(this.form);\n\n this.setErrorMessages(this.formErrors);\n\n this.formErrorSummaryMessage = this.removeErrorSummaryMessages(\n this.formErrorSummaryMessage,\n this.getDateFieldsToRemoveIndexes(),\n );\n }\n\n /**\n * Checks whether the form has been touched and submitted\n *\n * @returns boolean\n */\n protected hasUnsavedChanges(): boolean {\n return this.form.dirty && !this.formSubmitted;\n }\n\n /**\n * Sets the value of a form control specified by its path and marks it as touched.\n *\n * @param value - The value to set for the form control.\n * @param controlPath - The dot-delimited path to the form control within the form group.\n */\n protected setInputValue(value: string, controlPath: string): void {\n const control = this.form.get(controlPath);\n if (control) {\n control.patchValue(value);\n control.markAsTouched();\n }\n }\n\n /**\n * Handles the form errors for the date input fields.\n * @param formErrors - An array of form errors.\n * @returns An array of form errors with the manipulated error messages.\n */\n protected handleDateInputFormErrors() {\n const dateInputFields = ['dayOfMonth', 'monthOfYear', 'year'];\n const splitFormErrors = this.splitFormErrors(dateInputFields, this.formErrors);\n const highPriorityDateControlErrors = this.getHighPriorityFormErrors(splitFormErrors[1]);\n let manipulatedFormErrors: IAbstractFormBaseFormError[] = highPriorityDateControlErrors;\n\n // If we have more than one error then we want to manipulate the error message\n if (highPriorityDateControlErrors.length > 1) {\n manipulatedFormErrors = this.manipulateFormErrorMessage(\n dateInputFields,\n 'Please enter a DOB',\n 'required',\n manipulatedFormErrors,\n );\n }\n\n return [...splitFormErrors[0], ...manipulatedFormErrors];\n }\n\n /**\n * Sets the initial error messages for the form controls.\n *\n * @param form - The FormGroup instance.\n */\n protected setInitialErrorMessages(): void {\n const formControls = this.form.controls;\n const initialFormControlErrorMessages: IAbstractFormControlErrorMessage = {};\n\n Object.keys(formControls).forEach((controlName) => {\n initialFormControlErrorMessages[controlName] = null;\n });\n\n this.formControlErrorMessages = initialFormControlErrorMessages;\n this.formErrorSummaryMessage = [];\n }\n\n /**\n * Repopulates the search form with the data from the account enquiry search.\n * @param state - The state object containing the search form data.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected rePopulateForm(state: any): void {\n this.form.patchValue(state);\n }\n\n /**\n * Adds a new form control to the form group.\n *\n * @param controlName - The name of the control to add.\n * @param validators - An array of validators to apply to the control.\n */\n protected createControl(controlName: string, validators: ValidatorFn[]): void {\n this.form.addControl(controlName, new FormControl(null, validators));\n }\n\n /**\n * Updates the validators of an existing form control.\n *\n * @param controlName - The name of the control to update.\n * @param validators - An array of validators to apply to the control.\n */\n protected updateControl(controlName: string, validators: ValidatorFn[]): void {\n const control = this.form.get(controlName);\n if (control) {\n control.setValidators(validators);\n control.updateValueAndValidity();\n } else {\n this.createControl(controlName, validators);\n }\n }\n\n /**\n * Removes a control from the form.\n *\n * @param controlName - The name of the control to remove.\n */\n protected removeControl(controlName: string): void {\n if (this.formControlErrorMessages[controlName]) {\n this.removeControlErrors(controlName);\n }\n this.form.removeControl(controlName);\n }\n\n /**\n * Removes the error message associated with the specified control name from the formControlErrorMessages object.\n *\n * @param controlName - The name of the control for which to remove the error message.\n */\n protected removeControlErrors(controlName: string): void {\n delete this.formControlErrorMessages[controlName];\n }\n\n /**\n * Clears the search form.\n */\n public handleClearForm(): void {\n this.form.reset();\n }\n\n /**\n * Handles the scroll of the component error from the summary\n *\n * @param fieldId - Field id of the component\n */\n public scrollTo(fieldId: string): void {\n this['scroll'](fieldId);\n }\n\n /**\n * Handles route with the supplied route\n *\n * @param route string of route\n * @param nonRelative boolean indicating if route is relative to the parent\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public handleRoute(route: string, nonRelative: boolean = false, event?: Event, routeData?: any): void {\n if (event) {\n event.preventDefault();\n }\n\n this.unsavedChanges.emit(this.hasUnsavedChanges());\n\n const navigationExtras = {\n ...(nonRelative ? {} : { relativeTo: this.activatedRoute.parent }),\n ...(routeData !== undefined ? { state: routeData } : {}),\n };\n\n this.router.navigate([route], navigationExtras);\n }\n\n /**\n * Handles the form submission event.\n *\n * @param event - The form submission event.\n * @returns void\n */\n public handleFormSubmit(event: SubmitEvent): void {\n this.handleErrorMessages();\n\n if (this.form.valid) {\n this.formSubmitted = true;\n const nestedFlow = event.submitter ? event.submitter.className.includes('nested-flow') : false;\n this.unsavedChanges.emit(this.hasUnsavedChanges());\n this.formSubmit.emit({ formData: this.form.value, nestedFlow: nestedFlow });\n } else {\n this.focusAndScrollToErrorSummary();\n }\n }\n\n /**\n * Handles the input event to convert all letters in the input value to uppercase.\n * This method is triggered by an input event and modifies the input value directly.\n *\n * @param event - The input event triggered by the user.\n */\n public handleUppercaseInputMask(event: Event): void {\n const input = event.target as HTMLInputElement;\n input.value = this.utilsService.upperCaseAllLetters(input.value);\n }\n\n public ngOnInit(): void {\n if (this.form) {\n this.setupListener();\n }\n }\n\n public ngOnDestroy(): void {\n this.ngUnsubscribe.next();\n this.ngUnsubscribe.complete();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"hmcts-opal-frontend-common-components-abstract-abstract-form-base.mjs","sources":["../../../projects/opal-frontend-common/components/abstract/abstract-form-base/abstract-form-base.component.ts","../../../projects/opal-frontend-common/components/abstract/abstract-form-base/hmcts-opal-frontend-common-components-abstract-abstract-form-base.ts"],"sourcesContent":["import { ChangeDetectorRef, Component, EventEmitter, OnDestroy, OnInit, Output, inject } from '@angular/core';\nimport { FormArray, FormControl, FormGroup, ValidatorFn } from '@angular/forms';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { Subject, takeUntil } from 'rxjs';\nimport { IAbstractFormBaseFieldError } from './interfaces/abstract-form-base-field-error.interface';\nimport { IAbstractFormBaseFieldErrors } from './interfaces/abstract-form-base-field-errors.interface';\nimport { IAbstractFormBaseFormError } from './interfaces/abstract-form-base-form-error.interface';\nimport {\n IAbstractFormBaseFormErrorSummaryMessage,\n IAbstractFormControlErrorMessage,\n IAbstractFormArrayControlValidation,\n} from '@hmcts/opal-frontend-common/components/abstract/interfaces';\nimport { IAbstractFormBaseHighPriorityFormError } from './interfaces/abstract-form-base-high-priority-form-error.interface';\nimport { IAbstractFormBaseForm } from './interfaces/abstract-form-base-form.interface';\nimport { UtilsService } from '@hmcts/opal-frontend-common/services/utils-service';\n\n@Component({\n template: '',\n})\nexport abstract class AbstractFormBaseComponent implements OnInit, OnDestroy {\n private readonly changeDetectorRef = inject(ChangeDetectorRef);\n private readonly router = inject(Router);\n private readonly activatedRoute = inject(ActivatedRoute);\n\n @Output() protected unsavedChanges = new EventEmitter<boolean>();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n @Output() protected formSubmit = new EventEmitter<IAbstractFormBaseForm<any>>();\n protected readonly utilsService = inject(UtilsService);\n protected fieldErrors!: IAbstractFormBaseFieldErrors;\n protected formSubmitted = false;\n protected readonly ngUnsubscribe = new Subject<void>();\n\n public form!: FormGroup;\n public formControlErrorMessages!: IAbstractFormControlErrorMessage;\n public formErrorSummaryMessage!: IAbstractFormBaseFormErrorSummaryMessage[];\n public formErrors!: IAbstractFormBaseFormError[];\n\n constructor() {}\n\n /**\n * Scrolls to the label of the component and focuses on the field id\n *\n * @param fieldId - Field id of the component\n */\n private scroll(fieldId: string): void {\n let labelTarget;\n let fieldElement;\n\n const autocompleteLabel = document.querySelector(`label[for=${fieldId}-autocomplete]`);\n const regularLabel = document.querySelector(`label[for=${fieldId}]`);\n const fieldsetLegend = document.querySelector(`#${fieldId} .govuk-fieldset__legend`);\n\n if (autocompleteLabel) {\n labelTarget = autocompleteLabel;\n fieldElement = document.getElementById(`${fieldId}-autocomplete`);\n } else {\n labelTarget = regularLabel || fieldsetLegend;\n fieldElement = document.getElementById(fieldId);\n }\n\n if (fieldElement) {\n if (labelTarget) {\n labelTarget.scrollIntoView({ behavior: 'smooth' });\n }\n fieldElement.focus();\n }\n }\n\n /**\n * Returns the highest priority form error from the given error keys and field errors.\n * @param errorKeys - An array of error keys.\n * @param fieldErrors - An object containing field errors.\n * @returns The highest priority form error or null if no errors are found.\n */\n private getHighestPriorityError(\n errorKeys: string[] = [],\n fieldErrors: IAbstractFormBaseFieldError = {},\n ): IAbstractFormBaseHighPriorityFormError | null {\n if (errorKeys.length && Object.keys(fieldErrors).length) {\n const errors = errorKeys.map((errorType: string) => {\n return {\n ...fieldErrors[errorType],\n type: errorType,\n };\n });\n\n const sortedErrors = [...errors].sort((a, b) => a.priority - b.priority);\n\n return sortedErrors[0];\n }\n return null;\n }\n\n /**\n * Retrieves the details of the highest priority form error for a given control path.\n * @param controlPath - The path to the control in the form.\n * @returns The details of the highest priority form error, or null if there are no errors.\n */\n private getFieldErrorDetails(controlPath: (string | number)[]): IAbstractFormBaseHighPriorityFormError | null {\n // Get the control\n const control = this.form.get(controlPath);\n\n // If we have errors\n const controlErrors = control?.errors;\n\n if (controlErrors) {\n /// Get all the error keys\n const controlKey = controlPath[controlPath.length - 1];\n const errorKeys = Object.keys(controlErrors) || [];\n const fieldErrors = this.fieldErrors[controlKey] || {};\n\n if (errorKeys.length && Object.keys(fieldErrors).length) {\n return this.getHighestPriorityError(errorKeys, fieldErrors);\n }\n }\n return null;\n }\n\n /**\n * Retrieves all form errors from the provided form and its nested form groups.\n *\n * @param form - The form group to retrieve errors from.\n * @param controlPath - An optional array representing the path to the current control within the form group.\n * @returns An array of form errors, each containing the field ID, error message, priority, and type.\n */\n private getFormErrors(form: FormGroup, controlPath: (string | number)[] = []): IAbstractFormBaseFormError[] {\n // recursively get all errors from all controls in the form including nested form group controls\n const formControls = form.controls;\n\n const errorSummary = Object.keys(formControls)\n .filter((controlName) => formControls[controlName].invalid)\n .map((controlName) => {\n const control = formControls[controlName];\n\n if (control instanceof FormGroup) {\n return this.getFormErrors(control, [...controlPath, controlName]);\n }\n\n if (control instanceof FormArray) {\n return control.controls\n .map((controlItem, index) => {\n // We only support FormGroups in FormArrays\n if (controlItem instanceof FormGroup) {\n return this.getFormErrors(controlItem, [...controlPath, controlName, index]);\n }\n\n return [];\n })\n .flat();\n }\n\n const getFieldErrorDetails = this.getFieldErrorDetails([...controlPath, controlName]);\n\n // Return the error summary entry\n // If we don't have the error details, return a null message\n return {\n fieldId: controlName,\n message: getFieldErrorDetails?.message ?? null,\n priority: getFieldErrorDetails?.priority ?? 999999999,\n type: getFieldErrorDetails?.type ?? null,\n };\n })\n .flat();\n\n // Remove any null errors\n return errorSummary.filter((item) => item?.message !== null);\n }\n\n /**\n * Sets the error messages for the form controls and error summary based on the provided form errors.\n * @param formErrors - An array of form errors containing field IDs and error messages.\n */\n private setErrorMessages(formErrors: IAbstractFormBaseFormError[]) {\n // Reset the form error messages\n this.formControlErrorMessages = {};\n this.formErrorSummaryMessage = [];\n\n // Set the form error messages based on the error summary entries\n formErrors.forEach((entry) => {\n this.formControlErrorMessages[entry.fieldId] = entry.message;\n this.formErrorSummaryMessage.push({ fieldId: entry.fieldId, message: entry.message });\n });\n }\n\n /**\n * Gets the indexes of the date fields to remove based on the form error summary message.\n * @returns An array of indexes representing the date fields to remove.\n */\n private getDateFieldsToRemoveIndexes(): number[] {\n const indexesToRemove: number[] = [];\n // The order of the field ids is important\n // this is the order in which we want to remove them\n const foundIndexes = this.getFormErrorSummaryIndex(\n ['dayOfMonth', 'monthOfYear', 'year'],\n this.formErrorSummaryMessage,\n );\n\n // Determine which indexes to remove based on the found fields\n switch (foundIndexes.length) {\n case 3:\n // All three date fields are present\n indexesToRemove.push(foundIndexes[1], foundIndexes[2]);\n break;\n case 2:\n // Two date fields are present\n indexesToRemove.push(foundIndexes[1]);\n break;\n }\n\n return indexesToRemove;\n }\n\n /**\n * Returns an array of indices corresponding to the positions of the given field IDs in the form error summary message array.\n *\n * @param fieldIds - An array of field IDs to search for in the form error summary message array.\n * @param formErrorSummaryMessage - An array of form error summary messages.\n * @returns An array of indices corresponding to the positions of the field IDs in the form error summary message array.\n */\n private getFormErrorSummaryIndex(\n fieldIds: string[],\n formErrorSummaryMessage: IAbstractFormBaseFormErrorSummaryMessage[],\n ): number[] {\n return fieldIds.reduce((acc: number[], field) => {\n const index = formErrorSummaryMessage.findIndex((error) => error.fieldId === field);\n return index !== -1 ? [...acc, index] : acc;\n }, []);\n }\n\n /**\n * Removes error summary messages from the given array based on the specified indexes.\n *\n * @param formErrorSummaryMessage - The array of error summary messages.\n * @param indexes - The indexes of the error summary messages to be removed.\n * @returns The updated array of error summary messages.\n */\n private removeErrorSummaryMessages(\n formErrorSummaryMessage: IAbstractFormBaseFormErrorSummaryMessage[],\n indexes: number[],\n ): IAbstractFormBaseFormErrorSummaryMessage[] {\n return formErrorSummaryMessage.filter((_, index) => !indexes.includes(index));\n }\n\n /**\n * Splits the form errors into two arrays based on the provided field IDs.\n * Errors with field IDs included in the fieldIds array will be moved to the removedFormErrors array,\n * while the remaining errors will be moved to the cleanFormErrors array.\n *\n * @param fieldIds - An array of field IDs to filter the form errors.\n * @param formErrors - An array of form errors to be split.\n * @returns An array containing two arrays: cleanFormErrors and removedFormErrors.\n */\n private splitFormErrors(\n fieldIds: string[],\n formErrors: IAbstractFormBaseFormError[],\n ): IAbstractFormBaseFormError[][] {\n const cleanFormErrors: IAbstractFormBaseFormError[] = [];\n const removedFormErrors: IAbstractFormBaseFormError[] = [];\n\n formErrors.forEach((error) => {\n if (fieldIds.includes(error.fieldId)) {\n removedFormErrors.push(error);\n } else {\n cleanFormErrors.push(error);\n }\n });\n\n return [cleanFormErrors, removedFormErrors];\n }\n\n /**\n * Manipulates the error message for specific fields in the formErrors array.\n * @param fields - An array of field IDs to target for error message manipulation.\n * @param messageOverride - The new error message to be used for the targeted fields.\n * @param errorType - The type of error to match for the targeted fields.\n * @param formErrors - An array of IFormError objects representing the form errors.\n * @returns An array of IFormError objects with the manipulated error messages.\n */\n private manipulateFormErrorMessage(\n fields: string[],\n messageOverride: string,\n errorType: string,\n formErrors: IAbstractFormBaseFormError[],\n ): IAbstractFormBaseFormError[] {\n const manipulatedFields: IAbstractFormBaseFormError[] = [];\n formErrors.forEach((field) => {\n if (fields.includes(field.fieldId)) {\n if (field.type === errorType) {\n manipulatedFields.push({ ...field, message: messageOverride });\n } else {\n manipulatedFields.push(field);\n }\n } else {\n manipulatedFields.push(field);\n }\n });\n\n return manipulatedFields;\n }\n\n /**\n * Retrieves the form errors with the highest priority.\n *\n * @param formErrors - An array of form errors.\n * @returns An array of form errors with the highest priority.\n */\n private getHighPriorityFormErrors(formErrors: IAbstractFormBaseFormError[]): IAbstractFormBaseFormError[] {\n // Get the lowest priority (1 is the highest priority, 3 is the lowest priority)\n const lowestPriority = Math.min(...formErrors.map((item) => item.priority));\n return formErrors.filter((item) => item.priority === lowestPriority);\n }\n\n /**\n * Focuses on the error summary element and scrolls to the top of the page.\n *\n * This method first triggers change detection to ensure the view is up-to-date.\n * It then selects the error summary element with the class 'govuk-error-summary'.\n * If the error summary element is found, it sets focus on it without scrolling the page.\n * Finally, it calls a utility service to scroll to the top of the page.\n *\n * @private\n */\n private focusAndScrollToErrorSummary(): void {\n this.changeDetectorRef.detectChanges();\n\n const errorSummary = document.querySelector('.govuk-error-summary') as HTMLElement;\n if (errorSummary) {\n errorSummary.focus({ preventScroll: true });\n this.utilsService.scrollToTop();\n }\n }\n\n /**\n * Setup listener for the form value changes and to emit hasUnsavedChanges\n */\n private setupListener(): void {\n this.form.valueChanges.pipe(takeUntil(this.ngUnsubscribe)).subscribe(() => {\n this.unsavedChanges.emit(this.hasUnsavedChanges());\n });\n }\n\n /**\n * Adds controls to a form group.\n *\n * @param formGroup - The form group to add controls to.\n * @param controls - An array of form array control validations.\n * @param index - The index of the form array control.\n */\n protected addControlsToFormGroup(\n formGroup: FormGroup,\n controls: IAbstractFormArrayControlValidation[],\n index: number,\n ): void {\n controls.forEach(({ controlName, validators }) => {\n formGroup.addControl(`${controlName}_${index}`, new FormControl(null, validators));\n });\n }\n\n /**\n * Creates a form control with the specified validators and initial value.\n *\n * @param validators - An array of validator functions.\n * @param initialValue - The initial value for the form control. Defaults to null.\n * @returns The created form control.\n */\n protected createFormControl(validators: ValidatorFn[], initialValue: string | null = null): FormControl {\n return new FormControl(initialValue, { validators: [...validators] });\n }\n\n /**\n * Handles the error messages and populates the relevant variables\n */\n protected handleErrorMessages(): void {\n this.formErrors = this.getFormErrors(this.form);\n\n this.setErrorMessages(this.formErrors);\n\n this.formErrorSummaryMessage = this.removeErrorSummaryMessages(\n this.formErrorSummaryMessage,\n this.getDateFieldsToRemoveIndexes(),\n );\n }\n\n /**\n * Checks whether the form has been touched and submitted\n *\n * @returns boolean\n */\n protected hasUnsavedChanges(): boolean {\n return this.form.dirty && !this.formSubmitted;\n }\n\n /**\n * Sets the value of a form control specified by its path and marks it as touched.\n *\n * @param value - The value to set for the form control.\n * @param controlPath - The dot-delimited path to the form control within the form group.\n */\n protected setInputValue(value: string, controlPath: string): void {\n const control = this.form.get(controlPath);\n if (control) {\n control.patchValue(value);\n control.markAsTouched();\n }\n }\n\n /**\n * Handles the form errors for the date input fields.\n * @param formErrors - An array of form errors.\n * @returns An array of form errors with the manipulated error messages.\n */\n protected handleDateInputFormErrors() {\n const dateInputFields = ['dayOfMonth', 'monthOfYear', 'year'];\n const splitFormErrors = this.splitFormErrors(dateInputFields, this.formErrors);\n const highPriorityDateControlErrors = this.getHighPriorityFormErrors(splitFormErrors[1]);\n let manipulatedFormErrors: IAbstractFormBaseFormError[] = highPriorityDateControlErrors;\n\n // If we have more than one error then we want to manipulate the error message\n if (highPriorityDateControlErrors.length > 1) {\n manipulatedFormErrors = this.manipulateFormErrorMessage(\n dateInputFields,\n 'Please enter a DOB',\n 'required',\n manipulatedFormErrors,\n );\n }\n\n return [...splitFormErrors[0], ...manipulatedFormErrors];\n }\n\n /**\n * Sets the initial error messages for the form controls.\n *\n * @param form - The FormGroup instance.\n */\n protected setInitialErrorMessages(): void {\n const formControls = this.form.controls;\n const initialFormControlErrorMessages: IAbstractFormControlErrorMessage = {};\n\n Object.keys(formControls).forEach((controlName) => {\n initialFormControlErrorMessages[controlName] = null;\n });\n\n this.formControlErrorMessages = initialFormControlErrorMessages;\n this.formErrorSummaryMessage = [];\n }\n\n /**\n * Repopulates the search form with the data from the account enquiry search.\n * @param state - The state object containing the search form data.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected rePopulateForm(state: any): void {\n this.form.patchValue(state);\n }\n\n /**\n * Adds a new form control to the form group.\n *\n * @param controlName - The name of the control to add.\n * @param validators - An array of validators to apply to the control.\n */\n protected createControl(controlName: string, validators: ValidatorFn[]): void {\n this.form.addControl(controlName, new FormControl(null, validators));\n }\n\n /**\n * Updates the validators of an existing form control.\n *\n * @param controlName - The name of the control to update.\n * @param validators - An array of validators to apply to the control.\n */\n protected updateControl(controlName: string, validators: ValidatorFn[]): void {\n const control = this.form.get(controlName);\n if (control) {\n control.setValidators(validators);\n control.updateValueAndValidity();\n } else {\n this.createControl(controlName, validators);\n }\n }\n\n /**\n * Removes a control from the form.\n *\n * @param controlName - The name of the control to remove.\n */\n protected removeControl(controlName: string): void {\n if (this.formControlErrorMessages[controlName]) {\n this.removeControlErrors(controlName);\n }\n this.form.removeControl(controlName);\n }\n\n /**\n * Removes the error message associated with the specified control name from the formControlErrorMessages object.\n *\n * @param controlName - The name of the control for which to remove the error message.\n */\n protected removeControlErrors(controlName: string): void {\n delete this.formControlErrorMessages[controlName];\n }\n\n /**\n * Clears all error messages from the form.\n */\n protected clearAllErrorMessages(): void {\n this.formControlErrorMessages = {};\n this.formErrorSummaryMessage = [];\n this.formErrors = [];\n this.form.updateValueAndValidity({ onlySelf: false, emitEvent: false });\n }\n\n /**\n * Clears the search form.\n */\n public handleClearForm(): void {\n this.form.reset();\n }\n\n /**\n * Handles the scroll of the component error from the summary\n *\n * @param fieldId - Field id of the component\n */\n public scrollTo(fieldId: string): void {\n this['scroll'](fieldId);\n }\n\n /**\n * Handles route with the supplied route\n *\n * @param route string of route\n * @param nonRelative boolean indicating if route is relative to the parent\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public handleRoute(route: string, nonRelative: boolean = false, event?: Event, routeData?: any): void {\n if (event) {\n event.preventDefault();\n }\n\n this.unsavedChanges.emit(this.hasUnsavedChanges());\n\n const navigationExtras = {\n ...(nonRelative ? {} : { relativeTo: this.activatedRoute.parent }),\n ...(routeData !== undefined ? { state: routeData } : {}),\n };\n\n this.router.navigate([route], navigationExtras);\n }\n\n /**\n * Handles the form submission event.\n *\n * @param event - The form submission event.\n * @returns void\n */\n public handleFormSubmit(event: SubmitEvent): void {\n this.handleErrorMessages();\n\n if (this.form.valid) {\n this.formSubmitted = true;\n const nestedFlow = event.submitter ? event.submitter.className.includes('nested-flow') : false;\n this.unsavedChanges.emit(this.hasUnsavedChanges());\n this.formSubmit.emit({ formData: this.form.value, nestedFlow: nestedFlow });\n } else {\n this.focusAndScrollToErrorSummary();\n }\n }\n\n /**\n * Handles the input event to convert all letters in the input value to uppercase.\n * This method is triggered by an input event and modifies the input value directly.\n *\n * @param event - The input event triggered by the user.\n */\n public handleUppercaseInputMask(event: Event): void {\n const input = event.target as HTMLInputElement;\n input.value = this.utilsService.upperCaseAllLetters(input.value);\n }\n\n public ngOnInit(): void {\n if (this.form) {\n this.setupListener();\n }\n }\n\n public ngOnDestroy(): void {\n this.ngUnsubscribe.next();\n this.ngUnsubscribe.complete();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { Component } from '@angular/core';
|
|
3
|
+
import { AbstractFormBaseComponent } from '@hmcts/opal-frontend-common/components/abstract/abstract-form-base';
|
|
4
|
+
import { merge } from 'rxjs';
|
|
5
|
+
import { takeUntil } from 'rxjs/operators';
|
|
6
|
+
|
|
7
|
+
class AbstractNestedFormBaseComponent extends AbstractFormBaseComponent {
|
|
8
|
+
/**
|
|
9
|
+
* Installs all controls from a **detached** builder group into a target FormGroup (defaults to `this.form`).
|
|
10
|
+
*
|
|
11
|
+
* @param source A FormGroup created locally (its controls must not already belong to another parent).
|
|
12
|
+
* @param target The FormGroup to install the controls into. Defaults to `this.form`.
|
|
13
|
+
*
|
|
14
|
+
* Notes:
|
|
15
|
+
* - This method **moves** the control instances from `source` into `target` (no cloning).
|
|
16
|
+
* - If a control already has a parent, Angular will throw when adding it to `target`.
|
|
17
|
+
*/
|
|
18
|
+
addControlsToNestedFormGroup(source, target = this.form) {
|
|
19
|
+
Object.entries(source.controls).forEach(([name, ctrl]) => {
|
|
20
|
+
target.addControl(name, ctrl);
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Removes controls from `target` whose names are present in `source` (defaults to `this.form`).
|
|
25
|
+
*
|
|
26
|
+
* @param source A FormGroup whose control names identify which controls to remove.
|
|
27
|
+
* @param target The FormGroup to remove controls from. Defaults to `this.form`.
|
|
28
|
+
*
|
|
29
|
+
* Use this with the same builder group you used to add controls so you only remove what you added.
|
|
30
|
+
*/
|
|
31
|
+
removeControlsFromNestedFormGroup(source, target = this.form) {
|
|
32
|
+
Object.keys(source.controls).forEach((name) => {
|
|
33
|
+
target.removeControl(name);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Adds or removes one or more validators on a control and updates validity without emitting events.
|
|
38
|
+
*
|
|
39
|
+
* @param control The control to modify. If null/undefined, the method no-ops and returns `false`.
|
|
40
|
+
* @param validators A single `ValidatorFn` or an array of `ValidatorFn`s to add/remove.
|
|
41
|
+
* @param present When `true`, validators are added; when `false`, the same validators are removed.
|
|
42
|
+
* @returns The `present` flag (for convenient inline use in conditionals).
|
|
43
|
+
*/
|
|
44
|
+
setValidatorPresence(control, validators, present) {
|
|
45
|
+
if (!control)
|
|
46
|
+
return false;
|
|
47
|
+
const list = Array.isArray(validators) ? validators : [validators];
|
|
48
|
+
if (present) {
|
|
49
|
+
control.addValidators(list);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
control.removeValidators(list);
|
|
53
|
+
}
|
|
54
|
+
control.updateValueAndValidity({ emitEvent: false, onlySelf: true });
|
|
55
|
+
return present;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Truthy-value helper used by multiple sub-forms.
|
|
59
|
+
*
|
|
60
|
+
* Returns `false` for `null`/`undefined`. For strings, trims whitespace and checks for non-zero length.
|
|
61
|
+
* For all other types, returns `true` (treat non-string values as present).
|
|
62
|
+
*/
|
|
63
|
+
hasValue(v) {
|
|
64
|
+
if (v == null)
|
|
65
|
+
return false;
|
|
66
|
+
return typeof v === 'string' ? v.trim().length > 0 : true;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Resets a list of controls and re-computes validity without emitting value-change events.
|
|
70
|
+
*
|
|
71
|
+
* For each control: clears errors, resets the value to `null`, and calls `updateValueAndValidity`.
|
|
72
|
+
* This means built-in validators (e.g. `required`) will be re-applied after reset.
|
|
73
|
+
*/
|
|
74
|
+
resetAndValidateControls(controls) {
|
|
75
|
+
controls.forEach((c) => {
|
|
76
|
+
if (!c)
|
|
77
|
+
return;
|
|
78
|
+
c.setErrors(null);
|
|
79
|
+
c.reset(null, { emitEvent: false });
|
|
80
|
+
c.updateValueAndValidity({ emitEvent: false, onlySelf: true });
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Resets a FormGroup’s value/state and re-computes validity without emitting value-change events.
|
|
85
|
+
*
|
|
86
|
+
* Performs: `group.reset(undefined)`, marks pristine/untouched, then `updateValueAndValidity`.
|
|
87
|
+
*/
|
|
88
|
+
resetAndValidateFormGroup(group) {
|
|
89
|
+
group.reset(undefined, { emitEvent: false });
|
|
90
|
+
group.markAsPristine();
|
|
91
|
+
group.markAsUntouched();
|
|
92
|
+
group.updateValueAndValidity({ emitEvent: false, onlySelf: true });
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Subscribes a handler to the `valueChanges` of multiple controls, with auto-unsubscribe on destroy.
|
|
96
|
+
*
|
|
97
|
+
* @param handler Function invoked whenever **any** provided control emits a value change.
|
|
98
|
+
* @param controls One or more controls to observe; falsy entries are ignored.
|
|
99
|
+
*
|
|
100
|
+
* Implementation detail: merges the streams and unsubscribes via `takeUntil(this.ngUnsubscribe)`.
|
|
101
|
+
*/
|
|
102
|
+
subscribeValidation(handler, ...controls) {
|
|
103
|
+
const streams = controls.filter(Boolean).map((c) => c.valueChanges);
|
|
104
|
+
if (!streams.length)
|
|
105
|
+
return;
|
|
106
|
+
merge(...streams)
|
|
107
|
+
.pipe(takeUntil(this.ngUnsubscribe))
|
|
108
|
+
.subscribe(handler);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* @inheritdoc
|
|
112
|
+
*
|
|
113
|
+
* Handles cleanup logic when the component is destroyed.
|
|
114
|
+
*
|
|
115
|
+
* - Clears local child error definitions and emits an empty map to the parent.
|
|
116
|
+
* - Removes all controls added by this sub-form from the parent form, if nested.
|
|
117
|
+
* - Calls the base class's `ngOnDestroy` for additional teardown.
|
|
118
|
+
*/
|
|
119
|
+
ngOnDestroy() {
|
|
120
|
+
// Remove controls this sub-form added to the parent (if nested)
|
|
121
|
+
if (this.form?.parent) {
|
|
122
|
+
Object.keys(this.form.controls).forEach((name) => this.form.removeControl(name));
|
|
123
|
+
}
|
|
124
|
+
super.ngOnDestroy();
|
|
125
|
+
}
|
|
126
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: AbstractNestedFormBaseComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
127
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.7", type: AbstractNestedFormBaseComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: '', isInline: true });
|
|
128
|
+
}
|
|
129
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: AbstractNestedFormBaseComponent, decorators: [{
|
|
130
|
+
type: Component,
|
|
131
|
+
args: [{
|
|
132
|
+
template: '',
|
|
133
|
+
}]
|
|
134
|
+
}] });
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Generated bundle index. Do not edit.
|
|
138
|
+
*/
|
|
139
|
+
|
|
140
|
+
export { AbstractNestedFormBaseComponent };
|
|
141
|
+
//# sourceMappingURL=hmcts-opal-frontend-common-components-abstract-abstract-nested-form-base.mjs.map
|
package/fesm2022/hmcts-opal-frontend-common-components-abstract-abstract-nested-form-base.mjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hmcts-opal-frontend-common-components-abstract-abstract-nested-form-base.mjs","sources":["../../../projects/opal-frontend-common/components/abstract/abstract-nested-form-base/abstract-nested-form-base.component.ts","../../../projects/opal-frontend-common/components/abstract/abstract-nested-form-base/hmcts-opal-frontend-common-components-abstract-abstract-nested-form-base.ts"],"sourcesContent":["import { Component } from '@angular/core';\nimport { AbstractControl, FormGroup, ValidatorFn } from '@angular/forms';\nimport { AbstractFormBaseComponent } from '@hmcts/opal-frontend-common/components/abstract/abstract-form-base';\nimport { merge } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\n\n@Component({\n template: '',\n})\nexport abstract class AbstractNestedFormBaseComponent extends AbstractFormBaseComponent {\n /**\n * Installs all controls from a **detached** builder group into a target FormGroup (defaults to `this.form`).\n *\n * @param source A FormGroup created locally (its controls must not already belong to another parent).\n * @param target The FormGroup to install the controls into. Defaults to `this.form`.\n *\n * Notes:\n * - This method **moves** the control instances from `source` into `target` (no cloning).\n * - If a control already has a parent, Angular will throw when adding it to `target`.\n */\n protected addControlsToNestedFormGroup(source: FormGroup, target: FormGroup = this.form): void {\n Object.entries(source.controls).forEach(([name, ctrl]) => {\n target.addControl(name, ctrl);\n });\n }\n\n /**\n * Removes controls from `target` whose names are present in `source` (defaults to `this.form`).\n *\n * @param source A FormGroup whose control names identify which controls to remove.\n * @param target The FormGroup to remove controls from. Defaults to `this.form`.\n *\n * Use this with the same builder group you used to add controls so you only remove what you added.\n */\n protected removeControlsFromNestedFormGroup(source: FormGroup, target: FormGroup = this.form): void {\n Object.keys(source.controls).forEach((name) => {\n target.removeControl(name);\n });\n }\n\n /**\n * Adds or removes one or more validators on a control and updates validity without emitting events.\n *\n * @param control The control to modify. If null/undefined, the method no-ops and returns `false`.\n * @param validators A single `ValidatorFn` or an array of `ValidatorFn`s to add/remove.\n * @param present When `true`, validators are added; when `false`, the same validators are removed.\n * @returns The `present` flag (for convenient inline use in conditionals).\n */\n protected setValidatorPresence(\n control: AbstractControl | null,\n validators: ValidatorFn | ValidatorFn[],\n present: boolean,\n ): boolean {\n if (!control) return false;\n const list = Array.isArray(validators) ? validators : [validators];\n if (present) {\n control.addValidators(list);\n } else {\n control.removeValidators(list);\n }\n control.updateValueAndValidity({ emitEvent: false, onlySelf: true });\n return present;\n }\n\n /**\n * Truthy-value helper used by multiple sub-forms.\n *\n * Returns `false` for `null`/`undefined`. For strings, trims whitespace and checks for non-zero length.\n * For all other types, returns `true` (treat non-string values as present).\n */\n protected hasValue(v: unknown): boolean {\n if (v == null) return false;\n return typeof v === 'string' ? v.trim().length > 0 : true;\n }\n\n /**\n * Resets a list of controls and re-computes validity without emitting value-change events.\n *\n * For each control: clears errors, resets the value to `null`, and calls `updateValueAndValidity`.\n * This means built-in validators (e.g. `required`) will be re-applied after reset.\n */\n protected resetAndValidateControls(controls: (AbstractControl | null)[]): void {\n controls.forEach((c) => {\n if (!c) return;\n c.setErrors(null);\n c.reset(null, { emitEvent: false });\n c.updateValueAndValidity({ emitEvent: false, onlySelf: true });\n });\n }\n\n /**\n * Resets a FormGroup’s value/state and re-computes validity without emitting value-change events.\n *\n * Performs: `group.reset(undefined)`, marks pristine/untouched, then `updateValueAndValidity`.\n */\n protected resetAndValidateFormGroup(group: FormGroup): void {\n group.reset(undefined, { emitEvent: false });\n group.markAsPristine();\n group.markAsUntouched();\n group.updateValueAndValidity({ emitEvent: false, onlySelf: true });\n }\n\n /**\n * Subscribes a handler to the `valueChanges` of multiple controls, with auto-unsubscribe on destroy.\n *\n * @param handler Function invoked whenever **any** provided control emits a value change.\n * @param controls One or more controls to observe; falsy entries are ignored.\n *\n * Implementation detail: merges the streams and unsubscribes via `takeUntil(this.ngUnsubscribe)`.\n */\n protected subscribeValidation(handler: () => void, ...controls: (AbstractControl | null)[]): void {\n const streams = controls.filter(Boolean).map((c) => c!.valueChanges);\n if (!streams.length) return;\n merge(...streams)\n .pipe(takeUntil(this.ngUnsubscribe))\n .subscribe(handler);\n }\n\n /**\n * @inheritdoc\n *\n * Handles cleanup logic when the component is destroyed.\n *\n * - Clears local child error definitions and emits an empty map to the parent.\n * - Removes all controls added by this sub-form from the parent form, if nested.\n * - Calls the base class's `ngOnDestroy` for additional teardown.\n */\n public override ngOnDestroy(): void {\n // Remove controls this sub-form added to the parent (if nested)\n if (this.form?.parent) {\n Object.keys(this.form.controls).forEach((name) => this.form.removeControl(name));\n }\n\n super.ngOnDestroy();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -61,10 +61,10 @@ class AbstractSortableTablePaginationComponent extends AbstractSortableTableComp
|
|
|
61
61
|
const totalPages = Math.ceil(this.displayTableDataSignal().length / this.itemsPerPageSignal());
|
|
62
62
|
this.currentPageSignal.set(Math.max(1, Math.min(newPage, totalPages)));
|
|
63
63
|
}
|
|
64
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
65
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.
|
|
64
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: AbstractSortableTablePaginationComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
65
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.7", type: AbstractSortableTablePaginationComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: '', isInline: true });
|
|
66
66
|
}
|
|
67
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
67
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: AbstractSortableTablePaginationComponent, decorators: [{
|
|
68
68
|
type: Component,
|
|
69
69
|
args: [{
|
|
70
70
|
template: '',
|
|
@@ -185,10 +185,10 @@ class AbstractSortableTableComponent extends AbstractTableFilterComponent {
|
|
|
185
185
|
this.onSortChange({ key, sortType });
|
|
186
186
|
}
|
|
187
187
|
}
|
|
188
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
189
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.
|
|
188
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: AbstractSortableTableComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
189
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.7", type: AbstractSortableTableComponent, isStandalone: true, selector: "ng-component", outputs: { abstractSortState: "abstractSortState" }, usesInheritance: true, ngImport: i0, template: '', isInline: true });
|
|
190
190
|
}
|
|
191
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
191
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.7", ngImport: i0, type: AbstractSortableTableComponent, decorators: [{
|
|
192
192
|
type: Component,
|
|
193
193
|
args: [{
|
|
194
194
|
template: '',
|