@yuuvis/client-framework 3.2.1 → 3.3.0
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/fesm2022/yuuvis-client-framework-forms.mjs +124 -69
- package/fesm2022/yuuvis-client-framework-forms.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-query-list.mjs +33 -9
- package/fesm2022/yuuvis-client-framework-query-list.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-simple-search.mjs +3 -1
- package/fesm2022/yuuvis-client-framework-simple-search.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-tile-list.mjs +7 -5
- package/fesm2022/yuuvis-client-framework-tile-list.mjs.map +1 -1
- package/package.json +5 -5
- package/types/yuuvis-client-framework-forms.d.ts +21 -11
- package/types/yuuvis-client-framework-query-list.d.ts +19 -2
- package/types/yuuvis-client-framework-tile-list.d.ts +4 -2
|
@@ -48,40 +48,45 @@ class CatalogComponent extends AbstractMatFormField {
|
|
|
48
48
|
super(...arguments);
|
|
49
49
|
this.#system = inject(SystemService);
|
|
50
50
|
this.#dRef = inject(DestroyRef);
|
|
51
|
-
this
|
|
51
|
+
this.#translate = inject(TranslateService);
|
|
52
52
|
this.readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
|
|
53
53
|
this.multiple = input(false, ...(ngDevMode ? [{ debugName: "multiple" }] : /* istanbul ignore next */ []));
|
|
54
54
|
this._options = signal([], ...(ngDevMode ? [{ debugName: "_options" }] : /* istanbul ignore next */ []));
|
|
55
55
|
this.options = input([], ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
56
|
+
/**
|
|
57
|
+
* Additional semantics for the form element.
|
|
58
|
+
*/
|
|
59
|
+
this.classifications = input([], ...(ngDevMode ? [{ debugName: "classifications" }] : /* istanbul ignore next */ []));
|
|
60
|
+
/**
|
|
61
|
+
* Possibles values are `EDIT` (default),`SEARCH`,`CREATE`. In search situation validation
|
|
62
|
+
* of the form element will be turned off, so you are able to enter search terms that do not
|
|
63
|
+
* meet the elements validators.
|
|
64
|
+
*/
|
|
65
|
+
this.situation = input(...(ngDevMode ? [undefined, { debugName: "situation" }] : /* istanbul ignore next */ []));
|
|
66
|
+
this.ngControl = injectNgControl(this);
|
|
67
|
+
this.formCtrl = new FormControl(undefined);
|
|
56
68
|
this.#optionsEffect = effect(() => {
|
|
57
69
|
untracked(() => {
|
|
58
70
|
this.#setOptions(this.options() || [], false);
|
|
59
71
|
});
|
|
60
72
|
}, ...(ngDevMode ? [{ debugName: "#optionsEffect" }] : /* istanbul ignore next */ []));
|
|
61
|
-
/**
|
|
62
|
-
* Additional semantics for the form element.
|
|
63
|
-
*/
|
|
64
|
-
this.classifications = input([], ...(ngDevMode ? [{ debugName: "classifications" }] : /* istanbul ignore next */ []));
|
|
65
73
|
this.#classificationEffect = effect(() => {
|
|
66
74
|
const cls = this.classifications();
|
|
67
75
|
untracked(() => {
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
76
|
+
const cle = this.#system
|
|
77
|
+
.getClassifications(cls)
|
|
78
|
+
.get(Classification.STRING_CATALOG);
|
|
79
|
+
if (cle?.options) {
|
|
80
|
+
this.#setOptions(cle.options, false);
|
|
71
81
|
}
|
|
72
82
|
});
|
|
73
83
|
}, ...(ngDevMode ? [{ debugName: "#classificationEffect" }] : /* istanbul ignore next */ []));
|
|
74
|
-
/**
|
|
75
|
-
* Possibles values are `EDIT` (default),`SEARCH`,`CREATE`. In search situation validation of the form element will be turned off, so you are able to enter search terms that do not meet the elements validators.
|
|
76
|
-
*/
|
|
77
|
-
this.situation = input(...(ngDevMode ? [undefined, { debugName: "situation" }] : /* istanbul ignore next */ []));
|
|
78
|
-
this.ngControl = injectNgControl(this);
|
|
79
|
-
this.fc = new FormControl(undefined);
|
|
80
84
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
81
85
|
this.propagateChange = (_) => { };
|
|
82
86
|
}
|
|
83
87
|
#system;
|
|
84
88
|
#dRef;
|
|
89
|
+
#translate;
|
|
85
90
|
#optionsEffect;
|
|
86
91
|
#classificationEffect;
|
|
87
92
|
#onValueChange(val) {
|
|
@@ -90,57 +95,60 @@ class CatalogComponent extends AbstractMatFormField {
|
|
|
90
95
|
}
|
|
91
96
|
#setOptions(options, translate) {
|
|
92
97
|
if (translate) {
|
|
93
|
-
this._options.set(options.map((
|
|
94
|
-
label: this
|
|
95
|
-
value:
|
|
98
|
+
this._options.set(options.map((opt) => ({
|
|
99
|
+
label: this.#translate.instant(opt),
|
|
100
|
+
value: opt
|
|
96
101
|
})));
|
|
97
102
|
}
|
|
98
103
|
else {
|
|
99
|
-
this._options.set(options.map((
|
|
100
|
-
label:
|
|
101
|
-
value:
|
|
104
|
+
this._options.set(options.map((opt) => ({
|
|
105
|
+
label: opt,
|
|
106
|
+
value: opt
|
|
102
107
|
})));
|
|
103
108
|
}
|
|
104
109
|
}
|
|
105
110
|
writeValue(value) {
|
|
106
111
|
this.value = value;
|
|
107
|
-
this.
|
|
112
|
+
this.formCtrl.setValue(value, { emitEvent: false });
|
|
108
113
|
}
|
|
114
|
+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
|
|
109
115
|
registerOnChange(fn) {
|
|
110
116
|
this.propagateChange = fn;
|
|
111
117
|
}
|
|
112
118
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
113
|
-
registerOnTouched(
|
|
119
|
+
registerOnTouched() { }
|
|
114
120
|
setDisabledState(isDisabled) {
|
|
115
121
|
if (isDisabled) {
|
|
116
|
-
this.
|
|
122
|
+
this.formCtrl.disable();
|
|
117
123
|
}
|
|
118
124
|
else {
|
|
119
|
-
this.
|
|
125
|
+
this.formCtrl.enable();
|
|
120
126
|
}
|
|
121
127
|
this.disabled = isDisabled;
|
|
122
128
|
}
|
|
123
129
|
ngOnInit() {
|
|
124
130
|
if (this.required)
|
|
125
|
-
this.
|
|
126
|
-
this.
|
|
127
|
-
this.errorState = FormUtils.getErrorState(this.
|
|
131
|
+
this.formCtrl.setValidators(Validators.required);
|
|
132
|
+
this.formCtrl.statusChanges.pipe(takeUntilDestroyed(this.#dRef)).subscribe(() => {
|
|
133
|
+
this.errorState = FormUtils.getErrorState(this.formCtrl);
|
|
128
134
|
if (this.ngControl?.control) {
|
|
129
|
-
this.ngControl.control.setErrors(this.
|
|
135
|
+
this.ngControl.control.setErrors(this.formCtrl.errors);
|
|
130
136
|
}
|
|
131
137
|
});
|
|
132
|
-
this.
|
|
133
|
-
this.
|
|
138
|
+
this.formCtrl.updateValueAndValidity();
|
|
139
|
+
this.formCtrl.valueChanges
|
|
140
|
+
.pipe(takeUntilDestroyed(this.#dRef))
|
|
141
|
+
.subscribe((value) => this.#onValueChange(value));
|
|
134
142
|
}
|
|
135
143
|
ngOnDestroy() {
|
|
136
144
|
super.onNgOnDestroy();
|
|
137
145
|
}
|
|
138
146
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: CatalogComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
139
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: CatalogComponent, isStandalone: true, selector: "yuv-catalog", inputs: { readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, classifications: { classPropertyName: "classifications", publicName: "classifications", isSignal: true, isRequired: false, transformFunction: null }, situation: { classPropertyName: "situation", publicName: "situation", isSignal: true, isRequired: false, transformFunction: null } }, providers: [{ provide: MatFormFieldControl, useExisting: CatalogComponent }], usesInheritance: true, ngImport: i0, template: "<mat-select [multiple]=\"multiple()\" [disabled]=\"readonly()\" [formControl]=\"
|
|
147
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: CatalogComponent, isStandalone: true, selector: "yuv-catalog", inputs: { readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, classifications: { classPropertyName: "classifications", publicName: "classifications", isSignal: true, isRequired: false, transformFunction: null }, situation: { classPropertyName: "situation", publicName: "situation", isSignal: true, isRequired: false, transformFunction: null } }, providers: [{ provide: MatFormFieldControl, useExisting: CatalogComponent }], usesInheritance: true, ngImport: i0, template: "<mat-select [multiple]=\"multiple()\" [disabled]=\"readonly()\" [formControl]=\"formCtrl\">\n @for (o of _options(); track o) {\n <mat-option [value]=\"o.value\">{{ o.label }}</mat-option>\n }\n</mat-select>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] }); }
|
|
140
148
|
}
|
|
141
149
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: CatalogComponent, decorators: [{
|
|
142
150
|
type: Component,
|
|
143
|
-
args: [{ selector: 'yuv-catalog', imports: [MatSelectModule, ReactiveFormsModule], providers: [{ provide: MatFormFieldControl, useExisting: CatalogComponent }], template: "<mat-select [multiple]=\"multiple()\" [disabled]=\"readonly()\" [formControl]=\"
|
|
151
|
+
args: [{ selector: 'yuv-catalog', imports: [MatSelectModule, ReactiveFormsModule], providers: [{ provide: MatFormFieldControl, useExisting: CatalogComponent }], template: "<mat-select [multiple]=\"multiple()\" [disabled]=\"readonly()\" [formControl]=\"formCtrl\">\n @for (o of _options(); track o) {\n <mat-option [value]=\"o.value\">{{ o.label }}</mat-option>\n }\n</mat-select>\n" }]
|
|
144
152
|
}], propDecorators: { readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], classifications: [{ type: i0.Input, args: [{ isSignal: true, alias: "classifications", required: false }] }], situation: [{ type: i0.Input, args: [{ isSignal: true, alias: "situation", required: false }] }] } });
|
|
145
153
|
|
|
146
154
|
class EditTableDataComponent {
|
|
@@ -527,25 +535,6 @@ class DatetimeComponent extends AbstractMatFormField {
|
|
|
527
535
|
}
|
|
528
536
|
#dRef;
|
|
529
537
|
#localeEffect;
|
|
530
|
-
// constructor() {
|
|
531
|
-
// super();
|
|
532
|
-
// this.fc.valueChanges.pipe(takeUntilDestroyed()).subscribe((v) => this.onValueChange(v));
|
|
533
|
-
// this.fc.statusChanges.pipe(takeUntilDestroyed()).subscribe((v) => {
|
|
534
|
-
// this.errorState = FormUtils.getErrorState(this.fc);
|
|
535
|
-
// if (this.ngControl?.control) {
|
|
536
|
-
// this.ngControl.control.setErrors(this.fc.errors);
|
|
537
|
-
// }
|
|
538
|
-
// // this.errorState = v === 'INVALID';
|
|
539
|
-
// // this.ngControl?.control?.setErrors(this.errorState ? { datecontrol: true } : null);
|
|
540
|
-
// });
|
|
541
|
-
// }
|
|
542
|
-
#setLabels() {
|
|
543
|
-
this.labels = {
|
|
544
|
-
calendarApply: this.translate.instant('yuv.form.element.datetime.calendar.select'),
|
|
545
|
-
calendarCancel: this.translate.instant('yuv.form.element.datetime.calendar.cancel'),
|
|
546
|
-
shortcut: { today: this.translate.instant('yuv.form.element.datetime.calendar.today') }
|
|
547
|
-
};
|
|
548
|
-
}
|
|
549
538
|
openCalendar() {
|
|
550
539
|
this.pickerCmp().openCalendar();
|
|
551
540
|
}
|
|
@@ -563,14 +552,6 @@ class DatetimeComponent extends AbstractMatFormField {
|
|
|
563
552
|
// this.fc.setValue(this.value, { emitEvent: false });
|
|
564
553
|
this.fc.patchValue(this.value, { emitEvent: false, onlySelf: true });
|
|
565
554
|
}
|
|
566
|
-
#propagate(value) {
|
|
567
|
-
let propagateValue = value;
|
|
568
|
-
if (propagateValue && !this.withTime()) {
|
|
569
|
-
// returns a string in the format 'yyyy-MM-dd' like expected for resolution date
|
|
570
|
-
propagateValue = `${propagateValue.getFullYear()}-${(propagateValue.getMonth() + 1).toString().padStart(2, '0')}-${propagateValue.getDate().toString().padStart(2, '0')}`;
|
|
571
|
-
}
|
|
572
|
-
this.propagateChange(propagateValue);
|
|
573
|
-
}
|
|
574
555
|
registerOnChange(fn) {
|
|
575
556
|
this.propagateChange = fn;
|
|
576
557
|
}
|
|
@@ -591,15 +572,32 @@ class DatetimeComponent extends AbstractMatFormField {
|
|
|
591
572
|
ngOnInit() {
|
|
592
573
|
this.focusHandled.set(true);
|
|
593
574
|
this.#setLabels();
|
|
594
|
-
this.translate.onLangChange.subscribe((
|
|
595
|
-
this.fc.valueChanges.pipe(takeUntilDestroyed(this.#dRef)).subscribe((
|
|
596
|
-
this.fc.statusChanges.pipe(takeUntilDestroyed(this.#dRef)).subscribe((
|
|
575
|
+
this.translate.onLangChange.subscribe((evt) => this._locale.set(evt.lang));
|
|
576
|
+
this.fc.valueChanges.pipe(takeUntilDestroyed(this.#dRef)).subscribe((value) => this.onValueChange(value));
|
|
577
|
+
this.fc.statusChanges.pipe(takeUntilDestroyed(this.#dRef)).subscribe(() => {
|
|
597
578
|
this.errorState = FormUtils.getErrorState(this.fc);
|
|
598
579
|
if (this.ngControl?.control) {
|
|
599
580
|
this.ngControl.control.setErrors(this.fc.errors);
|
|
600
581
|
}
|
|
601
582
|
});
|
|
602
583
|
}
|
|
584
|
+
#setLabels() {
|
|
585
|
+
this.labels = {
|
|
586
|
+
calendarApply: this.translate.instant('yuv.form.element.datetime.calendar.select'),
|
|
587
|
+
calendarCancel: this.translate.instant('yuv.form.element.datetime.calendar.cancel'),
|
|
588
|
+
shortcut: { today: this.translate.instant('yuv.form.element.datetime.calendar.today') }
|
|
589
|
+
};
|
|
590
|
+
}
|
|
591
|
+
#propagate(value) {
|
|
592
|
+
let propagateValue = value;
|
|
593
|
+
if (propagateValue && !this.withTime()) {
|
|
594
|
+
// returns a string in the format 'yyyy-MM-dd' like expected for resolution date
|
|
595
|
+
const month = (propagateValue.getMonth() + 1).toString().padStart(2, '0');
|
|
596
|
+
const day = propagateValue.getDate().toString().padStart(2, '0');
|
|
597
|
+
propagateValue = `${propagateValue.getFullYear()}-${month}-${day}`;
|
|
598
|
+
}
|
|
599
|
+
this.propagateChange(propagateValue);
|
|
600
|
+
}
|
|
603
601
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: DatetimeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
604
602
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.12", type: DatetimeComponent, isStandalone: true, selector: "yuv-datetime", inputs: { locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, onlyFutureDates: { classPropertyName: "onlyFutureDates", publicName: "onlyFutureDates", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, calendar: { classPropertyName: "calendar", publicName: "calendar", isSignal: true, isRequired: false, transformFunction: null }, withTime: { classPropertyName: "withTime", publicName: "withTime", isSignal: true, isRequired: false, transformFunction: null } }, providers: [{ provide: MatFormFieldControl, useExisting: DatetimeComponent }], viewQueries: [{ propertyName: "pickerCmp", first: true, predicate: DatepickerComponent, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<yuv-datepicker\n [calendar]=\"calendar()\"\n [disabled]=\"readonly()\"\n [withTime]=\"withTime()\"\n [locale]=\"_locale()\"\n [labels]=\"labels!\"\n [onlyFutureDates]=\"onlyFutureDates()\"\n [formControl]=\"fc\"\n></yuv-datepicker>\n", styles: [":host{display:flex;overflow-x:auto;--ymt-scrollbar-outer-size: 0px;--ymt-scrollbar-inner-size: 0px}:host yuv-datepicker{flex:1}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: YuvDatepickerModule }, { kind: "component", type: i2$1.DatepickerComponent, selector: "yuv-datepicker", inputs: ["calendar", "readonly", "hour12", "locale", "labels", "withTime", "onlyFutureDates", "minDate", "maxDate", "disabled"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatDatepickerModule }] }); }
|
|
605
603
|
}
|
|
@@ -777,6 +775,8 @@ class DynamicCatalogComponent extends AbstractMatFormField {
|
|
|
777
775
|
#dRef;
|
|
778
776
|
#translate;
|
|
779
777
|
#currentLang;
|
|
778
|
+
#ctrlValue;
|
|
779
|
+
#optionIsActiveValidator;
|
|
780
780
|
#optionsResource;
|
|
781
781
|
constructor() {
|
|
782
782
|
super();
|
|
@@ -787,14 +787,62 @@ class DynamicCatalogComponent extends AbstractMatFormField {
|
|
|
787
787
|
this.readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
|
|
788
788
|
this.multiple = input(false, ...(ngDevMode ? [{ debugName: "multiple" }] : /* istanbul ignore next */ []));
|
|
789
789
|
this.#currentLang = signal(this.#translate.getCurrentLang(), ...(ngDevMode ? [{ debugName: "#currentLang" }] : /* istanbul ignore next */ []));
|
|
790
|
+
this.#ctrlValue = signal(undefined, ...(ngDevMode ? [{ debugName: "#ctrlValue" }] : /* istanbul ignore next */ []));
|
|
791
|
+
this.#optionIsActiveValidator = (control) => {
|
|
792
|
+
const val = control.value;
|
|
793
|
+
if (val === null || val === undefined || val === '' || (Array.isArray(val) && val.length === 0))
|
|
794
|
+
return null;
|
|
795
|
+
const opts = this.options();
|
|
796
|
+
const values = Array.isArray(val) ? val : [val];
|
|
797
|
+
const hasInvalid = values.some((v) => {
|
|
798
|
+
const opt = opts.find((o) => o.value === v);
|
|
799
|
+
return !opt || opt.disabled || opt.invalid;
|
|
800
|
+
});
|
|
801
|
+
return hasInvalid ? { invalidValue: true } : null;
|
|
802
|
+
};
|
|
790
803
|
this.#optionsResource = rxResource({
|
|
791
|
-
|
|
792
|
-
|
|
804
|
+
defaultValue: [],
|
|
805
|
+
params: computed(() => ({
|
|
806
|
+
catalog: this.catalog(),
|
|
807
|
+
situation: this.situation(),
|
|
808
|
+
locale: this.#currentLang()
|
|
809
|
+
})),
|
|
810
|
+
stream: ({ params }) => this.#catalogService
|
|
811
|
+
.getEntries(params.catalog, {
|
|
812
|
+
locale: params.locale,
|
|
813
|
+
includeInvalidEntries: true //params.situation === 'SEARCH' // include all entries in search situation
|
|
814
|
+
})
|
|
815
|
+
.pipe(map((res) => res.entries.map((entry) => ({
|
|
793
816
|
value: entry.name,
|
|
817
|
+
disabled: entry._state !== 'active', // disable entries that are not active
|
|
794
818
|
label: this.#resolveLabel(entry, params.locale)
|
|
795
|
-
}))))
|
|
819
|
+
}))), map((res) => {
|
|
820
|
+
const current = this.value;
|
|
821
|
+
const currentValues = Array.isArray(current) ? current : current ? [current] : [];
|
|
822
|
+
// pre-set values that are not part of the entries (e.g. deleted entry)
|
|
823
|
+
// get appended to the options list and marked as invalid.
|
|
824
|
+
for (const v of currentValues) {
|
|
825
|
+
if (!res.find((opt) => opt.value === v)) {
|
|
826
|
+
res.push({ value: v, disabled: true, invalid: true, label: v });
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
return res;
|
|
830
|
+
}))
|
|
796
831
|
});
|
|
797
832
|
this.options = this.#optionsResource.value;
|
|
833
|
+
this.selectedDisplay = computed(() => {
|
|
834
|
+
const val = this.#ctrlValue();
|
|
835
|
+
if (val === null || val === undefined || val === '')
|
|
836
|
+
return [];
|
|
837
|
+
const opts = this.options();
|
|
838
|
+
const values = Array.isArray(val) ? val : [val];
|
|
839
|
+
return values.map((v) => {
|
|
840
|
+
const opt = opts.find((o) => o.value === v);
|
|
841
|
+
if (!opt)
|
|
842
|
+
return { value: v, label: v, invalid: true };
|
|
843
|
+
return { value: v, label: opt.label, invalid: !!opt.invalid || !!opt.disabled };
|
|
844
|
+
});
|
|
845
|
+
}, ...(ngDevMode ? [{ debugName: "selectedDisplay" }] : /* istanbul ignore next */ []));
|
|
798
846
|
/**
|
|
799
847
|
* Possibles values are `EDIT` (default),`SEARCH`,`CREATE`. In search situation
|
|
800
848
|
* validation of the form element will be turned off, so you are able to enter
|
|
@@ -802,13 +850,19 @@ class DynamicCatalogComponent extends AbstractMatFormField {
|
|
|
802
850
|
*/
|
|
803
851
|
this.situation = input(...(ngDevMode ? [undefined, { debugName: "situation" }] : /* istanbul ignore next */ []));
|
|
804
852
|
this.ngControl = injectNgControl(this);
|
|
805
|
-
this.ctrl = new FormControl(undefined);
|
|
853
|
+
this.ctrl = new FormControl(undefined, this.#optionIsActiveValidator);
|
|
806
854
|
// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/explicit-module-boundary-types
|
|
807
855
|
this.propagateChange = (fnc) => { };
|
|
808
856
|
this.#translate.onLangChange.pipe(takeUntilDestroyed()).subscribe((evt) => this.#currentLang.set(evt.lang));
|
|
857
|
+
// re-run validation once options have resolved (writeValue may run before the catalog response arrives)
|
|
858
|
+
effect(() => {
|
|
859
|
+
this.options();
|
|
860
|
+
this.ctrl.updateValueAndValidity({ emitEvent: false });
|
|
861
|
+
});
|
|
809
862
|
}
|
|
810
863
|
writeValue(value) {
|
|
811
864
|
this.value = value;
|
|
865
|
+
this.#ctrlValue.set(value);
|
|
812
866
|
this.ctrl.setValue(value, { emitEvent: false });
|
|
813
867
|
}
|
|
814
868
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
|
|
@@ -828,7 +882,7 @@ class DynamicCatalogComponent extends AbstractMatFormField {
|
|
|
828
882
|
}
|
|
829
883
|
ngOnInit() {
|
|
830
884
|
if (this.required)
|
|
831
|
-
this.ctrl.setValidators(Validators.required);
|
|
885
|
+
this.ctrl.setValidators([this.#optionIsActiveValidator, Validators.required]);
|
|
832
886
|
this.ctrl.statusChanges.pipe(takeUntilDestroyed(this.#dRef)).subscribe(() => {
|
|
833
887
|
this.errorState = FormUtils.getErrorState(this.ctrl);
|
|
834
888
|
if (this.ngControl?.control) {
|
|
@@ -844,6 +898,7 @@ class DynamicCatalogComponent extends AbstractMatFormField {
|
|
|
844
898
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
845
899
|
#onValueChange(val) {
|
|
846
900
|
this.value = val;
|
|
901
|
+
this.#ctrlValue.set(val);
|
|
847
902
|
this.propagateChange(this.value);
|
|
848
903
|
}
|
|
849
904
|
#resolveLabel(entry, locale) {
|
|
@@ -851,11 +906,11 @@ class DynamicCatalogComponent extends AbstractMatFormField {
|
|
|
851
906
|
return locs.find((loc) => loc.locale === locale)?.label || locs[0]?.label || entry.name;
|
|
852
907
|
}
|
|
853
908
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: DynamicCatalogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
854
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: DynamicCatalogComponent, isStandalone: true, selector: "yuv-dynamic-catalog", inputs: { catalog: { classPropertyName: "catalog", publicName: "catalog", isSignal: true, isRequired: true, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, situation: { classPropertyName: "situation", publicName: "situation", isSignal: true, isRequired: false, transformFunction: null } }, providers: [{ provide: MatFormFieldControl, useExisting: DynamicCatalogComponent }], usesInheritance: true, ngImport: i0, template: "<mat-select [multiple]=\"multiple()\" [disabled]=\"readonly()\" [formControl]=\"ctrl\">\n @for (o of options(); track o) {\n <mat-option [value]=\"o.value\">{{ o.label }}</mat-option>\n }\n</mat-select>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] }); }
|
|
909
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: DynamicCatalogComponent, isStandalone: true, selector: "yuv-dynamic-catalog", inputs: { catalog: { classPropertyName: "catalog", publicName: "catalog", isSignal: true, isRequired: true, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, situation: { classPropertyName: "situation", publicName: "situation", isSignal: true, isRequired: false, transformFunction: null } }, providers: [{ provide: MatFormFieldControl, useExisting: DynamicCatalogComponent }], usesInheritance: true, ngImport: i0, template: "<mat-select [multiple]=\"multiple()\" [disabled]=\"readonly()\" [formControl]=\"ctrl\">\n <mat-select-trigger>\n @if (multiple()) {\n @for (s of selectedDisplay(); track s.value; let last = $last) {\n <span [class.invalid]=\"s.invalid\">{{ s.label }}</span>@if (!last) {<span>, </span>}\n }\n } @else {\n @if (selectedDisplay()[0]; as s) {\n <span [class.invalid]=\"s.invalid\">{{ s.label }}</span>\n }\n }\n </mat-select-trigger>\n @for (o of options(); track o.value) {\n <mat-option [disabled]=\"o.disabled\" [class.invalid]=\"o.invalid\" [value]=\"o.value\">{{ o.label }}</mat-option>\n }\n</mat-select>\n", styles: ["mat-option.invalid,.invalid{color:var(--ymt-danger)}\n"], dependencies: [{ kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i1.MatSelectTrigger, selector: "mat-select-trigger" }, { kind: "component", type: i1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] }); }
|
|
855
910
|
}
|
|
856
911
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: DynamicCatalogComponent, decorators: [{
|
|
857
912
|
type: Component,
|
|
858
|
-
args: [{ selector: 'yuv-dynamic-catalog', imports: [MatSelectModule, ReactiveFormsModule], providers: [{ provide: MatFormFieldControl, useExisting: DynamicCatalogComponent }], template: "<mat-select [multiple]=\"multiple()\" [disabled]=\"readonly()\" [formControl]=\"ctrl\">\n @for (o of options(); track o) {\n <mat-option [value]=\"o.value\">{{ o.label }}</mat-option>\n }\n</mat-select>\n" }]
|
|
913
|
+
args: [{ selector: 'yuv-dynamic-catalog', imports: [MatSelectModule, ReactiveFormsModule], providers: [{ provide: MatFormFieldControl, useExisting: DynamicCatalogComponent }], template: "<mat-select [multiple]=\"multiple()\" [disabled]=\"readonly()\" [formControl]=\"ctrl\">\n <mat-select-trigger>\n @if (multiple()) {\n @for (s of selectedDisplay(); track s.value; let last = $last) {\n <span [class.invalid]=\"s.invalid\">{{ s.label }}</span>@if (!last) {<span>, </span>}\n }\n } @else {\n @if (selectedDisplay()[0]; as s) {\n <span [class.invalid]=\"s.invalid\">{{ s.label }}</span>\n }\n }\n </mat-select-trigger>\n @for (o of options(); track o.value) {\n <mat-option [disabled]=\"o.disabled\" [class.invalid]=\"o.invalid\" [value]=\"o.value\">{{ o.label }}</mat-option>\n }\n</mat-select>\n", styles: ["mat-option.invalid,.invalid{color:var(--ymt-danger)}\n"] }]
|
|
859
914
|
}], ctorParameters: () => [], propDecorators: { catalog: [{ type: i0.Input, args: [{ isSignal: true, alias: "catalog", required: true }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], situation: [{ type: i0.Input, args: [{ isSignal: true, alias: "situation", required: false }] }] } });
|
|
860
915
|
|
|
861
916
|
/**
|