ngx-dynamic-entity 0.0.1

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 (47) hide show
  1. package/esm2022/lib/field-types/checkbox-field.component.mjs +73 -0
  2. package/esm2022/lib/field-types/date-field.component.mjs +82 -0
  3. package/esm2022/lib/field-types/dropdown-field.component.mjs +83 -0
  4. package/esm2022/lib/field-types/entity-ref-field.component.mjs +117 -0
  5. package/esm2022/lib/field-types/multi-select-field.component.mjs +91 -0
  6. package/esm2022/lib/field-types/number-field.component.mjs +73 -0
  7. package/esm2022/lib/field-types/text-field.component.mjs +74 -0
  8. package/esm2022/lib/field-types/textarea-field.component.mjs +73 -0
  9. package/esm2022/lib/form/dynamic-field/dynamic-field.component.mjs +86 -0
  10. package/esm2022/lib/form/dynamic-form.component.mjs +167 -0
  11. package/esm2022/lib/providers/provide-ngx-dynamic-entity.mjs +23 -0
  12. package/esm2022/lib/services/config.service.mjs +58 -0
  13. package/esm2022/lib/services/entity-ref-registry.service.mjs +31 -0
  14. package/esm2022/lib/services/field-registry.service.mjs +50 -0
  15. package/esm2022/lib/services/hook-registry.service.mjs +26 -0
  16. package/esm2022/lib/services/rbac.service.mjs +52 -0
  17. package/esm2022/lib/services/validator-registry.service.mjs +49 -0
  18. package/esm2022/lib/services/version.service.mjs +40 -0
  19. package/esm2022/lib/table/dynamic-table.component.mjs +160 -0
  20. package/esm2022/lib/tokens/injection-tokens.mjs +16 -0
  21. package/esm2022/ngx-dynamic-entity.mjs +5 -0
  22. package/esm2022/public-api.mjs +26 -0
  23. package/fesm2022/ngx-dynamic-entity.mjs +1352 -0
  24. package/fesm2022/ngx-dynamic-entity.mjs.map +1 -0
  25. package/index.d.ts +5 -0
  26. package/lib/field-types/checkbox-field.component.d.ts +12 -0
  27. package/lib/field-types/date-field.component.d.ts +14 -0
  28. package/lib/field-types/dropdown-field.component.d.ts +13 -0
  29. package/lib/field-types/entity-ref-field.component.d.ts +26 -0
  30. package/lib/field-types/multi-select-field.component.d.ts +13 -0
  31. package/lib/field-types/number-field.component.d.ts +12 -0
  32. package/lib/field-types/text-field.component.d.ts +13 -0
  33. package/lib/field-types/textarea-field.component.d.ts +12 -0
  34. package/lib/form/dynamic-field/dynamic-field.component.d.ts +30 -0
  35. package/lib/form/dynamic-form.component.d.ts +52 -0
  36. package/lib/providers/provide-ngx-dynamic-entity.d.ts +29 -0
  37. package/lib/services/config.service.d.ts +25 -0
  38. package/lib/services/entity-ref-registry.service.d.ts +20 -0
  39. package/lib/services/field-registry.service.d.ts +22 -0
  40. package/lib/services/hook-registry.service.d.ts +12 -0
  41. package/lib/services/rbac.service.d.ts +32 -0
  42. package/lib/services/validator-registry.service.d.ts +19 -0
  43. package/lib/services/version.service.d.ts +26 -0
  44. package/lib/table/dynamic-table.component.d.ts +56 -0
  45. package/lib/tokens/injection-tokens.d.ts +16 -0
  46. package/package.json +37 -0
  47. package/public-api.d.ts +21 -0
