@yuuvis/client-framework 3.2.2 → 3.4.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 +131 -69
- package/fesm2022/yuuvis-client-framework-forms.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-object-preview.mjs +43 -30
- package/fesm2022/yuuvis-client-framework-object-preview.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-query-list.mjs +74 -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 +81 -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-object-preview.d.ts +28 -38
- package/types/yuuvis-client-framework-query-list.d.ts +46 -2
- package/types/yuuvis-client-framework-tile-list.d.ts +31 -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
|
|
@@ -827,8 +881,15 @@ class DynamicCatalogComponent extends AbstractMatFormField {
|
|
|
827
881
|
this.disabled = isDisabled;
|
|
828
882
|
}
|
|
829
883
|
ngOnInit() {
|
|
884
|
+
const validators = [this.#optionIsActiveValidator];
|
|
830
885
|
if (this.required)
|
|
831
|
-
|
|
886
|
+
validators.push(Validators.required);
|
|
887
|
+
// Mirror the parent FormControl's validators so the inner ctrl evaluates
|
|
888
|
+
// the same rules the host's NgControl does. Read lazily — picks up
|
|
889
|
+
// validators added after init.
|
|
890
|
+
validators.push((control) => this.ngControl?.control?.validator?.(control) ?? null);
|
|
891
|
+
this.ctrl.setValidators(validators);
|
|
892
|
+
this.ctrl.setAsyncValidators((control) => this.ngControl?.control?.asyncValidator?.(control) ?? of(null));
|
|
832
893
|
this.ctrl.statusChanges.pipe(takeUntilDestroyed(this.#dRef)).subscribe(() => {
|
|
833
894
|
this.errorState = FormUtils.getErrorState(this.ctrl);
|
|
834
895
|
if (this.ngControl?.control) {
|
|
@@ -844,6 +905,7 @@ class DynamicCatalogComponent extends AbstractMatFormField {
|
|
|
844
905
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
845
906
|
#onValueChange(val) {
|
|
846
907
|
this.value = val;
|
|
908
|
+
this.#ctrlValue.set(val);
|
|
847
909
|
this.propagateChange(this.value);
|
|
848
910
|
}
|
|
849
911
|
#resolveLabel(entry, locale) {
|
|
@@ -851,11 +913,11 @@ class DynamicCatalogComponent extends AbstractMatFormField {
|
|
|
851
913
|
return locs.find((loc) => loc.locale === locale)?.label || locs[0]?.label || entry.name;
|
|
852
914
|
}
|
|
853
915
|
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"] }] }); }
|
|
916
|
+
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
917
|
}
|
|
856
918
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: DynamicCatalogComponent, decorators: [{
|
|
857
919
|
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" }]
|
|
920
|
+
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
921
|
}], 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
922
|
|
|
861
923
|
/**
|