@xiriframework/xiri-ng 0.2.49 → 0.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/xiriframework-xiri-ng.mjs +148 -135
- package/fesm2022/xiriframework-xiri-ng.mjs.map +1 -1
- package/package.json +2 -2
- package/skills/xiri-ng-expert/SKILL.md +1 -1
- package/skills/xiri-ng-expert/references/setup.md +18 -12
- package/skills/xiri-ng-expert/references/theming-i18n.md +24 -13
- package/types/xiriframework-xiri-ng.d.ts +39 -26
- package/types/xiriframework-xiri-ng.d.ts.map +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { inject, Pipe, input, computed, Directive, ElementRef, ChangeDetectorRef, Input, Component,
|
|
3
|
+
import { inject, Pipe, input, computed, Directive, ElementRef, ChangeDetectorRef, Input, Component, PLATFORM_ID, signal, effect, Service, output, numberAttribute, afterRenderEffect, booleanAttribute, viewChild, Injectable, DestroyRef, forwardRef, untracked, Injector, afterNextRender, ViewEncapsulation, linkedSignal, ChangeDetectionStrategy, NgZone, makeEnvironmentProviders } from '@angular/core';
|
|
4
4
|
import { DefaultUrlSerializer, RouterLink, Router, NavigationEnd } from '@angular/router';
|
|
5
5
|
import { takeUntilDestroyed, toSignal, rxResource } from '@angular/core/rxjs-interop';
|
|
6
6
|
import * as i1 from '@angular/forms';
|
|
@@ -20,6 +20,8 @@ import { MatCheckbox } from '@angular/material/checkbox';
|
|
|
20
20
|
import { MatRadioButton, MatRadioGroup } from '@angular/material/radio';
|
|
21
21
|
import { fromUnixTime, format, transpose } from 'date-fns';
|
|
22
22
|
import { tz } from '@date-fns/tz';
|
|
23
|
+
import { de } from 'date-fns/locale/de';
|
|
24
|
+
import { enGB } from 'date-fns/locale/en-GB';
|
|
23
25
|
import { MatDatepickerInput, MatDatepickerToggle, MatDatepickerToggleIcon, MatDatepicker, MatDateRangeInput, MatStartDate, MatEndDate, MatDateRangePicker } from '@angular/material/datepicker';
|
|
24
26
|
import { MatTree, MatTreeNestedDataSource, MatTreeNode, MatTreeNodeToggle, MatTreeNodePadding, MatTreeNodeDef } from '@angular/material/tree';
|
|
25
27
|
import { SelectionModel } from '@angular/cdk/collections';
|
|
@@ -31,8 +33,6 @@ import { NgxMatSelectSearchModule } from 'ngx-mat-select-search';
|
|
|
31
33
|
import { ENTER, COMMA, ESCAPE } from '@angular/cdk/keycodes';
|
|
32
34
|
import { MatAutocompleteTrigger, MatAutocomplete } from '@angular/material/autocomplete';
|
|
33
35
|
import { MatChipGrid, MatChipRow, MatChipRemove, MatChipInput, MatChipSet, MatChip } from '@angular/material/chips';
|
|
34
|
-
import { de } from 'date-fns/locale/de';
|
|
35
|
-
import { enGB } from 'date-fns/locale/en-GB';
|
|
36
36
|
import { MatTableDataSource, MatTable, MatColumnDef, MatHeaderCellDef, MatHeaderCell, MatCellDef, MatCell, MatHeaderRowDef, MatHeaderRow, MatRowDef, MatRow, MatFooterRow, MatFooterRowDef, MatFooterCell, MatFooterCellDef } from '@angular/material/table';
|
|
37
37
|
import { MatTooltip } from '@angular/material/tooltip';
|
|
38
38
|
import { MatDialogRef, MAT_DIALOG_DATA, MatDialogTitle, MatDialogContent, MatDialogActions, MatDialog } from '@angular/material/dialog';
|
|
@@ -682,16 +682,94 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
682
682
|
type: Input
|
|
683
683
|
}] } });
|
|
684
684
|
|
|
685
|
-
|
|
685
|
+
const deValidationMessages = {
|
|
686
|
+
required: 'Pflichtfeld – bitte ausfüllen',
|
|
687
|
+
invalidFormat: 'Bitte ein gültiges Format eingeben',
|
|
688
|
+
invalidEmail: 'Bitte eine gültige E-Mail-Adresse eingeben',
|
|
689
|
+
valueRequired: 'Bitte einen Wert angeben',
|
|
690
|
+
minLength: min => `Mindestens ${min} Zeichen erforderlich`,
|
|
691
|
+
maxLength: max => `Maximal ${max} Zeichen erlaubt`,
|
|
692
|
+
minNumber: min => `Mindestens ${min} erforderlich`,
|
|
693
|
+
maxNumber: max => `Maximal ${max} erlaubt`,
|
|
694
|
+
minDate: date => `Datum darf nicht vor ${date} liegen`,
|
|
695
|
+
maxDate: date => `Datum darf nicht nach ${date} liegen`,
|
|
696
|
+
minDateRange: date => `Startdatum muss nach ${date} liegen`,
|
|
697
|
+
maxDateRange: date => `Enddatum muss vor ${date} liegen`,
|
|
698
|
+
minSelection: min => `Mindestens ${min} Einträge auswählen`,
|
|
699
|
+
maxSelection: max => `Maximal ${max} Einträge auswählen`,
|
|
700
|
+
};
|
|
701
|
+
const enValidationMessages = {
|
|
702
|
+
required: 'Required field',
|
|
703
|
+
invalidFormat: 'Please enter a valid format',
|
|
704
|
+
invalidEmail: 'Please enter a valid email address',
|
|
705
|
+
valueRequired: 'Please provide a value',
|
|
706
|
+
minLength: min => `At least ${min} characters required`,
|
|
707
|
+
maxLength: max => `Maximum ${max} characters allowed`,
|
|
708
|
+
minNumber: min => `Minimum value is ${min}`,
|
|
709
|
+
maxNumber: max => `Maximum value is ${max}`,
|
|
710
|
+
minDate: date => `Date must not be before ${date}`,
|
|
711
|
+
maxDate: date => `Date must not be after ${date}`,
|
|
712
|
+
minDateRange: date => `Start date must be after ${date}`,
|
|
713
|
+
maxDateRange: date => `End date must be before ${date}`,
|
|
714
|
+
minSelection: min => `Select at least ${min} items`,
|
|
715
|
+
maxSelection: max => `Select at most ${max} items`,
|
|
716
|
+
};
|
|
717
|
+
class XiriLocaleService {
|
|
686
718
|
constructor() {
|
|
719
|
+
this.platformId = inject(PLATFORM_ID);
|
|
720
|
+
this.isBrowser = isPlatformBrowser(this.platformId);
|
|
721
|
+
this.dateAdapter = inject(DateAdapter, { optional: true });
|
|
722
|
+
// Registry aller bekannten Sprachen — de/en eingebaut, weitere per registerLanguage().
|
|
723
|
+
this.registry = new Map([
|
|
724
|
+
['de', { localeString: 'de-DE', dateFnsLocale: de, validationMessages: deValidationMessages }],
|
|
725
|
+
['en', { localeString: 'en-GB', dateFnsLocale: enGB, validationMessages: enValidationMessages }],
|
|
726
|
+
]);
|
|
727
|
+
this._language = signal('de', /* @ts-ignore */
|
|
728
|
+
...(ngDevMode ? [{ debugName: "_language" }] : /* istanbul ignore next */ []));
|
|
729
|
+
this.language = this._language.asReadonly();
|
|
730
|
+
this.localeString = computed(() => this.registry.get(this._language())?.localeString ?? 'de-DE', /* @ts-ignore */
|
|
731
|
+
...(ngDevMode ? [{ debugName: "localeString" }] : /* istanbul ignore next */ []));
|
|
732
|
+
// Aktives date-fns-Locale (für Datums-Formatierung + Datepicker). Undefined bei Text-only-Sprache.
|
|
733
|
+
this.dateFnsLocale = computed(() => this.registry.get(this._language())?.dateFnsLocale, /* @ts-ignore */
|
|
734
|
+
...(ngDevMode ? [{ debugName: "dateFnsLocale" }] : /* istanbul ignore next */ []));
|
|
735
|
+
// Zeitzone für alle Unix<->Local-Umrechnungen (locale-nahe Präsentations-Info, analog Go-uicontext).
|
|
687
736
|
this.currentTimezone = 'Europe/Vienna';
|
|
688
|
-
|
|
737
|
+
const stored = this.readStoredLanguage();
|
|
738
|
+
// Nur wiederherstellen, wenn die Sprache bekannt ist (de/en oder bereits registriert).
|
|
739
|
+
if (stored && this.registry.has(stored))
|
|
740
|
+
this._language.set(stored);
|
|
741
|
+
// Material-Datepicker-Locale (Picker-UI) an die Sprache angleichen — reine Frontend-Interaktion.
|
|
742
|
+
// Ohne bereitgestellten DateAdapter (Text-only-Formular) oder ohne date-fns-Locale wird übersprungen.
|
|
743
|
+
effect(() => {
|
|
744
|
+
const locale = this.dateFnsLocale();
|
|
745
|
+
if (locale)
|
|
746
|
+
this.dateAdapter?.setLocale(locale);
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
// Sprache registrieren/überschreiben. Vor setLanguage() bzw. dem ersten Formular-Render aufrufen (App-Init).
|
|
750
|
+
registerLanguage(code, def) {
|
|
751
|
+
this.registry.set(code, def);
|
|
752
|
+
// Über Reload persistierte Custom-Sprache einklinken, sobald sie (nach)registriert wird —
|
|
753
|
+
// der Konstruktor kennt beim Restore nur de/en.
|
|
754
|
+
if (this.readStoredLanguage() === code)
|
|
755
|
+
this._language.set(code);
|
|
756
|
+
}
|
|
757
|
+
setLanguage(lang) {
|
|
758
|
+
if (!this.registry.has(lang)) {
|
|
759
|
+
console.warn(`XiriLocaleService: unbekannte Sprache '${lang}' – zuerst registerLanguage() aufrufen.`);
|
|
760
|
+
return;
|
|
761
|
+
}
|
|
762
|
+
this._language.set(lang);
|
|
763
|
+
this.storeLanguage(lang);
|
|
689
764
|
}
|
|
690
|
-
|
|
691
|
-
|
|
765
|
+
// Validierungs-Fehlertexte der aktiven Sprache; Fallback de, falls (unerwartet) nicht vorhanden.
|
|
766
|
+
validationMessagesFor() {
|
|
767
|
+
return this.registry.get(this._language())?.validationMessages
|
|
768
|
+
?? this.registry.get('de').validationMessages;
|
|
692
769
|
}
|
|
693
|
-
|
|
694
|
-
|
|
770
|
+
// ── Zeitzone + Datums-/Zahlen-Formatierung (locale-abhängig) ─────────────────────────────
|
|
771
|
+
setTimezone(timezone) {
|
|
772
|
+
this.currentTimezone = timezone;
|
|
695
773
|
}
|
|
696
774
|
unixToLocal(stime) {
|
|
697
775
|
if (stime === null || stime === undefined)
|
|
@@ -700,28 +778,64 @@ class XiriDateService {
|
|
|
700
778
|
}
|
|
701
779
|
unixToStringDateTime(stime) {
|
|
702
780
|
const date = this.unixToLocal(stime);
|
|
703
|
-
return date === null ? '' : format(date, 'yyyy-MM-dd HH:mm');
|
|
781
|
+
return date === null ? '' : format(date, 'yyyy-MM-dd HH:mm', { locale: this.dateFnsLocale() });
|
|
704
782
|
}
|
|
705
783
|
unixToStringDate(stime) {
|
|
706
784
|
const date = this.unixToLocal(stime);
|
|
707
|
-
|
|
785
|
+
// Kein Punkt hinter LLL: die Interpunktion des Monatskürzels bringt das jeweilige Locale
|
|
786
|
+
// selbst mit (de/fr: 'Mär.'/'juil.', en: 'Jul' ohne) — ein fixer Punkt gäbe sonst '18. Mär..'.
|
|
787
|
+
return date === null ? '' : format(date, 'd. LLL', { locale: this.dateFnsLocale() });
|
|
708
788
|
}
|
|
709
789
|
unixToStringDateYear(stime) {
|
|
710
790
|
const date = this.unixToLocal(stime);
|
|
711
|
-
return date === null ? '' : format(date, 'd. LLL
|
|
791
|
+
return date === null ? '' : format(date, 'd. LLL yy', { locale: this.dateFnsLocale() });
|
|
712
792
|
}
|
|
713
793
|
dateToUnix(date) {
|
|
714
794
|
return Math.floor(transpose(date, tz(this.currentTimezone)).getTime() / 1000);
|
|
715
795
|
}
|
|
716
|
-
|
|
717
|
-
|
|
796
|
+
formatNumber(value, webformat) {
|
|
797
|
+
if (value === null || value === undefined)
|
|
798
|
+
return '';
|
|
799
|
+
const digits = webformat === 'integer'
|
|
800
|
+
? 0
|
|
801
|
+
: /^float\d+$/.test(webformat ?? '')
|
|
802
|
+
? Number(webformat.slice(5))
|
|
803
|
+
: undefined;
|
|
804
|
+
const options = { style: 'decimal' };
|
|
805
|
+
if (digits !== undefined) {
|
|
806
|
+
options.minimumFractionDigits = digits;
|
|
807
|
+
options.maximumFractionDigits = digits;
|
|
808
|
+
}
|
|
809
|
+
return new Intl.NumberFormat(this.localeString(), options).format(value);
|
|
810
|
+
}
|
|
811
|
+
// localStorage-Zugriff abgesichert: im SSR nicht vorhanden, in jsdom-Tests ggf. undefined,
|
|
812
|
+
// im Private-Mode wirft es SecurityError. In all diesen Fällen still ohne Persistenz weiterlaufen.
|
|
813
|
+
readStoredLanguage() {
|
|
814
|
+
if (!this.isBrowser)
|
|
815
|
+
return null;
|
|
816
|
+
try {
|
|
817
|
+
return localStorage.getItem('xiri-language');
|
|
818
|
+
}
|
|
819
|
+
catch {
|
|
820
|
+
return null;
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
storeLanguage(lang) {
|
|
824
|
+
if (!this.isBrowser)
|
|
825
|
+
return;
|
|
826
|
+
try {
|
|
827
|
+
localStorage.setItem('xiri-language', lang);
|
|
828
|
+
}
|
|
829
|
+
catch {
|
|
830
|
+
// Persistenz nicht verfügbar (Private-Mode o. Ä.) — Sprachwechsel gilt trotzdem für die Session.
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriLocaleService, deps: [], target: i0.ɵɵFactoryTarget.Service }); }
|
|
834
|
+
static { this.ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.0.7", ngImport: i0, type: XiriLocaleService }); }
|
|
718
835
|
}
|
|
719
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type:
|
|
720
|
-
type:
|
|
721
|
-
|
|
722
|
-
providedIn: 'root'
|
|
723
|
-
}]
|
|
724
|
-
}] });
|
|
836
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriLocaleService, decorators: [{
|
|
837
|
+
type: Service
|
|
838
|
+
}], ctorParameters: () => [] });
|
|
725
839
|
|
|
726
840
|
class XiriFieldMain {
|
|
727
841
|
constructor() {
|
|
@@ -935,7 +1049,7 @@ class XiriDateTimeRangeComponent extends XiriFieldMain {
|
|
|
935
1049
|
this.minutes = ['00', '05', '10', '15',
|
|
936
1050
|
'20', '25', '30', '35',
|
|
937
1051
|
'40', '45', '50', '55',];
|
|
938
|
-
this.dateService = inject(
|
|
1052
|
+
this.dateService = inject(XiriLocaleService);
|
|
939
1053
|
this.fb = inject(FormBuilder);
|
|
940
1054
|
this._id = this._uid;
|
|
941
1055
|
if (this.ngControl != null)
|
|
@@ -1093,7 +1207,7 @@ class XiriDateRangeComponent extends XiriFieldMain {
|
|
|
1093
1207
|
this.minDate = null;
|
|
1094
1208
|
this.maxDate = null;
|
|
1095
1209
|
this._lastValue = null;
|
|
1096
|
-
this.dateService = inject(
|
|
1210
|
+
this.dateService = inject(XiriLocaleService);
|
|
1097
1211
|
this.fb = inject(FormBuilder);
|
|
1098
1212
|
this._id = this._uid;
|
|
1099
1213
|
if (this.ngControl != null)
|
|
@@ -1237,7 +1351,7 @@ class XiriDateComponent extends XiriFieldMain {
|
|
|
1237
1351
|
'30', '31', '32', '33', '34', '35', '36', '37', '38', '39',
|
|
1238
1352
|
'40', '41', '42', '43', '44', '45', '46', '47', '48', '49',
|
|
1239
1353
|
'50', '51', '52', '53', '54', '55', '56', '57', '58', '59',];
|
|
1240
|
-
this.dateService = inject(
|
|
1354
|
+
this.dateService = inject(XiriLocaleService);
|
|
1241
1355
|
this.fb = inject(FormBuilder);
|
|
1242
1356
|
this._id = this._uid;
|
|
1243
1357
|
if (this.ngControl != null)
|
|
@@ -1375,7 +1489,7 @@ class XiriYearMonthComponent extends XiriFieldMain {
|
|
|
1375
1489
|
...(ngDevMode ? [{ debugName: "picker" }] : /* istanbul ignore next */ []));
|
|
1376
1490
|
this._lastValue = null;
|
|
1377
1491
|
this.type = 'yearmonth';
|
|
1378
|
-
this.dateService = inject(
|
|
1492
|
+
this.dateService = inject(XiriLocaleService);
|
|
1379
1493
|
this._id = this._uid;
|
|
1380
1494
|
if (this.ngControl != null)
|
|
1381
1495
|
this.ngControl.valueAccessor = this;
|
|
@@ -2167,77 +2281,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
2167
2281
|
], template: "<mat-form-field>\n\t@if (field().name) {\n\t\t<mat-label>{{ field().name }}</mat-label>\n\t}\n\t<mat-chip-grid #chipGrid>\n\t\t@for (chip of chips(); track chip) {\n\t\t\t<mat-chip-row (removed)=\"remove(chip)\" [class]=\"chipColor(chip)\">\n\t\t\t\t{{ displayLabel(chip) }}\n\t\t\t\t<button matChipRemove>\n\t\t\t\t\t<mat-icon>cancel</mat-icon>\n\t\t\t\t</button>\n\t\t\t</mat-chip-row>\n\t\t}\n\t</mat-chip-grid>\n\t<input #chipInput\n\t [matChipInputFor]=\"chipGrid\"\n\t [matChipInputSeparatorKeyCodes]=\"separatorKeyCodes\"\n\t [matChipInputAddOnBlur]=\"true\"\n\t (matChipInputTokenEnd)=\"add($event)\"\n\t (input)=\"onInputChange($event)\"\n\t (focus)=\"onFocus()\"\n\t [matAutocomplete]=\"auto\"\n\t [placeholder]=\"field().hint || ''\">\n\t<mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"selected($event)\">\n\t\t@for (option of filteredOptions(); track option.id) {\n\t\t\t<mat-option [value]=\"option\">{{ option.name }}</mat-option>\n\t\t}\n\t</mat-autocomplete>\n</mat-form-field>\n", styles: [":host{display:block;width:100%}mat-form-field{width:100%}\n"] }]
|
|
2168
2282
|
}], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], chipInput: [{ type: i0.ViewChild, args: ['chipInput', { isSignal: true }] }] } });
|
|
2169
2283
|
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
this.platformId = inject(PLATFORM_ID);
|
|
2173
|
-
this.isBrowser = isPlatformBrowser(this.platformId);
|
|
2174
|
-
this.dateAdapter = inject(DateAdapter, { optional: true });
|
|
2175
|
-
this._language = signal('de', /* @ts-ignore */
|
|
2176
|
-
...(ngDevMode ? [{ debugName: "_language" }] : /* istanbul ignore next */ []));
|
|
2177
|
-
this.language = this._language.asReadonly();
|
|
2178
|
-
this.localeString = computed(() => this._language() === 'en' ? 'en-GB' : 'de-DE', /* @ts-ignore */
|
|
2179
|
-
...(ngDevMode ? [{ debugName: "localeString" }] : /* istanbul ignore next */ []));
|
|
2180
|
-
if (this.isBrowser) {
|
|
2181
|
-
const stored = localStorage.getItem('xiri-language');
|
|
2182
|
-
if (stored === 'de' || stored === 'en')
|
|
2183
|
-
this._language.set(stored);
|
|
2184
|
-
}
|
|
2185
|
-
// Material-Datepicker-Locale (Picker-UI) an die Sprache angleichen — reine Frontend-Interaktion.
|
|
2186
|
-
// Ohne bereitgestellten DateAdapter (z. B. Text-only-Formular ohne provideDateFnsAdapter()) gibt es
|
|
2187
|
-
// ohnehin keinen Datepicker, daher wird der effect dann übersprungen.
|
|
2188
|
-
effect(() => {
|
|
2189
|
-
this.dateAdapter?.setLocale(this._language() === 'en' ? enGB : de);
|
|
2190
|
-
});
|
|
2191
|
-
}
|
|
2192
|
-
setLanguage(lang) {
|
|
2193
|
-
this._language.set(lang);
|
|
2194
|
-
if (this.isBrowser)
|
|
2195
|
-
localStorage.setItem('xiri-language', lang);
|
|
2196
|
-
}
|
|
2197
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriLocaleService, deps: [], target: i0.ɵɵFactoryTarget.Service }); }
|
|
2198
|
-
static { this.ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.0.7", ngImport: i0, type: XiriLocaleService }); }
|
|
2284
|
+
function formatValidationDate(localeString, unixSeconds) {
|
|
2285
|
+
return new Intl.DateTimeFormat(localeString).format(new Date(unixSeconds * 1000));
|
|
2199
2286
|
}
|
|
2200
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriLocaleService, decorators: [{
|
|
2201
|
-
type: Service
|
|
2202
|
-
}], ctorParameters: () => [] });
|
|
2203
|
-
|
|
2204
|
-
function formatValidationDate(lang, unixSeconds) {
|
|
2205
|
-
return new Intl.DateTimeFormat(lang === 'en' ? 'en-US' : 'de-AT').format(new Date(unixSeconds * 1000));
|
|
2206
|
-
}
|
|
2207
|
-
const validationMessages = {
|
|
2208
|
-
de: {
|
|
2209
|
-
required: 'Pflichtfeld – bitte ausfüllen',
|
|
2210
|
-
invalidFormat: 'Bitte ein gültiges Format eingeben',
|
|
2211
|
-
invalidEmail: 'Bitte eine gültige E-Mail-Adresse eingeben',
|
|
2212
|
-
valueRequired: 'Bitte einen Wert angeben',
|
|
2213
|
-
minLength: min => `Mindestens ${min} Zeichen erforderlich`,
|
|
2214
|
-
maxLength: max => `Maximal ${max} Zeichen erlaubt`,
|
|
2215
|
-
minNumber: min => `Mindestens ${min} erforderlich`,
|
|
2216
|
-
maxNumber: max => `Maximal ${max} erlaubt`,
|
|
2217
|
-
minDate: date => `Datum darf nicht vor ${date} liegen`,
|
|
2218
|
-
maxDate: date => `Datum darf nicht nach ${date} liegen`,
|
|
2219
|
-
minDateRange: date => `Startdatum muss nach ${date} liegen`,
|
|
2220
|
-
maxDateRange: date => `Enddatum muss vor ${date} liegen`,
|
|
2221
|
-
minSelection: min => `Mindestens ${min} Einträge auswählen`,
|
|
2222
|
-
maxSelection: max => `Maximal ${max} Einträge auswählen`,
|
|
2223
|
-
},
|
|
2224
|
-
en: {
|
|
2225
|
-
required: 'Required field',
|
|
2226
|
-
invalidFormat: 'Please enter a valid format',
|
|
2227
|
-
invalidEmail: 'Please enter a valid email address',
|
|
2228
|
-
valueRequired: 'Please provide a value',
|
|
2229
|
-
minLength: min => `At least ${min} characters required`,
|
|
2230
|
-
maxLength: max => `Maximum ${max} characters allowed`,
|
|
2231
|
-
minNumber: min => `Minimum value is ${min}`,
|
|
2232
|
-
maxNumber: max => `Maximum value is ${max}`,
|
|
2233
|
-
minDate: date => `Date must not be before ${date}`,
|
|
2234
|
-
maxDate: date => `Date must not be after ${date}`,
|
|
2235
|
-
minDateRange: date => `Start date must be after ${date}`,
|
|
2236
|
-
maxDateRange: date => `End date must be before ${date}`,
|
|
2237
|
-
minSelection: min => `Select at least ${min} items`,
|
|
2238
|
-
maxSelection: max => `Select at most ${max} items`,
|
|
2239
|
-
},
|
|
2240
|
-
};
|
|
2241
2287
|
class XiriFormFieldsComponent {
|
|
2242
2288
|
constructor() {
|
|
2243
2289
|
this.formBuilder = inject(UntypedFormBuilder);
|
|
@@ -2477,8 +2523,8 @@ class XiriFormFieldsComponent {
|
|
|
2477
2523
|
// Sprache wird bei jedem Zugriff auf `message` frisch aus dem Service gelesen (Getter),
|
|
2478
2524
|
// damit die Fehlertexte bei einem Sprachwechsel ohne Neuaufbau der Validatoren umschalten.
|
|
2479
2525
|
const localeService = this.localeService;
|
|
2480
|
-
const
|
|
2481
|
-
const
|
|
2526
|
+
const messagesFor = () => localeService.validationMessagesFor();
|
|
2527
|
+
const localeStringFor = () => localeService.localeString();
|
|
2482
2528
|
if (field.min !== undefined) {
|
|
2483
2529
|
const min = field.min;
|
|
2484
2530
|
if (field.type == 'number')
|
|
@@ -2491,13 +2537,13 @@ class XiriFormFieldsComponent {
|
|
|
2491
2537
|
field.validations.push({
|
|
2492
2538
|
id: 'min',
|
|
2493
2539
|
validator: Validators.min(min),
|
|
2494
|
-
get message() { return messagesFor().minDate(formatValidationDate(
|
|
2540
|
+
get message() { return messagesFor().minDate(formatValidationDate(localeStringFor(), min)); }
|
|
2495
2541
|
});
|
|
2496
2542
|
else if (field.type == 'daterange' || field.type == 'datetimerange')
|
|
2497
2543
|
field.validations.push({
|
|
2498
2544
|
id: 'min',
|
|
2499
2545
|
validator: validatorDateRangeStart(min),
|
|
2500
|
-
get message() { return messagesFor().minDateRange(formatValidationDate(
|
|
2546
|
+
get message() { return messagesFor().minDateRange(formatValidationDate(localeStringFor(), min)); }
|
|
2501
2547
|
});
|
|
2502
2548
|
else if (field.type == 'multiselect' || field.type == 'treeselect')
|
|
2503
2549
|
field.validations.push({
|
|
@@ -2524,13 +2570,13 @@ class XiriFormFieldsComponent {
|
|
|
2524
2570
|
field.validations.push({
|
|
2525
2571
|
id: 'max',
|
|
2526
2572
|
validator: Validators.max(max),
|
|
2527
|
-
get message() { return messagesFor().maxDate(formatValidationDate(
|
|
2573
|
+
get message() { return messagesFor().maxDate(formatValidationDate(localeStringFor(), max)); }
|
|
2528
2574
|
});
|
|
2529
2575
|
else if (field.type == 'daterange' || field.type == 'datetimerange')
|
|
2530
2576
|
field.validations.push({
|
|
2531
2577
|
id: 'max',
|
|
2532
2578
|
validator: validatorDateRangeEnd(max),
|
|
2533
|
-
get message() { return messagesFor().maxDateRange(formatValidationDate(
|
|
2579
|
+
get message() { return messagesFor().maxDateRange(formatValidationDate(localeStringFor(), max)); }
|
|
2534
2580
|
});
|
|
2535
2581
|
else if (field.type == 'multiselect' || field.type == 'treeselect')
|
|
2536
2582
|
field.validations.push({
|
|
@@ -4252,39 +4298,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
4252
4298
|
}]
|
|
4253
4299
|
}], ctorParameters: () => [] });
|
|
4254
4300
|
|
|
4255
|
-
class XiriNumberService {
|
|
4256
|
-
constructor() {
|
|
4257
|
-
this.currentLocale = 'de-DE';
|
|
4258
|
-
}
|
|
4259
|
-
setLocale(locale) {
|
|
4260
|
-
this.currentLocale = locale;
|
|
4261
|
-
}
|
|
4262
|
-
formatNumber(value, webformat) {
|
|
4263
|
-
if (value === null || value === undefined) {
|
|
4264
|
-
return '';
|
|
4265
|
-
}
|
|
4266
|
-
const digits = webformat === 'integer'
|
|
4267
|
-
? 0
|
|
4268
|
-
: /^float\d+$/.test(webformat ?? '')
|
|
4269
|
-
? Number(webformat.slice(5))
|
|
4270
|
-
: undefined;
|
|
4271
|
-
const options = { style: 'decimal' };
|
|
4272
|
-
if (digits !== undefined) {
|
|
4273
|
-
options.minimumFractionDigits = digits;
|
|
4274
|
-
options.maximumFractionDigits = digits;
|
|
4275
|
-
}
|
|
4276
|
-
return new Intl.NumberFormat(this.currentLocale, options).format(value);
|
|
4277
|
-
}
|
|
4278
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriNumberService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
4279
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriNumberService, providedIn: 'root' }); }
|
|
4280
|
-
}
|
|
4281
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriNumberService, decorators: [{
|
|
4282
|
-
type: Injectable,
|
|
4283
|
-
args: [{
|
|
4284
|
-
providedIn: 'root'
|
|
4285
|
-
}]
|
|
4286
|
-
}] });
|
|
4287
|
-
|
|
4288
4301
|
class XiriEmptyStateComponent {
|
|
4289
4302
|
constructor() {
|
|
4290
4303
|
this.settings = input.required(/* @ts-ignore */
|
|
@@ -4331,7 +4344,7 @@ class XiriTableComponent {
|
|
|
4331
4344
|
this.dataService = inject(XiriDataService);
|
|
4332
4345
|
this.router = inject(Router);
|
|
4333
4346
|
this.sessionStorageService = inject(XiriSessionStorageService);
|
|
4334
|
-
this.numberService = inject(
|
|
4347
|
+
this.numberService = inject(XiriLocaleService);
|
|
4335
4348
|
this.snackbar = inject(XiriSnackbarService);
|
|
4336
4349
|
this.responseHandler = inject(XiriResponseHandlerService);
|
|
4337
4350
|
this.downloadService = inject(XiriDownloadService);
|
|
@@ -8309,5 +8322,5 @@ function provideXiriServices(config) {
|
|
|
8309
8322
|
* Generated bundle index. Do not edit.
|
|
8310
8323
|
*/
|
|
8311
8324
|
|
|
8312
|
-
export { COLOR_CSS_VAR, DEFAULT_COMPARE, DEFAULT_PREDICATE, FALLBACK_COLORS, SafehtmlPipe, ThemeService, XiriAlertComponent, XiriBarChartComponent, XiriBreadcrumbComponent, XiriBulletChartComponent, XiriButtonComponent, XiriButtonlineComponent, XiriButtonstyleComponent, XiriCalendarComponent, XiriCalloutComponent, XiriCardComponent, XiriCardlinkComponent, XiriColsDirective, XiriDataService, XiriDataServiceConfig,
|
|
8325
|
+
export { COLOR_CSS_VAR, DEFAULT_COMPARE, DEFAULT_PREDICATE, FALLBACK_COLORS, SafehtmlPipe, ThemeService, XiriAlertComponent, XiriBarChartComponent, XiriBreadcrumbComponent, XiriBulletChartComponent, XiriButtonComponent, XiriButtonlineComponent, XiriButtonstyleComponent, XiriCalendarComponent, XiriCalloutComponent, XiriCardComponent, XiriCardlinkComponent, XiriColsDirective, XiriDataService, XiriDataServiceConfig, XiriDescriptionListComponent, XiriDialogComponent, XiriDividerComponent, XiriDoneComponent, XiriDownloadService, XiriDynComponentComponent, XiriEchartsHostComponent, XiriEmptyStateComponent, XiriErrorComponent, XiriExpansionComponent, XiriFormComponent, XiriFormFieldsComponent, XiriFormService, XiriGanttComponent, XiriGaugeChartComponent, XiriHeaderComponent, XiriHeatmapComponent, XiriImagetextComponent, XiriInfopointComponent, XiriLineChartComponent, XiriLinksComponent, XiriListComponent, XiriLocalStorageService, XiriLocaleService, XiriMultiStatComponent, XiriMultiprogressComponent, XiriPageHeaderComponent, XiriPieChartComponent, XiriProgressComponent, XiriQueryComponent, XiriRawTableComponent, XiriResponseHandlerService, XiriSankeyComponent, XiriSearchComponent, XiriSectionComponent, XiriSelectDirective, XiriSessionStorageService, XiriSidenavComponent, XiriSidepanelComponent, XiriSidepanelRef, XiriSidepanelService, XiriSkeletonComponent, XiriSnackbarService, XiriStatComponent, XiriStatGridComponent, XiriStatusComponent, XiriStepperComponent, XiriTableComponent, XiriTabsComponent, XiriTimelineComponent, XiriToolbarComponent, XiriTreeComponent, XiriUrlPipe, colsToClasses, defaultXiriDataServiceConfig, escapeHtml, provideXiriServices, resolveColor };
|
|
8313
8326
|
//# sourceMappingURL=xiriframework-xiri-ng.mjs.map
|