@xiriframework/xiri-ng 0.4.10 → 0.4.12

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.
@@ -31,12 +31,12 @@ import { SelectionModel } from '@angular/cdk/collections';
31
31
  import { filter, takeUntil, debounceTime as debounceTime$1 } from 'rxjs/operators';
32
32
  import * as i2 from 'ngx-mat-select-search';
33
33
  import { NgxMatSelectSearchModule } from 'ngx-mat-select-search';
34
+ import { MatDialog, MatDialogRef, MAT_DIALOG_DATA, MatDialogTitle, MatDialogContent, MatDialogActions } from '@angular/material/dialog';
34
35
  import { ENTER, COMMA, ESCAPE } from '@angular/cdk/keycodes';
35
36
  import { MatAutocompleteTrigger, MatAutocomplete } from '@angular/material/autocomplete';
36
37
  import { MatChipGrid, MatChipRow, MatChipRemove, MatChipInput, MatChipSet, MatChip } from '@angular/material/chips';
37
38
  import { MatTableDataSource, MatTable, MatColumnDef, MatHeaderCellDef, MatHeaderCell, MatCellDef, MatCell, MatHeaderRowDef, MatHeaderRow, MatRowDef, MatRow, MatFooterRow, MatFooterRowDef, MatFooterCell, MatFooterCellDef } from '@angular/material/table';
38
39
  import { MatTooltip } from '@angular/material/tooltip';
39
- import { MatDialogRef, MAT_DIALOG_DATA, MatDialogTitle, MatDialogContent, MatDialogActions, MatDialog } from '@angular/material/dialog';
40
40
  import { MatPaginator } from '@angular/material/paginator';
41
41
  import { MatSort, MatSortHeader } from '@angular/material/sort';
42
42
  import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
@@ -2283,7 +2283,11 @@ class XiriSelectDirective {
2283
2283
  return of([]);
2284
2284
  }));
2285
2285
  }), tap((filteredList) => {
2286
- this.emit(this._allValues.slice().concat(filteredList));
2286
+ // Server kann Optionen liefern, die schon in der Startliste stehen (z. B. eine per addUrl
2287
+ // angelegte): nicht doppelt anzeigen.
2288
+ const known = new Set(this._allValues.map(o => o.id));
2289
+ const fresh = filteredList.filter(o => !known.has(o.id));
2290
+ this.emit(this._allValues.slice().concat(fresh));
2287
2291
  }), tap(() => {
2288
2292
  this.searching = false;
2289
2293
  this.cdr.markForCheck();
@@ -2508,6 +2512,9 @@ class XiriFormFieldsComponent {
2508
2512
  constructor() {
2509
2513
  this.formBuilder = inject(UntypedFormBuilder);
2510
2514
  this.destroyRef = inject(DestroyRef);
2515
+ this.dialog = inject(MatDialog);
2516
+ // Der lazy Import in openAdd() kann nach der Zerstörung auflösen; takeUntilDestroyed greift erst danach.
2517
+ this.destroyed = false;
2511
2518
  this.elementRef = inject(ElementRef);
2512
2519
  this.localeService = inject(XiriLocaleService);
2513
2520
  this.dataService = inject(XiriDataService);
@@ -2564,33 +2571,39 @@ class XiriFormFieldsComponent {
2564
2571
  return fields.map(f => this.patchedClones.get(f.id) ?? f);
2565
2572
  }, /* @ts-ignore */
2566
2573
  ...(ngDevMode ? [{ debugName: "displayFields" }] : /* istanbul ignore next */ []));
2574
+ // Hängt bewusst nur an form(). Der Control-Umbau ist ein Seiteneffekt und läuft untracked:
2575
+ // addControl lässt die FormGroupDirective das neue Control sofort an eine wiederverwendete
2576
+ // Directive binden (writeValue), und MatSelect schreibt dabei ein Signal im KeyManager -
2577
+ // in einer Computed wäre das NG0600.
2567
2578
  this.fields = computed(() => {
2568
- this._fieldsLoaded = false;
2569
- if (this._fields !== null) {
2570
- for (let i = 0; i != this._fields.length; i++) {
2571
- this.formGroup.removeControl(this._fields[i].id);
2572
- }
2573
- this._fields = null;
2574
- }
2575
2579
  const fields = this.form();
2576
- if (fields == null) {
2577
- return null;
2578
- }
2579
- this._fields = fields;
2580
- // Neue Feldliste: alte Render-Kopien und Patch-Stände gehören zum vorherigen Formular.
2581
- this.formGeneration++;
2582
- this.patchedClones.clear();
2583
- this.lastPatch.clear();
2584
- const initialCollapsed = new Set();
2585
- for (const f of fields) {
2586
- if (f.type === 'header' && f.collapsible && f.collapsed)
2587
- initialCollapsed.add(f.id);
2588
- }
2589
- untracked(() => this.collapsedSections.set(initialCollapsed));
2590
- this.createControl();
2591
- this.lastValue = JSON.stringify(this.formGroup.value);
2592
- this._fieldsLoaded = true;
2593
- return this._fields;
2580
+ return untracked(() => {
2581
+ this._fieldsLoaded = false;
2582
+ if (this._fields !== null) {
2583
+ for (let i = 0; i != this._fields.length; i++) {
2584
+ this.formGroup.removeControl(this._fields[i].id);
2585
+ }
2586
+ this._fields = null;
2587
+ }
2588
+ if (fields == null) {
2589
+ return null;
2590
+ }
2591
+ this._fields = fields;
2592
+ // Neue Feldliste: alte Render-Kopien und Patch-Stände gehören zum vorherigen Formular.
2593
+ this.formGeneration++;
2594
+ this.patchedClones.clear();
2595
+ this.lastPatch.clear();
2596
+ const initialCollapsed = new Set();
2597
+ for (const f of fields) {
2598
+ if (f.type === 'header' && f.collapsible && f.collapsed)
2599
+ initialCollapsed.add(f.id);
2600
+ }
2601
+ this.collapsedSections.set(initialCollapsed);
2602
+ this.createControl();
2603
+ this.lastValue = JSON.stringify(this.formGroup.value);
2604
+ this._fieldsLoaded = true;
2605
+ return this._fields;
2606
+ });
2594
2607
  }, /* @ts-ignore */
2595
2608
  ...(ngDevMode ? [{ debugName: "fields" }] : /* istanbul ignore next */ []));
2596
2609
  // Fokussiert nach dem ersten Render das erste sichtbare, interaktive Feld (spart den ersten Klick).
@@ -2610,6 +2623,7 @@ class XiriFormFieldsComponent {
2610
2623
  }
2611
2624
  });
2612
2625
  this.formGroup = this.formBuilder.group({});
2626
+ this.destroyRef.onDestroy(() => this.destroyed = true);
2613
2627
  effect(() => {
2614
2628
  const isDisabled = this.disabled();
2615
2629
  if (isDisabled) {
@@ -2721,6 +2735,50 @@ class XiriFormFieldsComponent {
2721
2735
  return EMPTY;
2722
2736
  }))));
2723
2737
  }
2738
+ // "+"-Button (field.addUrl): öffnet den Server-Dialog per GET und übernimmt die angelegte Option.
2739
+ openAdd(id) {
2740
+ const field = this._fields?.find(f => f.id === id);
2741
+ const control = this.formGroup.get(id);
2742
+ if (!field?.addUrl || !control)
2743
+ return;
2744
+ const url = field.addUrl;
2745
+ // Lazy: dialog.component importiert xiri-form-fields, ein statischer Import wäre ein Zyklus.
2746
+ Promise.resolve().then(function () { return dialog_component; }).then(m => {
2747
+ if (this.destroyed || this.formGroup.get(id) !== control)
2748
+ return;
2749
+ this.dialog.open(m.XiriDialogComponent, { data: { type: 'load', url } })
2750
+ .afterClosed()
2751
+ .pipe(takeUntilDestroyed(this.destroyRef))
2752
+ .subscribe((res) => this.addOption(id, control, res));
2753
+ }).catch(err => console.error('xiri-form-fields: dialog import failed', err));
2754
+ }
2755
+ addOption(id, control, res) {
2756
+ const field = this._fields?.find(f => f.id === id);
2757
+ const { done, created } = (res ?? {});
2758
+ // Das Formular kann inzwischen gewechselt haben (auch mit gleicher Feld-ID): nur ins Control
2759
+ // schreiben, das den Dialog geöffnet hat.
2760
+ if (!field || this.formGroup.get(id) !== control || control.disabled || done !== true || !isCreatedOption(created))
2761
+ return;
2762
+ // Bei chips sind Strings Freitext, nur Zahlen werden als Option aufgelöst.
2763
+ if (field.type === 'chips' && typeof created.id !== 'number')
2764
+ return;
2765
+ if (!collectOptionIds(field.list ?? []).has(created.id))
2766
+ field.list = [...(field.list ?? []), { id: created.id, name: created.name }];
2767
+ // Nicht über Array.isArray entscheiden: ein leeres Single-Select startet intern mit [].
2768
+ if (field.multiple || field.type === 'treeselect' || field.type === 'chips') {
2769
+ const current = Array.isArray(control.value) ? control.value : [];
2770
+ if (!current.includes(created.id)) {
2771
+ control.markAsDirty();
2772
+ control.setValue([...current, created.id]);
2773
+ }
2774
+ }
2775
+ else if (control.value !== created.id) {
2776
+ control.markAsDirty();
2777
+ control.setValue(created.id);
2778
+ }
2779
+ this.patchedClones.set(id, { ...field });
2780
+ this.patchVersion.update(v => v + 1);
2781
+ }
2724
2782
  applyPatch(url, patch) {
2725
2783
  const fields = this._fields;
2726
2784
  if (fields === null || !patch)
@@ -3103,7 +3161,7 @@ class XiriFormFieldsComponent {
3103
3161
  }
3104
3162
  }