@@ -0,0 +1,73 @@
1
+ import { Component, Input } from '@angular/core';
2
+ import { ReactiveFormsModule } from '@angular/forms';
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "@angular/forms";
5
+ export class CheckboxFieldComponent {
6
+ field;
7
+ control;
8
+ language = 'en';
9
+ readonly = false;
10
+ masked = false;
11
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CheckboxFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: CheckboxFieldComponent, isStandalone: true, selector: "ngx-checkbox-field", inputs: { field: "field", control: "control", language: "language", readonly: "readonly", masked: "masked" }, ngImport: i0, template: `
13
+ <div class="ngx-field ngx-field--checkbox" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
14
+ @if (masked) {
15
+ <label class="ngx-field__label">{{ field.label[language] || field.label['en'] }}</label>
16
+ <span class="ngx-field__value ngx-field__value--masked">XXXXXXXXX</span>
17
+ } @else if (readonly) {
18
+ <label class="ngx-field__label">{{ field.label[language] || field.label['en'] }}</label>
19
+ <span class="ngx-field__value">{{ control.value ? 'Yes' : 'No' }}</span>
20
+ } @else {
21
+ <label class="ngx-field__label">
22
+ <input
23
+ class="ngx-field__input"
24
+ type="checkbox"
25
+ [formControl]="$any(control)"
26
+ [attr.disabled]="field.disabled ? true : null"
27
+ />
28
+ {{ field.label[language] || field.label['en'] }}
29
+ </label>
30
+ }
31
+ </div>
32
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] });
33
+ }
34
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CheckboxFieldComponent, decorators: [{
35
+ type: Component,
36
+ args: [{
37
+ selector: 'ngx-checkbox-field',
38
+ standalone: true,
39
+ imports: [ReactiveFormsModule],
40
+ template: `
41
+ <div class="ngx-field ngx-field--checkbox" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
42
+ @if (masked) {
43
+ <label class="ngx-field__label">{{ field.label[language] || field.label['en'] }}</label>
44
+ <span class="ngx-field__value ngx-field__value--masked">XXXXXXXXX</span>
45
+ } @else if (readonly) {
46
+ <label class="ngx-field__label">{{ field.label[language] || field.label['en'] }}</label>
47
+ <span class="ngx-field__value">{{ control.value ? 'Yes' : 'No' }}</span>
48
+ } @else {
49
+ <label class="ngx-field__label">
50
+ <input
51
+ class="ngx-field__input"
52
+ type="checkbox"
53
+ [formControl]="$any(control)"
54
+ [attr.disabled]="field.disabled ? true : null"
55
+ />
56
+ {{ field.label[language] || field.label['en'] }}
57
+ </label>
58
+ }
59
+ </div>
60
+ `,
61
+ }]
62
+ }], propDecorators: { field: [{
63
+ type: Input
64
+ }], control: [{
65
+ type: Input
66
+ }], language: [{
67
+ type: Input
68
+ }], readonly: [{
69
+ type: Input
70
+ }], masked: [{
71
+ type: Input
72
+ }] } });
73
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2tib3gtZmllbGQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9maWVsZC10eXBlcy9jaGVja2JveC1maWVsZC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDakQsT0FBTyxFQUFtQixtQkFBbUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7QUE2QnRFLE1BQU0sT0FBTyxzQkFBc0I7SUFDeEIsS0FBSyxDQUFlO0lBQ3BCLE9BQU8sQ0FBbUI7SUFDMUIsUUFBUSxHQUFXLElBQUksQ0FBQztJQUN4QixRQUFRLEdBQVksS0FBSyxDQUFDO0lBQzFCLE1BQU0sR0FBWSxLQUFLLENBQUM7d0dBTHRCLHNCQUFzQjs0RkFBdEIsc0JBQXNCLDRMQXRCdkI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JULDJEQXJCUyxtQkFBbUI7OzRGQXVCbEIsc0JBQXNCO2tCQTFCbEMsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsb0JBQW9CO29CQUM5QixVQUFVLEVBQUUsSUFBSTtvQkFDaEIsT0FBTyxFQUFFLENBQUMsbUJBQW1CLENBQUM7b0JBQzlCLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQlQ7aUJBQ0Y7OEJBRVUsS0FBSztzQkFBYixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWJzdHJhY3RDb250cm9sLCBSZWFjdGl2ZUZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHR5cGUgeyBGaWVsZENvbmZpZyB9IGZyb20gJ0BkeW5hbWljLWVudGl0eS9jb3JlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmd4LWNoZWNrYm94LWZpZWxkJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1JlYWN0aXZlRm9ybXNNb2R1bGVdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgY2xhc3M9XCJuZ3gtZmllbGQgbmd4LWZpZWxkLS1jaGVja2JveFwiIFtjbGFzcy5uZ3gtZmllbGQtLXJlYWRvbmx5XT1cInJlYWRvbmx5XCIgW2NsYXNzLm5neC1maWVsZC0tbWFza2VkXT1cIm1hc2tlZFwiPlxuICAgICAgQGlmIChtYXNrZWQpIHtcbiAgICAgICAgPGxhYmVsIGNsYXNzPVwibmd4LWZpZWxkX19sYWJlbFwiPnt7IGZpZWxkLmxhYmVsW2xhbmd1YWdlXSB8fCBmaWVsZC5sYWJlbFsnZW4nXSB9fTwvbGFiZWw+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwibmd4LWZpZWxkX192YWx1ZSBuZ3gtZmllbGRfX3ZhbHVlLS1tYXNrZWRcIj5YWFhYWFhYWFg8L3NwYW4+XG4gICAgICB9IEBlbHNlIGlmIChyZWFkb25seSkge1xuICAgICAgICA8bGFiZWwgY2xhc3M9XCJuZ3gtZmllbGRfX2xhYmVsXCI+e3sgZmllbGQubGFiZWxbbGFuZ3VhZ2VdIHx8IGZpZWxkLmxhYmVsWydlbiddIH19PC9sYWJlbD5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJuZ3gtZmllbGRfX3ZhbHVlXCI+e3sgY29udHJvbC52YWx1ZSA/ICdZZXMnIDogJ05vJyB9fTwvc3Bhbj5cbiAgICAgIH0gQGVsc2Uge1xuICAgICAgICA8bGFiZWwgY2xhc3M9XCJuZ3gtZmllbGRfX2xhYmVsXCI+XG4gICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICBjbGFzcz1cIm5neC1maWVsZF9faW5wdXRcIlxuICAgICAgICAgICAgdHlwZT1cImNoZWNrYm94XCJcbiAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCIkYW55KGNvbnRyb2wpXCJcbiAgICAgICAgICAgIFthdHRyLmRpc2FibGVkXT1cImZpZWxkLmRpc2FibGVkID8gdHJ1ZSA6IG51bGxcIlxuICAgICAgICAgIC8+XG4gICAgICAgICAge3sgZmllbGQubGFiZWxbbGFuZ3VhZ2VdIHx8IGZpZWxkLmxhYmVsWydlbiddIH19XG4gICAgICAgIDwvbGFiZWw+XG4gICAgICB9XG4gICAgPC9kaXY+XG4gIGAsXG59KVxuZXhwb3J0IGNsYXNzIENoZWNrYm94RmllbGRDb21wb25lbnQge1xuICBASW5wdXQoKSBmaWVsZCE6IEZpZWxkQ29uZmlnO1xuICBASW5wdXQoKSBjb250cm9sITogQWJzdHJhY3RDb250cm9sO1xuICBASW5wdXQoKSBsYW5ndWFnZTogc3RyaW5nID0gJ2VuJztcbiAgQElucHV0KCkgcmVhZG9ubHk6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgbWFza2VkOiBib29sZWFuID0gZmFsc2U7XG59XG4iXX0=
@@ -0,0 +1,82 @@
1
+ import { Component, Input } from '@angular/core';
2
+ import { ReactiveFormsModule } from '@angular/forms';
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "@angular/forms";
5
+ export class DateFieldComponent {
6
+ field;
7
+ control;
8
+ language = 'en';
9
+ readonly = false;
10
+ masked = false;
11
+ /** ISO 8601 date → locale display string (ONEHERMES convention: always UTC, display in user locale) */
12
+ formatDate(value) {
13
+ if (!value)
14
+ return '—';
15
+ try {
16
+ return new Date(value).toLocaleDateString();
17
+ }
18
+ catch {
19
+ return value;
20
+ }
21
+ }
22
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DateFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
23
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: DateFieldComponent, isStandalone: true, selector: "ngx-date-field", inputs: { field: "field", control: "control", language: "language", readonly: "readonly", masked: "masked" }, ngImport: i0, template: `
24
+ <div class="ngx-field ngx-field--date" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
25
+ <label class="ngx-field__label">{{ field.label[language] || field.label['en'] }}</label>
26
+ @if (masked) {
27
+ <span class="ngx-field__value ngx-field__value--masked">XXXXXXXXX</span>
28
+ } @else if (readonly) {
29
+ <span class="ngx-field__value">{{ formatDate(control.value) }}</span>
30
+ } @else {
31
+ <input
32
+ class="ngx-field__input"
33
+ type="date"
34
+ [formControl]="$any(control)"
35
+ [attr.disabled]="field.disabled ? true : null"
36
+ />
37
+ @if (control.invalid && control.touched) {
38
+ <span class="ngx-field__error">This field has an error</span>
39
+ }
40
+ }
41
+ </div>
42
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] });
43
+ }
44
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DateFieldComponent, decorators: [{
45
+ type: Component,
46
+ args: [{
47
+ selector: 'ngx-date-field',
48
+ standalone: true,
49
+ imports: [ReactiveFormsModule],
50
+ template: `
51
+ <div class="ngx-field ngx-field--date" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
52
+ <label class="ngx-field__label">{{ field.label[language] || field.label['en'] }}</label>
53
+ @if (masked) {
54
+ <span class="ngx-field__value ngx-field__value--masked">XXXXXXXXX</span>
55
+ } @else if (readonly) {
56
+ <span class="ngx-field__value">{{ formatDate(control.value) }}</span>
57
+ } @else {
58
+ <input
59
+ class="ngx-field__input"
60
+ type="date"
61
+ [formControl]="$any(control)"
62
+ [attr.disabled]="field.disabled ? true : null"
63
+ />
64
+ @if (control.invalid && control.touched) {
65
+ <span class="ngx-field__error">This field has an error</span>
66
+ }
67
+ }
68
+ </div>
69
+ `,
70
+ }]
71
+ }], propDecorators: { field: [{
72
+ type: Input
73
+ }], control: [{
74
+ type: Input
75
+ }], language: [{
76
+ type: Input
77
+ }], readonly: [{
78
+ type: Input
79
+ }], masked: [{
80
+ type: Input
81
+ }] } });
82
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS1maWVsZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL2ZpZWxkLXR5cGVzL2RhdGUtZmllbGQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2pELE9BQU8sRUFBbUIsbUJBQW1CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7O0FBNEJ0RSxNQUFNLE9BQU8sa0JBQWtCO0lBQ3BCLEtBQUssQ0FBZTtJQUNwQixPQUFPLENBQW1CO0lBQzFCLFFBQVEsR0FBVyxJQUFJLENBQUM7SUFDeEIsUUFBUSxHQUFZLEtBQUssQ0FBQztJQUMxQixNQUFNLEdBQVksS0FBSyxDQUFDO0lBRWpDLHVHQUF1RztJQUN2RyxVQUFVLENBQUMsS0FBb0I7UUFDN0IsSUFBSSxDQUFDLEtBQUs7WUFBRSxPQUFPLEdBQUcsQ0FBQztRQUN2QixJQUFJLENBQUM7WUFDSCxPQUFPLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDOUMsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztJQUNILENBQUM7d0dBZlUsa0JBQWtCOzRGQUFsQixrQkFBa0Isd0xBckJuQjs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CVCwyREFwQlMsbUJBQW1COzs0RkFzQmxCLGtCQUFrQjtrQkF6QjlCLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLGdCQUFnQjtvQkFDMUIsVUFBVSxFQUFFLElBQUk7b0JBQ2hCLE9BQU8sRUFBRSxDQUFDLG1CQUFtQixDQUFDO29CQUM5QixRQUFRLEVBQUU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FtQlQ7aUJBQ0Y7OEJBRVUsS0FBSztzQkFBYixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWJzdHJhY3RDb250cm9sLCBSZWFjdGl2ZUZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHR5cGUgeyBGaWVsZENvbmZpZyB9IGZyb20gJ0BkeW5hbWljLWVudGl0eS9jb3JlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmd4LWRhdGUtZmllbGQnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbUmVhY3RpdmVGb3Jtc01vZHVsZV0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBjbGFzcz1cIm5neC1maWVsZCBuZ3gtZmllbGQtLWRhdGVcIiBbY2xhc3Mubmd4LWZpZWxkLS1yZWFkb25seV09XCJyZWFkb25seVwiIFtjbGFzcy5uZ3gtZmllbGQtLW1hc2tlZF09XCJtYXNrZWRcIj5cbiAgICAgIDxsYWJlbCBjbGFzcz1cIm5neC1maWVsZF9fbGFiZWxcIj57eyBmaWVsZC5sYWJlbFtsYW5ndWFnZV0gfHwgZmllbGQubGFiZWxbJ2VuJ10gfX08L2xhYmVsPlxuICAgICAgQGlmIChtYXNrZWQpIHtcbiAgICAgICAgPHNwYW4gY2xhc3M9XCJuZ3gtZmllbGRfX3ZhbHVlIG5neC1maWVsZF9fdmFsdWUtLW1hc2tlZFwiPlhYWFhYWFhYWDwvc3Bhbj5cbiAgICAgIH0gQGVsc2UgaWYgKHJlYWRvbmx5KSB7XG4gICAgICAgIDxzcGFuIGNsYXNzPVwibmd4LWZpZWxkX192YWx1ZVwiPnt7IGZvcm1hdERhdGUoY29udHJvbC52YWx1ZSkgfX08L3NwYW4+XG4gICAgICB9IEBlbHNlIHtcbiAgICAgICAgPGlucHV0XG4gICAgICAgICAgY2xhc3M9XCJuZ3gtZmllbGRfX2lucHV0XCJcbiAgICAgICAgICB0eXBlPVwiZGF0ZVwiXG4gICAgICAgICAgW2Zvcm1Db250cm9sXT1cIiRhbnkoY29udHJvbClcIlxuICAgICAgICAgIFthdHRyLmRpc2FibGVkXT1cImZpZWxkLmRpc2FibGVkID8gdHJ1ZSA6IG51bGxcIlxuICAgICAgICAvPlxuICAgICAgICBAaWYgKGNvbnRyb2wuaW52YWxpZCAmJiBjb250cm9sLnRvdWNoZWQpIHtcbiAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5neC1maWVsZF9fZXJyb3JcIj5UaGlzIGZpZWxkIGhhcyBhbiBlcnJvcjwvc3Bhbj5cbiAgICAgICAgfVxuICAgICAgfVxuICAgIDwvZGl2PlxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBEYXRlRmllbGRDb21wb25lbnQge1xuICBASW5wdXQoKSBmaWVsZCE6IEZpZWxkQ29uZmlnO1xuICBASW5wdXQoKSBjb250cm9sITogQWJzdHJhY3RDb250cm9sO1xuICBASW5wdXQoKSBsYW5ndWFnZTogc3RyaW5nID0gJ2VuJztcbiAgQElucHV0KCkgcmVhZG9ubHk6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgbWFza2VkOiBib29sZWFuID0gZmFsc2U7XG5cbiAgLyoqIElTTyA4NjAxIGRhdGUg4oaSIGxvY2FsZSBkaXNwbGF5IHN0cmluZyAoT05FSEVSTUVTIGNvbnZlbnRpb246IGFsd2F5cyBVVEMsIGRpc3BsYXkgaW4gdXNlciBsb2NhbGUpICovXG4gIGZvcm1hdERhdGUodmFsdWU6IHN0cmluZyB8IG51bGwpOiBzdHJpbmcge1xuICAgIGlmICghdmFsdWUpIHJldHVybiAn4oCUJztcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIG5ldyBEYXRlKHZhbHVlKS50b0xvY2FsZURhdGVTdHJpbmcoKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,83 @@
1
+ import { Component, Input } from '@angular/core';
2
+ import { ReactiveFormsModule } from '@angular/forms';
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "@angular/forms";
5
+ export class DropdownFieldComponent {
6
+ field;
7
+ control;
8
+ language = 'en';
9
+ readonly = false;
10
+ masked = false;
11
+ getLabel(value) {
12
+ const option = (this.field.options || []).find(o => o.value === value);
13
+ return option ? (option.label[this.language] || option.label['en'] || String(value)) : (value ?? '—');
14
+ }
15
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DropdownFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
16
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: DropdownFieldComponent, isStandalone: true, selector: "ngx-dropdown-field", inputs: { field: "field", control: "control", language: "language", readonly: "readonly", masked: "masked" }, ngImport: i0, template: `
17
+ <div class="ngx-field ngx-field--dropdown" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
18
+ <label class="ngx-field__label">{{ field.label[language] || field.label['en'] }}</label>
19
+ @if (masked) {
20
+ <span class="ngx-field__value ngx-field__value--masked">XXXXXXXXX</span>
21
+ } @else if (readonly) {
22
+ <span class="ngx-field__value">{{ getLabel(control.value) }}</span>
23
+ } @else {
24
+ <select
25
+ class="ngx-field__input"
26
+ [formControl]="$any(control)"
27
+ [attr.disabled]="field.disabled ? true : null"
28
+ >
29
+ <option value="">{{ field.placeholder?.[language] || field.placeholder?.['en'] || 'Select...' }}</option>
30
+ @for (option of field.options || []; track option.value) {
31
+ <option [value]="option.value">{{ option.label[language] || option.label['en'] }}</option>
32
+ }
33
+ </select>
34
+ @if (control.invalid && control.touched) {
35
+ <span class="ngx-field__error">This field has an error</span>
36
+ }
37
+ }
38
+ </div>
39
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] });
40
+ }
41
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DropdownFieldComponent, decorators: [{
42
+ type: Component,
43
+ args: [{
44
+ selector: 'ngx-dropdown-field',
45
+ standalone: true,
46
+ imports: [ReactiveFormsModule],
47
+ template: `
48
+ <div class="ngx-field ngx-field--dropdown" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
49
+ <label class="ngx-field__label">{{ field.label[language] || field.label['en'] }}</label>
50
+ @if (masked) {
51
+ <span class="ngx-field__value ngx-field__value--masked">XXXXXXXXX</span>
52
+ } @else if (readonly) {
53
+ <span class="ngx-field__value">{{ getLabel(control.value) }}</span>
54
+ } @else {
55
+ <select
56
+ class="ngx-field__input"
57
+ [formControl]="$any(control)"
58
+ [attr.disabled]="field.disabled ? true : null"
59
+ >
60
+ <option value="">{{ field.placeholder?.[language] || field.placeholder?.['en'] || 'Select...' }}</option>
61
+ @for (option of field.options || []; track option.value) {
62
+ <option [value]="option.value">{{ option.label[language] || option.label['en'] }}</option>
63
+ }
64
+ </select>
65
+ @if (control.invalid && control.touched) {
66
+ <span class="ngx-field__error">This field has an error</span>
67
+ }
68
+ }
69
+ </div>
70
+ `,
71
+ }]
72
+ }], propDecorators: { field: [{
73
+ type: Input
74
+ }], control: [{
75
+ type: Input
76
+ }], language: [{
77
+ type: Input
78
+ }], readonly: [{
79
+ type: Input
80
+ }], masked: [{
81
+ type: Input
82
+ }] } });
83
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJvcGRvd24tZmllbGQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9maWVsZC10eXBlcy9kcm9wZG93bi1maWVsZC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQWtCLE1BQU0sZUFBZSxDQUFDO0FBQ2pFLE9BQU8sRUFBbUIsbUJBQW1CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7O0FBZ0N0RSxNQUFNLE9BQU8sc0JBQXNCO0lBQ3hCLEtBQUssQ0FBZTtJQUNwQixPQUFPLENBQW1CO0lBQzFCLFFBQVEsR0FBVyxJQUFJLENBQUM7SUFDeEIsUUFBUSxHQUFZLEtBQUssQ0FBQztJQUMxQixNQUFNLEdBQVksS0FBSyxDQUFDO0lBRWpDLFFBQVEsQ0FBQyxLQUFVO1FBQ2pCLE1BQU0sTUFBTSxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssS0FBSyxLQUFLLENBQUMsQ0FBQztRQUN2RSxPQUFPLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxHQUFHLENBQUMsQ0FBQztJQUN4RyxDQUFDO3dHQVZVLHNCQUFzQjs0RkFBdEIsc0JBQXNCLDRMQXpCdkI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBdUJULDJEQXhCUyxtQkFBbUI7OzRGQTBCbEIsc0JBQXNCO2tCQTdCbEMsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsb0JBQW9CO29CQUM5QixVQUFVLEVBQUUsSUFBSTtvQkFDaEIsT0FBTyxFQUFFLENBQUMsbUJBQW1CLENBQUM7b0JBQzlCLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F1QlQ7aUJBQ0Y7OEJBRVUsS0FBSztzQkFBYixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT25Jbml0LCBzaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFic3RyYWN0Q29udHJvbCwgUmVhY3RpdmVGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB0eXBlIHsgRmllbGRDb25maWcsIERyb3Bkb3duT3B0aW9uIH0gZnJvbSAnQGR5bmFtaWMtZW50aXR5L2NvcmUnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduZ3gtZHJvcGRvd24tZmllbGQnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbUmVhY3RpdmVGb3Jtc01vZHVsZV0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBjbGFzcz1cIm5neC1maWVsZCBuZ3gtZmllbGQtLWRyb3Bkb3duXCIgW2NsYXNzLm5neC1maWVsZC0tcmVhZG9ubHldPVwicmVhZG9ubHlcIiBbY2xhc3Mubmd4LWZpZWxkLS1tYXNrZWRdPVwibWFza2VkXCI+XG4gICAgICA8bGFiZWwgY2xhc3M9XCJuZ3gtZmllbGRfX2xhYmVsXCI+e3sgZmllbGQubGFiZWxbbGFuZ3VhZ2VdIHx8IGZpZWxkLmxhYmVsWydlbiddIH19PC9sYWJlbD5cbiAgICAgIEBpZiAobWFza2VkKSB7XG4gICAgICAgIDxzcGFuIGNsYXNzPVwibmd4LWZpZWxkX192YWx1ZSBuZ3gtZmllbGRfX3ZhbHVlLS1tYXNrZWRcIj5YWFhYWFhYWFg8L3NwYW4+XG4gICAgICB9IEBlbHNlIGlmIChyZWFkb25seSkge1xuICAgICAgICA8c3BhbiBjbGFzcz1cIm5neC1maWVsZF9fdmFsdWVcIj57eyBnZXRMYWJlbChjb250cm9sLnZhbHVlKSB9fTwvc3Bhbj5cbiAgICAgIH0gQGVsc2Uge1xuICAgICAgICA8c2VsZWN0XG4gICAgICAgICAgY2xhc3M9XCJuZ3gtZmllbGRfX2lucHV0XCJcbiAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwiJGFueShjb250cm9sKVwiXG4gICAgICAgICAgW2F0dHIuZGlzYWJsZWRdPVwiZmllbGQuZGlzYWJsZWQgPyB0cnVlIDogbnVsbFwiXG4gICAgICAgID5cbiAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+e3sgZmllbGQucGxhY2Vob2xkZXI/LltsYW5ndWFnZV0gfHwgZmllbGQucGxhY2Vob2xkZXI/LlsnZW4nXSB8fCAnU2VsZWN0Li4uJyB9fTwvb3B0aW9uPlxuICAgICAgICAgIEBmb3IgKG9wdGlvbiBvZiBmaWVsZC5vcHRpb25zIHx8IFtdOyB0cmFjayBvcHRpb24udmFsdWUpIHtcbiAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cIm9wdGlvbi52YWx1ZVwiPnt7IG9wdGlvbi5sYWJlbFtsYW5ndWFnZV0gfHwgb3B0aW9uLmxhYmVsWydlbiddIH19PC9vcHRpb24+XG4gICAgICAgICAgfVxuICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgQGlmIChjb250cm9sLmludmFsaWQgJiYgY29udHJvbC50b3VjaGVkKSB7XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJuZ3gtZmllbGRfX2Vycm9yXCI+VGhpcyBmaWVsZCBoYXMgYW4gZXJyb3I8L3NwYW4+XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICA8L2Rpdj5cbiAgYCxcbn0pXG5leHBvcnQgY2xhc3MgRHJvcGRvd25GaWVsZENvbXBvbmVudCB7XG4gIEBJbnB1dCgpIGZpZWxkITogRmllbGRDb25maWc7XG4gIEBJbnB1dCgpIGNvbnRyb2whOiBBYnN0cmFjdENvbnRyb2w7XG4gIEBJbnB1dCgpIGxhbmd1YWdlOiBzdHJpbmcgPSAnZW4nO1xuICBASW5wdXQoKSByZWFkb25seTogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBtYXNrZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBnZXRMYWJlbCh2YWx1ZTogYW55KTogc3RyaW5nIHtcbiAgICBjb25zdCBvcHRpb24gPSAodGhpcy5maWVsZC5vcHRpb25zIHx8IFtdKS5maW5kKG8gPT4gby52YWx1ZSA9PT0gdmFsdWUpO1xuICAgIHJldHVybiBvcHRpb24gPyAob3B0aW9uLmxhYmVsW3RoaXMubGFuZ3VhZ2VdIHx8IG9wdGlvbi5sYWJlbFsnZW4nXSB8fCBTdHJpbmcodmFsdWUpKSA6ICh2YWx1ZSA/PyAn4oCUJyk7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,117 @@
1
+ import { Component, Input, signal } from '@angular/core';
2
+ import { ReactiveFormsModule } from '@angular/forms';
3
+ import { EntityRefRegistryService } from '../services/entity-ref-registry.service';
4
+ import { inject } from '@angular/core';
5
+ import * as i0 from "@angular/core";
6
+ import * as i1 from "@angular/forms";
7
+ /**
8
+ * EntityRefFieldComponent — renders a dropdown populated by a loader from EntityRefRegistryService.
9
+ * ADR-006: Options come ONLY from the registry. Never via @Input() loader.
10
+ * Uses field.component (if set) or field.id as the registry lookup key.
11
+ */
12
+ export class EntityRefFieldComponent {
13
+ field;
14
+ control;
15
+ language = 'en';
16
+ readonly = false;
17
+ masked = false;
18
+ entityRefRegistry = inject(EntityRefRegistryService);
19
+ options = signal([]);
20
+ loading = signal(false);
21
+ async ngOnInit() {
22
+ if (this.masked)
23
+ return; // No need to load options if masked
24
+ const entityKey = this.field.component ?? this.field.id;
25
+ const loader = this.entityRefRegistry.resolve(entityKey);
26
+ if (!loader)
27
+ return;
28
+ this.loading.set(true);
29
+ try {
30
+ const raw = await loader();
31
+ this.options.set(raw);
32
+ }
33
+ finally {
34
+ this.loading.set(false);
35
+ }
36
+ }
37
+ getLabel(value) {
38
+ const option = this.options().find(o => o.value === value);
39
+ return option?.label ?? (value ?? '—');
40
+ }
41
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EntityRefFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
42
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: EntityRefFieldComponent, isStandalone: true, selector: "ngx-entity-ref-field", inputs: { field: "field", control: "control", language: "language", readonly: "readonly", masked: "masked" }, ngImport: i0, template: `
43
+ <div class="ngx-field ngx-field--entity-ref" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
44
+ <label class="ngx-field__label">{{ field.label[language] || field.label['en'] }}</label>
45
+ @if (masked) {
46
+ <span class="ngx-field__value ngx-field__value--masked">XXXXXXXXX</span>
47
+ } @else if (readonly) {
48
+ <span class="ngx-field__value">{{ getLabel(control.value) }}</span>
49
+ } @else {
50
+ @if (loading()) {
51
+ <span class="ngx-field__value">Loading...</span>
52
+ } @else {
53
+ <select
54
+ class="ngx-field__input"
55
+ [formControl]="$any(control)"
56
+ [attr.disabled]="field.disabled ? true : null"
57
+ >
58
+ <option value="">{{ field.placeholder?.[language] || 'Select...' }}</option>
59
+ @for (option of options(); track option.value) {
60
+ <option [value]="option.value">{{ option.label }}</option>
61
+ }
62
+ </select>
63
+ }
64
+ @if (control.invalid && control.touched) {
65
+ <span class="ngx-field__error">This field has an error</span>
66
+ }
67
+ }
68
+ </div>
69
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] });
70
+ }
71
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EntityRefFieldComponent, decorators: [{
72
+ type: Component,
73
+ args: [{
74
+ selector: 'ngx-entity-ref-field',
75
+ standalone: true,
76
+ imports: [ReactiveFormsModule],
77
+ template: `
78
+ <div class="ngx-field ngx-field--entity-ref" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
79
+ <label class="ngx-field__label">{{ field.label[language] || field.label['en'] }}</label>
80
+ @if (masked) {
81
+ <span class="ngx-field__value ngx-field__value--masked">XXXXXXXXX</span>
82
+ } @else if (readonly) {
83
+ <span class="ngx-field__value">{{ getLabel(control.value) }}</span>
84
+ } @else {
85
+ @if (loading()) {
86
+ <span class="ngx-field__value">Loading...</span>
87
+ } @else {
88
+ <select
89
+ class="ngx-field__input"
90
+ [formControl]="$any(control)"
91
+ [attr.disabled]="field.disabled ? true : null"
92
+ >
93
+ <option value="">{{ field.placeholder?.[language] || 'Select...' }}</option>
94
+ @for (option of options(); track option.value) {
95
+ <option [value]="option.value">{{ option.label }}</option>
96
+ }
97
+ </select>
98
+ }
99
+ @if (control.invalid && control.touched) {
100
+ <span class="ngx-field__error">This field has an error</span>
101
+ }
102
+ }
103
+ </div>
104
+ `,
105
+ }]
106
+ }], propDecorators: { field: [{
107
+ type: Input
108
+ }], control: [{
109
+ type: Input
110
+ }], language: [{
111
+ type: Input
112
+ }], readonly: [{
113
+ type: Input
114
+ }], masked: [{
115
+ type: Input
116
+ }] } });
117
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50aXR5LXJlZi1maWVsZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL2ZpZWxkLXR5cGVzL2VudGl0eS1yZWYtZmllbGQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFVLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNqRSxPQUFPLEVBQW1CLG1CQUFtQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFdEUsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDbkYsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQzs7O0FBRXZDOzs7O0dBSUc7QUFrQ0gsTUFBTSxPQUFPLHVCQUF1QjtJQUN6QixLQUFLLENBQWU7SUFDcEIsT0FBTyxDQUFtQjtJQUMxQixRQUFRLEdBQVcsSUFBSSxDQUFDO0lBQ3hCLFFBQVEsR0FBWSxLQUFLLENBQUM7SUFDMUIsTUFBTSxHQUFZLEtBQUssQ0FBQztJQUVoQixpQkFBaUIsR0FBRyxNQUFNLENBQUMsd0JBQXdCLENBQUMsQ0FBQztJQUU3RCxPQUFPLEdBQUcsTUFBTSxDQUF1QyxFQUFFLENBQUMsQ0FBQztJQUMzRCxPQUFPLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBRWpDLEtBQUssQ0FBQyxRQUFRO1FBQ1osSUFBSSxJQUFJLENBQUMsTUFBTTtZQUFFLE9BQU8sQ0FBQyxvQ0FBb0M7UUFDN0QsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDeEQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN6RCxJQUFJLENBQUMsTUFBTTtZQUFFLE9BQU87UUFFcEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdkIsSUFBSSxDQUFDO1lBQ0gsTUFBTSxHQUFHLEdBQUcsTUFBTSxNQUFNLEVBQUUsQ0FBQztZQUMzQixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN4QixDQUFDO2dCQUFTLENBQUM7WUFDVCxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMxQixDQUFDO0lBQ0gsQ0FBQztJQUVELFFBQVEsQ0FBQyxLQUFVO1FBQ2pCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxLQUFLLEtBQUssQ0FBQyxDQUFDO1FBQzNELE9BQU8sTUFBTSxFQUFFLEtBQUssSUFBSSxDQUFDLEtBQUssSUFBSSxHQUFHLENBQUMsQ0FBQztJQUN6QyxDQUFDO3dHQTlCVSx1QkFBdUI7NEZBQXZCLHVCQUF1Qiw4TEE3QnhCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0EyQlQsMkRBNUJTLG1CQUFtQjs7NEZBOEJsQix1QkFBdUI7a0JBakNuQyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxzQkFBc0I7b0JBQ2hDLFVBQVUsRUFBRSxJQUFJO29CQUNoQixPQUFPLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQztvQkFDOUIsUUFBUSxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0EyQlQ7aUJBQ0Y7OEJBRVUsS0FBSztzQkFBYixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT25Jbml0LCBzaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFic3RyYWN0Q29udHJvbCwgUmVhY3RpdmVGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB0eXBlIHsgRmllbGRDb25maWcgfSBmcm9tICdAZHluYW1pYy1lbnRpdHkvY29yZSc7XG5pbXBvcnQgeyBFbnRpdHlSZWZSZWdpc3RyeVNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9lbnRpdHktcmVmLXJlZ2lzdHJ5LnNlcnZpY2UnO1xuaW1wb3J0IHsgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbi8qKlxuICogRW50aXR5UmVmRmllbGRDb21wb25lbnQg4oCUIHJlbmRlcnMgYSBkcm9wZG93biBwb3B1bGF0ZWQgYnkgYSBsb2FkZXIgZnJvbSBFbnRpdHlSZWZSZWdpc3RyeVNlcnZpY2UuXG4gKiBBRFItMDA2OiBPcHRpb25zIGNvbWUgT05MWSBmcm9tIHRoZSByZWdpc3RyeS4gTmV2ZXIgdmlhIEBJbnB1dCgpIGxvYWRlci5cbiAqIFVzZXMgZmllbGQuY29tcG9uZW50IChpZiBzZXQpIG9yIGZpZWxkLmlkIGFzIHRoZSByZWdpc3RyeSBsb29rdXAga2V5LlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduZ3gtZW50aXR5LXJlZi1maWVsZCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtSZWFjdGl2ZUZvcm1zTW9kdWxlXSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2IGNsYXNzPVwibmd4LWZpZWxkIG5neC1maWVsZC0tZW50aXR5LXJlZlwiIFtjbGFzcy5uZ3gtZmllbGQtLXJlYWRvbmx5XT1cInJlYWRvbmx5XCIgW2NsYXNzLm5neC1maWVsZC0tbWFza2VkXT1cIm1hc2tlZFwiPlxuICAgICAgPGxhYmVsIGNsYXNzPVwibmd4LWZpZWxkX19sYWJlbFwiPnt7IGZpZWxkLmxhYmVsW2xhbmd1YWdlXSB8fCBmaWVsZC5sYWJlbFsnZW4nXSB9fTwvbGFiZWw+XG4gICAgICBAaWYgKG1hc2tlZCkge1xuICAgICAgICA8c3BhbiBjbGFzcz1cIm5neC1maWVsZF9fdmFsdWUgbmd4LWZpZWxkX192YWx1ZS0tbWFza2VkXCI+WFhYWFhYWFhYPC9zcGFuPlxuICAgICAgfSBAZWxzZSBpZiAocmVhZG9ubHkpIHtcbiAgICAgICAgPHNwYW4gY2xhc3M9XCJuZ3gtZmllbGRfX3ZhbHVlXCI+e3sgZ2V0TGFiZWwoY29udHJvbC52YWx1ZSkgfX08L3NwYW4+XG4gICAgICB9IEBlbHNlIHtcbiAgICAgICAgQGlmIChsb2FkaW5nKCkpIHtcbiAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5neC1maWVsZF9fdmFsdWVcIj5Mb2FkaW5nLi4uPC9zcGFuPlxuICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICA8c2VsZWN0XG4gICAgICAgICAgICBjbGFzcz1cIm5neC1maWVsZF9faW5wdXRcIlxuICAgICAgICAgICAgW2Zvcm1Db250cm9sXT1cIiRhbnkoY29udHJvbClcIlxuICAgICAgICAgICAgW2F0dHIuZGlzYWJsZWRdPVwiZmllbGQuZGlzYWJsZWQgPyB0cnVlIDogbnVsbFwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPnt7IGZpZWxkLnBsYWNlaG9sZGVyPy5bbGFuZ3VhZ2VdIHx8ICdTZWxlY3QuLi4nIH19PC9vcHRpb24+XG4gICAgICAgICAgICBAZm9yIChvcHRpb24gb2Ygb3B0aW9ucygpOyB0cmFjayBvcHRpb24udmFsdWUpIHtcbiAgICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwib3B0aW9uLnZhbHVlXCI+e3sgb3B0aW9uLmxhYmVsIH19PC9vcHRpb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgIH1cbiAgICAgICAgQGlmIChjb250cm9sLmludmFsaWQgJiYgY29udHJvbC50b3VjaGVkKSB7XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJuZ3gtZmllbGRfX2Vycm9yXCI+VGhpcyBmaWVsZCBoYXMgYW4gZXJyb3I8L3NwYW4+XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICA8L2Rpdj5cbiAgYCxcbn0pXG5leHBvcnQgY2xhc3MgRW50aXR5UmVmRmllbGRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBASW5wdXQoKSBmaWVsZCE6IEZpZWxkQ29uZmlnO1xuICBASW5wdXQoKSBjb250cm9sITogQWJzdHJhY3RDb250cm9sO1xuICBASW5wdXQoKSBsYW5ndWFnZTogc3RyaW5nID0gJ2VuJztcbiAgQElucHV0KCkgcmVhZG9ubHk6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgbWFza2VkOiBib29sZWFuID0gZmFsc2U7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBlbnRpdHlSZWZSZWdpc3RyeSA9IGluamVjdChFbnRpdHlSZWZSZWdpc3RyeVNlcnZpY2UpO1xuXG4gIHJlYWRvbmx5IG9wdGlvbnMgPSBzaWduYWw8QXJyYXk8eyB2YWx1ZTogYW55OyBsYWJlbDogc3RyaW5nIH0+PihbXSk7XG4gIHJlYWRvbmx5IGxvYWRpbmcgPSBzaWduYWwoZmFsc2UpO1xuXG4gIGFzeW5jIG5nT25Jbml0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLm1hc2tlZCkgcmV0dXJuOyAvLyBObyBuZWVkIHRvIGxvYWQgb3B0aW9ucyBpZiBtYXNrZWRcbiAgICBjb25zdCBlbnRpdHlLZXkgPSB0aGlzLmZpZWxkLmNvbXBvbmVudCA/PyB0aGlzLmZpZWxkLmlkO1xuICAgIGNvbnN0IGxvYWRlciA9IHRoaXMuZW50aXR5UmVmUmVnaXN0cnkucmVzb2x2ZShlbnRpdHlLZXkpO1xuICAgIGlmICghbG9hZGVyKSByZXR1cm47XG5cbiAgICB0aGlzLmxvYWRpbmcuc2V0KHRydWUpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByYXcgPSBhd2FpdCBsb2FkZXIoKTtcbiAgICAgIHRoaXMub3B0aW9ucy5zZXQocmF3KTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5sb2FkaW5nLnNldChmYWxzZSk7XG4gICAgfVxuICB9XG5cbiAgZ2V0TGFiZWwodmFsdWU6IGFueSk6IHN0cmluZyB7XG4gICAgY29uc3Qgb3B0aW9uID0gdGhpcy5vcHRpb25zKCkuZmluZChvID0+IG8udmFsdWUgPT09IHZhbHVlKTtcbiAgICByZXR1cm4gb3B0aW9uPy5sYWJlbCA/PyAodmFsdWUgPz8gJ+KAlCcpO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,91 @@
1
+ import { Component, Input } from '@angular/core';
2
+ import { ReactiveFormsModule } from '@angular/forms';
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "@angular/forms";
5
+ export class MultiSelectFieldComponent {
6
+ field;
7
+ control;
8
+ language = 'en';
9
+ readonly = false;
10
+ masked = false;
11
+ getLabels(values) {
12
+ if (!Array.isArray(values) || !values.length)
13
+ return '—';
14
+ return values
15
+ .map(v => {
16
+ const opt = (this.field.options || []).find(o => o.value === v);
17
+ return opt ? (opt.label[this.language] || opt.label['en']) : String(v);
18
+ })
19
+ .join(', ');
20
+ }
21
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MultiSelectFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
22
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: MultiSelectFieldComponent, isStandalone: true, selector: "ngx-multi-select-field", inputs: { field: "field", control: "control", language: "language", readonly: "readonly", masked: "masked" }, ngImport: i0, template: `
23
+ <div class="ngx-field ngx-field--multiSelect" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
24
+ <label class="ngx-field__label">{{ field.label[language] || field.label['en'] }}</label>
25
+ @if (masked) {
26
+ <span class="ngx-field__value ngx-field__value--masked">XXXXXXXXX</span>
27
+ } @else if (readonly) {
28
+ <span class="ngx-field__value">{{ getLabels(control.value) }}</span>
29
+ } @else {
30
+ <select
31
+ class="ngx-field__input"
32
+ [formControl]="$any(control)"
33
+ [attr.disabled]="field.disabled ? true : null"
34
+ multiple
35
+ size="4"
36
+ >
37
+ @for (option of field.options || []; track option.value) {
38
+ <option [value]="option.value">{{ option.label[language] || option.label['en'] }}</option>
39
+ }
40
+ </select>
41
+ @if (control.invalid && control.touched) {
42
+ <span class="ngx-field__error">This field has an error</span>
43
+ }
44
+ }
45
+ </div>
46
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.SelectMultipleControlValueAccessor, selector: "select[multiple][formControlName],select[multiple][formControl],select[multiple][ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] });
47
+ }
48
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MultiSelectFieldComponent, decorators: [{
49
+ type: Component,
50
+ args: [{
51
+ selector: 'ngx-multi-select-field',
52
+ standalone: true,
53
+ imports: [ReactiveFormsModule],
54
+ template: `
55
+ <div class="ngx-field ngx-field--multiSelect" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
56
+ <label class="ngx-field__label">{{ field.label[language] || field.label['en'] }}</label>
57
+ @if (masked) {
58
+ <span class="ngx-field__value ngx-field__value--masked">XXXXXXXXX</span>
59
+ } @else if (readonly) {
60
+ <span class="ngx-field__value">{{ getLabels(control.value) }}</span>
61
+ } @else {
62
+ <select
63
+ class="ngx-field__input"
64
+ [formControl]="$any(control)"
65
+ [attr.disabled]="field.disabled ? true : null"
66
+ multiple
67
+ size="4"
68
+ >
69
+ @for (option of field.options || []; track option.value) {
70
+ <option [value]="option.value">{{ option.label[language] || option.label['en'] }}</option>
71
+ }
72
+ </select>
73
+ @if (control.invalid && control.touched) {
74
+ <span class="ngx-field__error">This field has an error</span>
75
+ }
76
+ }
77
+ </div>
78
+ `,
79
+ }]
80
+ }], propDecorators: { field: [{
81
+ type: Input
82
+ }], control: [{
83
+ type: Input
84
+ }], language: [{
85
+ type: Input
86
+ }], readonly: [{
87
+ type: Input
88
+ }], masked: [{
89
+ type: Input
90
+ }] } });
91
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVsdGktc2VsZWN0LWZpZWxkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvZmllbGQtdHlwZXMvbXVsdGktc2VsZWN0LWZpZWxkLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNqRCxPQUFPLEVBQW1CLG1CQUFtQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7OztBQWlDdEUsTUFBTSxPQUFPLHlCQUF5QjtJQUMzQixLQUFLLENBQWU7SUFDcEIsT0FBTyxDQUFtQjtJQUMxQixRQUFRLEdBQVcsSUFBSSxDQUFDO0lBQ3hCLFFBQVEsR0FBWSxLQUFLLENBQUM7SUFDMUIsTUFBTSxHQUFZLEtBQUssQ0FBQztJQUVqQyxTQUFTLENBQUMsTUFBYTtRQUNyQixJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNO1lBQUUsT0FBTyxHQUFHLENBQUM7UUFDekQsT0FBTyxNQUFNO2FBQ1YsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ1AsTUFBTSxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDO1lBQ2hFLE9BQU8sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3pFLENBQUMsQ0FBQzthQUNELElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNoQixDQUFDO3dHQWZVLHlCQUF5Qjs0RkFBekIseUJBQXlCLGdNQTFCMUI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXdCVCwyREF6QlMsbUJBQW1COzs0RkEyQmxCLHlCQUF5QjtrQkE5QnJDLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLHdCQUF3QjtvQkFDbEMsVUFBVSxFQUFFLElBQUk7b0JBQ2hCLE9BQU8sRUFBRSxDQUFDLG1CQUFtQixDQUFDO29CQUM5QixRQUFRLEVBQUU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXdCVDtpQkFDRjs4QkFFVSxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBYnN0cmFjdENvbnRyb2wsIFJlYWN0aXZlRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgdHlwZSB7IEZpZWxkQ29uZmlnIH0gZnJvbSAnQGR5bmFtaWMtZW50aXR5L2NvcmUnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduZ3gtbXVsdGktc2VsZWN0LWZpZWxkJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1JlYWN0aXZlRm9ybXNNb2R1bGVdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgY2xhc3M9XCJuZ3gtZmllbGQgbmd4LWZpZWxkLS1tdWx0aVNlbGVjdFwiIFtjbGFzcy5uZ3gtZmllbGQtLXJlYWRvbmx5XT1cInJlYWRvbmx5XCIgW2NsYXNzLm5neC1maWVsZC0tbWFza2VkXT1cIm1hc2tlZFwiPlxuICAgICAgPGxhYmVsIGNsYXNzPVwibmd4LWZpZWxkX19sYWJlbFwiPnt7IGZpZWxkLmxhYmVsW2xhbmd1YWdlXSB8fCBmaWVsZC5sYWJlbFsnZW4nXSB9fTwvbGFiZWw+XG4gICAgICBAaWYgKG1hc2tlZCkge1xuICAgICAgICA8c3BhbiBjbGFzcz1cIm5neC1maWVsZF9fdmFsdWUgbmd4LWZpZWxkX192YWx1ZS0tbWFza2VkXCI+WFhYWFhYWFhYPC9zcGFuPlxuICAgICAgfSBAZWxzZSBpZiAocmVhZG9ubHkpIHtcbiAgICAgICAgPHNwYW4gY2xhc3M9XCJuZ3gtZmllbGRfX3ZhbHVlXCI+e3sgZ2V0TGFiZWxzKGNvbnRyb2wudmFsdWUpIH19PC9zcGFuPlxuICAgICAgfSBAZWxzZSB7XG4gICAgICAgIDxzZWxlY3RcbiAgICAgICAgICBjbGFzcz1cIm5neC1maWVsZF9faW5wdXRcIlxuICAgICAgICAgIFtmb3JtQ29udHJvbF09XCIkYW55KGNvbnRyb2wpXCJcbiAgICAgICAgICBbYXR0ci5kaXNhYmxlZF09XCJmaWVsZC5kaXNhYmxlZCA/IHRydWUgOiBudWxsXCJcbiAgICAgICAgICBtdWx0aXBsZVxuICAgICAgICAgIHNpemU9XCI0XCJcbiAgICAgICAgPlxuICAgICAgICAgIEBmb3IgKG9wdGlvbiBvZiBmaWVsZC5vcHRpb25zIHx8IFtdOyB0cmFjayBvcHRpb24udmFsdWUpIHtcbiAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cIm9wdGlvbi52YWx1ZVwiPnt7IG9wdGlvbi5sYWJlbFtsYW5ndWFnZV0gfHwgb3B0aW9uLmxhYmVsWydlbiddIH19PC9vcHRpb24+XG4gICAgICAgICAgfVxuICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgQGlmIChjb250cm9sLmludmFsaWQgJiYgY29udHJvbC50b3VjaGVkKSB7XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJuZ3gtZmllbGRfX2Vycm9yXCI+VGhpcyBmaWVsZCBoYXMgYW4gZXJyb3I8L3NwYW4+XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICA8L2Rpdj5cbiAgYCxcbn0pXG5leHBvcnQgY2xhc3MgTXVsdGlTZWxlY3RGaWVsZENvbXBvbmVudCB7XG4gIEBJbnB1dCgpIGZpZWxkITogRmllbGRDb25maWc7XG4gIEBJbnB1dCgpIGNvbnRyb2whOiBBYnN0cmFjdENvbnRyb2w7XG4gIEBJbnB1dCgpIGxhbmd1YWdlOiBzdHJpbmcgPSAnZW4nO1xuICBASW5wdXQoKSByZWFkb25seTogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBtYXNrZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBnZXRMYWJlbHModmFsdWVzOiBhbnlbXSk6IHN0cmluZyB7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlcykgfHwgIXZhbHVlcy5sZW5ndGgpIHJldHVybiAn4oCUJztcbiAgICByZXR1cm4gdmFsdWVzXG4gICAgICAubWFwKHYgPT4ge1xuICAgICAgICBjb25zdCBvcHQgPSAodGhpcy5maWVsZC5vcHRpb25zIHx8IFtdKS5maW5kKG8gPT4gby52YWx1ZSA9PT0gdik7XG4gICAgICAgIHJldHVybiBvcHQgPyAob3B0LmxhYmVsW3RoaXMubGFuZ3VhZ2VdIHx8IG9wdC5sYWJlbFsnZW4nXSkgOiBTdHJpbmcodik7XG4gICAgICB9KVxuICAgICAgLmpvaW4oJywgJyk7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,73 @@
1
+ import { Component, Input } from '@angular/core';
2
+ import { ReactiveFormsModule } from '@angular/forms';
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "@angular/forms";
5
+ export class NumberFieldComponent {
6
+ field;
7
+ control;
8
+ language = 'en';
9
+ readonly = false;
10
+ masked = false;
11
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NumberFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: NumberFieldComponent, isStandalone: true, selector: "ngx-number-field", inputs: { field: "field", control: "control", language: "language", readonly: "readonly", masked: "masked" }, ngImport: i0, template: `
13
+ <div class="ngx-field ngx-field--number" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
14
+ <label class="ngx-field__label">{{ field.label[language] || field.label['en'] }}</label>
15
+ @if (masked) {
16
+ <span class="ngx-field__value ngx-field__value--masked">XXXXXXXXX</span>
17
+ } @else if (readonly) {
18
+ <span class="ngx-field__value">{{ control.value }}</span>
19
+ } @else {
20
+ <input
21
+ class="ngx-field__input"
22
+ type="number"
23
+ [formControl]="$any(control)"
24
+ [placeholder]="field.placeholder?.[language] || field.placeholder?.['en'] || ''"
25
+ [attr.disabled]="field.disabled ? true : null"
26
+ />
27
+ @if (control.invalid && control.touched) {
28
+ <span class="ngx-field__error">This field has an error</span>
29
+ }
30
+ }
31
+ </div>
32
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] });
33
+ }
34
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NumberFieldComponent, decorators: [{
35
+ type: Component,
36
+ args: [{
37
+ selector: 'ngx-number-field',
38
+ standalone: true,
39
+ imports: [ReactiveFormsModule],
40
+ template: `
41
+ <div class="ngx-field ngx-field--number" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
42
+ <label class="ngx-field__label">{{ field.label[language] || field.label['en'] }}</label>
43
+ @if (masked) {
44
+ <span class="ngx-field__value ngx-field__value--masked">XXXXXXXXX</span>
45
+ } @else if (readonly) {
46
+ <span class="ngx-field__value">{{ control.value }}</span>
47
+ } @else {
48
+ <input
49
+ class="ngx-field__input"
50
+ type="number"
51
+ [formControl]="$any(control)"
52
+ [placeholder]="field.placeholder?.[language] || field.placeholder?.['en'] || ''"
53
+ [attr.disabled]="field.disabled ? true : null"
54
+ />
55
+ @if (control.invalid && control.touched) {
56
+ <span class="ngx-field__error">This field has an error</span>
57
+ }
58
+ }
59
+ </div>
60
+ `,
61
+ }]
62
+ }], propDecorators: { field: [{
63
+ type: Input
64
+ }], control: [{
65
+ type: Input
66
+ }], language: [{
67
+ type: Input
68
+ }], readonly: [{
69
+ type: Input
70
+ }], masked: [{
71
+ type: Input
72
+ }] } });
73
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnVtYmVyLWZpZWxkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvZmllbGQtdHlwZXMvbnVtYmVyLWZpZWxkLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNqRCxPQUFPLEVBQW1CLG1CQUFtQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7OztBQTZCdEUsTUFBTSxPQUFPLG9CQUFvQjtJQUN0QixLQUFLLENBQWU7SUFDcEIsT0FBTyxDQUFtQjtJQUMxQixRQUFRLEdBQVcsSUFBSSxDQUFDO0lBQ3hCLFFBQVEsR0FBWSxLQUFLLENBQUM7SUFDMUIsTUFBTSxHQUFZLEtBQUssQ0FBQzt3R0FMdEIsb0JBQW9COzRGQUFwQixvQkFBb0IsMExBdEJyQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQlQsMkRBckJTLG1CQUFtQjs7NEZBdUJsQixvQkFBb0I7a0JBMUJoQyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxrQkFBa0I7b0JBQzVCLFVBQVUsRUFBRSxJQUFJO29CQUNoQixPQUFPLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQztvQkFDOUIsUUFBUSxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9CVDtpQkFDRjs4QkFFVSxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBYnN0cmFjdENvbnRyb2wsIFJlYWN0aXZlRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgdHlwZSB7IEZpZWxkQ29uZmlnIH0gZnJvbSAnQGR5bmFtaWMtZW50aXR5L2NvcmUnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduZ3gtbnVtYmVyLWZpZWxkJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1JlYWN0aXZlRm9ybXNNb2R1bGVdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgY2xhc3M9XCJuZ3gtZmllbGQgbmd4LWZpZWxkLS1udW1iZXJcIiBbY2xhc3Mubmd4LWZpZWxkLS1yZWFkb25seV09XCJyZWFkb25seVwiIFtjbGFzcy5uZ3gtZmllbGQtLW1hc2tlZF09XCJtYXNrZWRcIj5cbiAgICAgIDxsYWJlbCBjbGFzcz1cIm5neC1maWVsZF9fbGFiZWxcIj57eyBmaWVsZC5sYWJlbFtsYW5ndWFnZV0gfHwgZmllbGQubGFiZWxbJ2VuJ10gfX08L2xhYmVsPlxuICAgICAgQGlmIChtYXNrZWQpIHtcbiAgICAgICAgPHNwYW4gY2xhc3M9XCJuZ3gtZmllbGRfX3ZhbHVlIG5neC1maWVsZF9fdmFsdWUtLW1hc2tlZFwiPlhYWFhYWFhYWDwvc3Bhbj5cbiAgICAgIH0gQGVsc2UgaWYgKHJlYWRvbmx5KSB7XG4gICAgICAgIDxzcGFuIGNsYXNzPVwibmd4LWZpZWxkX192YWx1ZVwiPnt7IGNvbnRyb2wudmFsdWUgfX08L3NwYW4+XG4gICAgICB9IEBlbHNlIHtcbiAgICAgICAgPGlucHV0XG4gICAgICAgICAgY2xhc3M9XCJuZ3gtZmllbGRfX2lucHV0XCJcbiAgICAgICAgICB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwiJGFueShjb250cm9sKVwiXG4gICAgICAgICAgW3BsYWNlaG9sZGVyXT1cImZpZWxkLnBsYWNlaG9sZGVyPy5bbGFuZ3VhZ2VdIHx8IGZpZWxkLnBsYWNlaG9sZGVyPy5bJ2VuJ10gfHwgJydcIlxuICAgICAgICAgIFthdHRyLmRpc2FibGVkXT1cImZpZWxkLmRpc2FibGVkID8gdHJ1ZSA6IG51bGxcIlxuICAgICAgICAvPlxuICAgICAgICBAaWYgKGNvbnRyb2wuaW52YWxpZCAmJiBjb250cm9sLnRvdWNoZWQpIHtcbiAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5neC1maWVsZF9fZXJyb3JcIj5UaGlzIGZpZWxkIGhhcyBhbiBlcnJvcjwvc3Bhbj5cbiAgICAgICAgfVxuICAgICAgfVxuICAgIDwvZGl2PlxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBOdW1iZXJGaWVsZENvbXBvbmVudCB7XG4gIEBJbnB1dCgpIGZpZWxkITogRmllbGRDb25maWc7XG4gIEBJbnB1dCgpIGNvbnRyb2whOiBBYnN0cmFjdENvbnRyb2w7XG4gIEBJbnB1dCgpIGxhbmd1YWdlOiBzdHJpbmcgPSAnZW4nO1xuICBASW5wdXQoKSByZWFkb25seTogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBtYXNrZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbn1cbiJdfQ==