3105
3163
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: XiriFormFieldsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3106
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: XiriFormFieldsComponent, isStandalone: true, selector: "xiri-form-fields", inputs: { form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: false, transformFunction: null }, display: { classPropertyName: "display", publicName: "display", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, check: { classPropertyName: "check", publicName: "check", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { formChange: "formChange" }, ngImport: i0, template: "@if (reloading()) {\n\t<mat-progress-bar class=\"reloadbar\" mode=\"indeterminate\"></mat-progress-bar>\n}\n<form class=\"xrow dynamic-form\" [formGroup]=\"formGroup\" [class]=\"display()\">\n\t@for (field of displayFields(); track field.id) {\n\t\t@if (isFieldVisible(field)) {\n\t\t@switch (field.type) {\n\t\t\t@case ('text') {\n\t\t\t\t<mat-form-field [class]=\"field.class\" [formGroup]=\"formGroup\" floatLabel=\"auto\" [hidden]=\"field.hide\">\n\t\t\t\t\t@if (field.name) {\n\t\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t}\n\t\t\t\t\t<input matInput\n\t\t\t\t\t [formControlName]=\"field.id\"\n\t\t\t\t\t [type]=\"field.subtype || 'text'\"\n\t\t\t\t\t [autocomplete]=\"field.name\"\n\t\t\t\t\t [attr.minlength]=\"field.min\"\n\t\t\t\t\t [attr.maxlength]=\"field.max\"\n\t\t\t\t\t [required]=\"!!field.required\">\n\t\t\t\t\t@if (field.textPrefix) {\n\t\t\t\t\t\t<span matTextPrefix=\"\">{{ field.textPrefix }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.textSuffix) {\n\t\t\t\t\t\t<span matTextSuffix=\"\">{{ field.textSuffix }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.iconPrefix) {\n\t\t\t\t\t\t<mat-icon matPrefix>{{ field.iconPrefix }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.iconSuffix) {\n\t\t\t\t\t\t<mat-icon matSuffix>{{ field.iconSuffix }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.max) {\n\t\t\t\t\t\t<mat-hint align=\"end\">{{ formGroup.get(field.id)?.value?.length || 0 }} / {{ field.max }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('number') {\n\t\t\t\t<mat-form-field [class]=\"field.class\" [formGroup]=\"formGroup\" floatLabel=\"auto\" [hidden]=\"field.hide\">\n\t\t\t\t\t@if (field.name) {\n\t\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t}\n\t\t\t\t\t<input matInput\n\t\t\t\t\t [formControlName]=\"field.id\"\n\t\t\t\t\t [autocomplete]=\"field.name || field.id\"\n\t\t\t\t\t [lang]=\"field.locale || ''\"\n\t\t\t\t\t [type]=\"field.type\"\n\t\t\t\t\t [attr.min]=\"field.min\"\n\t\t\t\t\t [attr.max]=\"field.max\"\n\t\t\t\t\t [required]=\"!!field.required\">\n\t\t\t\t\t@if (field.textPrefix) {\n\t\t\t\t\t\t<span matTextPrefix=\"\">{{ field.textPrefix }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.textSuffix) {\n\t\t\t\t\t\t<span matTextSuffix=\"\">{{ field.textSuffix }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.iconPrefix) {\n\t\t\t\t\t\t<mat-icon matPrefix>{{ field.iconPrefix }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.iconSuffix) {\n\t\t\t\t\t\t<mat-icon matSuffix>{{ field.iconSuffix }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('password') {\n\t\t\t\t<mat-form-field [class]=\"field.class\" [formGroup]=\"formGroup\" floatLabel=\"auto\" [hidden]=\"field.hide\">\n\t\t\t\t\t@if (field.name) {\n\t\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t}\n\t\t\t\t\t<input matInput\n\t\t\t\t\t [formControlName]=\"field.id\"\n\t\t\t\t\t [type]=\"field.pwdhide ? 'password' : 'text'\"\n\t\t\t\t\t [autocomplete]=\"field.name\"\n\t\t\t\t\t [attr.minlength]=\"field.min\"\n\t\t\t\t\t [attr.maxlength]=\"field.max\"\n\t\t\t\t\t [required]=\"!!field.required\">\n\t\t\t\t\t<button mat-icon-button matSuffix class=\"form-field-button\" (click)=\"field.pwdhide = !field.pwdhide\" [attr.aria-label]=\"'Hide password'\"\n\t\t\t\t\t [attr.aria-pressed]=\"field.pwdhide\">\n\t\t\t\t\t\t<mat-icon>{{ field.pwdhide ? 'visibility_off' : 'visibility' }}</mat-icon>\n\t\t\t\t\t</button>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.max) {\n\t\t\t\t\t\t<mat-hint align=\"end\">{{ formGroup.get(field.id)?.value?.length || 0 }} / {{ field.max }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('select') {\n\t\t\t\t<mat-form-field [class]=\"field.class\" [formGroup]=\"formGroup\" floatLabel=\"auto\" [hidden]=\"field.hide\">\n\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t@if (field.search === false && !field.selectAll) {\n\t\t\t\t\t\t<mat-select [formControlName]=\"field.id\" [multiple]=\"field.multiple\" [required]=\"!!field.required\" panelClass=\"selectPanel\">\n\t\t\t\t\t\t\t@for (x of field.list; track x.id) {\n\t\t\t\t\t\t\t\t<mat-option [value]=\"x.id\" [disabled]=\"x.disabled\">{{ x.name }}</mat-option>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</mat-select>\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<mat-select [formControlName]=\"field.id\" [multiple]=\"field.multiple\" [required]=\"!!field.required\" panelClass=\"selectPanel\">\n\t\t\t\t\t\t\t<mat-option>\n\t\t\t\t\t\t\t\t<ngx-mat-select-search [formControl]=\"xiriSelect.formControl\" xiriSelect #xiriSelect=\"xiriSelect\"\n\t\t\t\t\t\t\t\t [values]=\"field.list || []\" [searching]=\"xiriSelect.searching\"\n\t\t\t\t\t\t\t\t [serverSideSearch]=\"!!field.serverSideSearch\" [serverUrl]=\"field.url || ''\"\n\t\t\t\t\t\t\t\t [serverParams]=\"field.params || {}\"\n\t\t\t\t\t\t\t\t [showToggleAllCheckbox]=\"!!field.multiple && !!field.selectAll && xiriSelect.hasSelectable()\"\n\t\t\t\t\t\t\t\t [toggleAllCheckboxChecked]=\"!!field.multiple && !!field.selectAll && xiriSelect.allSelected(formGroup.get(field.id)?.value)\"\n\t\t\t\t\t\t\t\t [toggleAllCheckboxIndeterminate]=\"!!field.multiple && !!field.selectAll && xiriSelect.someSelected(formGroup.get(field.id)?.value)\"\n\t\t\t\t\t\t\t\t (toggleAll)=\"xiriSelect.toggleSelectAll($event, formGroup.get(field.id))\"></ngx-mat-select-search>\n\t\t\t\t\t\t\t</mat-option>\n\t\t\t\t\t\t\t@for (x of xiriSelect.filter | async; track x.id) {\n\t\t\t\t\t\t\t\t<mat-option [value]=\"x.id\" [disabled]=\"x.disabled\">{{ x.name }}</mat-option>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</mat-select>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('treeselect') {\n\t\t\t\t<div class=\"treeselect\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<xiri-treeselect [field]=\"field\" [formControlName]=\"field.id\"\n\t\t\t\t\t [class.error]=\"formGroup.get(field.id)?.touched && formGroup.get(field.id)?.invalid\"></xiri-treeselect>\n\t\t\t\t\t<div class=\"xhint\" aria-live=\"polite\" [class.error]=\"formGroup.get(field.id)?.touched && formGroup.get(field.id)?.invalid\">\n\t\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (field.max) {\n\t\t\t\t\t\t\t<mat-hint align=\"end\">{{ formGroup.get(field.id)?.value?.length || 0 }} / {{ field.max }}</mat-hint>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.touched && formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('date') {\n\t\t\t\t<mat-form-field [formGroup]=\"formGroup\" class=\"date\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t<xiri-date [field]=\"field\" [formControlName]=\"field.id\"></xiri-date>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('yearmonth') {\n\t\t\t\t<mat-form-field [formGroup]=\"formGroup\" class=\"yearmonth\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t<xiri-yearmonth [field]=\"field\" [formControlName]=\"field.id\"></xiri-yearmonth>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('daterange') {\n\t\t\t\t<mat-form-field [formGroup]=\"formGroup\" class=\"daterange\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t<xiri-date-range [field]=\"field\" [formControlName]=\"field.id\"></xiri-date-range>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('datetimerange') {\n\t\t\t\t<mat-form-field [formGroup]=\"formGroup\" class=\"datetimerange\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t<xiri-date-time-range [field]=\"field\" [formControlName]=\"field.id\"></xiri-date-time-range>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('bool') {\n\t\t\t\t<div class=\"bool\" [class]=\"field.class\" [formGroup]=\"formGroup\" [hidden]=\"field.hide\">\n\t\t\t\t\t<mat-checkbox [formControlName]=\"field.id\">{{ field.name }}</mat-checkbox>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('radio') {\n\t\t\t\t<div class=\"radio\" [class]=\"field.class\" [formGroup]=\"formGroup\" [hidden]=\"field.hide\">\n\t\t\t\t\t@if (field.name) {\n\t\t\t\t\t\t<span class=\"radio-label\" [id]=\"field.id + '-label'\">{{ field.name }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t<mat-radio-group\n\t\t\t\t\t\t[formControlName]=\"field.id\"\n\t\t\t\t\t\t[attr.aria-labelledby]=\"field.name ? field.id + '-label' : null\"\n\t\t\t\t\t>\n\t\t\t\t\t\t@for (x of field.list; track x.id) {\n\t\t\t\t\t\t\t<mat-radio-button [value]=\"x.id\" [disabled]=\"x.disabled\">{{ x.name }}</mat-radio-button>\n\t\t\t\t\t\t}\n\t\t\t\t\t</mat-radio-group>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('volume') {\n\t\t\t\t<div [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<xiri-volume [field]=\"field\" [formControlName]=\"field.id\"></xiri-volume>\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('timelimit') {\n\t\t\t\t<div [class]=\"field.class\" [formGroup]=\"formGroup\" [hidden]=\"field.hide\">\n\t\t\t\t\t<xiri-timelimit matInput [formControlName]=\"field.id\" [required]=\"!!field.required\" [texts]=\"field.texts || {}\"></xiri-timelimit>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('textarea') {\n\t\t\t\t<mat-form-field [class]=\"field.class\" [formGroup]=\"formGroup\" [hidden]=\"field.hide\">\n\t\t\t\t\t@if (field.name) {\n\t\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t}\n\t\t\t\t\t<textarea matInput [formControlName]=\"field.id\" [required]=\"!!field.required\" [rows]=\"field.rows || 5\"></textarea>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.max) {\n\t\t\t\t\t\t<mat-hint align=\"end\">{{ formGroup.get(field.id)?.value?.length || 0 }} / {{ field.max }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('file') {\n\t\t\t\t<div [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<xiri-file [field]=\"field\" [formControlName]=\"field.id\"></xiri-file>\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('info') {\n\t\t\t\t<div class=\"info\" [class]=\"field.class\">{{ field.value }}</div>\n\t\t\t}\n\t\t\t@case ('header') {\n\t\t\t\t@if (field.collapsible) {\n\t\t\t\t\t<div class=\"header collapsible\" [class]=\"field.class\" role=\"button\" tabindex=\"0\"\n\t\t\t\t\t [attr.aria-expanded]=\"!isSectionCollapsed(field.id)\"\n\t\t\t\t\t (click)=\"toggleSection(field)\" (keydown.enter)=\"toggleSection(field)\" (keydown.space)=\"toggleSection(field); $event.preventDefault()\">\n\t\t\t\t\t\t<mat-icon class=\"collapse-icon\" [class.collapsed]=\"isSectionCollapsed(field.id)\">expand_more</mat-icon>\n\t\t\t\t\t\t{{ field.value }}\n\t\t\t\t\t</div>\n\t\t\t\t} @else {\n\t\t\t\t\t<div class=\"header\" [class]=\"field.class\">{{ field.value }}</div>\n\t\t\t\t}\n\t\t\t}\n\t\t\t@case ('divider') {\n\t\t\t\t<div class=\"divider\" [class]=\"field.class\">\n\t\t\t\t\t@if (field.value) {\n\t\t\t\t\t\t<span class=\"divider-text\">{{ field.value }}</span>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('html') {\n\t\t\t\t<div class=\"html\" [class]=\"field.class\" [innerHtml]=\"$any(field.value) | safeHtml\"></div>\n\t\t\t}\n\t\t\t@case ('question') {\n\t\t\t\t<div class=\"xcol question\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<div class=\"left\">\n\t\t\t\t\t\t<mat-icon [class]=\"field.iconColor || 'warn'\" inline=\"true\">{{ field.icon }}</mat-icon>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"right\">{{ field.value }}</div>\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('waiting') {\n\t\t\t\t<div class=\"xcol waiting\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<div class=\"left\">\n\t\t\t\t\t\t@if (!field.done) {\n\t\t\t\t\t\t\t<mat-spinner diameter=\"40\"></mat-spinner>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (field.done) {\n\t\t\t\t\t\t\t<mat-icon inline=\"true\">done</mat-icon>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"right\">{{ field.value }}</div>\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('chips') {\n\t\t\t\t<div [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<xiri-chips [field]=\"field\" [formControlName]=\"field.id\"></xiri-chips>\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@default {\n\t\t\t\t<div>default: {{ field.type }}</div>\n\t\t\t}\n\t\t}\n\t\t}\n\t}\n</form>\n", styles: [":host{position:relative}.reloadbar{position:absolute;top:0;left:0;right:0;z-index:1}.dynamic-form{grid-row-gap:7px}.dynamic-form>mat-form-field{align-self:start}.dynamic-form mat-form-field mat-icon{--mat-icon-color: var(--xiri-formfield-icon-color)}.dynamic-form.line{grid-row-gap:5px}.dynamic-form.small{grid-row-gap:2px}.dynamic-form textarea{white-space:pre}.dynamic-form .xhint{display:flex;min-height:20px;margin-top:4px}.dynamic-form .xhint mat-hint{font-size:var(--xiri-font-size-helper);padding:1px 16px 0}.dynamic-form .xhint mat-hint.mat-mdc-form-field-hint-end{flex:1;text-align:right}.dynamic-form .xhint mat-error{font-size:var(--xiri-font-size-helper);padding:1px 16px 0}.dynamic-form .xhint.error mat-hint{display:none}.dynamic-form .date{min-width:min(9.5rem,100%)}.dynamic-form .date.datetime,.dynamic-form .daterange{min-width:min(14.5rem,100%)}.dynamic-form .datetimerange{min-width:min(18.5rem,100%)}.dynamic-form .bool{display:flex;flex-direction:column}.dynamic-form .bool mat-hint{font-size:var(--xiri-font-size-helper);margin-top:-8px;padding-left:44px}.dynamic-form .radio{display:flex;flex-direction:column;gap:var(--xiri-spacing-xs)}.dynamic-form .radio .radio-label{font-size:var(--xiri-font-size-label)}.dynamic-form .radio mat-radio-group{display:flex;flex-wrap:wrap;gap:var(--xiri-spacing-xs) var(--xiri-spacing-md)}.dynamic-form .radio mat-hint{font-size:var(--xiri-font-size-helper)}.dynamic-form .info{padding-top:.8rem;padding-bottom:.4rem;color:var(--primary, #2892D9)}.dynamic-form .header{font-size:var(--xiri-font-size-title);padding-top:.8rem;padding-bottom:.4rem;color:var(--primary, #2892D9)}.dynamic-form .header.collapsible{cursor:pointer;display:flex;align-items:center;gap:.25rem;-webkit-user-select:none;user-select:none;border-radius:var(--xiri-radius-xs);padding:.5rem .25rem;margin:.25rem 0}.dynamic-form .header.collapsible:hover{background:color-mix(in srgb,var(--primary, #2892D9) 8%,transparent)}.dynamic-form .header.collapsible .collapse-icon{transition:transform var(--xiri-duration-fast) var(--xiri-easing-standard)}.dynamic-form .header.collapsible .collapse-icon.collapsed{transform:rotate(-90deg)}.dynamic-form .divider{width:100%;display:flex;align-items:center;padding:.5rem 0;margin:.25rem 0}.dynamic-form .divider:before,.dynamic-form .divider:after{content:\"\";flex:1;height:1px;background:var(--outline-variant, var(--mat-sys-outline-variant, rgba(0, 0, 0, .12)))}.dynamic-form .divider .divider-text{padding:0 1rem;font-size:var(--xiri-font-size-helper);color:var(--on-surface-variant, var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6)));white-space:nowrap}.dynamic-form .question,.dynamic-form .waiting{display:flex}.dynamic-form .question .left,.dynamic-form .waiting .left{font-size:var(--xiri-font-size-display);padding-right:1rem}.dynamic-form .question{align-items:center}.dynamic-form .question .left mat-icon{height:auto;width:auto;line-height:1;overflow:visible}.dynamic-form .form-field-button{margin-left:12px;margin-right:12px}.mat-mdc-select-panel.selectPanel{max-height:max(50vh,256px)}[hidden]{display:none!important}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: 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: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: NgxMatSelectSearchModule }, { kind: "component", type: i2.MatSelectSearchComponent, selector: "ngx-mat-select-search", inputs: ["placeholderLabel", "type", "closeIcon", "closeSvgIcon", "noEntriesFoundLabel", "clearSearchInput", "searching", "disableInitialFocus", "enableClearOnEscapePressed", "preventHomeEndKeyPropagation", "disableScrollToActiveOnOptionsChanged", "ariaLabel", "showToggleAllCheckbox", "toggleAllCheckboxChecked", "toggleAllCheckboxIndeterminate", "toggleAllCheckboxTooltipMessage", "toggleAllCheckboxTooltipPosition", "hideClearSearchButton", "alwaysRestoreSelectedOptionsMulti", "recreateValuesArray"], outputs: ["toggleAll"] }, { kind: "directive", type: XiriSelectDirective, selector: "[xiriSelect]", inputs: ["predicate", "compare", "serverSideSearch", "serverUrl", "serverParams", "values"], exportAs: ["xiriSelect"] }, { kind: "component", type: XiriTreeselectComponent, selector: "xiri-treeselect", inputs: ["field", "value"] }, { kind: "component", type: XiriDateComponent, selector: "xiri-date", inputs: ["field", "value"] }, { kind: "component", type: XiriYearMonthComponent, selector: "xiri-yearmonth", inputs: ["field", "value"] }, { kind: "component", type: XiriDateRangeComponent, selector: "xiri-date-range", inputs: ["field", "value"] }, { kind: "component", type: XiriDateTimeRangeComponent, selector: "xiri-date-time-range", inputs: ["field", "value"] }, { kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: MatRadioButton, selector: "mat-radio-button", inputs: ["id", "name", "aria-label", "aria-labelledby", "aria-describedby", "disableRipple", "tabIndex", "checked", "value", "labelPosition", "disabled", "required", "color", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioButton"] }, { kind: "directive", type: MatRadioGroup, selector: "mat-radio-group", inputs: ["color", "name", "labelPosition", "value", "selected", "disabled", "required", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioGroup"] }, { kind: "component", type: XiriVolumeComponent, selector: "xiri-volume", inputs: ["field", "value"] }, { kind: "component", type: XiriTimelimitComponent, selector: "xiri-timelimit", inputs: ["placeholder", "required", "disabled", "value", "texts"] }, { kind: "component", type: XiriFileComponent, selector: "xiri-file", inputs: ["value", "field"] }, { kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: XiriChipsComponent, selector: "xiri-chips", inputs: ["field"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: SafehtmlPipe, name: "safeHtml" }] }); }
3164
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: XiriFormFieldsComponent, isStandalone: true, selector: "xiri-form-fields", inputs: { form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: false, transformFunction: null }, display: { classPropertyName: "display", publicName: "display", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, check: { classPropertyName: "check", publicName: "check", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { formChange: "formChange" }, ngImport: i0, template: "@if (reloading()) {\n\t<mat-progress-bar class=\"reloadbar\" mode=\"indeterminate\"></mat-progress-bar>\n}\n<form class=\"xrow dynamic-form\" [formGroup]=\"formGroup\" [class]=\"display()\">\n\t@for (field of displayFields(); track field.id) {\n\t\t@if (isFieldVisible(field)) {\n\t\t@switch (field.type) {\n\t\t\t@case ('text') {\n\t\t\t\t<mat-form-field [class]=\"field.class\" [formGroup]=\"formGroup\" floatLabel=\"auto\" [hidden]=\"field.hide\">\n\t\t\t\t\t@if (field.name) {\n\t\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t}\n\t\t\t\t\t<input matInput\n\t\t\t\t\t [formControlName]=\"field.id\"\n\t\t\t\t\t [type]=\"field.subtype || 'text'\"\n\t\t\t\t\t [autocomplete]=\"field.name\"\n\t\t\t\t\t [attr.minlength]=\"field.min\"\n\t\t\t\t\t [attr.maxlength]=\"field.max\"\n\t\t\t\t\t [required]=\"!!field.required\">\n\t\t\t\t\t@if (field.textPrefix) {\n\t\t\t\t\t\t<span matTextPrefix=\"\">{{ field.textPrefix }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.textSuffix) {\n\t\t\t\t\t\t<span matTextSuffix=\"\">{{ field.textSuffix }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.iconPrefix) {\n\t\t\t\t\t\t<mat-icon matPrefix>{{ field.iconPrefix }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.iconSuffix) {\n\t\t\t\t\t\t<mat-icon matSuffix>{{ field.iconSuffix }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.max) {\n\t\t\t\t\t\t<mat-hint align=\"end\">{{ formGroup.get(field.id)?.value?.length || 0 }} / {{ field.max }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('number') {\n\t\t\t\t<mat-form-field [class]=\"field.class\" [formGroup]=\"formGroup\" floatLabel=\"auto\" [hidden]=\"field.hide\">\n\t\t\t\t\t@if (field.name) {\n\t\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t}\n\t\t\t\t\t<input matInput\n\t\t\t\t\t [formControlName]=\"field.id\"\n\t\t\t\t\t [autocomplete]=\"field.name || field.id\"\n\t\t\t\t\t [lang]=\"field.locale || ''\"\n\t\t\t\t\t [type]=\"field.type\"\n\t\t\t\t\t [attr.min]=\"field.min\"\n\t\t\t\t\t [attr.max]=\"field.max\"\n\t\t\t\t\t [required]=\"!!field.required\">\n\t\t\t\t\t@if (field.textPrefix) {\n\t\t\t\t\t\t<span matTextPrefix=\"\">{{ field.textPrefix }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.textSuffix) {\n\t\t\t\t\t\t<span matTextSuffix=\"\">{{ field.textSuffix }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.iconPrefix) {\n\t\t\t\t\t\t<mat-icon matPrefix>{{ field.iconPrefix }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.iconSuffix) {\n\t\t\t\t\t\t<mat-icon matSuffix>{{ field.iconSuffix }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('password') {\n\t\t\t\t<mat-form-field [class]=\"field.class\" [formGroup]=\"formGroup\" floatLabel=\"auto\" [hidden]=\"field.hide\">\n\t\t\t\t\t@if (field.name) {\n\t\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t}\n\t\t\t\t\t<input matInput\n\t\t\t\t\t [formControlName]=\"field.id\"\n\t\t\t\t\t [type]=\"field.pwdhide ? 'password' : 'text'\"\n\t\t\t\t\t [autocomplete]=\"field.name\"\n\t\t\t\t\t [attr.minlength]=\"field.min\"\n\t\t\t\t\t [attr.maxlength]=\"field.max\"\n\t\t\t\t\t [required]=\"!!field.required\">\n\t\t\t\t\t<button mat-icon-button matSuffix class=\"form-field-button\" (click)=\"field.pwdhide = !field.pwdhide\" [attr.aria-label]=\"'Hide password'\"\n\t\t\t\t\t [attr.aria-pressed]=\"field.pwdhide\">\n\t\t\t\t\t\t<mat-icon>{{ field.pwdhide ? 'visibility_off' : 'visibility' }}</mat-icon>\n\t\t\t\t\t</button>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.max) {\n\t\t\t\t\t\t<mat-hint align=\"end\">{{ formGroup.get(field.id)?.value?.length || 0 }} / {{ field.max }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('select') {\n\t\t\t\t<div class=\"add-wrap\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t<mat-form-field class=\"add-wrap-control\" [formGroup]=\"formGroup\" floatLabel=\"auto\">\n\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t@if (field.search === false && !field.selectAll) {\n\t\t\t\t\t\t<mat-select [formControlName]=\"field.id\" [multiple]=\"field.multiple\" [required]=\"!!field.required\" panelClass=\"selectPanel\">\n\t\t\t\t\t\t\t@for (x of field.list; track x.id) {\n\t\t\t\t\t\t\t\t<mat-option [value]=\"x.id\" [disabled]=\"x.disabled\">{{ x.name }}</mat-option>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</mat-select>\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<mat-select [formControlName]=\"field.id\" [multiple]=\"field.multiple\" [required]=\"!!field.required\" panelClass=\"selectPanel\">\n\t\t\t\t\t\t\t<mat-option>\n\t\t\t\t\t\t\t\t<ngx-mat-select-search [formControl]=\"xiriSelect.formControl\" xiriSelect #xiriSelect=\"xiriSelect\"\n\t\t\t\t\t\t\t\t [values]=\"field.list || []\" [searching]=\"xiriSelect.searching\"\n\t\t\t\t\t\t\t\t [serverSideSearch]=\"!!field.serverSideSearch\" [serverUrl]=\"field.url || ''\"\n\t\t\t\t\t\t\t\t [serverParams]=\"field.params || {}\"\n\t\t\t\t\t\t\t\t [showToggleAllCheckbox]=\"!!field.multiple && !!field.selectAll && xiriSelect.hasSelectable()\"\n\t\t\t\t\t\t\t\t [toggleAllCheckboxChecked]=\"!!field.multiple && !!field.selectAll && xiriSelect.allSelected(formGroup.get(field.id)?.value)\"\n\t\t\t\t\t\t\t\t [toggleAllCheckboxIndeterminate]=\"!!field.multiple && !!field.selectAll && xiriSelect.someSelected(formGroup.get(field.id)?.value)\"\n\t\t\t\t\t\t\t\t (toggleAll)=\"xiriSelect.toggleSelectAll($event, formGroup.get(field.id))\"></ngx-mat-select-search>\n\t\t\t\t\t\t\t</mat-option>\n\t\t\t\t\t\t\t@for (x of xiriSelect.filter | async; track x.id) {\n\t\t\t\t\t\t\t\t<mat-option [value]=\"x.id\" [disabled]=\"x.disabled\">{{ x.name }}</mat-option>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</mat-select>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t\t@if (field.addUrl) {\n\t\t\t\t\t<button mat-icon-button type=\"button\" class=\"add-option\" aria-label=\"Neu anlegen\"\n\t\t\t\t\t [disabled]=\"disabled() || formGroup.get(field.id)?.disabled\" (click)=\"openAdd(field.id)\"><mat-icon>add</mat-icon></button>\n\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('treeselect') {\n\t\t\t\t<div class=\"treeselect add-wrap\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t<div class=\"add-wrap-control\">\n\t\t\t\t\t<xiri-treeselect [field]=\"field\" [formControlName]=\"field.id\"\n\t\t\t\t\t [class.error]=\"formGroup.get(field.id)?.touched && formGroup.get(field.id)?.invalid\"></xiri-treeselect>\n\t\t\t\t\t<div class=\"xhint\" aria-live=\"polite\" [class.error]=\"formGroup.get(field.id)?.touched && formGroup.get(field.id)?.invalid\">\n\t\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (field.max) {\n\t\t\t\t\t\t\t<mat-hint align=\"end\">{{ formGroup.get(field.id)?.value?.length || 0 }} / {{ field.max }}</mat-hint>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.touched && formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t@if (field.addUrl) {\n\t\t\t\t\t<button mat-icon-button type=\"button\" class=\"add-option\" aria-label=\"Neu anlegen\"\n\t\t\t\t\t [disabled]=\"disabled() || formGroup.get(field.id)?.disabled\" (click)=\"openAdd(field.id)\"><mat-icon>add</mat-icon></button>\n\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('date') {\n\t\t\t\t<mat-form-field [formGroup]=\"formGroup\" class=\"date\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t<xiri-date [field]=\"field\" [formControlName]=\"field.id\"></xiri-date>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('yearmonth') {\n\t\t\t\t<mat-form-field [formGroup]=\"formGroup\" class=\"yearmonth\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t<xiri-yearmonth [field]=\"field\" [formControlName]=\"field.id\"></xiri-yearmonth>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('daterange') {\n\t\t\t\t<mat-form-field [formGroup]=\"formGroup\" class=\"daterange\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t<xiri-date-range [field]=\"field\" [formControlName]=\"field.id\"></xiri-date-range>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('datetimerange') {\n\t\t\t\t<mat-form-field [formGroup]=\"formGroup\" class=\"datetimerange\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t<xiri-date-time-range [field]=\"field\" [formControlName]=\"field.id\"></xiri-date-time-range>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('bool') {\n\t\t\t\t<div class=\"bool\" [class]=\"field.class\" [formGroup]=\"formGroup\" [hidden]=\"field.hide\">\n\t\t\t\t\t<mat-checkbox [formControlName]=\"field.id\">{{ field.name }}</mat-checkbox>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('radio') {\n\t\t\t\t<div class=\"radio\" [class]=\"field.class\" [formGroup]=\"formGroup\" [hidden]=\"field.hide\">\n\t\t\t\t\t@if (field.name) {\n\t\t\t\t\t\t<span class=\"radio-label\" [id]=\"field.id + '-label'\">{{ field.name }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t<mat-radio-group\n\t\t\t\t\t\t[formControlName]=\"field.id\"\n\t\t\t\t\t\t[attr.aria-labelledby]=\"field.name ? field.id + '-label' : null\"\n\t\t\t\t\t>\n\t\t\t\t\t\t@for (x of field.list; track x.id) {\n\t\t\t\t\t\t\t<mat-radio-button [value]=\"x.id\" [disabled]=\"x.disabled\">{{ x.name }}</mat-radio-button>\n\t\t\t\t\t\t}\n\t\t\t\t\t</mat-radio-group>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('volume') {\n\t\t\t\t<div [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<xiri-volume [field]=\"field\" [formControlName]=\"field.id\"></xiri-volume>\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('timelimit') {\n\t\t\t\t<div [class]=\"field.class\" [formGroup]=\"formGroup\" [hidden]=\"field.hide\">\n\t\t\t\t\t<xiri-timelimit matInput [formControlName]=\"field.id\" [required]=\"!!field.required\" [texts]=\"field.texts || {}\"></xiri-timelimit>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('textarea') {\n\t\t\t\t<mat-form-field [class]=\"field.class\" [formGroup]=\"formGroup\" [hidden]=\"field.hide\">\n\t\t\t\t\t@if (field.name) {\n\t\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t}\n\t\t\t\t\t<textarea matInput [formControlName]=\"field.id\" [required]=\"!!field.required\" [rows]=\"field.rows || 5\"></textarea>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.max) {\n\t\t\t\t\t\t<mat-hint align=\"end\">{{ formGroup.get(field.id)?.value?.length || 0 }} / {{ field.max }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('file') {\n\t\t\t\t<div [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<xiri-file [field]=\"field\" [formControlName]=\"field.id\"></xiri-file>\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('info') {\n\t\t\t\t<div class=\"info\" [class]=\"field.class\">{{ field.value }}</div>\n\t\t\t}\n\t\t\t@case ('header') {\n\t\t\t\t@if (field.collapsible) {\n\t\t\t\t\t<div class=\"header collapsible\" [class]=\"field.class\" role=\"button\" tabindex=\"0\"\n\t\t\t\t\t [attr.aria-expanded]=\"!isSectionCollapsed(field.id)\"\n\t\t\t\t\t (click)=\"toggleSection(field)\" (keydown.enter)=\"toggleSection(field)\" (keydown.space)=\"toggleSection(field); $event.preventDefault()\">\n\t\t\t\t\t\t<mat-icon class=\"collapse-icon\" [class.collapsed]=\"isSectionCollapsed(field.id)\">expand_more</mat-icon>\n\t\t\t\t\t\t{{ field.value }}\n\t\t\t\t\t</div>\n\t\t\t\t} @else {\n\t\t\t\t\t<div class=\"header\" [class]=\"field.class\">{{ field.value }}</div>\n\t\t\t\t}\n\t\t\t}\n\t\t\t@case ('divider') {\n\t\t\t\t<div class=\"divider\" [class]=\"field.class\">\n\t\t\t\t\t@if (field.value) {\n\t\t\t\t\t\t<span class=\"divider-text\">{{ field.value }}</span>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('html') {\n\t\t\t\t<div class=\"html\" [class]=\"field.class\" [innerHtml]=\"$any(field.value) | safeHtml\"></div>\n\t\t\t}\n\t\t\t@case ('question') {\n\t\t\t\t<div class=\"xcol question\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<div class=\"left\">\n\t\t\t\t\t\t<mat-icon [class]=\"field.iconColor || 'warn'\" inline=\"true\">{{ field.icon }}</mat-icon>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"right\">{{ field.value }}</div>\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('waiting') {\n\t\t\t\t<div class=\"xcol waiting\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<div class=\"left\">\n\t\t\t\t\t\t@if (!field.done) {\n\t\t\t\t\t\t\t<mat-spinner diameter=\"40\"></mat-spinner>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (field.done) {\n\t\t\t\t\t\t\t<mat-icon inline=\"true\">done</mat-icon>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"right\">{{ field.value }}</div>\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('chips') {\n\t\t\t\t<div class=\"add-wrap\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<xiri-chips class=\"add-wrap-control\" [field]=\"field\" [formControlName]=\"field.id\"></xiri-chips>\n\t\t\t\t\t@if (field.addUrl) {\n\t\t\t\t\t\t<button mat-icon-button type=\"button\" class=\"add-option\" aria-label=\"Neu anlegen\"\n\t\t\t\t\t\t [disabled]=\"disabled() || formGroup.get(field.id)?.disabled\" (click)=\"openAdd(field.id)\"><mat-icon>add</mat-icon></button>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@default {\n\t\t\t\t<div>default: {{ field.type }}</div>\n\t\t\t}\n\t\t}\n\t\t}\n\t}\n</form>\n", styles: [":host{position:relative}.reloadbar{position:absolute;top:0;left:0;right:0;z-index:1}.dynamic-form{grid-row-gap:7px}.dynamic-form>mat-form-field,.dynamic-form>.add-wrap{align-self:start}.dynamic-form .add-wrap{display:flex;align-items:flex-start;gap:4px}.dynamic-form .add-wrap .add-wrap-control{flex:1;min-width:0}.dynamic-form .add-wrap .add-option{margin-top:4px}.dynamic-form mat-form-field mat-icon{--mat-icon-color: var(--xiri-formfield-icon-color)}.dynamic-form.line{grid-row-gap:5px}.dynamic-form.small{grid-row-gap:2px}.dynamic-form textarea{white-space:pre}.dynamic-form .xhint{display:flex;min-height:20px;margin-top:4px}.dynamic-form .xhint mat-hint{font-size:var(--xiri-font-size-helper);padding:1px 16px 0}.dynamic-form .xhint mat-hint.mat-mdc-form-field-hint-end{flex:1;text-align:right}.dynamic-form .xhint mat-error{font-size:var(--xiri-font-size-helper);padding:1px 16px 0}.dynamic-form .xhint.error mat-hint{display:none}.dynamic-form .date{min-width:min(9.5rem,100%)}.dynamic-form .date.datetime,.dynamic-form .daterange{min-width:min(14.5rem,100%)}.dynamic-form .datetimerange{min-width:min(18.5rem,100%)}.dynamic-form .bool{display:flex;flex-direction:column}.dynamic-form .bool mat-hint{font-size:var(--xiri-font-size-helper);margin-top:-8px;padding-left:44px}.dynamic-form .radio{display:flex;flex-direction:column;gap:var(--xiri-spacing-xs)}.dynamic-form .radio .radio-label{font-size:var(--xiri-font-size-label)}.dynamic-form .radio mat-radio-group{display:flex;flex-wrap:wrap;gap:var(--xiri-spacing-xs) var(--xiri-spacing-md)}.dynamic-form .radio mat-hint{font-size:var(--xiri-font-size-helper)}.dynamic-form .info{padding-top:.8rem;padding-bottom:.4rem;color:var(--primary, #2892D9)}.dynamic-form .header{font-size:var(--xiri-font-size-title);padding-top:.8rem;padding-bottom:.4rem;color:var(--primary, #2892D9)}.dynamic-form .header.collapsible{cursor:pointer;display:flex;align-items:center;gap:.25rem;-webkit-user-select:none;user-select:none;border-radius:var(--xiri-radius-xs);padding:.5rem .25rem;margin:.25rem 0}.dynamic-form .header.collapsible:hover{background:color-mix(in srgb,var(--primary, #2892D9) 8%,transparent)}.dynamic-form .header.collapsible .collapse-icon{transition:transform var(--xiri-duration-fast) var(--xiri-easing-standard)}.dynamic-form .header.collapsible .collapse-icon.collapsed{transform:rotate(-90deg)}.dynamic-form .divider{width:100%;display:flex;align-items:center;padding:.5rem 0;margin:.25rem 0}.dynamic-form .divider:before,.dynamic-form .divider:after{content:\"\";flex:1;height:1px;background:var(--outline-variant, var(--mat-sys-outline-variant, rgba(0, 0, 0, .12)))}.dynamic-form .divider .divider-text{padding:0 1rem;font-size:var(--xiri-font-size-helper);color:var(--on-surface-variant, var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6)));white-space:nowrap}.dynamic-form .question,.dynamic-form .waiting{display:flex}.dynamic-form .question .left,.dynamic-form .waiting .left{font-size:var(--xiri-font-size-display);padding-right:1rem}.dynamic-form .question{align-items:center}.dynamic-form .question .left mat-icon{height:auto;width:auto;line-height:1;overflow:visible}.dynamic-form .form-field-button{margin-left:12px;margin-right:12px}.mat-mdc-select-panel.selectPanel{max-height:max(50vh,256px)}[hidden]{display:none!important}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: 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: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: NgxMatSelectSearchModule }, { kind: "component", type: i2.MatSelectSearchComponent, selector: "ngx-mat-select-search", inputs: ["placeholderLabel", "type", "closeIcon", "closeSvgIcon", "noEntriesFoundLabel", "clearSearchInput", "searching", "disableInitialFocus", "enableClearOnEscapePressed", "preventHomeEndKeyPropagation", "disableScrollToActiveOnOptionsChanged", "ariaLabel", "showToggleAllCheckbox", "toggleAllCheckboxChecked", "toggleAllCheckboxIndeterminate", "toggleAllCheckboxTooltipMessage", "toggleAllCheckboxTooltipPosition", "hideClearSearchButton", "alwaysRestoreSelectedOptionsMulti", "recreateValuesArray"], outputs: ["toggleAll"] }, { kind: "directive", type: XiriSelectDirective, selector: "[xiriSelect]", inputs: ["predicate", "compare", "serverSideSearch", "serverUrl", "serverParams", "values"], exportAs: ["xiriSelect"] }, { kind: "component", type: XiriTreeselectComponent, selector: "xiri-treeselect", inputs: ["field", "value"] }, { kind: "component", type: XiriDateComponent, selector: "xiri-date", inputs: ["field", "value"] }, { kind: "component", type: XiriYearMonthComponent, selector: "xiri-yearmonth", inputs: ["field", "value"] }, { kind: "component", type: XiriDateRangeComponent, selector: "xiri-date-range", inputs: ["field", "value"] }, { kind: "component", type: XiriDateTimeRangeComponent, selector: "xiri-date-time-range", inputs: ["field", "value"] }, { kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: MatRadioButton, selector: "mat-radio-button", inputs: ["id", "name", "aria-label", "aria-labelledby", "aria-describedby", "disableRipple", "tabIndex", "checked", "value", "labelPosition", "disabled", "required", "color", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioButton"] }, { kind: "directive", type: MatRadioGroup, selector: "mat-radio-group", inputs: ["color", "name", "labelPosition", "value", "selected", "disabled", "required", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioGroup"] }, { kind: "component", type: XiriVolumeComponent, selector: "xiri-volume", inputs: ["field", "value"] }, { kind: "component", type: XiriTimelimitComponent, selector: "xiri-timelimit", inputs: ["placeholder", "required", "disabled", "value", "texts"] }, { kind: "component", type: XiriFileComponent, selector: "xiri-file", inputs: ["value", "field"] }, { kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: XiriChipsComponent, selector: "xiri-chips", inputs: ["field"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: SafehtmlPipe, name: "safeHtml" }] }); }
3107
3165
  }
3108
3166
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: XiriFormFieldsComponent, decorators: [{
3109
3167
  type: Component,
@@ -3139,7 +3197,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImpor
3139
3197
  AsyncPipe,
3140
3198
  SafehtmlPipe,
3141
3199
  XiriChipsComponent,
3142
- ], template: "@if (reloading()) {\n\t<mat-progress-bar class=\"reloadbar\" mode=\"indeterminate\"></mat-progress-bar>\n}\n<form class=\"xrow dynamic-form\" [formGroup]=\"formGroup\" [class]=\"display()\">\n\t@for (field of displayFields(); track field.id) {\n\t\t@if (isFieldVisible(field)) {\n\t\t@switch (field.type) {\n\t\t\t@case ('text') {\n\t\t\t\t<mat-form-field [class]=\"field.class\" [formGroup]=\"formGroup\" floatLabel=\"auto\" [hidden]=\"field.hide\">\n\t\t\t\t\t@if (field.name) {\n\t\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t}\n\t\t\t\t\t<input matInput\n\t\t\t\t\t [formControlName]=\"field.id\"\n\t\t\t\t\t [type]=\"field.subtype || 'text'\"\n\t\t\t\t\t [autocomplete]=\"field.name\"\n\t\t\t\t\t [attr.minlength]=\"field.min\"\n\t\t\t\t\t [attr.maxlength]=\"field.max\"\n\t\t\t\t\t [required]=\"!!field.required\">\n\t\t\t\t\t@if (field.textPrefix) {\n\t\t\t\t\t\t<span matTextPrefix=\"\">{{ field.textPrefix }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.textSuffix) {\n\t\t\t\t\t\t<span matTextSuffix=\"\">{{ field.textSuffix }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.iconPrefix) {\n\t\t\t\t\t\t<mat-icon matPrefix>{{ field.iconPrefix }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.iconSuffix) {\n\t\t\t\t\t\t<mat-icon matSuffix>{{ field.iconSuffix }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.max) {\n\t\t\t\t\t\t<mat-hint align=\"end\">{{ formGroup.get(field.id)?.value?.length || 0 }} / {{ field.max }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('number') {\n\t\t\t\t<mat-form-field [class]=\"field.class\" [formGroup]=\"formGroup\" floatLabel=\"auto\" [hidden]=\"field.hide\">\n\t\t\t\t\t@if (field.name) {\n\t\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t}\n\t\t\t\t\t<input matInput\n\t\t\t\t\t [formControlName]=\"field.id\"\n\t\t\t\t\t [autocomplete]=\"field.name || field.id\"\n\t\t\t\t\t [lang]=\"field.locale || ''\"\n\t\t\t\t\t [type]=\"field.type\"\n\t\t\t\t\t [attr.min]=\"field.min\"\n\t\t\t\t\t [attr.max]=\"field.max\"\n\t\t\t\t\t [required]=\"!!field.required\">\n\t\t\t\t\t@if (field.textPrefix) {\n\t\t\t\t\t\t<span matTextPrefix=\"\">{{ field.textPrefix }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.textSuffix) {\n\t\t\t\t\t\t<span matTextSuffix=\"\">{{ field.textSuffix }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.iconPrefix) {\n\t\t\t\t\t\t<mat-icon matPrefix>{{ field.iconPrefix }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.iconSuffix) {\n\t\t\t\t\t\t<mat-icon matSuffix>{{ field.iconSuffix }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('password') {\n\t\t\t\t<mat-form-field [class]=\"field.class\" [formGroup]=\"formGroup\" floatLabel=\"auto\" [hidden]=\"field.hide\">\n\t\t\t\t\t@if (field.name) {\n\t\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t}\n\t\t\t\t\t<input matInput\n\t\t\t\t\t [formControlName]=\"field.id\"\n\t\t\t\t\t [type]=\"field.pwdhide ? 'password' : 'text'\"\n\t\t\t\t\t [autocomplete]=\"field.name\"\n\t\t\t\t\t [attr.minlength]=\"field.min\"\n\t\t\t\t\t [attr.maxlength]=\"field.max\"\n\t\t\t\t\t [required]=\"!!field.required\">\n\t\t\t\t\t<button mat-icon-button matSuffix class=\"form-field-button\" (click)=\"field.pwdhide = !field.pwdhide\" [attr.aria-label]=\"'Hide password'\"\n\t\t\t\t\t [attr.aria-pressed]=\"field.pwdhide\">\n\t\t\t\t\t\t<mat-icon>{{ field.pwdhide ? 'visibility_off' : 'visibility' }}</mat-icon>\n\t\t\t\t\t</button>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.max) {\n\t\t\t\t\t\t<mat-hint align=\"end\">{{ formGroup.get(field.id)?.value?.length || 0 }} / {{ field.max }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('select') {\n\t\t\t\t<mat-form-field [class]=\"field.class\" [formGroup]=\"formGroup\" floatLabel=\"auto\" [hidden]=\"field.hide\">\n\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t@if (field.search === false && !field.selectAll) {\n\t\t\t\t\t\t<mat-select [formControlName]=\"field.id\" [multiple]=\"field.multiple\" [required]=\"!!field.required\" panelClass=\"selectPanel\">\n\t\t\t\t\t\t\t@for (x of field.list; track x.id) {\n\t\t\t\t\t\t\t\t<mat-option [value]=\"x.id\" [disabled]=\"x.disabled\">{{ x.name }}</mat-option>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</mat-select>\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<mat-select [formControlName]=\"field.id\" [multiple]=\"field.multiple\" [required]=\"!!field.required\" panelClass=\"selectPanel\">\n\t\t\t\t\t\t\t<mat-option>\n\t\t\t\t\t\t\t\t<ngx-mat-select-search [formControl]=\"xiriSelect.formControl\" xiriSelect #xiriSelect=\"xiriSelect\"\n\t\t\t\t\t\t\t\t [values]=\"field.list || []\" [searching]=\"xiriSelect.searching\"\n\t\t\t\t\t\t\t\t [serverSideSearch]=\"!!field.serverSideSearch\" [serverUrl]=\"field.url || ''\"\n\t\t\t\t\t\t\t\t [serverParams]=\"field.params || {}\"\n\t\t\t\t\t\t\t\t [showToggleAllCheckbox]=\"!!field.multiple && !!field.selectAll && xiriSelect.hasSelectable()\"\n\t\t\t\t\t\t\t\t [toggleAllCheckboxChecked]=\"!!field.multiple && !!field.selectAll && xiriSelect.allSelected(formGroup.get(field.id)?.value)\"\n\t\t\t\t\t\t\t\t [toggleAllCheckboxIndeterminate]=\"!!field.multiple && !!field.selectAll && xiriSelect.someSelected(formGroup.get(field.id)?.value)\"\n\t\t\t\t\t\t\t\t (toggleAll)=\"xiriSelect.toggleSelectAll($event, formGroup.get(field.id))\"></ngx-mat-select-search>\n\t\t\t\t\t\t\t</mat-option>\n\t\t\t\t\t\t\t@for (x of xiriSelect.filter | async; track x.id) {\n\t\t\t\t\t\t\t\t<mat-option [value]=\"x.id\" [disabled]=\"x.disabled\">{{ x.name }}</mat-option>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</mat-select>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('treeselect') {\n\t\t\t\t<div class=\"treeselect\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<xiri-treeselect [field]=\"field\" [formControlName]=\"field.id\"\n\t\t\t\t\t [class.error]=\"formGroup.get(field.id)?.touched && formGroup.get(field.id)?.invalid\"></xiri-treeselect>\n\t\t\t\t\t<div class=\"xhint\" aria-live=\"polite\" [class.error]=\"formGroup.get(field.id)?.touched && formGroup.get(field.id)?.invalid\">\n\t\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (field.max) {\n\t\t\t\t\t\t\t<mat-hint align=\"end\">{{ formGroup.get(field.id)?.value?.length || 0 }} / {{ field.max }}</mat-hint>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.touched && formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('date') {\n\t\t\t\t<mat-form-field [formGroup]=\"formGroup\" class=\"date\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t<xiri-date [field]=\"field\" [formControlName]=\"field.id\"></xiri-date>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('yearmonth') {\n\t\t\t\t<mat-form-field [formGroup]=\"formGroup\" class=\"yearmonth\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t<xiri-yearmonth [field]=\"field\" [formControlName]=\"field.id\"></xiri-yearmonth>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('daterange') {\n\t\t\t\t<mat-form-field [formGroup]=\"formGroup\" class=\"daterange\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t<xiri-date-range [field]=\"field\" [formControlName]=\"field.id\"></xiri-date-range>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('datetimerange') {\n\t\t\t\t<mat-form-field [formGroup]=\"formGroup\" class=\"datetimerange\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t<xiri-date-time-range [field]=\"field\" [formControlName]=\"field.id\"></xiri-date-time-range>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('bool') {\n\t\t\t\t<div class=\"bool\" [class]=\"field.class\" [formGroup]=\"formGroup\" [hidden]=\"field.hide\">\n\t\t\t\t\t<mat-checkbox [formControlName]=\"field.id\">{{ field.name }}</mat-checkbox>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('radio') {\n\t\t\t\t<div class=\"radio\" [class]=\"field.class\" [formGroup]=\"formGroup\" [hidden]=\"field.hide\">\n\t\t\t\t\t@if (field.name) {\n\t\t\t\t\t\t<span class=\"radio-label\" [id]=\"field.id + '-label'\">{{ field.name }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t<mat-radio-group\n\t\t\t\t\t\t[formControlName]=\"field.id\"\n\t\t\t\t\t\t[attr.aria-labelledby]=\"field.name ? field.id + '-label' : null\"\n\t\t\t\t\t>\n\t\t\t\t\t\t@for (x of field.list; track x.id) {\n\t\t\t\t\t\t\t<mat-radio-button [value]=\"x.id\" [disabled]=\"x.disabled\">{{ x.name }}</mat-radio-button>\n\t\t\t\t\t\t}\n\t\t\t\t\t</mat-radio-group>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('volume') {\n\t\t\t\t<div [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<xiri-volume [field]=\"field\" [formControlName]=\"field.id\"></xiri-volume>\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('timelimit') {\n\t\t\t\t<div [class]=\"field.class\" [formGroup]=\"formGroup\" [hidden]=\"field.hide\">\n\t\t\t\t\t<xiri-timelimit matInput [formControlName]=\"field.id\" [required]=\"!!field.required\" [texts]=\"field.texts || {}\"></xiri-timelimit>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('textarea') {\n\t\t\t\t<mat-form-field [class]=\"field.class\" [formGroup]=\"formGroup\" [hidden]=\"field.hide\">\n\t\t\t\t\t@if (field.name) {\n\t\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t}\n\t\t\t\t\t<textarea matInput [formControlName]=\"field.id\" [required]=\"!!field.required\" [rows]=\"field.rows || 5\"></textarea>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.max) {\n\t\t\t\t\t\t<mat-hint align=\"end\">{{ formGroup.get(field.id)?.value?.length || 0 }} / {{ field.max }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('file') {\n\t\t\t\t<div [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<xiri-file [field]=\"field\" [formControlName]=\"field.id\"></xiri-file>\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('info') {\n\t\t\t\t<div class=\"info\" [class]=\"field.class\">{{ field.value }}</div>\n\t\t\t}\n\t\t\t@case ('header') {\n\t\t\t\t@if (field.collapsible) {\n\t\t\t\t\t<div class=\"header collapsible\" [class]=\"field.class\" role=\"button\" tabindex=\"0\"\n\t\t\t\t\t [attr.aria-expanded]=\"!isSectionCollapsed(field.id)\"\n\t\t\t\t\t (click)=\"toggleSection(field)\" (keydown.enter)=\"toggleSection(field)\" (keydown.space)=\"toggleSection(field); $event.preventDefault()\">\n\t\t\t\t\t\t<mat-icon class=\"collapse-icon\" [class.collapsed]=\"isSectionCollapsed(field.id)\">expand_more</mat-icon>\n\t\t\t\t\t\t{{ field.value }}\n\t\t\t\t\t</div>\n\t\t\t\t} @else {\n\t\t\t\t\t<div class=\"header\" [class]=\"field.class\">{{ field.value }}</div>\n\t\t\t\t}\n\t\t\t}\n\t\t\t@case ('divider') {\n\t\t\t\t<div class=\"divider\" [class]=\"field.class\">\n\t\t\t\t\t@if (field.value) {\n\t\t\t\t\t\t<span class=\"divider-text\">{{ field.value }}</span>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('html') {\n\t\t\t\t<div class=\"html\" [class]=\"field.class\" [innerHtml]=\"$any(field.value) | safeHtml\"></div>\n\t\t\t}\n\t\t\t@case ('question') {\n\t\t\t\t<div class=\"xcol question\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<div class=\"left\">\n\t\t\t\t\t\t<mat-icon [class]=\"field.iconColor || 'warn'\" inline=\"true\">{{ field.icon }}</mat-icon>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"right\">{{ field.value }}</div>\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('waiting') {\n\t\t\t\t<div class=\"xcol waiting\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<div class=\"left\">\n\t\t\t\t\t\t@if (!field.done) {\n\t\t\t\t\t\t\t<mat-spinner diameter=\"40\"></mat-spinner>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (field.done) {\n\t\t\t\t\t\t\t<mat-icon inline=\"true\">done</mat-icon>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"right\">{{ field.value }}</div>\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('chips') {\n\t\t\t\t<div [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<xiri-chips [field]=\"field\" [formControlName]=\"field.id\"></xiri-chips>\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@default {\n\t\t\t\t<div>default: {{ field.type }}</div>\n\t\t\t}\n\t\t}\n\t\t}\n\t}\n</form>\n", styles: [":host{position:relative}.reloadbar{position:absolute;top:0;left:0;right:0;z-index:1}.dynamic-form{grid-row-gap:7px}.dynamic-form>mat-form-field{align-self:start}.dynamic-form mat-form-field mat-icon{--mat-icon-color: var(--xiri-formfield-icon-color)}.dynamic-form.line{grid-row-gap:5px}.dynamic-form.small{grid-row-gap:2px}.dynamic-form textarea{white-space:pre}.dynamic-form .xhint{display:flex;min-height:20px;margin-top:4px}.dynamic-form .xhint mat-hint{font-size:var(--xiri-font-size-helper);padding:1px 16px 0}.dynamic-form .xhint mat-hint.mat-mdc-form-field-hint-end{flex:1;text-align:right}.dynamic-form .xhint mat-error{font-size:var(--xiri-font-size-helper);padding:1px 16px 0}.dynamic-form .xhint.error mat-hint{display:none}.dynamic-form .date{min-width:min(9.5rem,100%)}.dynamic-form .date.datetime,.dynamic-form .daterange{min-width:min(14.5rem,100%)}.dynamic-form .datetimerange{min-width:min(18.5rem,100%)}.dynamic-form .bool{display:flex;flex-direction:column}.dynamic-form .bool mat-hint{font-size:var(--xiri-font-size-helper);margin-top:-8px;padding-left:44px}.dynamic-form .radio{display:flex;flex-direction:column;gap:var(--xiri-spacing-xs)}.dynamic-form .radio .radio-label{font-size:var(--xiri-font-size-label)}.dynamic-form .radio mat-radio-group{display:flex;flex-wrap:wrap;gap:var(--xiri-spacing-xs) var(--xiri-spacing-md)}.dynamic-form .radio mat-hint{font-size:var(--xiri-font-size-helper)}.dynamic-form .info{padding-top:.8rem;padding-bottom:.4rem;color:var(--primary, #2892D9)}.dynamic-form .header{font-size:var(--xiri-font-size-title);padding-top:.8rem;padding-bottom:.4rem;color:var(--primary, #2892D9)}.dynamic-form .header.collapsible{cursor:pointer;display:flex;align-items:center;gap:.25rem;-webkit-user-select:none;user-select:none;border-radius:var(--xiri-radius-xs);padding:.5rem .25rem;margin:.25rem 0}.dynamic-form .header.collapsible:hover{background:color-mix(in srgb,var(--primary, #2892D9) 8%,transparent)}.dynamic-form .header.collapsible .collapse-icon{transition:transform var(--xiri-duration-fast) var(--xiri-easing-standard)}.dynamic-form .header.collapsible .collapse-icon.collapsed{transform:rotate(-90deg)}.dynamic-form .divider{width:100%;display:flex;align-items:center;padding:.5rem 0;margin:.25rem 0}.dynamic-form .divider:before,.dynamic-form .divider:after{content:\"\";flex:1;height:1px;background:var(--outline-variant, var(--mat-sys-outline-variant, rgba(0, 0, 0, .12)))}.dynamic-form .divider .divider-text{padding:0 1rem;font-size:var(--xiri-font-size-helper);color:var(--on-surface-variant, var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6)));white-space:nowrap}.dynamic-form .question,.dynamic-form .waiting{display:flex}.dynamic-form .question .left,.dynamic-form .waiting .left{font-size:var(--xiri-font-size-display);padding-right:1rem}.dynamic-form .question{align-items:center}.dynamic-form .question .left mat-icon{height:auto;width:auto;line-height:1;overflow:visible}.dynamic-form .form-field-button{margin-left:12px;margin-right:12px}.mat-mdc-select-panel.selectPanel{max-height:max(50vh,256px)}[hidden]{display:none!important}\n"] }]
3200
+ ], template: "@if (reloading()) {\n\t<mat-progress-bar class=\"reloadbar\" mode=\"indeterminate\"></mat-progress-bar>\n}\n<form class=\"xrow dynamic-form\" [formGroup]=\"formGroup\" [class]=\"display()\">\n\t@for (field of displayFields(); track field.id) {\n\t\t@if (isFieldVisible(field)) {\n\t\t@switch (field.type) {\n\t\t\t@case ('text') {\n\t\t\t\t<mat-form-field [class]=\"field.class\" [formGroup]=\"formGroup\" floatLabel=\"auto\" [hidden]=\"field.hide\">\n\t\t\t\t\t@if (field.name) {\n\t\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t}\n\t\t\t\t\t<input matInput\n\t\t\t\t\t [formControlName]=\"field.id\"\n\t\t\t\t\t [type]=\"field.subtype || 'text'\"\n\t\t\t\t\t [autocomplete]=\"field.name\"\n\t\t\t\t\t [attr.minlength]=\"field.min\"\n\t\t\t\t\t [attr.maxlength]=\"field.max\"\n\t\t\t\t\t [required]=\"!!field.required\">\n\t\t\t\t\t@if (field.textPrefix) {\n\t\t\t\t\t\t<span matTextPrefix=\"\">{{ field.textPrefix }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.textSuffix) {\n\t\t\t\t\t\t<span matTextSuffix=\"\">{{ field.textSuffix }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.iconPrefix) {\n\t\t\t\t\t\t<mat-icon matPrefix>{{ field.iconPrefix }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.iconSuffix) {\n\t\t\t\t\t\t<mat-icon matSuffix>{{ field.iconSuffix }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.max) {\n\t\t\t\t\t\t<mat-hint align=\"end\">{{ formGroup.get(field.id)?.value?.length || 0 }} / {{ field.max }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('number') {\n\t\t\t\t<mat-form-field [class]=\"field.class\" [formGroup]=\"formGroup\" floatLabel=\"auto\" [hidden]=\"field.hide\">\n\t\t\t\t\t@if (field.name) {\n\t\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t}\n\t\t\t\t\t<input matInput\n\t\t\t\t\t [formControlName]=\"field.id\"\n\t\t\t\t\t [autocomplete]=\"field.name || field.id\"\n\t\t\t\t\t [lang]=\"field.locale || ''\"\n\t\t\t\t\t [type]=\"field.type\"\n\t\t\t\t\t [attr.min]=\"field.min\"\n\t\t\t\t\t [attr.max]=\"field.max\"\n\t\t\t\t\t [required]=\"!!field.required\">\n\t\t\t\t\t@if (field.textPrefix) {\n\t\t\t\t\t\t<span matTextPrefix=\"\">{{ field.textPrefix }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.textSuffix) {\n\t\t\t\t\t\t<span matTextSuffix=\"\">{{ field.textSuffix }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.iconPrefix) {\n\t\t\t\t\t\t<mat-icon matPrefix>{{ field.iconPrefix }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.iconSuffix) {\n\t\t\t\t\t\t<mat-icon matSuffix>{{ field.iconSuffix }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('password') {\n\t\t\t\t<mat-form-field [class]=\"field.class\" [formGroup]=\"formGroup\" floatLabel=\"auto\" [hidden]=\"field.hide\">\n\t\t\t\t\t@if (field.name) {\n\t\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t}\n\t\t\t\t\t<input matInput\n\t\t\t\t\t [formControlName]=\"field.id\"\n\t\t\t\t\t [type]=\"field.pwdhide ? 'password' : 'text'\"\n\t\t\t\t\t [autocomplete]=\"field.name\"\n\t\t\t\t\t [attr.minlength]=\"field.min\"\n\t\t\t\t\t [attr.maxlength]=\"field.max\"\n\t\t\t\t\t [required]=\"!!field.required\">\n\t\t\t\t\t<button mat-icon-button matSuffix class=\"form-field-button\" (click)=\"field.pwdhide = !field.pwdhide\" [attr.aria-label]=\"'Hide password'\"\n\t\t\t\t\t [attr.aria-pressed]=\"field.pwdhide\">\n\t\t\t\t\t\t<mat-icon>{{ field.pwdhide ? 'visibility_off' : 'visibility' }}</mat-icon>\n\t\t\t\t\t</button>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.max) {\n\t\t\t\t\t\t<mat-hint align=\"end\">{{ formGroup.get(field.id)?.value?.length || 0 }} / {{ field.max }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('select') {\n\t\t\t\t<div class=\"add-wrap\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t<mat-form-field class=\"add-wrap-control\" [formGroup]=\"formGroup\" floatLabel=\"auto\">\n\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t@if (field.search === false && !field.selectAll) {\n\t\t\t\t\t\t<mat-select [formControlName]=\"field.id\" [multiple]=\"field.multiple\" [required]=\"!!field.required\" panelClass=\"selectPanel\">\n\t\t\t\t\t\t\t@for (x of field.list; track x.id) {\n\t\t\t\t\t\t\t\t<mat-option [value]=\"x.id\" [disabled]=\"x.disabled\">{{ x.name }}</mat-option>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</mat-select>\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<mat-select [formControlName]=\"field.id\" [multiple]=\"field.multiple\" [required]=\"!!field.required\" panelClass=\"selectPanel\">\n\t\t\t\t\t\t\t<mat-option>\n\t\t\t\t\t\t\t\t<ngx-mat-select-search [formControl]=\"xiriSelect.formControl\" xiriSelect #xiriSelect=\"xiriSelect\"\n\t\t\t\t\t\t\t\t [values]=\"field.list || []\" [searching]=\"xiriSelect.searching\"\n\t\t\t\t\t\t\t\t [serverSideSearch]=\"!!field.serverSideSearch\" [serverUrl]=\"field.url || ''\"\n\t\t\t\t\t\t\t\t [serverParams]=\"field.params || {}\"\n\t\t\t\t\t\t\t\t [showToggleAllCheckbox]=\"!!field.multiple && !!field.selectAll && xiriSelect.hasSelectable()\"\n\t\t\t\t\t\t\t\t [toggleAllCheckboxChecked]=\"!!field.multiple && !!field.selectAll && xiriSelect.allSelected(formGroup.get(field.id)?.value)\"\n\t\t\t\t\t\t\t\t [toggleAllCheckboxIndeterminate]=\"!!field.multiple && !!field.selectAll && xiriSelect.someSelected(formGroup.get(field.id)?.value)\"\n\t\t\t\t\t\t\t\t (toggleAll)=\"xiriSelect.toggleSelectAll($event, formGroup.get(field.id))\"></ngx-mat-select-search>\n\t\t\t\t\t\t\t</mat-option>\n\t\t\t\t\t\t\t@for (x of xiriSelect.filter | async; track x.id) {\n\t\t\t\t\t\t\t\t<mat-option [value]=\"x.id\" [disabled]=\"x.disabled\">{{ x.name }}</mat-option>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</mat-select>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t\t@if (field.addUrl) {\n\t\t\t\t\t<button mat-icon-button type=\"button\" class=\"add-option\" aria-label=\"Neu anlegen\"\n\t\t\t\t\t [disabled]=\"disabled() || formGroup.get(field.id)?.disabled\" (click)=\"openAdd(field.id)\"><mat-icon>add</mat-icon></button>\n\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('treeselect') {\n\t\t\t\t<div class=\"treeselect add-wrap\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t<div class=\"add-wrap-control\">\n\t\t\t\t\t<xiri-treeselect [field]=\"field\" [formControlName]=\"field.id\"\n\t\t\t\t\t [class.error]=\"formGroup.get(field.id)?.touched && formGroup.get(field.id)?.invalid\"></xiri-treeselect>\n\t\t\t\t\t<div class=\"xhint\" aria-live=\"polite\" [class.error]=\"formGroup.get(field.id)?.touched && formGroup.get(field.id)?.invalid\">\n\t\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (field.max) {\n\t\t\t\t\t\t\t<mat-hint align=\"end\">{{ formGroup.get(field.id)?.value?.length || 0 }} / {{ field.max }}</mat-hint>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.touched && formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t@if (field.addUrl) {\n\t\t\t\t\t<button mat-icon-button type=\"button\" class=\"add-option\" aria-label=\"Neu anlegen\"\n\t\t\t\t\t [disabled]=\"disabled() || formGroup.get(field.id)?.disabled\" (click)=\"openAdd(field.id)\"><mat-icon>add</mat-icon></button>\n\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('date') {\n\t\t\t\t<mat-form-field [formGroup]=\"formGroup\" class=\"date\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t<xiri-date [field]=\"field\" [formControlName]=\"field.id\"></xiri-date>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('yearmonth') {\n\t\t\t\t<mat-form-field [formGroup]=\"formGroup\" class=\"yearmonth\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t<xiri-yearmonth [field]=\"field\" [formControlName]=\"field.id\"></xiri-yearmonth>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('daterange') {\n\t\t\t\t<mat-form-field [formGroup]=\"formGroup\" class=\"daterange\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t<xiri-date-range [field]=\"field\" [formControlName]=\"field.id\"></xiri-date-range>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('datetimerange') {\n\t\t\t\t<mat-form-field [formGroup]=\"formGroup\" class=\"datetimerange\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t<xiri-date-time-range [field]=\"field\" [formControlName]=\"field.id\"></xiri-date-time-range>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('bool') {\n\t\t\t\t<div class=\"bool\" [class]=\"field.class\" [formGroup]=\"formGroup\" [hidden]=\"field.hide\">\n\t\t\t\t\t<mat-checkbox [formControlName]=\"field.id\">{{ field.name }}</mat-checkbox>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('radio') {\n\t\t\t\t<div class=\"radio\" [class]=\"field.class\" [formGroup]=\"formGroup\" [hidden]=\"field.hide\">\n\t\t\t\t\t@if (field.name) {\n\t\t\t\t\t\t<span class=\"radio-label\" [id]=\"field.id + '-label'\">{{ field.name }}</span>\n\t\t\t\t\t}\n\t\t\t\t\t<mat-radio-group\n\t\t\t\t\t\t[formControlName]=\"field.id\"\n\t\t\t\t\t\t[attr.aria-labelledby]=\"field.name ? field.id + '-label' : null\"\n\t\t\t\t\t>\n\t\t\t\t\t\t@for (x of field.list; track x.id) {\n\t\t\t\t\t\t\t<mat-radio-button [value]=\"x.id\" [disabled]=\"x.disabled\">{{ x.name }}</mat-radio-button>\n\t\t\t\t\t\t}\n\t\t\t\t\t</mat-radio-group>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('volume') {\n\t\t\t\t<div [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<xiri-volume [field]=\"field\" [formControlName]=\"field.id\"></xiri-volume>\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('timelimit') {\n\t\t\t\t<div [class]=\"field.class\" [formGroup]=\"formGroup\" [hidden]=\"field.hide\">\n\t\t\t\t\t<xiri-timelimit matInput [formControlName]=\"field.id\" [required]=\"!!field.required\" [texts]=\"field.texts || {}\"></xiri-timelimit>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('textarea') {\n\t\t\t\t<mat-form-field [class]=\"field.class\" [formGroup]=\"formGroup\" [hidden]=\"field.hide\">\n\t\t\t\t\t@if (field.name) {\n\t\t\t\t\t\t<mat-label>{{ field.name }}</mat-label>\n\t\t\t\t\t}\n\t\t\t\t\t<textarea matInput [formControlName]=\"field.id\" [required]=\"!!field.required\" [rows]=\"field.rows || 5\"></textarea>\n\t\t\t\t\t@if (field.hint) {\n\t\t\t\t\t\t<mat-hint>{{ field.hint }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@if (field.max) {\n\t\t\t\t\t\t<mat-hint align=\"end\">{{ formGroup.get(field.id)?.value?.length || 0 }} / {{ field.max }}</mat-hint>\n\t\t\t\t\t}\n\t\t\t\t\t@for (vali of field.validations; track vali.id) {\n\t\t\t\t\t\t<ng-container ngProjectAs=\"mat-error\">\n\t\t\t\t\t\t\t@if (formGroup.get(field.id)?.hasError(vali.id)) {\n\t\t\t\t\t\t\t\t<mat-error>{{ vali.message }}</mat-error>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t</mat-form-field>\n\t\t\t}\n\t\t\t@case ('file') {\n\t\t\t\t<div [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<xiri-file [field]=\"field\" [formControlName]=\"field.id\"></xiri-file>\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('info') {\n\t\t\t\t<div class=\"info\" [class]=\"field.class\">{{ field.value }}</div>\n\t\t\t}\n\t\t\t@case ('header') {\n\t\t\t\t@if (field.collapsible) {\n\t\t\t\t\t<div class=\"header collapsible\" [class]=\"field.class\" role=\"button\" tabindex=\"0\"\n\t\t\t\t\t [attr.aria-expanded]=\"!isSectionCollapsed(field.id)\"\n\t\t\t\t\t (click)=\"toggleSection(field)\" (keydown.enter)=\"toggleSection(field)\" (keydown.space)=\"toggleSection(field); $event.preventDefault()\">\n\t\t\t\t\t\t<mat-icon class=\"collapse-icon\" [class.collapsed]=\"isSectionCollapsed(field.id)\">expand_more</mat-icon>\n\t\t\t\t\t\t{{ field.value }}\n\t\t\t\t\t</div>\n\t\t\t\t} @else {\n\t\t\t\t\t<div class=\"header\" [class]=\"field.class\">{{ field.value }}</div>\n\t\t\t\t}\n\t\t\t}\n\t\t\t@case ('divider') {\n\t\t\t\t<div class=\"divider\" [class]=\"field.class\">\n\t\t\t\t\t@if (field.value) {\n\t\t\t\t\t\t<span class=\"divider-text\">{{ field.value }}</span>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('html') {\n\t\t\t\t<div class=\"html\" [class]=\"field.class\" [innerHtml]=\"$any(field.value) | safeHtml\"></div>\n\t\t\t}\n\t\t\t@case ('question') {\n\t\t\t\t<div class=\"xcol question\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<div class=\"left\">\n\t\t\t\t\t\t<mat-icon [class]=\"field.iconColor || 'warn'\" inline=\"true\">{{ field.icon }}</mat-icon>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"right\">{{ field.value }}</div>\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('waiting') {\n\t\t\t\t<div class=\"xcol waiting\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<div class=\"left\">\n\t\t\t\t\t\t@if (!field.done) {\n\t\t\t\t\t\t\t<mat-spinner diameter=\"40\"></mat-spinner>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@if (field.done) {\n\t\t\t\t\t\t\t<mat-icon inline=\"true\">done</mat-icon>\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"right\">{{ field.value }}</div>\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@case ('chips') {\n\t\t\t\t<div class=\"add-wrap\" [class]=\"field.class\" [hidden]=\"field.hide\">\n\t\t\t\t\t<xiri-chips class=\"add-wrap-control\" [field]=\"field\" [formControlName]=\"field.id\"></xiri-chips>\n\t\t\t\t\t@if (field.addUrl) {\n\t\t\t\t\t\t<button mat-icon-button type=\"button\" class=\"add-option\" aria-label=\"Neu anlegen\"\n\t\t\t\t\t\t [disabled]=\"disabled() || formGroup.get(field.id)?.disabled\" (click)=\"openAdd(field.id)\"><mat-icon>add</mat-icon></button>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@default {\n\t\t\t\t<div>default: {{ field.type }}</div>\n\t\t\t}\n\t\t}\n\t\t}\n\t}\n</form>\n", styles: [":host{position:relative}.reloadbar{position:absolute;top:0;left:0;right:0;z-index:1}.dynamic-form{grid-row-gap:7px}.dynamic-form>mat-form-field,.dynamic-form>.add-wrap{align-self:start}.dynamic-form .add-wrap{display:flex;align-items:flex-start;gap:4px}.dynamic-form .add-wrap .add-wrap-control{flex:1;min-width:0}.dynamic-form .add-wrap .add-option{margin-top:4px}.dynamic-form mat-form-field mat-icon{--mat-icon-color: var(--xiri-formfield-icon-color)}.dynamic-form.line{grid-row-gap:5px}.dynamic-form.small{grid-row-gap:2px}.dynamic-form textarea{white-space:pre}.dynamic-form .xhint{display:flex;min-height:20px;margin-top:4px}.dynamic-form .xhint mat-hint{font-size:var(--xiri-font-size-helper);padding:1px 16px 0}.dynamic-form .xhint mat-hint.mat-mdc-form-field-hint-end{flex:1;text-align:right}.dynamic-form .xhint mat-error{font-size:var(--xiri-font-size-helper);padding:1px 16px 0}.dynamic-form .xhint.error mat-hint{display:none}.dynamic-form .date{min-width:min(9.5rem,100%)}.dynamic-form .date.datetime,.dynamic-form .daterange{min-width:min(14.5rem,100%)}.dynamic-form .datetimerange{min-width:min(18.5rem,100%)}.dynamic-form .bool{display:flex;flex-direction:column}.dynamic-form .bool mat-hint{font-size:var(--xiri-font-size-helper);margin-top:-8px;padding-left:44px}.dynamic-form .radio{display:flex;flex-direction:column;gap:var(--xiri-spacing-xs)}.dynamic-form .radio .radio-label{font-size:var(--xiri-font-size-label)}.dynamic-form .radio mat-radio-group{display:flex;flex-wrap:wrap;gap:var(--xiri-spacing-xs) var(--xiri-spacing-md)}.dynamic-form .radio mat-hint{font-size:var(--xiri-font-size-helper)}.dynamic-form .info{padding-top:.8rem;padding-bottom:.4rem;color:var(--primary, #2892D9)}.dynamic-form .header{font-size:var(--xiri-font-size-title);padding-top:.8rem;padding-bottom:.4rem;color:var(--primary, #2892D9)}.dynamic-form .header.collapsible{cursor:pointer;display:flex;align-items:center;gap:.25rem;-webkit-user-select:none;user-select:none;border-radius:var(--xiri-radius-xs);padding:.5rem .25rem;margin:.25rem 0}.dynamic-form .header.collapsible:hover{background:color-mix(in srgb,var(--primary, #2892D9) 8%,transparent)}.dynamic-form .header.collapsible .collapse-icon{transition:transform var(--xiri-duration-fast) var(--xiri-easing-standard)}.dynamic-form .header.collapsible .collapse-icon.collapsed{transform:rotate(-90deg)}.dynamic-form .divider{width:100%;display:flex;align-items:center;padding:.5rem 0;margin:.25rem 0}.dynamic-form .divider:before,.dynamic-form .divider:after{content:\"\";flex:1;height:1px;background:var(--outline-variant, var(--mat-sys-outline-variant, rgba(0, 0, 0, .12)))}.dynamic-form .divider .divider-text{padding:0 1rem;font-size:var(--xiri-font-size-helper);color:var(--on-surface-variant, var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6)));white-space:nowrap}.dynamic-form .question,.dynamic-form .waiting{display:flex}.dynamic-form .question .left,.dynamic-form .waiting .left{font-size:var(--xiri-font-size-display);padding-right:1rem}.dynamic-form .question{align-items:center}.dynamic-form .question .left mat-icon{height:auto;width:auto;line-height:1;overflow:visible}.dynamic-form .form-field-button{margin-left:12px;margin-right:12px}.mat-mdc-select-panel.selectPanel{max-height:max(50vh,256px)}[hidden]{display:none!important}\n"] }]
3143
3201
  }], ctorParameters: () => [], propDecorators: { form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: false }] }], display: [{ type: i0.Input, args: [{ isSignal: true, alias: "display", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], formChange: [{ type: i0.Output, args: ["formChange"] }], check: [{ type: i0.Input, args: [{ isSignal: true, alias: "check", required: false }] }] } });
3144
3202
  // Was ein Reload-Patch am Feld ändern darf, jeweils mit Typprüfung. Der Server ist eine
3145
3203
  // Trust-Boundary: eine kaputte `list` oder ein `min: "3"` dürfen weder das Pruning noch den
@@ -3288,6 +3346,12 @@ function validatorArrayMax(max) {
3288
3346
  return ok ? null : { max: { value: control.value } };
3289
3347
  };
3290
3348
  }
3349
+ function isCreatedOption(value) {
3350
+ if (value === null || typeof value !== 'object')
3351
+ return false;
3352
+ const { id, name } = value;
3353
+ return (typeof id === 'string' || (typeof id === 'number' && Number.isFinite(id))) && typeof name === 'string';
3354
+ }
3291
3355
 
3292
3356
  class XiriRawTableComponent {
3293
3357
  constructor() {
@@ -3625,6 +3689,8 @@ class XiriDialogComponent {
3625
3689
  }
3626
3690
  }
3627
3691
  else if (res.done) {
3692
+ // Bis zum close(res) darf nichts anderes schließen, sonst geht das Ergebnis (z. B. created) verloren.
3693
+ this.dialogRef.disableClose = true;
3628
3694
  this.done.set(true);
3629
3695
  this.formFields.set(null);
3630
3696
  this.type.set('');
@@ -3764,7 +3830,7 @@ class XiriDialogComponent {
3764
3830
  clearTimeout(this.to);
3765
3831
  }
3766
3832
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: XiriDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3767
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: XiriDialogComponent, isStandalone: true, selector: "xiri-dialog", ngImport: i0, template: "<div class=\"dialog\">\n\t<div class=\"dialog-header\">\n\t\t<h1 mat-dialog-title>{{ header() }}</h1>\n\t\t@if (type() !== 'waiting') {\n\t\t\t<button mat-icon-button aria-label=\"Schlie\u00DFen\" (click)=\"dialogRef.close(null)\"><mat-icon>close</mat-icon></button>\n\t\t}\n\t</div>\n\t<mat-dialog-content>\n\t\t@if (loading() && formFields() === null) {\n\t\t\t<mat-spinner diameter=\"30\"></mat-spinner>\n\t\t}\n\t\t@if (formFields() !== null) {\n\t\t\t@if (type() === 'table') {\n\t\t\t\t<xiri-raw-table [settings]=\"rawTable\"></xiri-raw-table>\n\t\t\t} @else {\n\t\t\t\t<xiri-form-fields [form]=\"formFields()\" (formChange)=\"formChanged($event)\" [disabled]=\"loading()\"\n\t\t\t\t [check]=\"checkSubject.asObservable()\"></xiri-form-fields>\n\t\t\t}\n\t\t}\n\t\t@if (componentData() !== null && dynComponentType() !== null) {\n\t\t\t<ng-container [ngComponentOutlet]=\"dynComponentType()\"\n\t\t\t [ngComponentOutletInputs]=\"{ data: componentData() }\"></ng-container>\n\t\t}\n\t\t@if (error()) {\n\t\t\t<xiri-error class=\"error\" [text]=\"error()\"></xiri-error>\n\t\t}\n\t\t@if (done()) {\n\t\t\t<div class=\"xcol done\">\n\t\t\t\t<xiri-done></xiri-done>\n\t\t\t</div>\n\t\t}\n\t</mat-dialog-content>\n\t@if (!done() && !(loading() && formFields() === null) && (loading() || buttons().length > 0)) {\n\t\t<mat-divider></mat-divider>\n\t\t<mat-dialog-actions [class.one]=\"buttons().length===1\">\n\t\t\t@if (loading()) {\n\t\t\t\t<mat-spinner diameter=\"30\" class=\"actions-spinner\"></mat-spinner>\n\t\t\t} @else {\n\t\t\t\t@for (button of buttons(); track $index) {\n\t\t\t\t\t<xiri-buttonstyle [button]=\"button\" (click)=\"clickButton( button )\" [disabled]=\"!!button.default && !formValid()\"></xiri-buttonstyle>\n\t\t\t\t}\n\t\t\t}\n\t\t</mat-dialog-actions>\n\t}\n</div>", styles: ["mat-spinner{margin:var(--xiri-spacing-md)}.dialog-header{display:flex;align-items:center;justify-content:space-between;padding-inline-end:var(--xiri-spacing-lg)}.dialog-header h1[mat-dialog-title]{margin-bottom:0;flex:0 1 auto;min-width:0;overflow-wrap:anywhere}mat-dialog-content{overflow-x:auto}.dynamic-form{margin-bottom:var(--xiri-spacing-md)}.dynamic-form .field{width:100%;margin-top:var(--xiri-spacing-sm)}.question,.waiting{display:flex}.question .left,.waiting .left{font-size:var(--xiri-font-size-display);padding-right:var(--xiri-spacing-md)}.waiting mat-icon{color:var(--color-success, #2ECC71);font-size:var(--xiri-font-size-headline)}.error{color:var(--error, red);font-size:var(--xiri-font-size-title);margin-top:var(--xiri-spacing-md);margin-bottom:var(--xiri-spacing-md)}mat-dialog-actions{justify-content:space-between;padding-left:var(--xiri-spacing-lg);padding-right:var(--xiri-spacing-lg)}mat-dialog-actions.one{justify-content:end}mat-dialog-actions .actions-spinner{margin:0 0 0 auto}mat-dialog-content{min-height:4rem}mat-dialog-content.mat-mdc-dialog-content{padding-bottom:var(--xiri-spacing-md)}mat-dialog-content>*{animation:fadeIn var(--xiri-duration-fast, .15s) var(--xiri-easing-standard, cubic-bezier(.4, 0, .2, 1))}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.done{text-align:center;font-size:var(--xiri-font-size-display)}[hidden]{display:none!important}\n"], dependencies: [{ kind: "directive", type: MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: XiriRawTableComponent, selector: "xiri-raw-table", inputs: ["settings"] }, { kind: "component", type: XiriFormFieldsComponent, selector: "xiri-form-fields", inputs: ["form", "display", "disabled", "check"], outputs: ["formChange"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "component", type: XiriErrorComponent, selector: "xiri-error", inputs: ["text"] }, { kind: "component", type: XiriDoneComponent, selector: "xiri-done" }, { kind: "component", type: MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "component", type: XiriButtonstyleComponent, selector: "xiri-buttonstyle", inputs: ["button", "disabled", "loading", "countdown", "pollText"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] }); }
3833
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: XiriDialogComponent, isStandalone: true, selector: "xiri-dialog", ngImport: i0, template: "<div class=\"dialog\">\n\t<div class=\"dialog-header\">\n\t\t<h1 mat-dialog-title>{{ header() }}</h1>\n\t\t@if (type() !== 'waiting' && !done()) {\n\t\t\t<button mat-icon-button aria-label=\"Schlie\u00DFen\" (click)=\"dialogRef.close(null)\"><mat-icon>close</mat-icon></button>\n\t\t}\n\t</div>\n\t<mat-dialog-content>\n\t\t@if (loading() && formFields() === null) {\n\t\t\t<mat-spinner diameter=\"30\"></mat-spinner>\n\t\t}\n\t\t@if (formFields() !== null) {\n\t\t\t@if (type() === 'table') {\n\t\t\t\t<xiri-raw-table [settings]=\"rawTable\"></xiri-raw-table>\n\t\t\t} @else {\n\t\t\t\t<xiri-form-fields [form]=\"formFields()\" (formChange)=\"formChanged($event)\" [disabled]=\"loading()\"\n\t\t\t\t [check]=\"checkSubject.asObservable()\"></xiri-form-fields>\n\t\t\t}\n\t\t}\n\t\t@if (componentData() !== null && dynComponentType() !== null) {\n\t\t\t<ng-container [ngComponentOutlet]=\"dynComponentType()\"\n\t\t\t [ngComponentOutletInputs]=\"{ data: componentData() }\"></ng-container>\n\t\t}\n\t\t@if (error()) {\n\t\t\t<xiri-error class=\"error\" [text]=\"error()\"></xiri-error>\n\t\t}\n\t\t@if (done()) {\n\t\t\t<div class=\"xcol done\">\n\t\t\t\t<xiri-done></xiri-done>\n\t\t\t</div>\n\t\t}\n\t</mat-dialog-content>\n\t@if (!done() && !(loading() && formFields() === null) && (loading() || buttons().length > 0)) {\n\t\t<mat-divider></mat-divider>\n\t\t<mat-dialog-actions [class.one]=\"buttons().length===1\">\n\t\t\t@if (loading()) {\n\t\t\t\t<mat-spinner diameter=\"30\" class=\"actions-spinner\"></mat-spinner>\n\t\t\t} @else {\n\t\t\t\t@for (button of buttons(); track $index) {\n\t\t\t\t\t<xiri-buttonstyle [button]=\"button\" (click)=\"clickButton( button )\" [disabled]=\"!!button.default && !formValid()\"></xiri-buttonstyle>\n\t\t\t\t}\n\t\t\t}\n\t\t</mat-dialog-actions>\n\t}\n</div>", styles: ["mat-spinner{margin:var(--xiri-spacing-md)}.dialog-header{display:flex;align-items:center;justify-content:space-between;padding-inline-end:var(--xiri-spacing-lg)}.dialog-header h1[mat-dialog-title]{margin-bottom:0;flex:0 1 auto;min-width:0;overflow-wrap:anywhere}mat-dialog-content{overflow-x:auto}.dynamic-form{margin-bottom:var(--xiri-spacing-md)}.dynamic-form .field{width:100%;margin-top:var(--xiri-spacing-sm)}.question,.waiting{display:flex}.question .left,.waiting .left{font-size:var(--xiri-font-size-display);padding-right:var(--xiri-spacing-md)}.waiting mat-icon{color:var(--color-success, #2ECC71);font-size:var(--xiri-font-size-headline)}.error{color:var(--error, red);font-size:var(--xiri-font-size-title);margin-top:var(--xiri-spacing-md);margin-bottom:var(--xiri-spacing-md)}mat-dialog-actions{justify-content:space-between;padding-left:var(--xiri-spacing-lg);padding-right:var(--xiri-spacing-lg)}mat-dialog-actions.one{justify-content:end}mat-dialog-actions .actions-spinner{margin:0 0 0 auto}mat-dialog-content{min-height:4rem}mat-dialog-content.mat-mdc-dialog-content{padding-bottom:var(--xiri-spacing-md)}mat-dialog-content>*{animation:fadeIn var(--xiri-duration-fast, .15s) var(--xiri-easing-standard, cubic-bezier(.4, 0, .2, 1))}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.done{text-align:center;font-size:var(--xiri-font-size-display)}[hidden]{display:none!important}\n"], dependencies: [{ kind: "directive", type: MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: XiriRawTableComponent, selector: "xiri-raw-table", inputs: ["settings"] }, { kind: "component", type: XiriFormFieldsComponent, selector: "xiri-form-fields", inputs: ["form", "display", "disabled", "check"], outputs: ["formChange"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "component", type: XiriErrorComponent, selector: "xiri-error", inputs: ["text"] }, { kind: "component", type: XiriDoneComponent, selector: "xiri-done" }, { kind: "component", type: MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "component", type: XiriButtonstyleComponent, selector: "xiri-buttonstyle", inputs: ["button", "disabled", "loading", "countdown", "pollText"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] }); }
3768
3834
  }
3769
3835
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: XiriDialogComponent, decorators: [{
3770
3836
  type: Component,
@@ -3780,9 +3846,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImpor
3780
3846
  MatDialogActions,
3781
3847
  XiriButtonstyleComponent,
3782
3848
  MatIconButton,
3783
- MatIcon], template: "<div class=\"dialog\">\n\t<div class=\"dialog-header\">\n\t\t<h1 mat-dialog-title>{{ header() }}</h1>\n\t\t@if (type() !== 'waiting') {\n\t\t\t<button mat-icon-button aria-label=\"Schlie\u00DFen\" (click)=\"dialogRef.close(null)\"><mat-icon>close</mat-icon></button>\n\t\t}\n\t</div>\n\t<mat-dialog-content>\n\t\t@if (loading() && formFields() === null) {\n\t\t\t<mat-spinner diameter=\"30\"></mat-spinner>\n\t\t}\n\t\t@if (formFields() !== null) {\n\t\t\t@if (type() === 'table') {\n\t\t\t\t<xiri-raw-table [settings]=\"rawTable\"></xiri-raw-table>\n\t\t\t} @else {\n\t\t\t\t<xiri-form-fields [form]=\"formFields()\" (formChange)=\"formChanged($event)\" [disabled]=\"loading()\"\n\t\t\t\t [check]=\"checkSubject.asObservable()\"></xiri-form-fields>\n\t\t\t}\n\t\t}\n\t\t@if (componentData() !== null && dynComponentType() !== null) {\n\t\t\t<ng-container [ngComponentOutlet]=\"dynComponentType()\"\n\t\t\t [ngComponentOutletInputs]=\"{ data: componentData() }\"></ng-container>\n\t\t}\n\t\t@if (error()) {\n\t\t\t<xiri-error class=\"error\" [text]=\"error()\"></xiri-error>\n\t\t}\n\t\t@if (done()) {\n\t\t\t<div class=\"xcol done\">\n\t\t\t\t<xiri-done></xiri-done>\n\t\t\t</div>\n\t\t}\n\t</mat-dialog-content>\n\t@if (!done() && !(loading() && formFields() === null) && (loading() || buttons().length > 0)) {\n\t\t<mat-divider></mat-divider>\n\t\t<mat-dialog-actions [class.one]=\"buttons().length===1\">\n\t\t\t@if (loading()) {\n\t\t\t\t<mat-spinner diameter=\"30\" class=\"actions-spinner\"></mat-spinner>\n\t\t\t} @else {\n\t\t\t\t@for (button of buttons(); track $index) {\n\t\t\t\t\t<xiri-buttonstyle [button]=\"button\" (click)=\"clickButton( button )\" [disabled]=\"!!button.default && !formValid()\"></xiri-buttonstyle>\n\t\t\t\t}\n\t\t\t}\n\t\t</mat-dialog-actions>\n\t}\n</div>", styles: ["mat-spinner{margin:var(--xiri-spacing-md)}.dialog-header{display:flex;align-items:center;justify-content:space-between;padding-inline-end:var(--xiri-spacing-lg)}.dialog-header h1[mat-dialog-title]{margin-bottom:0;flex:0 1 auto;min-width:0;overflow-wrap:anywhere}mat-dialog-content{overflow-x:auto}.dynamic-form{margin-bottom:var(--xiri-spacing-md)}.dynamic-form .field{width:100%;margin-top:var(--xiri-spacing-sm)}.question,.waiting{display:flex}.question .left,.waiting .left{font-size:var(--xiri-font-size-display);padding-right:var(--xiri-spacing-md)}.waiting mat-icon{color:var(--color-success, #2ECC71);font-size:var(--xiri-font-size-headline)}.error{color:var(--error, red);font-size:var(--xiri-font-size-title);margin-top:var(--xiri-spacing-md);margin-bottom:var(--xiri-spacing-md)}mat-dialog-actions{justify-content:space-between;padding-left:var(--xiri-spacing-lg);padding-right:var(--xiri-spacing-lg)}mat-dialog-actions.one{justify-content:end}mat-dialog-actions .actions-spinner{margin:0 0 0 auto}mat-dialog-content{min-height:4rem}mat-dialog-content.mat-mdc-dialog-content{padding-bottom:var(--xiri-spacing-md)}mat-dialog-content>*{animation:fadeIn var(--xiri-duration-fast, .15s) var(--xiri-easing-standard, cubic-bezier(.4, 0, .2, 1))}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.done{text-align:center;font-size:var(--xiri-font-size-display)}[hidden]{display:none!important}\n"] }]
3849
+ MatIcon], template: "<div class=\"dialog\">\n\t<div class=\"dialog-header\">\n\t\t<h1 mat-dialog-title>{{ header() }}</h1>\n\t\t@if (type() !== 'waiting' && !done()) {\n\t\t\t<button mat-icon-button aria-label=\"Schlie\u00DFen\" (click)=\"dialogRef.close(null)\"><mat-icon>close</mat-icon></button>\n\t\t}\n\t</div>\n\t<mat-dialog-content>\n\t\t@if (loading() && formFields() === null) {\n\t\t\t<mat-spinner diameter=\"30\"></mat-spinner>\n\t\t}\n\t\t@if (formFields() !== null) {\n\t\t\t@if (type() === 'table') {\n\t\t\t\t<xiri-raw-table [settings]=\"rawTable\"></xiri-raw-table>\n\t\t\t} @else {\n\t\t\t\t<xiri-form-fields [form]=\"formFields()\" (formChange)=\"formChanged($event)\" [disabled]=\"loading()\"\n\t\t\t\t [check]=\"checkSubject.asObservable()\"></xiri-form-fields>\n\t\t\t}\n\t\t}\n\t\t@if (componentData() !== null && dynComponentType() !== null) {\n\t\t\t<ng-container [ngComponentOutlet]=\"dynComponentType()\"\n\t\t\t [ngComponentOutletInputs]=\"{ data: componentData() }\"></ng-container>\n\t\t}\n\t\t@if (error()) {\n\t\t\t<xiri-error class=\"error\" [text]=\"error()\"></xiri-error>\n\t\t}\n\t\t@if (done()) {\n\t\t\t<div class=\"xcol done\">\n\t\t\t\t<xiri-done></xiri-done>\n\t\t\t</div>\n\t\t}\n\t</mat-dialog-content>\n\t@if (!done() && !(loading() && formFields() === null) && (loading() || buttons().length > 0)) {\n\t\t<mat-divider></mat-divider>\n\t\t<mat-dialog-actions [class.one]=\"buttons().length===1\">\n\t\t\t@if (loading()) {\n\t\t\t\t<mat-spinner diameter=\"30\" class=\"actions-spinner\"></mat-spinner>\n\t\t\t} @else {\n\t\t\t\t@for (button of buttons(); track $index) {\n\t\t\t\t\t<xiri-buttonstyle [button]=\"button\" (click)=\"clickButton( button )\" [disabled]=\"!!button.default && !formValid()\"></xiri-buttonstyle>\n\t\t\t\t}\n\t\t\t}\n\t\t</mat-dialog-actions>\n\t}\n</div>", styles: ["mat-spinner{margin:var(--xiri-spacing-md)}.dialog-header{display:flex;align-items:center;justify-content:space-between;padding-inline-end:var(--xiri-spacing-lg)}.dialog-header h1[mat-dialog-title]{margin-bottom:0;flex:0 1 auto;min-width:0;overflow-wrap:anywhere}mat-dialog-content{overflow-x:auto}.dynamic-form{margin-bottom:var(--xiri-spacing-md)}.dynamic-form .field{width:100%;margin-top:var(--xiri-spacing-sm)}.question,.waiting{display:flex}.question .left,.waiting .left{font-size:var(--xiri-font-size-display);padding-right:var(--xiri-spacing-md)}.waiting mat-icon{color:var(--color-success, #2ECC71);font-size:var(--xiri-font-size-headline)}.error{color:var(--error, red);font-size:var(--xiri-font-size-title);margin-top:var(--xiri-spacing-md);margin-bottom:var(--xiri-spacing-md)}mat-dialog-actions{justify-content:space-between;padding-left:var(--xiri-spacing-lg);padding-right:var(--xiri-spacing-lg)}mat-dialog-actions.one{justify-content:end}mat-dialog-actions .actions-spinner{margin:0 0 0 auto}mat-dialog-content{min-height:4rem}mat-dialog-content.mat-mdc-dialog-content{padding-bottom:var(--xiri-spacing-md)}mat-dialog-content>*{animation:fadeIn var(--xiri-duration-fast, .15s) var(--xiri-easing-standard, cubic-bezier(.4, 0, .2, 1))}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.done{text-align:center;font-size:var(--xiri-font-size-display)}[hidden]{display:none!important}\n"] }]
3784
3850
  }], ctorParameters: () => [] });
3785
3851
 
3852
+ var dialog_component = /*#__PURE__*/Object.freeze({
3853
+ __proto__: null,
3854
+ XiriDialogComponent: XiriDialogComponent
3855
+ });
3856
+
3786
3857
  const XIRI_PANEL_HOST = new InjectionToken('XIRI_PANEL_HOST');
3787
3858
  class XiriResponseHandlerService {
3788
3859
  constructor() {
@@ -4017,11 +4088,12 @@ class XiriButtonComponent {
4017
4088
  loading: false,
4018
4089
  });
4019
4090
  }
4091
+ // Ohne umschließende Card: wie eine Card ohne url → Page-Reload.
4020
4092
  refreshPanel() {
4021
4093
  if (this.panelHost)
4022
4094
  this.panelHost.reloadPanel();
4023
4095
  else
4024
- console.warn('xiri-button: refresh:panel ohne umschließende Card', this.button().url);
4096
+ this.responseHandler.handle({ refresh: 'page' });
4025
4097
  }
4026
4098
  startPolling(url, intervalMs, text) {
4027
4099
  this.cancelPollTimers();
@@ -5078,6 +5150,16 @@ class XiriTableComponent {
5078
5150
  return dataStr.indexOf(filter) !== -1;
5079
5151
  };
5080
5152
  }
5153
+ // Gespeicherten Suchtext VOR dem ersten Load wiederherstellen: server-side muss er im ersten
5154
+ // Request stehen, client-side (flach) muss der filter auf der dataSource gesetzt sein.
5155
+ // Sort/Paginator werden erst in setData() restauriert, weil sie die geladene Datenmenge brauchen.
5156
+ const savedFilter = this.savedState()?.filter;
5157
+ if (savedFilter) {
5158
+ this.searchText = savedFilter;
5159
+ this.searchTextInit = savedFilter;
5160
+ if (!this.options.serverSide && !this.tree.enabled)
5161
+ this.dataSource.filter = savedFilter;
5162
+ }
5081
5163
  if (this.options.buttons)
5082
5164
  this.options.buttons.class = 'small';
5083
5165
  this.dataSource.connect()
@@ -5232,24 +5314,23 @@ class XiriTableComponent {
5232
5314
  this._alldata.set(data);
5233
5315
  if (this._firstData) {
5234
5316
  this._firstData = false;
5235
- const stateKey = this.tableStateKey();
5236
- if (this.options.saveState && stateKey) {
5237
- const saved = this.sessionStorageService.getTimeout(stateKey, 3600);
5238
- if (!saved)
5239
- return;
5240
- if (saved.filter !== undefined) {
5241
- this.searchText = saved.filter;
5242
- this.searchTextInit = saved.filter;
5243
- }
5244
- if (saved.sort !== undefined && saved.sortDirection !== undefined)
5245
- this.sort().sort(({ id: saved.sort, start: saved.sortDirection }));
5246
- if (saved.pageSize !== undefined && saved.pageIndex !== undefined) {
5247
- this.paginator().pageIndex = saved.pageIndex;
5248
- this.paginator()._changePageSize(saved.pageSize);
5249
- }
5317
+ const saved = this.savedState();
5318
+ if (!saved)
5319
+ return;
5320
+ if (saved.sort !== undefined && saved.sortDirection !== undefined)
5321
+ this.sort().sort(({ id: saved.sort, start: saved.sortDirection }));
5322
+ if (saved.pageSize !== undefined && saved.pageIndex !== undefined) {
5323
+ this.paginator().pageIndex = saved.pageIndex;
5324
+ this.paginator()._changePageSize(saved.pageSize);
5250
5325
  }
5251
5326
  }
5252
5327
  }
5328
+ savedState() {
5329
+ const stateKey = this.tableStateKey();
5330
+ if (!this.options.saveState || !stateKey)
5331
+ return null;
5332
+ return this.sessionStorageService.getTimeout(stateKey, 3600);
5333
+ }
5253
5334
  setFooter(footer) {
5254
5335
  this.footer = footer;
5255
5336
  this.displayedColumns.forEach((column) => {
@@ -5599,7 +5680,7 @@ class XiriTableComponent {
5599
5680
  buttonReturn(event) {
5600
5681
  if (!event.done)
5601
5682
  return;
5602
- // xiri-button hat refresh:'panel' schon an den Panel-Host gegeben – hier nicht noch einmal.
5683
+ // xiri-button hat refresh:'panel' schon behandelt (Panel-Host oder Page-Fallback) – hier nicht noch einmal.
5603
5684
  this.callReturn(event.result, true);
5604
5685
  }
5605
5686
  callReturn(result, fromButton = false) {
@@ -5615,11 +5696,12 @@ class XiriTableComponent {
5615
5696
  onPanelRefresh: fromButton ? undefined : () => this.refreshPanel(),
5616
5697
  });
5617
5698
  }
5699
+ // Ohne umschließende Card: wie eine Card ohne url → Page-Reload.
5618
5700
  refreshPanel() {
5619
5701
  if (this.panelHost)
5620
5702
  this.panelHost.reloadPanel();
5621
5703
  else
5622
- console.warn('xiri-table: refresh:panel ohne umschließende Card');
5704
+ this.responseHandler.handle({ refresh: 'page' });
5623
5705
  }
5624
5706
  // Row ids are backend values (int64 or string) and are passed through untouched.
5625
5707
  // Coercing them to number would round anything above 2^53 and turn a non-numeric