@xiriframework/xiri-ng 0.3.2 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2039,7 +2039,7 @@ class XiriTreeselectComponent extends XiriFieldMain {
2039
2039
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: XiriTreeselectComponent, isStandalone: true, selector: "xiri-treeselect", inputs: { field: "field", value: "value" }, host: { listeners: { "focus": "focus()" }, properties: { "id": "id" } }, providers: [{
2040
2040
  provide: MatFormFieldControl,
2041
2041
  useExisting: XiriTreeselectComponent
2042
- }], viewQueries: [{ propertyName: "tree", first: true, predicate: MatTree, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"main\">\n\t<div class=\"line\">\n\t\t<div class=\"xrow xsmall\">\n\t\t\t<div class=\"xcol xcol-md-6 header\"><span>{{ field.name }}</span></div>\n\t\t\t<div class=\"xcol xcol-md-6 search\">\n\t\t\t\t@if (field.search !== false) {\n\t\t\t\t\t<xiri-search (changed)=\"searchDo($event)\"></xiri-search>\n\t\t\t\t}\n\t\t\t</div>\n\t\t</div>\n\t</div>\n\t<div class=\"tree\">\n\t\t@if (loading()) {\n\t\t\t<mat-spinner diameter=\"30\"></mat-spinner>\n\t\t}\n\t\t<mat-tree [dataSource]=\"dataSource\" [childrenAccessor]=\"getChildren\">\n\t\t\t<mat-tree-node *matTreeNodeDef=\"let node\" matTreeNodeToggle matTreeNodePadding=\"\" matTreeNodePaddingIndent=\"20px\" [hidden]=\"node.hidden\"\n\t\t\t [class.notree]=\"!field.tree\">\n\t\t\t\t<button mat-icon-button disabled aria-hidden=\"true\">\n\t\t\t\t\t<mat-icon style=\"visibility: hidden\">chevron_right</mat-icon>\n\t\t\t\t</button>\n\t\t\t\t<mat-checkbox class=\"checklist-leaf-node\" [checked]=\"node.state === 1\"\n\t\t\t\t (change)=\"treeItemSelectionToggle(node)\">{{ node.name }}\n\t\t\t\t</mat-checkbox>\n\t\t\t</mat-tree-node>\n\t\t\t<mat-tree-node *matTreeNodeDef=\"let node; when: hasChild\" matTreeNodePadding=\"\" matTreeNodePaddingIndent=\"20px\" [hidden]=\"node.hidden\">\n\t\t\t\t<button mat-icon-button matTreeNodeToggle [attr.aria-label]=\"tree().isExpanded(node) ? 'Zuklappen' : 'Aufklappen'\">\n\t\t\t\t\t<mat-icon class=\"mat-icon-rtl-mirror\">\n\t\t\t\t\t\t{{ tree().isExpanded(node) ? 'expand_more' : 'chevron_right' }}\n\t\t\t\t\t</mat-icon>\n\t\t\t\t</button>\n\t\t\t\t<mat-checkbox class=\"group\"\n\t\t\t\t [checked]=\"node.state === 1\"\n\t\t\t\t [indeterminate]=\"node.state === 2\"\n\t\t\t\t (change)=\"treeItemSelectionToggle(node)\">{{ node.name }}\n\t\t\t\t</mat-checkbox>\n\t\t\t</mat-tree-node>\n\t\t</mat-tree>\n\t</div>\n</div>", styles: [".main{border:1px solid var(--outline-variant, #C2C7CF);border-radius:var(--mat-form-field-filled-container-shape, var(--mat-sys-corner-extra-small));overflow:hidden}:host.error .main{border:1px solid var(--error, red)}.line{background-color:var(--surface-bright, #F9F9FC);padding:0 0 0 1rem;border-bottom:1px solid var(--outline-variant, #C2C7CF);border-top-left-radius:var(--mat-form-field-filled-container-shape, var(--mat-sys-corner-extra-small));border-top-right-radius:var(--mat-form-field-filled-container-shape, var(--mat-sys-corner-extra-small))}.line .header{color:var(--on-surface-variant, rgba(0, 0, 0, .54));display:flex;align-items:center;min-height:32px}.line .search{display:flex;justify-content:flex-end;padding-right:.5rem}.tree{height:300px;width:100%;overflow-y:scroll;background-color:var(--surface, #FFF)}.tree mat-spinner{margin:1rem}.tree .group{font-size:var(--xiri-font-size-label);color:var(--on-surface-variant, rgba(0, 0, 0, .54))}.tree mat-tree-node{min-height:20px;max-height:38px}.tree mat-tree-node.notree{margin-left:-25px}[hidden]{display:none!important}\n"], dependencies: [{ kind: "component", type: XiriSearchComponent, selector: "xiri-search", inputs: ["placeholder", "open", "reset", "escape", "focus", "text"], outputs: ["changed"] }, { kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: MatTree, selector: "mat-tree", exportAs: ["matTree"] }, { kind: "directive", type: MatTreeNode, selector: "mat-tree-node", inputs: ["tabIndex", "disabled"], outputs: ["activation", "expandedChange"], exportAs: ["matTreeNode"] }, { kind: "directive", type: MatTreeNodeToggle, selector: "[matTreeNodeToggle]", inputs: ["matTreeNodeToggleRecursive"] }, { kind: "directive", type: MatTreeNodePadding, selector: "[matTreeNodePadding]", inputs: ["matTreeNodePadding", "matTreeNodePaddingIndent"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { 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: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatTreeNodeDef, selector: "[matTreeNodeDef]", inputs: ["matTreeNodeDefWhen", "matTreeNode"] }] }); }
2042
+ }], viewQueries: [{ propertyName: "tree", first: true, predicate: MatTree, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"main\">\n\t<div class=\"line\">\n\t\t<div class=\"xrow xsmall\">\n\t\t\t<div class=\"xcol xcol-md-6 header\"><span>{{ field.name }}</span></div>\n\t\t\t<div class=\"xcol xcol-md-6 search\">\n\t\t\t\t@if (field.search !== false) {\n\t\t\t\t\t<xiri-search (changed)=\"searchDo($event)\"></xiri-search>\n\t\t\t\t}\n\t\t\t</div>\n\t\t</div>\n\t</div>\n\t<div class=\"tree\">\n\t\t@if (loading()) {\n\t\t\t<mat-spinner diameter=\"30\"></mat-spinner>\n\t\t}\n\t\t<mat-tree [dataSource]=\"dataSource\" [childrenAccessor]=\"getChildren\">\n\t\t\t<mat-tree-node *matTreeNodeDef=\"let node\" matTreeNodeToggle matTreeNodePadding=\"\" matTreeNodePaddingIndent=\"20px\" [hidden]=\"node.hidden\"\n\t\t\t [class.notree]=\"!field.tree\">\n\t\t\t\t<button mat-icon-button disabled aria-hidden=\"true\">\n\t\t\t\t\t<mat-icon style=\"visibility: hidden\">chevron_right</mat-icon>\n\t\t\t\t</button>\n\t\t\t\t<mat-checkbox class=\"checklist-leaf-node\" [checked]=\"node.state === 1\"\n\t\t\t\t (change)=\"treeItemSelectionToggle(node)\">{{ node.name }}\n\t\t\t\t</mat-checkbox>\n\t\t\t</mat-tree-node>\n\t\t\t<mat-tree-node *matTreeNodeDef=\"let node; when: hasChild\" matTreeNodePadding=\"\" matTreeNodePaddingIndent=\"20px\" [hidden]=\"node.hidden\">\n\t\t\t\t<button mat-icon-button matTreeNodeToggle [attr.aria-label]=\"tree().isExpanded(node) ? 'Zuklappen' : 'Aufklappen'\">\n\t\t\t\t\t<mat-icon class=\"mat-icon-rtl-mirror\">\n\t\t\t\t\t\t{{ tree().isExpanded(node) ? 'expand_more' : 'chevron_right' }}\n\t\t\t\t\t</mat-icon>\n\t\t\t\t</button>\n\t\t\t\t<mat-checkbox class=\"group\"\n\t\t\t\t [checked]=\"node.state === 1\"\n\t\t\t\t [indeterminate]=\"node.state === 2\"\n\t\t\t\t (change)=\"treeItemSelectionToggle(node)\">{{ node.name }}\n\t\t\t\t</mat-checkbox>\n\t\t\t</mat-tree-node>\n\t\t</mat-tree>\n\t</div>\n</div>", styles: [".main{border:1px solid var(--outline-variant, #C2C7CF);border-radius:var(--mat-form-field-filled-container-shape, var(--xiri-radius-xs, var(--mat-sys-corner-extra-small)));overflow:hidden}:host.error .main{border:1px solid var(--error, red)}.line{background-color:var(--surface-bright, #F9F9FC);padding:0 0 0 1rem;border-bottom:1px solid var(--outline-variant, #C2C7CF);border-top-left-radius:var(--mat-form-field-filled-container-shape, var(--xiri-radius-xs, var(--mat-sys-corner-extra-small)));border-top-right-radius:var(--mat-form-field-filled-container-shape, var(--xiri-radius-xs, var(--mat-sys-corner-extra-small)))}.line .header{color:var(--on-surface-variant, rgba(0, 0, 0, .54));display:flex;align-items:center;min-height:32px}.line .search{display:flex;justify-content:flex-end;padding-right:.5rem}.tree{height:300px;width:100%;overflow-y:scroll;background-color:var(--surface, #FFF)}.tree mat-spinner{margin:1rem}.tree .group{font-size:var(--xiri-font-size-label);color:var(--on-surface-variant, rgba(0, 0, 0, .54))}.tree mat-tree-node{min-height:20px;max-height:38px}.tree mat-tree-node.notree{margin-left:-25px}[hidden]{display:none!important}\n"], dependencies: [{ kind: "component", type: XiriSearchComponent, selector: "xiri-search", inputs: ["placeholder", "open", "reset", "escape", "focus", "text"], outputs: ["changed"] }, { kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: MatTree, selector: "mat-tree", exportAs: ["matTree"] }, { kind: "directive", type: MatTreeNode, selector: "mat-tree-node", inputs: ["tabIndex", "disabled"], outputs: ["activation", "expandedChange"], exportAs: ["matTreeNode"] }, { kind: "directive", type: MatTreeNodeToggle, selector: "[matTreeNodeToggle]", inputs: ["matTreeNodeToggleRecursive"] }, { kind: "directive", type: MatTreeNodePadding, selector: "[matTreeNodePadding]", inputs: ["matTreeNodePadding", "matTreeNodePaddingIndent"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { 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: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatTreeNodeDef, selector: "[matTreeNodeDef]", inputs: ["matTreeNodeDefWhen", "matTreeNode"] }] }); }
2043
2043
  }
2044
2044
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriTreeselectComponent, decorators: [{
2045
2045
  type: Component,
@@ -2060,7 +2060,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
2060
2060
  MatCheckbox,
2061
2061
  MatIcon,
2062
2062
  MatTreeNodeDef,
2063
- ], template: "<div class=\"main\">\n\t<div class=\"line\">\n\t\t<div class=\"xrow xsmall\">\n\t\t\t<div class=\"xcol xcol-md-6 header\"><span>{{ field.name }}</span></div>\n\t\t\t<div class=\"xcol xcol-md-6 search\">\n\t\t\t\t@if (field.search !== false) {\n\t\t\t\t\t<xiri-search (changed)=\"searchDo($event)\"></xiri-search>\n\t\t\t\t}\n\t\t\t</div>\n\t\t</div>\n\t</div>\n\t<div class=\"tree\">\n\t\t@if (loading()) {\n\t\t\t<mat-spinner diameter=\"30\"></mat-spinner>\n\t\t}\n\t\t<mat-tree [dataSource]=\"dataSource\" [childrenAccessor]=\"getChildren\">\n\t\t\t<mat-tree-node *matTreeNodeDef=\"let node\" matTreeNodeToggle matTreeNodePadding=\"\" matTreeNodePaddingIndent=\"20px\" [hidden]=\"node.hidden\"\n\t\t\t [class.notree]=\"!field.tree\">\n\t\t\t\t<button mat-icon-button disabled aria-hidden=\"true\">\n\t\t\t\t\t<mat-icon style=\"visibility: hidden\">chevron_right</mat-icon>\n\t\t\t\t</button>\n\t\t\t\t<mat-checkbox class=\"checklist-leaf-node\" [checked]=\"node.state === 1\"\n\t\t\t\t (change)=\"treeItemSelectionToggle(node)\">{{ node.name }}\n\t\t\t\t</mat-checkbox>\n\t\t\t</mat-tree-node>\n\t\t\t<mat-tree-node *matTreeNodeDef=\"let node; when: hasChild\" matTreeNodePadding=\"\" matTreeNodePaddingIndent=\"20px\" [hidden]=\"node.hidden\">\n\t\t\t\t<button mat-icon-button matTreeNodeToggle [attr.aria-label]=\"tree().isExpanded(node) ? 'Zuklappen' : 'Aufklappen'\">\n\t\t\t\t\t<mat-icon class=\"mat-icon-rtl-mirror\">\n\t\t\t\t\t\t{{ tree().isExpanded(node) ? 'expand_more' : 'chevron_right' }}\n\t\t\t\t\t</mat-icon>\n\t\t\t\t</button>\n\t\t\t\t<mat-checkbox class=\"group\"\n\t\t\t\t [checked]=\"node.state === 1\"\n\t\t\t\t [indeterminate]=\"node.state === 2\"\n\t\t\t\t (change)=\"treeItemSelectionToggle(node)\">{{ node.name }}\n\t\t\t\t</mat-checkbox>\n\t\t\t</mat-tree-node>\n\t\t</mat-tree>\n\t</div>\n</div>", styles: [".main{border:1px solid var(--outline-variant, #C2C7CF);border-radius:var(--mat-form-field-filled-container-shape, var(--mat-sys-corner-extra-small));overflow:hidden}:host.error .main{border:1px solid var(--error, red)}.line{background-color:var(--surface-bright, #F9F9FC);padding:0 0 0 1rem;border-bottom:1px solid var(--outline-variant, #C2C7CF);border-top-left-radius:var(--mat-form-field-filled-container-shape, var(--mat-sys-corner-extra-small));border-top-right-radius:var(--mat-form-field-filled-container-shape, var(--mat-sys-corner-extra-small))}.line .header{color:var(--on-surface-variant, rgba(0, 0, 0, .54));display:flex;align-items:center;min-height:32px}.line .search{display:flex;justify-content:flex-end;padding-right:.5rem}.tree{height:300px;width:100%;overflow-y:scroll;background-color:var(--surface, #FFF)}.tree mat-spinner{margin:1rem}.tree .group{font-size:var(--xiri-font-size-label);color:var(--on-surface-variant, rgba(0, 0, 0, .54))}.tree mat-tree-node{min-height:20px;max-height:38px}.tree mat-tree-node.notree{margin-left:-25px}[hidden]{display:none!important}\n"] }]
2063
+ ], template: "<div class=\"main\">\n\t<div class=\"line\">\n\t\t<div class=\"xrow xsmall\">\n\t\t\t<div class=\"xcol xcol-md-6 header\"><span>{{ field.name }}</span></div>\n\t\t\t<div class=\"xcol xcol-md-6 search\">\n\t\t\t\t@if (field.search !== false) {\n\t\t\t\t\t<xiri-search (changed)=\"searchDo($event)\"></xiri-search>\n\t\t\t\t}\n\t\t\t</div>\n\t\t</div>\n\t</div>\n\t<div class=\"tree\">\n\t\t@if (loading()) {\n\t\t\t<mat-spinner diameter=\"30\"></mat-spinner>\n\t\t}\n\t\t<mat-tree [dataSource]=\"dataSource\" [childrenAccessor]=\"getChildren\">\n\t\t\t<mat-tree-node *matTreeNodeDef=\"let node\" matTreeNodeToggle matTreeNodePadding=\"\" matTreeNodePaddingIndent=\"20px\" [hidden]=\"node.hidden\"\n\t\t\t [class.notree]=\"!field.tree\">\n\t\t\t\t<button mat-icon-button disabled aria-hidden=\"true\">\n\t\t\t\t\t<mat-icon style=\"visibility: hidden\">chevron_right</mat-icon>\n\t\t\t\t</button>\n\t\t\t\t<mat-checkbox class=\"checklist-leaf-node\" [checked]=\"node.state === 1\"\n\t\t\t\t (change)=\"treeItemSelectionToggle(node)\">{{ node.name }}\n\t\t\t\t</mat-checkbox>\n\t\t\t</mat-tree-node>\n\t\t\t<mat-tree-node *matTreeNodeDef=\"let node; when: hasChild\" matTreeNodePadding=\"\" matTreeNodePaddingIndent=\"20px\" [hidden]=\"node.hidden\">\n\t\t\t\t<button mat-icon-button matTreeNodeToggle [attr.aria-label]=\"tree().isExpanded(node) ? 'Zuklappen' : 'Aufklappen'\">\n\t\t\t\t\t<mat-icon class=\"mat-icon-rtl-mirror\">\n\t\t\t\t\t\t{{ tree().isExpanded(node) ? 'expand_more' : 'chevron_right' }}\n\t\t\t\t\t</mat-icon>\n\t\t\t\t</button>\n\t\t\t\t<mat-checkbox class=\"group\"\n\t\t\t\t [checked]=\"node.state === 1\"\n\t\t\t\t [indeterminate]=\"node.state === 2\"\n\t\t\t\t (change)=\"treeItemSelectionToggle(node)\">{{ node.name }}\n\t\t\t\t</mat-checkbox>\n\t\t\t</mat-tree-node>\n\t\t</mat-tree>\n\t</div>\n</div>", styles: [".main{border:1px solid var(--outline-variant, #C2C7CF);border-radius:var(--mat-form-field-filled-container-shape, var(--xiri-radius-xs, var(--mat-sys-corner-extra-small)));overflow:hidden}:host.error .main{border:1px solid var(--error, red)}.line{background-color:var(--surface-bright, #F9F9FC);padding:0 0 0 1rem;border-bottom:1px solid var(--outline-variant, #C2C7CF);border-top-left-radius:var(--mat-form-field-filled-container-shape, var(--xiri-radius-xs, var(--mat-sys-corner-extra-small)));border-top-right-radius:var(--mat-form-field-filled-container-shape, var(--xiri-radius-xs, var(--mat-sys-corner-extra-small)))}.line .header{color:var(--on-surface-variant, rgba(0, 0, 0, .54));display:flex;align-items:center;min-height:32px}.line .search{display:flex;justify-content:flex-end;padding-right:.5rem}.tree{height:300px;width:100%;overflow-y:scroll;background-color:var(--surface, #FFF)}.tree mat-spinner{margin:1rem}.tree .group{font-size:var(--xiri-font-size-label);color:var(--on-surface-variant, rgba(0, 0, 0, .54))}.tree mat-tree-node{min-height:20px;max-height:38px}.tree mat-tree-node.notree{margin-left:-25px}[hidden]{display:none!important}\n"] }]
2064
2064
  }], ctorParameters: () => [], propDecorators: { field: [{
2065
2065
  type: Input
2066
2066
  }], value: [{
@@ -2259,7 +2259,7 @@ class XiriChipsComponent {
2259
2259
  provide: NG_VALUE_ACCESSOR,
2260
2260
  useExisting: forwardRef(() => XiriChipsComponent),
2261
2261
  multi: true
2262
- }], viewQueries: [{ propertyName: "chipInput", first: true, predicate: ["chipInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<mat-form-field>\n\t@if (field().name) {\n\t\t<mat-label>{{ field().name }}</mat-label>\n\t}\n\t<mat-chip-grid #chipGrid>\n\t\t@for (chip of chips(); track chip) {\n\t\t\t<mat-chip-row (removed)=\"remove(chip)\" [class]=\"chipColor(chip)\">\n\t\t\t\t{{ displayLabel(chip) }}\n\t\t\t\t<button matChipRemove>\n\t\t\t\t\t<mat-icon>cancel</mat-icon>\n\t\t\t\t</button>\n\t\t\t</mat-chip-row>\n\t\t}\n\t</mat-chip-grid>\n\t<input #chipInput\n\t [matChipInputFor]=\"chipGrid\"\n\t [matChipInputSeparatorKeyCodes]=\"separatorKeyCodes\"\n\t [matChipInputAddOnBlur]=\"true\"\n\t (matChipInputTokenEnd)=\"add($event)\"\n\t (input)=\"onInputChange($event)\"\n\t (focus)=\"onFocus()\"\n\t [matAutocomplete]=\"auto\"\n\t [placeholder]=\"field().hint || ''\">\n\t<mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"selected($event)\">\n\t\t@for (option of filteredOptions(); track option.id) {\n\t\t\t<mat-option [value]=\"option\">{{ option.name }}</mat-option>\n\t\t}\n\t</mat-autocomplete>\n</mat-form-field>\n", styles: [":host{display:block;width:100%}mat-form-field{width:100%}\n"], dependencies: [{ 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: "component", type: MatChipGrid, selector: "mat-chip-grid", inputs: ["disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "component", type: MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "directive", type: MatChipRemove, selector: "[matChipRemove]" }, { kind: "directive", type: MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled", "readonly", "matChipInputDisabledInteractive"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "component", type: MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] }); }
2262
+ }], viewQueries: [{ propertyName: "chipInput", first: true, predicate: ["chipInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<mat-form-field>\n\t@if (field().name) {\n\t\t<mat-label>{{ field().name }}</mat-label>\n\t}\n\t<mat-chip-grid #chipGrid>\n\t\t@for (chip of chips(); track chip) {\n\t\t\t<mat-chip-row (removed)=\"remove(chip)\" [class]=\"chipColor(chip)\">\n\t\t\t\t{{ displayLabel(chip) }}\n\t\t\t\t<button matChipRemove [attr.aria-label]=\"'Entfernen: ' + displayLabel( chip )\">\n\t\t\t\t\t<mat-icon>cancel</mat-icon>\n\t\t\t\t</button>\n\t\t\t</mat-chip-row>\n\t\t}\n\t</mat-chip-grid>\n\t<input #chipInput\n\t [matChipInputFor]=\"chipGrid\"\n\t [matChipInputSeparatorKeyCodes]=\"separatorKeyCodes\"\n\t [matChipInputAddOnBlur]=\"true\"\n\t (matChipInputTokenEnd)=\"add($event)\"\n\t (input)=\"onInputChange($event)\"\n\t (focus)=\"onFocus()\"\n\t [matAutocomplete]=\"auto\"\n\t [placeholder]=\"field().hint || ''\">\n\t<mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"selected($event)\">\n\t\t@for (option of filteredOptions(); track option.id) {\n\t\t\t<mat-option [value]=\"option\">{{ option.name }}</mat-option>\n\t\t}\n\t</mat-autocomplete>\n</mat-form-field>\n", styles: [":host{display:block;width:100%}mat-form-field{width:100%}\n"], dependencies: [{ 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: "component", type: MatChipGrid, selector: "mat-chip-grid", inputs: ["disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "component", type: MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "directive", type: MatChipRemove, selector: "[matChipRemove]" }, { kind: "directive", type: MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled", "readonly", "matChipInputDisabledInteractive"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "component", type: MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] }); }
2263
2263
  }
2264
2264
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriChipsComponent, decorators: [{
2265
2265
  type: Component,
@@ -2278,7 +2278,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
2278
2278
  MatAutocomplete,
2279
2279
  MatOption,
2280
2280
  MatIcon
2281
- ], template: "<mat-form-field>\n\t@if (field().name) {\n\t\t<mat-label>{{ field().name }}</mat-label>\n\t}\n\t<mat-chip-grid #chipGrid>\n\t\t@for (chip of chips(); track chip) {\n\t\t\t<mat-chip-row (removed)=\"remove(chip)\" [class]=\"chipColor(chip)\">\n\t\t\t\t{{ displayLabel(chip) }}\n\t\t\t\t<button matChipRemove>\n\t\t\t\t\t<mat-icon>cancel</mat-icon>\n\t\t\t\t</button>\n\t\t\t</mat-chip-row>\n\t\t}\n\t</mat-chip-grid>\n\t<input #chipInput\n\t [matChipInputFor]=\"chipGrid\"\n\t [matChipInputSeparatorKeyCodes]=\"separatorKeyCodes\"\n\t [matChipInputAddOnBlur]=\"true\"\n\t (matChipInputTokenEnd)=\"add($event)\"\n\t (input)=\"onInputChange($event)\"\n\t (focus)=\"onFocus()\"\n\t [matAutocomplete]=\"auto\"\n\t [placeholder]=\"field().hint || ''\">\n\t<mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"selected($event)\">\n\t\t@for (option of filteredOptions(); track option.id) {\n\t\t\t<mat-option [value]=\"option\">{{ option.name }}</mat-option>\n\t\t}\n\t</mat-autocomplete>\n</mat-form-field>\n", styles: [":host{display:block;width:100%}mat-form-field{width:100%}\n"] }]
2281
+ ], template: "<mat-form-field>\n\t@if (field().name) {\n\t\t<mat-label>{{ field().name }}</mat-label>\n\t}\n\t<mat-chip-grid #chipGrid>\n\t\t@for (chip of chips(); track chip) {\n\t\t\t<mat-chip-row (removed)=\"remove(chip)\" [class]=\"chipColor(chip)\">\n\t\t\t\t{{ displayLabel(chip) }}\n\t\t\t\t<button matChipRemove [attr.aria-label]=\"'Entfernen: ' + displayLabel( chip )\">\n\t\t\t\t\t<mat-icon>cancel</mat-icon>\n\t\t\t\t</button>\n\t\t\t</mat-chip-row>\n\t\t}\n\t</mat-chip-grid>\n\t<input #chipInput\n\t [matChipInputFor]=\"chipGrid\"\n\t [matChipInputSeparatorKeyCodes]=\"separatorKeyCodes\"\n\t [matChipInputAddOnBlur]=\"true\"\n\t (matChipInputTokenEnd)=\"add($event)\"\n\t (input)=\"onInputChange($event)\"\n\t (focus)=\"onFocus()\"\n\t [matAutocomplete]=\"auto\"\n\t [placeholder]=\"field().hint || ''\">\n\t<mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"selected($event)\">\n\t\t@for (option of filteredOptions(); track option.id) {\n\t\t\t<mat-option [value]=\"option\">{{ option.name }}</mat-option>\n\t\t}\n\t</mat-autocomplete>\n</mat-form-field>\n", styles: [":host{display:block;width:100%}mat-form-field{width:100%}\n"] }]
2282
2282
  }], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], chipInput: [{ type: i0.ViewChild, args: ['chipInput', { isSignal: true }] }] } });
2283
2283
 
2284
2284
  function formatValidationDate(localeString, unixSeconds) {
@@ -2703,7 +2703,7 @@ class XiriFormFieldsComponent {
2703
2703
  }
2704
2704
  }
2705
2705
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriFormFieldsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2706
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", 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: "<form class=\"xrow dynamic-form\" [formGroup]=\"formGroup\" [class]=\"display()\">\n\t@for (field of fields(); 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) {\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) {\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) {\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) {\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 || {}\"></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) {\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) {\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) {\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) {\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) {\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) {\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) {\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) {\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) {\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) {\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: [".dynamic-form{grid-row-gap:7px}.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{align-self:start;min-width:min(9.5rem,100%)}.dynamic-form .date.datetime{min-width:min(14.5rem,100%)}.dynamic-form .daterange{align-self:start;min-width:min(14.5rem,100%)}.dynamic-form .datetimerange{align-self:start;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(--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(--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: XiriChipsComponent, selector: "xiri-chips", inputs: ["field"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: SafehtmlPipe, name: "safeHtml" }] }); }
2706
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", 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: "<form class=\"xrow dynamic-form\" [formGroup]=\"formGroup\" [class]=\"display()\">\n\t@for (field of fields(); 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) {\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) {\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) {\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) {\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 || {}\"></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) {\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) {\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) {\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) {\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) {\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) {\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) {\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) {\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) {\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) {\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: [".dynamic-form{grid-row-gap:7px}.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{align-self:start;min-width:min(9.5rem,100%)}.dynamic-form .date.datetime{min-width:min(14.5rem,100%)}.dynamic-form .daterange{align-self:start;min-width:min(14.5rem,100%)}.dynamic-form .datetimerange{align-self:start;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: XiriChipsComponent, selector: "xiri-chips", inputs: ["field"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: SafehtmlPipe, name: "safeHtml" }] }); }
2707
2707
  }
2708
2708
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriFormFieldsComponent, decorators: [{
2709
2709
  type: Component,
@@ -2738,7 +2738,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
2738
2738
  AsyncPipe,
2739
2739
  SafehtmlPipe,
2740
2740
  XiriChipsComponent,
2741
- ], template: "<form class=\"xrow dynamic-form\" [formGroup]=\"formGroup\" [class]=\"display()\">\n\t@for (field of fields(); 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) {\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) {\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) {\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) {\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 || {}\"></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) {\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) {\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) {\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) {\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) {\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) {\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) {\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) {\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) {\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) {\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: [".dynamic-form{grid-row-gap:7px}.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{align-self:start;min-width:min(9.5rem,100%)}.dynamic-form .date.datetime{min-width:min(14.5rem,100%)}.dynamic-form .daterange{align-self:start;min-width:min(14.5rem,100%)}.dynamic-form .datetimerange{align-self:start;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(--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(--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"] }]
2741
+ ], template: "<form class=\"xrow dynamic-form\" [formGroup]=\"formGroup\" [class]=\"display()\">\n\t@for (field of fields(); 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) {\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) {\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) {\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) {\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 || {}\"></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) {\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) {\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) {\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) {\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) {\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) {\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) {\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) {\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) {\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) {\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: [".dynamic-form{grid-row-gap:7px}.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{align-self:start;min-width:min(9.5rem,100%)}.dynamic-form .date.datetime{min-width:min(14.5rem,100%)}.dynamic-form .daterange{align-self:start;min-width:min(14.5rem,100%)}.dynamic-form .datetimerange{align-self:start;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"] }]
2742
2742
  }], 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 }] }] } });
2743
2743
  function fillListFromArray(field) {
2744
2744
  if (field.list === undefined && field.array !== undefined) {
@@ -2865,7 +2865,7 @@ class XiriButtonstyleComponent {
2865
2865
  ...(ngDevMode ? [{ debugName: "pollText" }] : /* istanbul ignore next */ []));
2866
2866
  }
2867
2867
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriButtonstyleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2868
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: XiriButtonstyleComponent, isStandalone: true, selector: "xiri-buttonstyle", inputs: { button: { classPropertyName: "button", publicName: "button", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: true, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, countdown: { classPropertyName: "countdown", publicName: "countdown", isSignal: true, isRequired: false, transformFunction: null }, pollText: { classPropertyName: "pollText", publicName: "pollText", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ng-template #textContent>\n\t@if (loading()) {\n\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t@if (pollText() || countdown() > 0) {\n\t\t\t<span class=\"poll-countdown\">{{ pollText() || countdown() + 's' }}</span>\n\t\t}\n\t} @else {\n\t\t{{ button().text }}\n\t}\n</ng-template>\n\n@switch (button().type) {\n\t@case ('icon') {\n\t\t<button mat-icon-button [matTooltip]=\"button().hint\" [matTooltipDisabled]=\"!button().hint\"\n\t\t [attr.aria-label]=\"button().hint || button().text\"\n\t\t [color]=\"button().color || 'primary'\" [disabled]=\"disabled() || loading()\">\n\t\t\t@if (loading()) {\n\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t} @else {\n\t\t\t\t<mat-icon>{{ button().icon }}</mat-icon>\n\t\t\t}\n\t\t</button>\n\t}\n\t@case ('icontext') {\n\t\t<button mat-fab extended=\"true\"\n\t\t class=\"icontext\"\n\t\t [matTooltip]=\"button().hint\"\n\t\t [matTooltipDisabled]=\"!button().hint\"\n\t\t [color]=\"button().color || 'primary'\"\n\t\t [disabled]=\"disabled() || loading()\"\n\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t@if (loading()) {\n\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t\t@if (pollText() || countdown() > 0) {\n\t\t\t\t\t<span class=\"poll-countdown\">{{ pollText() || countdown() + 's' }}</span>\n\t\t\t\t}\n\t\t\t} @else {\n\t\t\t\t<mat-icon>{{ button().icon }}</mat-icon>\n\t\t\t}\n\t\t\t{{ button().text }}\n\t\t</button>\n\t}\n\t@case ('raised') {\n\t\t<button mat-raised-button\n\t\t [matTooltip]=\"button().hint\"\n\t\t [matTooltipDisabled]=\"!button().hint\"\n\t\t [color]=\"button().color || 'primary'\"\n\t\t [disabled]=\"disabled() || loading()\"\n\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t<ng-container [ngTemplateOutlet]=\"textContent\"></ng-container>\n\t\t</button>\n\t}\n\t@case ('basic') {\n\t\t<button mat-button\n\t\t [matTooltip]=\"button().hint\"\n\t\t [matTooltipDisabled]=\"!button().hint\"\n\t\t [color]=\"button().color || 'primary'\"\n\t\t [disabled]=\"disabled() || loading()\"\n\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t<ng-container [ngTemplateOutlet]=\"textContent\"></ng-container>\n\t\t</button>\n\t}\n\t@case ('stroked') {\n\t\t<button mat-stroked-button\n\t\t [matTooltip]=\"button().hint\"\n\t\t [matTooltipDisabled]=\"!button().hint\"\n\t\t [color]=\"button().color || 'primary'\"\n\t\t [disabled]=\"disabled() || loading()\"\n\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t<ng-container [ngTemplateOutlet]=\"textContent\"></ng-container>\n\t\t</button>\n\t}\n\t@case ('flat') {\n\t\t<button mat-flat-button\n\t\t [matTooltip]=\"button().hint\"\n\t\t [matTooltipDisabled]=\"!button().hint\"\n\t\t [color]=\"button().color || 'primary'\"\n\t\t [disabled]=\"disabled() || loading()\"\n\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t<ng-container [ngTemplateOutlet]=\"textContent\"></ng-container>\n\t\t</button>\n\t}\n\t@case ('minifab') {\n\t\t<button mat-mini-fab [matTooltip]=\"button().hint\" [matTooltipDisabled]=\"!button().hint\"\n\t\t [attr.aria-label]=\"button().hint || button().text\"\n\t\t [color]=\"button().color || 'primary'\" [disabled]=\"disabled() || loading()\"\n\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t@if (loading()) {\n\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t} @else {\n\t\t\t\t<mat-icon>{{ button().icon }}</mat-icon>\n\t\t\t}\n\t\t</button>\n\t}\n\t@case ('fab') {\n\t\t<button mat-fab [matTooltip]=\"button().hint\" [matTooltipDisabled]=\"!button().hint\"\n\t\t [attr.aria-label]=\"button().hint || button().text\"\n\t\t [color]=\"button().color || 'primary'\" [disabled]=\"disabled() || loading()\"\n\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t@if (loading()) {\n\t\t\t\t<mat-spinner diameter=\"24\"></mat-spinner>\n\t\t\t} @else {\n\t\t\t\t<mat-icon>{{ button().icon }}</mat-icon>\n\t\t\t}\n\t\t</button>\n\t}\n\t@default {\n\t\t@if (button().icon) {\n\t\t\t<button mat-icon-button [matTooltip]=\"button().hint\" [matTooltipDisabled]=\"!button().hint\"\n\t\t\t [attr.aria-label]=\"button().hint || button().text\"\n\t\t\t [color]=\"button().color || 'primary'\" [disabled]=\"disabled() || loading()\"\n\t\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t\t@if (loading()) {\n\t\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t\t} @else {\n\t\t\t\t\t<mat-icon>{{ button().icon }}</mat-icon>\n\t\t\t\t}\n\t\t\t</button>\n\t\t}\n\t\t@if (button().text) {\n\t\t\t<button mat-raised-button\n\t\t\t [matTooltip]=\"button().hint\"\n\t\t\t [matTooltipDisabled]=\"!button().hint\"\n\t\t\t [color]=\"button().color || 'primary'\"\n\t\t\t [disabled]=\"disabled() || loading()\"\n\t\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"textContent\"></ng-container>\n\t\t\t</button>\n\t\t}\n\t}\n}\n", styles: ["mat-spinner{display:inline-block;--mat-progress-spinner-active-indicator-color: currentColor}.poll-countdown{display:inline-block;margin-left:6px;font-variant-numeric:tabular-nums;font-size:.85em;opacity:.9}\n"], dependencies: [{ kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] }); }
2868
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: XiriButtonstyleComponent, isStandalone: true, selector: "xiri-buttonstyle", inputs: { button: { classPropertyName: "button", publicName: "button", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: true, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, countdown: { classPropertyName: "countdown", publicName: "countdown", isSignal: true, isRequired: false, transformFunction: null }, pollText: { classPropertyName: "pollText", publicName: "pollText", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ng-template #textContent>\n\t@if (loading()) {\n\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t@if (pollText() || countdown() > 0) {\n\t\t\t<span class=\"poll-countdown\">{{ pollText() || countdown() + 's' }}</span>\n\t\t}\n\t} @else {\n\t\t{{ button().text }}\n\t}\n</ng-template>\n\n<!-- Guard sitzt hier, nicht nur in xiri-button: form, dialog, alert und stepper\n rendern XiriButton direkt ueber buttonstyle. -->\n@if (!button().hide) {\n\t@switch (button().type) {\n\t\t@case ('icon') {\n\t\t\t<button mat-icon-button [matTooltip]=\"button().hint\" [matTooltipDisabled]=\"!button().hint\"\n\t\t\t [attr.aria-label]=\"button().hint || button().text\"\n\t\t\t [color]=\"button().color || 'primary'\" [disabled]=\"disabled() || loading()\">\n\t\t\t\t@if (loading()) {\n\t\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t\t} @else {\n\t\t\t\t\t<mat-icon>{{ button().icon }}</mat-icon>\n\t\t\t\t}\n\t\t\t</button>\n\t\t}\n\t\t@case ('icontext') {\n\t\t\t<button mat-fab extended=\"true\"\n\t\t\t class=\"icontext\"\n\t\t\t [matTooltip]=\"button().hint\"\n\t\t\t [matTooltipDisabled]=\"!button().hint\"\n\t\t\t [color]=\"button().color || 'primary'\"\n\t\t\t [disabled]=\"disabled() || loading()\"\n\t\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t\t@if (loading()) {\n\t\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t\t\t@if (pollText() || countdown() > 0) {\n\t\t\t\t\t\t<span class=\"poll-countdown\">{{ pollText() || countdown() + 's' }}</span>\n\t\t\t\t\t}\n\t\t\t\t} @else {\n\t\t\t\t\t<mat-icon>{{ button().icon }}</mat-icon>\n\t\t\t\t}\n\t\t\t\t{{ button().text }}\n\t\t\t</button>\n\t\t}\n\t\t@case ('raised') {\n\t\t\t<button mat-raised-button\n\t\t\t [matTooltip]=\"button().hint\"\n\t\t\t [matTooltipDisabled]=\"!button().hint\"\n\t\t\t [color]=\"button().color || 'primary'\"\n\t\t\t [disabled]=\"disabled() || loading()\"\n\t\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"textContent\"></ng-container>\n\t\t\t</button>\n\t\t}\n\t\t@case ('basic') {\n\t\t\t<button mat-button\n\t\t\t [matTooltip]=\"button().hint\"\n\t\t\t [matTooltipDisabled]=\"!button().hint\"\n\t\t\t [color]=\"button().color || 'primary'\"\n\t\t\t [disabled]=\"disabled() || loading()\"\n\t\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"textContent\"></ng-container>\n\t\t\t</button>\n\t\t}\n\t\t@case ('stroked') {\n\t\t\t<button mat-stroked-button\n\t\t\t [matTooltip]=\"button().hint\"\n\t\t\t [matTooltipDisabled]=\"!button().hint\"\n\t\t\t [color]=\"button().color || 'primary'\"\n\t\t\t [disabled]=\"disabled() || loading()\"\n\t\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"textContent\"></ng-container>\n\t\t\t</button>\n\t\t}\n\t\t@case ('flat') {\n\t\t\t<button mat-flat-button\n\t\t\t [matTooltip]=\"button().hint\"\n\t\t\t [matTooltipDisabled]=\"!button().hint\"\n\t\t\t [color]=\"button().color || 'primary'\"\n\t\t\t [disabled]=\"disabled() || loading()\"\n\t\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"textContent\"></ng-container>\n\t\t\t</button>\n\t\t}\n\t\t@case ('minifab') {\n\t\t\t<button mat-mini-fab [matTooltip]=\"button().hint\" [matTooltipDisabled]=\"!button().hint\"\n\t\t\t [attr.aria-label]=\"button().hint || button().text\"\n\t\t\t [color]=\"button().color || 'primary'\" [disabled]=\"disabled() || loading()\"\n\t\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t\t@if (loading()) {\n\t\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t\t} @else {\n\t\t\t\t\t<mat-icon>{{ button().icon }}</mat-icon>\n\t\t\t\t}\n\t\t\t</button>\n\t\t}\n\t\t@case ('fab') {\n\t\t\t<button mat-fab [matTooltip]=\"button().hint\" [matTooltipDisabled]=\"!button().hint\"\n\t\t\t [attr.aria-label]=\"button().hint || button().text\"\n\t\t\t [color]=\"button().color || 'primary'\" [disabled]=\"disabled() || loading()\"\n\t\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t\t@if (loading()) {\n\t\t\t\t\t<mat-spinner diameter=\"24\"></mat-spinner>\n\t\t\t\t} @else {\n\t\t\t\t\t<mat-icon>{{ button().icon }}</mat-icon>\n\t\t\t\t}\n\t\t\t</button>\n\t\t}\n\t\t@default {\n\t\t\t@if (button().icon) {\n\t\t\t\t<button mat-icon-button [matTooltip]=\"button().hint\" [matTooltipDisabled]=\"!button().hint\"\n\t\t\t\t [attr.aria-label]=\"button().hint || button().text\"\n\t\t\t\t [color]=\"button().color || 'primary'\" [disabled]=\"disabled() || loading()\"\n\t\t\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t\t\t@if (loading()) {\n\t\t\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<mat-icon>{{ button().icon }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t</button>\n\t\t\t}\n\t\t\t@if (button().text) {\n\t\t\t\t<button mat-raised-button\n\t\t\t\t [matTooltip]=\"button().hint\"\n\t\t\t\t [matTooltipDisabled]=\"!button().hint\"\n\t\t\t\t [color]=\"button().color || 'primary'\"\n\t\t\t\t [disabled]=\"disabled() || loading()\"\n\t\t\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"textContent\"></ng-container>\n\t\t\t\t</button>\n\t\t\t}\n\t\t}\n\t}\n}\n", styles: ["mat-spinner{display:inline-block;--mat-progress-spinner-active-indicator-color: currentColor}.poll-countdown{display:inline-block;margin-left:6px;font-variant-numeric:tabular-nums;font-size:.85em;opacity:.9}\n"], dependencies: [{ kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] }); }
2869
2869
  }
2870
2870
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriButtonstyleComponent, decorators: [{
2871
2871
  type: Component,
@@ -2878,7 +2878,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
2878
2878
  MatTooltip,
2879
2879
  MatProgressSpinner,
2880
2880
  NgTemplateOutlet
2881
- ], template: "<ng-template #textContent>\n\t@if (loading()) {\n\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t@if (pollText() || countdown() > 0) {\n\t\t\t<span class=\"poll-countdown\">{{ pollText() || countdown() + 's' }}</span>\n\t\t}\n\t} @else {\n\t\t{{ button().text }}\n\t}\n</ng-template>\n\n@switch (button().type) {\n\t@case ('icon') {\n\t\t<button mat-icon-button [matTooltip]=\"button().hint\" [matTooltipDisabled]=\"!button().hint\"\n\t\t [attr.aria-label]=\"button().hint || button().text\"\n\t\t [color]=\"button().color || 'primary'\" [disabled]=\"disabled() || loading()\">\n\t\t\t@if (loading()) {\n\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t} @else {\n\t\t\t\t<mat-icon>{{ button().icon }}</mat-icon>\n\t\t\t}\n\t\t</button>\n\t}\n\t@case ('icontext') {\n\t\t<button mat-fab extended=\"true\"\n\t\t class=\"icontext\"\n\t\t [matTooltip]=\"button().hint\"\n\t\t [matTooltipDisabled]=\"!button().hint\"\n\t\t [color]=\"button().color || 'primary'\"\n\t\t [disabled]=\"disabled() || loading()\"\n\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t@if (loading()) {\n\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t\t@if (pollText() || countdown() > 0) {\n\t\t\t\t\t<span class=\"poll-countdown\">{{ pollText() || countdown() + 's' }}</span>\n\t\t\t\t}\n\t\t\t} @else {\n\t\t\t\t<mat-icon>{{ button().icon }}</mat-icon>\n\t\t\t}\n\t\t\t{{ button().text }}\n\t\t</button>\n\t}\n\t@case ('raised') {\n\t\t<button mat-raised-button\n\t\t [matTooltip]=\"button().hint\"\n\t\t [matTooltipDisabled]=\"!button().hint\"\n\t\t [color]=\"button().color || 'primary'\"\n\t\t [disabled]=\"disabled() || loading()\"\n\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t<ng-container [ngTemplateOutlet]=\"textContent\"></ng-container>\n\t\t</button>\n\t}\n\t@case ('basic') {\n\t\t<button mat-button\n\t\t [matTooltip]=\"button().hint\"\n\t\t [matTooltipDisabled]=\"!button().hint\"\n\t\t [color]=\"button().color || 'primary'\"\n\t\t [disabled]=\"disabled() || loading()\"\n\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t<ng-container [ngTemplateOutlet]=\"textContent\"></ng-container>\n\t\t</button>\n\t}\n\t@case ('stroked') {\n\t\t<button mat-stroked-button\n\t\t [matTooltip]=\"button().hint\"\n\t\t [matTooltipDisabled]=\"!button().hint\"\n\t\t [color]=\"button().color || 'primary'\"\n\t\t [disabled]=\"disabled() || loading()\"\n\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t<ng-container [ngTemplateOutlet]=\"textContent\"></ng-container>\n\t\t</button>\n\t}\n\t@case ('flat') {\n\t\t<button mat-flat-button\n\t\t [matTooltip]=\"button().hint\"\n\t\t [matTooltipDisabled]=\"!button().hint\"\n\t\t [color]=\"button().color || 'primary'\"\n\t\t [disabled]=\"disabled() || loading()\"\n\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t<ng-container [ngTemplateOutlet]=\"textContent\"></ng-container>\n\t\t</button>\n\t}\n\t@case ('minifab') {\n\t\t<button mat-mini-fab [matTooltip]=\"button().hint\" [matTooltipDisabled]=\"!button().hint\"\n\t\t [attr.aria-label]=\"button().hint || button().text\"\n\t\t [color]=\"button().color || 'primary'\" [disabled]=\"disabled() || loading()\"\n\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t@if (loading()) {\n\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t} @else {\n\t\t\t\t<mat-icon>{{ button().icon }}</mat-icon>\n\t\t\t}\n\t\t</button>\n\t}\n\t@case ('fab') {\n\t\t<button mat-fab [matTooltip]=\"button().hint\" [matTooltipDisabled]=\"!button().hint\"\n\t\t [attr.aria-label]=\"button().hint || button().text\"\n\t\t [color]=\"button().color || 'primary'\" [disabled]=\"disabled() || loading()\"\n\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t@if (loading()) {\n\t\t\t\t<mat-spinner diameter=\"24\"></mat-spinner>\n\t\t\t} @else {\n\t\t\t\t<mat-icon>{{ button().icon }}</mat-icon>\n\t\t\t}\n\t\t</button>\n\t}\n\t@default {\n\t\t@if (button().icon) {\n\t\t\t<button mat-icon-button [matTooltip]=\"button().hint\" [matTooltipDisabled]=\"!button().hint\"\n\t\t\t [attr.aria-label]=\"button().hint || button().text\"\n\t\t\t [color]=\"button().color || 'primary'\" [disabled]=\"disabled() || loading()\"\n\t\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t\t@if (loading()) {\n\t\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t\t} @else {\n\t\t\t\t\t<mat-icon>{{ button().icon }}</mat-icon>\n\t\t\t\t}\n\t\t\t</button>\n\t\t}\n\t\t@if (button().text) {\n\t\t\t<button mat-raised-button\n\t\t\t [matTooltip]=\"button().hint\"\n\t\t\t [matTooltipDisabled]=\"!button().hint\"\n\t\t\t [color]=\"button().color || 'primary'\"\n\t\t\t [disabled]=\"disabled() || loading()\"\n\t\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"textContent\"></ng-container>\n\t\t\t</button>\n\t\t}\n\t}\n}\n", styles: ["mat-spinner{display:inline-block;--mat-progress-spinner-active-indicator-color: currentColor}.poll-countdown{display:inline-block;margin-left:6px;font-variant-numeric:tabular-nums;font-size:.85em;opacity:.9}\n"] }]
2881
+ ], template: "<ng-template #textContent>\n\t@if (loading()) {\n\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t@if (pollText() || countdown() > 0) {\n\t\t\t<span class=\"poll-countdown\">{{ pollText() || countdown() + 's' }}</span>\n\t\t}\n\t} @else {\n\t\t{{ button().text }}\n\t}\n</ng-template>\n\n<!-- Guard sitzt hier, nicht nur in xiri-button: form, dialog, alert und stepper\n rendern XiriButton direkt ueber buttonstyle. -->\n@if (!button().hide) {\n\t@switch (button().type) {\n\t\t@case ('icon') {\n\t\t\t<button mat-icon-button [matTooltip]=\"button().hint\" [matTooltipDisabled]=\"!button().hint\"\n\t\t\t [attr.aria-label]=\"button().hint || button().text\"\n\t\t\t [color]=\"button().color || 'primary'\" [disabled]=\"disabled() || loading()\">\n\t\t\t\t@if (loading()) {\n\t\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t\t} @else {\n\t\t\t\t\t<mat-icon>{{ button().icon }}</mat-icon>\n\t\t\t\t}\n\t\t\t</button>\n\t\t}\n\t\t@case ('icontext') {\n\t\t\t<button mat-fab extended=\"true\"\n\t\t\t class=\"icontext\"\n\t\t\t [matTooltip]=\"button().hint\"\n\t\t\t [matTooltipDisabled]=\"!button().hint\"\n\t\t\t [color]=\"button().color || 'primary'\"\n\t\t\t [disabled]=\"disabled() || loading()\"\n\t\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t\t@if (loading()) {\n\t\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t\t\t@if (pollText() || countdown() > 0) {\n\t\t\t\t\t\t<span class=\"poll-countdown\">{{ pollText() || countdown() + 's' }}</span>\n\t\t\t\t\t}\n\t\t\t\t} @else {\n\t\t\t\t\t<mat-icon>{{ button().icon }}</mat-icon>\n\t\t\t\t}\n\t\t\t\t{{ button().text }}\n\t\t\t</button>\n\t\t}\n\t\t@case ('raised') {\n\t\t\t<button mat-raised-button\n\t\t\t [matTooltip]=\"button().hint\"\n\t\t\t [matTooltipDisabled]=\"!button().hint\"\n\t\t\t [color]=\"button().color || 'primary'\"\n\t\t\t [disabled]=\"disabled() || loading()\"\n\t\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"textContent\"></ng-container>\n\t\t\t</button>\n\t\t}\n\t\t@case ('basic') {\n\t\t\t<button mat-button\n\t\t\t [matTooltip]=\"button().hint\"\n\t\t\t [matTooltipDisabled]=\"!button().hint\"\n\t\t\t [color]=\"button().color || 'primary'\"\n\t\t\t [disabled]=\"disabled() || loading()\"\n\t\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"textContent\"></ng-container>\n\t\t\t</button>\n\t\t}\n\t\t@case ('stroked') {\n\t\t\t<button mat-stroked-button\n\t\t\t [matTooltip]=\"button().hint\"\n\t\t\t [matTooltipDisabled]=\"!button().hint\"\n\t\t\t [color]=\"button().color || 'primary'\"\n\t\t\t [disabled]=\"disabled() || loading()\"\n\t\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"textContent\"></ng-container>\n\t\t\t</button>\n\t\t}\n\t\t@case ('flat') {\n\t\t\t<button mat-flat-button\n\t\t\t [matTooltip]=\"button().hint\"\n\t\t\t [matTooltipDisabled]=\"!button().hint\"\n\t\t\t [color]=\"button().color || 'primary'\"\n\t\t\t [disabled]=\"disabled() || loading()\"\n\t\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"textContent\"></ng-container>\n\t\t\t</button>\n\t\t}\n\t\t@case ('minifab') {\n\t\t\t<button mat-mini-fab [matTooltip]=\"button().hint\" [matTooltipDisabled]=\"!button().hint\"\n\t\t\t [attr.aria-label]=\"button().hint || button().text\"\n\t\t\t [color]=\"button().color || 'primary'\" [disabled]=\"disabled() || loading()\"\n\t\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t\t@if (loading()) {\n\t\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t\t} @else {\n\t\t\t\t\t<mat-icon>{{ button().icon }}</mat-icon>\n\t\t\t\t}\n\t\t\t</button>\n\t\t}\n\t\t@case ('fab') {\n\t\t\t<button mat-fab [matTooltip]=\"button().hint\" [matTooltipDisabled]=\"!button().hint\"\n\t\t\t [attr.aria-label]=\"button().hint || button().text\"\n\t\t\t [color]=\"button().color || 'primary'\" [disabled]=\"disabled() || loading()\"\n\t\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t\t@if (loading()) {\n\t\t\t\t\t<mat-spinner diameter=\"24\"></mat-spinner>\n\t\t\t\t} @else {\n\t\t\t\t\t<mat-icon>{{ button().icon }}</mat-icon>\n\t\t\t\t}\n\t\t\t</button>\n\t\t}\n\t\t@default {\n\t\t\t@if (button().icon) {\n\t\t\t\t<button mat-icon-button [matTooltip]=\"button().hint\" [matTooltipDisabled]=\"!button().hint\"\n\t\t\t\t [attr.aria-label]=\"button().hint || button().text\"\n\t\t\t\t [color]=\"button().color || 'primary'\" [disabled]=\"disabled() || loading()\"\n\t\t\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t\t\t@if (loading()) {\n\t\t\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<mat-icon>{{ button().icon }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t</button>\n\t\t\t}\n\t\t\t@if (button().text) {\n\t\t\t\t<button mat-raised-button\n\t\t\t\t [matTooltip]=\"button().hint\"\n\t\t\t\t [matTooltipDisabled]=\"!button().hint\"\n\t\t\t\t [color]=\"button().color || 'primary'\"\n\t\t\t\t [disabled]=\"disabled() || loading()\"\n\t\t\t\t [tabIndex]=\"button().tabIndex\">\n\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"textContent\"></ng-container>\n\t\t\t\t</button>\n\t\t\t}\n\t\t}\n\t}\n}\n", styles: ["mat-spinner{display:inline-block;--mat-progress-spinner-active-indicator-color: currentColor}.poll-countdown{display:inline-block;margin-left:6px;font-variant-numeric:tabular-nums;font-size:.85em;opacity:.9}\n"] }]
2882
2882
  }], propDecorators: { button: [{ type: i0.Input, args: [{ isSignal: true, alias: "button", required: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: true }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], countdown: [{ type: i0.Input, args: [{ isSignal: true, alias: "countdown", required: false }] }], pollText: [{ type: i0.Input, args: [{ isSignal: true, alias: "pollText", required: false }] }] } });
2883
2883
 
2884
2884
  class XiriDoneComponent {
@@ -2904,7 +2904,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
2904
2904
  }], propDecorators: { text: [{ type: i0.Input, args: [{ isSignal: true, alias: "text", required: true }] }] } });
2905
2905
 
2906
2906
  class XiriDownloadService {
2907
- download(result, filename, open) {
2907
+ /**
2908
+ * Opens an empty tab and returns its handle for a later download( …, tab ).
2909
+ *
2910
+ * MUST be called synchronously from the click handler: after an HTTP round trip the
2911
+ * transient user activation is gone and the browser blocks the popup. Returns null
2912
+ * when it was blocked anyway — pass that through, download() then saves the file.
2913
+ */
2914
+ openTab() {
2915
+ return window.open('about:blank', '_blank');
2916
+ }
2917
+ /**
2918
+ * Turns the response body into a file. With a tab handle from openTab() the file is
2919
+ * displayed in that tab, otherwise it is saved via a download anchor.
2920
+ */
2921
+ download(result, filename, tab) {
2908
2922
  const contentDisposition = result.headers.get('content-disposition');
2909
2923
  if (contentDisposition) {
2910
2924
  filename = contentDisposition.split('filename=')[1];
@@ -2913,9 +2927,14 @@ class XiriDownloadService {
2913
2927
  const contentType = result.headers.get('content-type') ?? undefined;
2914
2928
  const file = new File([result.body], filename, { type: contentType });
2915
2929
  const fileData = URL.createObjectURL(file);
2916
- if (open) {
2917
- const ret = window.open(fileData, '_blank');
2918
- return !(ret === null || typeof (ret) == 'undefined');
2930
+ if (tab) {
2931
+ // ponytail: caps window.opener reach. A blob: document is same-origin anyway, so this is
2932
+ // no licence to display untrusted HTML only a correct Content-Type keeps it a viewer.
2933
+ tab.opener = null;
2934
+ tab.location.replace(fileData);
2935
+ // ponytail: 60s is plenty to load; without it the blob lives until the page reloads.
2936
+ setTimeout(() => URL.revokeObjectURL(fileData), 60 * 1000);
2937
+ return true;
2919
2938
  }
2920
2939
  const a = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
2921
2940
  a.download = filename;
@@ -3162,7 +3181,7 @@ class XiriDialogComponent {
3162
3181
  });
3163
3182
  }, this.refreshTime);
3164
3183
  }
3165
- download(data) {
3184
+ download(data, tab) {
3166
3185
  if (data === null) {
3167
3186
  // TODO: fix, this is actually an external link
3168
3187
  const file = window.open(this.dataService.getConfigApi() + this.url, 'Report');
@@ -3182,7 +3201,7 @@ class XiriDialogComponent {
3182
3201
  .pipe(takeUntilDestroyed(this.destroyRef))
3183
3202
  .subscribe({
3184
3203
  next: (result) => {
3185
- const ret = this.downloadService.download(result, 'Report', false);
3204
+ const ret = this.downloadService.download(result, 'Report', tab);
3186
3205
  if (!ret)
3187
3206
  this.buttons.set([{
3188
3207
  text: 'Download',
@@ -3194,6 +3213,7 @@ class XiriDialogComponent {
3194
3213
  else
3195
3214
  this.dialogRef.close(this.extra);
3196
3215
  }, error: (err) => {
3216
+ tab?.close();
3197
3217
  this.snackbar.error(err.error?.error || 'Unknown Error');
3198
3218
  }
3199
3219
  });
@@ -3217,7 +3237,10 @@ class XiriDialogComponent {
3217
3237
  this.startSend(button.data);
3218
3238
  }
3219
3239
  else if (button.action == 'download') {
3220
- this.download(this.type() == 'form' ? this.formValues : null);
3240
+ const data = this.type() == 'form' ? this.formValues : null;
3241
+ // Only the blob path needs a tab handle; data === null is an external link that
3242
+ // opens its own tab. openTab() must run here, inside the click.
3243
+ this.download(data, data !== null && button.target === '_blank' ? this.downloadService.openTab() : null);
3221
3244
  }
3222
3245
  else if (button.action == 'link') {
3223
3246
  this.router.navigate([button.url]).then();
@@ -3370,7 +3393,8 @@ class XiriButtonComponent {
3370
3393
  // re-trigger it — only the initial load is automatic.
3371
3394
  effect(() => {
3372
3395
  this.filterData(); // track filter changes so the effect re-evaluates
3373
- if (this.button().autoLoad && !this._autoTriggered && !this._disabled()) {
3396
+ // A hidden button is not rendered, so it must not fire its action either.
3397
+ if (this.button().autoLoad && !this.displayButton().hide && !this._autoTriggered && !this._disabled()) {
3374
3398
  this._autoTriggered = true;
3375
3399
  this.runAction();
3376
3400
  }
@@ -3545,6 +3569,9 @@ class XiriButtonComponent {
3545
3569
  actionDownload() {
3546
3570
  const data = { ...this.filterData(), ...this.button().data };
3547
3571
  this.loading.set(true);
3572
+ // Must happen before the request: openTab() needs the click's user activation.
3573
+ // Without one (e.g. autoLoad) it returns null and the file is saved instead.
3574
+ const tab = this.button().target === '_blank' ? this.downloadService.openTab() : null;
3548
3575
  this.dataService.postFileResponse(this._url() ?? '', data)
3549
3576
  .pipe(takeUntilDestroyed(this.destroyRef))
3550
3577
  .subscribe({
@@ -3554,9 +3581,11 @@ class XiriButtonComponent {
3554
3581
  if (btn.filename != undefined)
3555
3582
  filename = btn.filename;
3556
3583
  else
3557
- filename =
3558
- (btn.text != undefined ? btn.text : 'Download') + '.csv';
3559
- this.downloadService.download(result, filename, false);
3584
+ // ponytail: no extension guess when the file is displayed — the
3585
+ // viewer would offer "Report.csv" for a PDF on save.
3586
+ filename = (btn.text != undefined ? btn.text : 'Download')
3587
+ + (tab ? '' : '.csv');
3588
+ this.downloadService.download(result, filename, tab);
3560
3589
  this.result.emit({
3561
3590
  button: this.button(),
3562
3591
  result: result,
@@ -3567,6 +3596,7 @@ class XiriButtonComponent {
3567
3596
  },
3568
3597
  error: (err) => {
3569
3598
  console.log("xiri-button download error", err);
3599
+ tab?.close();
3570
3600
  this.result.emit({
3571
3601
  button: this.button(),
3572
3602
  result: null,
@@ -3584,7 +3614,7 @@ class XiriButtonComponent {
3584
3614
  }
3585
3615
  }
3586
3616
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3587
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: XiriButtonComponent, isStandalone: true, selector: "xiri-button", inputs: { button: { classPropertyName: "button", publicName: "button", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, filterData: { classPropertyName: "filterData", publicName: "filterData", isSignal: true, isRequired: false, transformFunction: null }, url: { classPropertyName: "url", publicName: "url", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { result: "result" }, ngImport: i0, template: "@switch (button().action) {\n\t@case ('link') {\n\t\t@let linkUrl = _url() | xiriUrl;\n\t\t<a [routerLink]=\"linkUrl?.path\" [queryParams]=\"linkUrl?.queryParams\" [href]=\"_url()\" (click)=\"clicked($event)\">\n\t\t\t<xiri-buttonstyle [button]=\"displayButton()\" [disabled]=\"_disabled()\" [loading]=\"loading()\" [countdown]=\"countdown()\" [pollText]=\"pollText()\"></xiri-buttonstyle>\n\t\t</a>\n\t}\n\t@case ('href') {\n\t\t<a [href]=\"_url()\" [target]=\"button().target\" (click)=\"clicked($event)\">\n\t\t\t<xiri-buttonstyle [button]=\"displayButton()\" [disabled]=\"_disabled()\" [loading]=\"loading()\" [countdown]=\"countdown()\" [pollText]=\"pollText()\"></xiri-buttonstyle>\n\t\t</a>\n\t}\n\t@case ('menu') {\n\t\t<button mat-icon-button [matMenuTriggerFor]=\"menuRef\"\n\t\t [class]=\"displayButton().color || 'primary'\"\n\t\t [matTooltip]=\"button().hint\"\n\t\t [matTooltipDisabled]=\"!button().hint\"\n\t\t (click)=\"$event.stopPropagation()\">\n\t\t\t<mat-icon>{{ displayButton().icon }}</mat-icon>\n\t\t</button>\n\t\t<mat-menu #menuRef=\"matMenu\">\n\t\t\t@for (item of button().menuItems; track item) {\n\t\t\t\t@switch (item.action) {\n\t\t\t\t\t@case ('link') {\n\t\t\t\t\t\t@let menuUrl = item.url | xiriUrl;\n\t\t\t\t\t\t<a mat-menu-item [routerLink]=\"menuUrl?.path\" [queryParams]=\"menuUrl?.queryParams\">\n\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t<mat-icon [class]=\"item.color || 'primary'\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t<span>{{ item.text }}</span>\n\t\t\t\t\t\t</a>\n\t\t\t\t\t}\n\t\t\t\t\t@case ('href') {\n\t\t\t\t\t\t<a mat-menu-item [href]=\"item.url\" target=\"_blank\">\n\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t<mat-icon [class]=\"item.color || 'primary'\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t<span>{{ item.text }}</span>\n\t\t\t\t\t\t</a>\n\t\t\t\t\t}\n\t\t\t\t\t@case ('dialog') {\n\t\t\t\t\t\t<button mat-menu-item (click)=\"openMenuDialog($event, item)\">\n\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t<mat-icon [class]=\"item.color || 'primary'\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t<span>{{ item.text }}</span>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t</mat-menu>\n\t}\n\t@default {\n\t\t<xiri-buttonstyle [button]=\"displayButton()\" [disabled]=\"_disabled()\" [loading]=\"loading()\" [countdown]=\"countdown()\" [pollText]=\"pollText()\" (click)=\"clicked($event)\"></xiri-buttonstyle>\n\t}\n}\n", styles: [""], dependencies: [{ kind: "component", type: XiriButtonstyleComponent, selector: "xiri-buttonstyle", inputs: ["button", "disabled", "loading", "countdown", "pollText"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "component", type: MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: XiriUrlPipe, name: "xiriUrl" }] }); }
3617
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: XiriButtonComponent, isStandalone: true, selector: "xiri-button", inputs: { button: { classPropertyName: "button", publicName: "button", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, filterData: { classPropertyName: "filterData", publicName: "filterData", isSignal: true, isRequired: false, transformFunction: null }, url: { classPropertyName: "url", publicName: "url", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { result: "result" }, ngImport: i0, template: "<!-- hide has always been part of the XiriButton contract; a hidden button must not\n render and must not run its action (see the autoLoad effect). -->\n@if (!displayButton().hide) {\n\t@switch (button().action) {\n\t\t@case ('link') {\n\t\t\t@let linkUrl = _url() | xiriUrl;\n\t\t\t<a [routerLink]=\"linkUrl?.path\" [queryParams]=\"linkUrl?.queryParams\" [href]=\"_url()\" (click)=\"clicked($event)\">\n\t\t\t\t<xiri-buttonstyle [button]=\"displayButton()\" [disabled]=\"_disabled()\" [loading]=\"loading()\" [countdown]=\"countdown()\" [pollText]=\"pollText()\"></xiri-buttonstyle>\n\t\t\t</a>\n\t\t}\n\t\t@case ('href') {\n\t\t\t<a [href]=\"_url()\" [target]=\"button().target\" (click)=\"clicked($event)\">\n\t\t\t\t<xiri-buttonstyle [button]=\"displayButton()\" [disabled]=\"_disabled()\" [loading]=\"loading()\" [countdown]=\"countdown()\" [pollText]=\"pollText()\"></xiri-buttonstyle>\n\t\t\t</a>\n\t\t}\n\t\t@case ('menu') {\n\t\t\t<button mat-icon-button [matMenuTriggerFor]=\"menuRef\"\n\t\t\t [class]=\"displayButton().color || 'primary'\"\n\t\t\t [matTooltip]=\"button().hint\"\n\t\t\t [matTooltipDisabled]=\"!button().hint\"\n\t\t\t [attr.aria-label]=\"displayButton().hint || displayButton().text\"\n\t\t\t (click)=\"$event.stopPropagation()\">\n\t\t\t\t<mat-icon>{{ displayButton().icon }}</mat-icon>\n\t\t\t</button>\n\t\t\t<mat-menu #menuRef=\"matMenu\">\n\t\t\t\t@for (item of button().menuItems; track item) {\n\t\t\t\t\t@switch (item.action) {\n\t\t\t\t\t\t@case ('link') {\n\t\t\t\t\t\t\t@let menuUrl = item.url | xiriUrl;\n\t\t\t\t\t\t\t<a mat-menu-item [routerLink]=\"menuUrl?.path\" [queryParams]=\"menuUrl?.queryParams\">\n\t\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t\t<mat-icon [class]=\"item.color || 'primary'\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t<span>{{ item.text }}</span>\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@case ('href') {\n\t\t\t\t\t\t\t<a mat-menu-item [href]=\"item.url\" target=\"_blank\">\n\t\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t\t<mat-icon [class]=\"item.color || 'primary'\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t<span>{{ item.text }}</span>\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@case ('dialog') {\n\t\t\t\t\t\t\t<button mat-menu-item (click)=\"openMenuDialog($event, item)\">\n\t\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t\t<mat-icon [class]=\"item.color || 'primary'\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t<span>{{ item.text }}</span>\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t</mat-menu>\n\t\t}\n\t\t@default {\n\t\t\t<xiri-buttonstyle [button]=\"displayButton()\" [disabled]=\"_disabled()\" [loading]=\"loading()\" [countdown]=\"countdown()\" [pollText]=\"pollText()\" (click)=\"clicked($event)\"></xiri-buttonstyle>\n\t\t}\n\t}\n}\n", styles: [""], dependencies: [{ kind: "component", type: XiriButtonstyleComponent, selector: "xiri-buttonstyle", inputs: ["button", "disabled", "loading", "countdown", "pollText"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "component", type: MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: XiriUrlPipe, name: "xiriUrl" }] }); }
3588
3618
  }
3589
3619
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriButtonComponent, decorators: [{
3590
3620
  type: Component,
@@ -3594,7 +3624,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
3594
3624
  MatMenu, MatMenuItem, MatMenuTrigger,
3595
3625
  MatIcon, MatIconButton, MatTooltip,
3596
3626
  XiriUrlPipe
3597
- ], template: "@switch (button().action) {\n\t@case ('link') {\n\t\t@let linkUrl = _url() | xiriUrl;\n\t\t<a [routerLink]=\"linkUrl?.path\" [queryParams]=\"linkUrl?.queryParams\" [href]=\"_url()\" (click)=\"clicked($event)\">\n\t\t\t<xiri-buttonstyle [button]=\"displayButton()\" [disabled]=\"_disabled()\" [loading]=\"loading()\" [countdown]=\"countdown()\" [pollText]=\"pollText()\"></xiri-buttonstyle>\n\t\t</a>\n\t}\n\t@case ('href') {\n\t\t<a [href]=\"_url()\" [target]=\"button().target\" (click)=\"clicked($event)\">\n\t\t\t<xiri-buttonstyle [button]=\"displayButton()\" [disabled]=\"_disabled()\" [loading]=\"loading()\" [countdown]=\"countdown()\" [pollText]=\"pollText()\"></xiri-buttonstyle>\n\t\t</a>\n\t}\n\t@case ('menu') {\n\t\t<button mat-icon-button [matMenuTriggerFor]=\"menuRef\"\n\t\t [class]=\"displayButton().color || 'primary'\"\n\t\t [matTooltip]=\"button().hint\"\n\t\t [matTooltipDisabled]=\"!button().hint\"\n\t\t (click)=\"$event.stopPropagation()\">\n\t\t\t<mat-icon>{{ displayButton().icon }}</mat-icon>\n\t\t</button>\n\t\t<mat-menu #menuRef=\"matMenu\">\n\t\t\t@for (item of button().menuItems; track item) {\n\t\t\t\t@switch (item.action) {\n\t\t\t\t\t@case ('link') {\n\t\t\t\t\t\t@let menuUrl = item.url | xiriUrl;\n\t\t\t\t\t\t<a mat-menu-item [routerLink]=\"menuUrl?.path\" [queryParams]=\"menuUrl?.queryParams\">\n\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t<mat-icon [class]=\"item.color || 'primary'\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t<span>{{ item.text }}</span>\n\t\t\t\t\t\t</a>\n\t\t\t\t\t}\n\t\t\t\t\t@case ('href') {\n\t\t\t\t\t\t<a mat-menu-item [href]=\"item.url\" target=\"_blank\">\n\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t<mat-icon [class]=\"item.color || 'primary'\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t<span>{{ item.text }}</span>\n\t\t\t\t\t\t</a>\n\t\t\t\t\t}\n\t\t\t\t\t@case ('dialog') {\n\t\t\t\t\t\t<button mat-menu-item (click)=\"openMenuDialog($event, item)\">\n\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t<mat-icon [class]=\"item.color || 'primary'\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t<span>{{ item.text }}</span>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t</mat-menu>\n\t}\n\t@default {\n\t\t<xiri-buttonstyle [button]=\"displayButton()\" [disabled]=\"_disabled()\" [loading]=\"loading()\" [countdown]=\"countdown()\" [pollText]=\"pollText()\" (click)=\"clicked($event)\"></xiri-buttonstyle>\n\t}\n}\n" }]
3627
+ ], template: "<!-- hide has always been part of the XiriButton contract; a hidden button must not\n render and must not run its action (see the autoLoad effect). -->\n@if (!displayButton().hide) {\n\t@switch (button().action) {\n\t\t@case ('link') {\n\t\t\t@let linkUrl = _url() | xiriUrl;\n\t\t\t<a [routerLink]=\"linkUrl?.path\" [queryParams]=\"linkUrl?.queryParams\" [href]=\"_url()\" (click)=\"clicked($event)\">\n\t\t\t\t<xiri-buttonstyle [button]=\"displayButton()\" [disabled]=\"_disabled()\" [loading]=\"loading()\" [countdown]=\"countdown()\" [pollText]=\"pollText()\"></xiri-buttonstyle>\n\t\t\t</a>\n\t\t}\n\t\t@case ('href') {\n\t\t\t<a [href]=\"_url()\" [target]=\"button().target\" (click)=\"clicked($event)\">\n\t\t\t\t<xiri-buttonstyle [button]=\"displayButton()\" [disabled]=\"_disabled()\" [loading]=\"loading()\" [countdown]=\"countdown()\" [pollText]=\"pollText()\"></xiri-buttonstyle>\n\t\t\t</a>\n\t\t}\n\t\t@case ('menu') {\n\t\t\t<button mat-icon-button [matMenuTriggerFor]=\"menuRef\"\n\t\t\t [class]=\"displayButton().color || 'primary'\"\n\t\t\t [matTooltip]=\"button().hint\"\n\t\t\t [matTooltipDisabled]=\"!button().hint\"\n\t\t\t [attr.aria-label]=\"displayButton().hint || displayButton().text\"\n\t\t\t (click)=\"$event.stopPropagation()\">\n\t\t\t\t<mat-icon>{{ displayButton().icon }}</mat-icon>\n\t\t\t</button>\n\t\t\t<mat-menu #menuRef=\"matMenu\">\n\t\t\t\t@for (item of button().menuItems; track item) {\n\t\t\t\t\t@switch (item.action) {\n\t\t\t\t\t\t@case ('link') {\n\t\t\t\t\t\t\t@let menuUrl = item.url | xiriUrl;\n\t\t\t\t\t\t\t<a mat-menu-item [routerLink]=\"menuUrl?.path\" [queryParams]=\"menuUrl?.queryParams\">\n\t\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t\t<mat-icon [class]=\"item.color || 'primary'\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t<span>{{ item.text }}</span>\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@case ('href') {\n\t\t\t\t\t\t\t<a mat-menu-item [href]=\"item.url\" target=\"_blank\">\n\t\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t\t<mat-icon [class]=\"item.color || 'primary'\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t<span>{{ item.text }}</span>\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t@case ('dialog') {\n\t\t\t\t\t\t\t<button mat-menu-item (click)=\"openMenuDialog($event, item)\">\n\t\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t\t<mat-icon [class]=\"item.color || 'primary'\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t<span>{{ item.text }}</span>\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t</mat-menu>\n\t\t}\n\t\t@default {\n\t\t\t<xiri-buttonstyle [button]=\"displayButton()\" [disabled]=\"_disabled()\" [loading]=\"loading()\" [countdown]=\"countdown()\" [pollText]=\"pollText()\" (click)=\"clicked($event)\"></xiri-buttonstyle>\n\t\t}\n\t}\n}\n" }]
3598
3628
  }], ctorParameters: () => [], propDecorators: { button: [{ type: i0.Input, args: [{ isSignal: true, alias: "button", required: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], filterData: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterData", required: false }] }], url: [{ type: i0.Input, args: [{ isSignal: true, alias: "url", required: false }] }], result: [{ type: i0.Output, args: ["result"] }] } });
3599
3629
 
3600
3630
  // Reads a human-readable message out of an unknown HTTP error value.
@@ -4906,12 +4936,18 @@ class XiriTableComponent {
4906
4936
  });
4907
4937
  break;
4908
4938
  }
4909
- case 'download':
4939
+ case 'download': {
4940
+ // Before the request — openTab() needs the click's user activation.
4941
+ const tab = button.target === '_blank' ? this.downloadService.openTab() : null;
4910
4942
  this.dataService.postFileResponse(button.url ?? '', payload).pipe(takeUntil(this.reloadAbort$)).subscribe({
4911
- next: (result) => this.downloadService.download(result, button.filename || 'download.csv', false),
4912
- error: (err) => this.snackbar.error(errorMessage(err) || 'Download Error'),
4943
+ next: (result) => this.downloadService.download(result, button.filename || 'download.csv', tab),
4944
+ error: (err) => {
4945
+ tab?.close();
4946
+ this.snackbar.error(errorMessage(err) || 'Download Error');
4947
+ },
4913
4948
  });
4914
4949
  break;
4950
+ }
4915
4951
  default:
4916
4952
  this.dataService.post(button.url ?? '', payload).pipe(takeUntil(this.reloadAbort$)).subscribe({
4917
4953
  next: (result) => {
@@ -5003,11 +5039,14 @@ class XiriTableComponent {
5003
5039
  if (this.selection.isEmpty())
5004
5040
  return;
5005
5041
  const url = button.url ? button.url : '';
5042
+ // Before the request — openTab() needs the click's user activation.
5043
+ const tab = button.target === '_blank' ? this.downloadService.openTab() : null;
5006
5044
  this.dataService.postFileResponse(url, this.getSelectionIDs()).pipe(takeUntil(this.reloadAbort$)).subscribe({
5007
5045
  next: (result) => {
5008
- this.downloadService.download(result, 'download.csv', false);
5046
+ this.downloadService.download(result, 'download.csv', tab);
5009
5047
  },
5010
5048
  error: (err) => {
5049
+ tab?.close();
5011
5050
  this.snackbar.error(errorMessage(err) || 'Download Error');
5012
5051
  }
5013
5052
  });
@@ -5141,7 +5180,7 @@ class XiriTableComponent {
5141
5180
  };
5142
5181
  }
5143
5182
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5144
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: XiriTableComponent, isStandalone: true, selector: "xiri-table", inputs: { dyncomponent: { classPropertyName: "dyncomponent", publicName: "dyncomponent", isSignal: true, isRequired: false, transformFunction: null }, settings: { classPropertyName: "settings", publicName: "settings", isSignal: true, isRequired: true, transformFunction: null }, filterData: { classPropertyName: "filterData", publicName: "filterData", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clickedRow: "clickedRow" }, providers: [XiriTableInlineEditService, XiriTableTreeService], viewQueries: [{ propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true, isSignal: true }, { propertyName: "sort", first: true, predicate: MatSort, descendants: true, isSignal: true }, { propertyName: "table", first: true, predicate: MatTable, descendants: true, isSignal: true }], ngImport: i0, template: "<mat-card class=\"xiritablecard mat-mdc-elevation-specific mat-elevation-z3\">\n\t<div class=\"xiritable\" [class]=\"options.class\">\n\t\t<div class=\"table-full\">\n\t\t\t@if (bulkBarActive) {\n\t\t\t\t<div class=\"xiri-bulk-bar\" [class.sticky]=\"options.stickyBulkBar\" role=\"toolbar\"\n\t\t\t\t aria-label=\"Massenaktionen\" data-testid=\"table-bulk-bar\">\n\t\t\t\t\t<button mat-icon-button (click)=\"cancelBulk()\" matTooltip=\"Auswahl aufheben\"\n\t\t\t\t\t aria-label=\"Auswahl aufheben\">\n\t\t\t\t\t\t<mat-icon>close</mat-icon>\n\t\t\t\t\t</button>\n\t\t\t\t\t<span class=\"xiri-bulk-count\" aria-live=\"polite\" data-testid=\"table-bulk-count\">\n\t\t\t\t\t\t@if (bulkAllResults()) {\n\t\t\t\t\t\t\tAlle {{ bulkTotalCount() }} Ergebnisse ausgew\u00E4hlt\n\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t{{ selection.selected.length }} ausgew\u00E4hlt\n\t\t\t\t\t\t}\n\t\t\t\t\t</span>\n\t\t\t\t\t@if (canSelectAllResults()) {\n\t\t\t\t\t\t<button mat-button color=\"primary\" (click)=\"selectAllResults()\"\n\t\t\t\t\t\t data-testid=\"table-bulk-selectall\">\n\t\t\t\t\t\t\tAlle {{ bulkTotalCount() }} Ergebnisse ausw\u00E4hlen\n\t\t\t\t\t\t</button>\n\t\t\t\t\t}\n\t\t\t\t\t<span class=\"xiri-bulk-spacer\"></span>\n\t\t\t\t\t@for (button of options.bulkActions; track button) {\n\t\t\t\t\t\t<button mat-button [color]=\"button.color || 'primary'\"\n\t\t\t\t\t\t (click)=\"bulkAction($event, button)\"\n\t\t\t\t\t\t [matTooltip]=\"button.hint\" [matTooltipDisabled]=\"!button.hint\">\n\t\t\t\t\t\t\t@if (button.icon) {\n\t\t\t\t\t\t\t\t<mat-icon>{{ button.icon }}</mat-icon>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t{{ button.text }}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t<div class=\"header\" [hidden]=\"bulkBarActive\">\n\t\t\t\t@if (options.reload) {\n\t\t\t\t\t<div class=\"buttons\">\n\t\t\t\t\t\t<button mat-icon-button (click)=\"reload()\" color=\"primary\" aria-label=\"Tabelle neu laden\">\n\t\t\t\t\t\t\t<mat-icon>autorenew</mat-icon>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t@if (autoRefresh()) {\n\t\t\t\t\t<div class=\"autorefresh-indicator\" role=\"status\" aria-live=\"polite\"\n\t\t\t\t\t matTooltip=\"Tabelle aktualisiert sich automatisch\">\n\t\t\t\t\t\t<mat-icon class=\"spin\">sync</mat-icon>\n\t\t\t\t\t\t<span>Auto-Refresh aktiv \u00B7 n\u00E4chste in {{ countdown() }}s</span>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t@if (lastUpdated(); as updated) {\n\t\t\t\t\t<div class=\"lastupdated-indicator\" data-testid=\"table-last-updated\" role=\"status\" aria-live=\"polite\">\n\t\t\t\t\t\tStand {{ updated | date:'HH:mm' }}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t@if (treeEnabled) {\n\t\t\t\t\t<div class=\"buttons xiri-tree-actions\">\n\t\t\t\t\t\t<button mat-icon-button (click)=\"expandAllNodes()\" color=\"primary\"\n\t\t\t\t\t\t matTooltip=\"Alle ausklappen\" aria-label=\"Alle ausklappen\">\n\t\t\t\t\t\t\t<mat-icon>unfold_more</mat-icon>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<button mat-icon-button (click)=\"collapseAllNodes()\" color=\"primary\"\n\t\t\t\t\t\t matTooltip=\"Alle einklappen\" aria-label=\"Alle einklappen\">\n\t\t\t\t\t\t\t<mat-icon>unfold_less</mat-icon>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t<div class=\"middle\" [class.hasButtons]=\"options.buttons\">{{ options.title }}</div>\n\t\t\t\t@if (options.buttons) {\n\t\t\t\t\t<xiri-buttonline [settings]=\"options.buttons\" (result)=\"buttonReturn($event)\"\n\t\t\t\t\t [filterData]=\"_filterData()\"></xiri-buttonline>\n\t\t\t\t}\n\t\t\t\t@if (options.search) {\n\t\t\t\t\t<xiri-search (changed)=\"searchDo($event)\" [placeholder]=\"''\" [text]=\"searchTextInit\"></xiri-search>\n\t\t\t\t}\n\t\t\t\t@if (options.saveInput) {\n\t\t\t\t\t<div class=\"buttons saveInput\">\n\t\t\t\t\t\t<button mat-raised-button (click)=\"saveInputData()\" color=\"primary\">\n\t\t\t\t\t\t\t{{ options.saveInput }}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t</div>\n\t\t\t<div class=\"tableout-wrap\">\n\t\t\t<div class=\"tableout\" [class.is-loading]=\"loading()\" [style.max-height]=\"options.scrollHeight || null\">\n\t\t\t\t<table mat-table [dataSource]=\"dataSource\" matSort [style.min-width]=\"options.minWidth ?? '100%'\"\n\t\t\t\t [class]=\"densityClass()\"\n\t\t\t\t [class.borders]=\"options.borders\" [class.bordersHeader]=\"options.bordersHeader\"\n\t\t\t\t [trackBy]=\"trackByRowId\">\n\n\t\t\t\t\t@for (column of displayedColumns; track column.id) {\n\t\t\t\t\t\t<ng-container [matColumnDef]=\"column.id\" [sticky]=\"column.sticky\">\n\t\t\t\t\t\t\t<th mat-header-cell *matHeaderCellDef mat-sort-header=\"{{ column.id }}\" [disabled]=\"!column.sort || !options.sort\" disableClear\n\t\t\t\t\t\t\t [style.width]=\"column.width\" [style.min-width]=\"column.minWidth\"\n\t\t\t\t\t\t\t [class]=\"column.display + ' ' + (column.header || '')\"> {{ column.name }}\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t@switch (column.format) {\n\t\t\t\t\t\t\t\t@case ('buttons') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t\t@for (button of column.buttons; track button; let i = $index) {\n\t\t\t\t\t\t\t\t\t\t\t@if (row[column.id][i] !== false) {\n\t\t\t\t\t\t\t\t\t\t\t\t@switch (button.action) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('link') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<xiri-button [button]=\"button\" [disabled]=\"false\" [url]=\"row[column.id][ i ]\"></xiri-button>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('href') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<xiri-button [button]=\"button\" [disabled]=\"false\" [url]=\"row[column.id][ i ]\"></xiri-button>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('download') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<xiri-button [button]=\"button\" [disabled]=\"false\" [url]=\"row[column.id][ i ]\"></xiri-button>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('dialog') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<xiri-buttonstyle [button]=\"button\" [disabled]=\"false\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t (click)=\"openDialog( $event, button, column.id, i, row)\"></xiri-buttonstyle>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('api') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<xiri-buttonstyle [button]=\"button\" [disabled]=\"false\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t (click)=\"apiCall( $event, row[column.id][ i ] )\"></xiri-buttonstyle>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('save') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<xiri-buttonstyle [button]=\"button\" (click)=\"saveCall( $event, button, row, row[column.id][ i ] )\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t [disabled]=\"!saveCallCheck( button, row )\"></xiri-buttonstyle>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('icon') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon class=\"btnicon\" [class]=\"button.color || 'primary'\" [matTooltip]=\"button.hint\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t [matTooltipDisabled]=\"!button.hint\">{{ button.icon }}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('menu') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<button mat-icon-button [matMenuTriggerFor]=\"menuRef\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t [class]=\"button.color || 'primary'\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t [matTooltip]=\"button.hint\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t [matTooltipDisabled]=\"!button.hint\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t (click)=\"$event.stopPropagation()\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon>{{ button.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-menu #menuRef=\"matMenu\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@for (item of button.menuItems; track item; let j = $index) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@if (row[column.id][i][j] !== false) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@switch (item.action) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('link') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@let menuUrl = row[column.id][i][j] | xiriUrl;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<a mat-menu-item [routerLink]=\"menuUrl?.path\" [queryParams]=\"menuUrl?.queryParams\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon [class]=\"item.color || 'primary'\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span>{{ item.text }}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('href') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<a mat-menu-item [href]=\"row[column.id][i][j]\" target=\"_blank\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon [class]=\"item.color || 'primary'\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span>{{ item.text }}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('dialog') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<button mat-menu-item (click)=\"openMenuDialog($event, item, column.id, i, j, row)\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon [class]=\"item.color || 'primary'\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span>{{ item.text }}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</mat-menu>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('icon') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t\t@if (column.icons?.[ $any(row[ column.id ]) ]; as icon) {\n\t\t\t\t\t\t\t\t\t\t\t<mat-icon [class]=\"icon[ 'color' ] || 'primary'\"\n\t\t\t\t\t\t\t\t\t\t\t [matTooltip]=\"icon[ 'hint' ] || '' \"\n\t\t\t\t\t\t\t\t\t\t\t [matTooltipDisabled]=\"!icon[ 'hint' ]\">{{ icon['icon'] }}\n\t\t\t\t\t\t\t\t\t\t\t</mat-icon>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('html') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [innerHtml]=\"row[column.id] | safeHtml\" [class]=\"column.display\"></td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('link') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\"\n\t\t\t\t\t\t\t\t\t [class.xiri-tree-td]=\"treeEnabled && column.id === treeColumnId\">\n\t\t\t\t\t\t\t\t\t\t@if (treeEnabled && column.id === treeColumnId) {\n\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"treePrefix; context: { $implicit: row }\"></ng-container>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t@if (row[column.id + 'Link']) {\n\t\t\t\t\t\t\t\t\t\t\t@let cellUrl = row[column.id + 'Link'] | xiriUrl;\n\t\t\t\t\t\t\t\t\t\t\t<a [routerLink]=\"cellUrl?.path\" [queryParams]=\"cellUrl?.queryParams\" class=\"tablelink\">{{ row[column.id] }}</a>\n\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t<span>{{ row[column.id] }}</span>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t@if (treeEnabled && column.id === treeColumnId) {\n\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"treeSuffix; context: { $implicit: row }\"></ng-container>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('input') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t\t<mat-form-field subscriptSizing=\"dynamic\">\n\t\t\t\t\t\t\t\t\t\t\t<input matInput\n\t\t\t\t\t\t\t\t\t\t\t [type]=\"column.inputType || 'text'\"\n\t\t\t\t\t\t\t\t\t\t\t [(ngModel)]=\"row[ column.id ]\"\n\t\t\t\t\t\t\t\t\t\t\t [lang]=\"column.inputLang || ''\"\n\t\t\t\t\t\t\t\t\t\t\t [required]=\"column.inputRequired || true\"\n\t\t\t\t\t\t\t\t\t\t\t (paste)=\"pasteInput( $event, row, column )\">\n\t\t\t\t\t\t\t\t\t\t</mat-form-field>\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('text2') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t\t<div>{{ row[column.id][0] }}</div>\n\t\t\t\t\t\t\t\t\t\t<div>{{ row[column.id][1] }}</div>\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('textn') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t\t@for (line of row[column.id]; track $index) {\n\t\t\t\t\t\t\t\t\t\t\t<div>{{ line }}</div>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('number') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t\t{{ column.textPrefix }}{{ row[column.id][0] }}{{ column.textSuffix }}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('chips') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t\t@if (isSaving(row, column.id)) {\n\t\t\t\t\t\t\t\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t\t\t\t\t\t\t\t} @else if (column.editable && options.editUrl && isEditing(row, column.id)) {\n\t\t\t\t\t\t\t\t\t\t\t@if (editableOptionsLoading()) {\n\t\t\t\t\t\t\t\t\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t\t<mat-form-field class=\"xiri-inline-edit\" subscriptSizing=\"dynamic\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-select multiple\n\t\t\t\t\t\t\t\t\t\t\t\t\t [ngModel]=\"editingChipsValues()\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t (selectionChange)=\"onChipsSelectionChange(row, column, $event.value)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t (keydown)=\"onInlineEditKeydown($event, row, column)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t (openedChange)=\"!$event && saveInlineEdit(row, column)\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t@if (column.editableOptionsSearch || column.editableSearchUrl) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-option>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<ngx-mat-select-search [formControl]=\"inlineSearchControl\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t [searching]=\"inlineSearching()\"></ngx-mat-select-search>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</mat-option>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t@for (opt of getEditableOptions(column); track opt.value) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-option [value]=\"opt.value\">{{ opt.label }}</mat-option>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</mat-select>\n\t\t\t\t\t\t\t\t\t\t\t\t</mat-form-field>\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t} @else if (column.editable && options.editUrl) {\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"xiri-editable-cell\" role=\"button\" tabindex=\"0\"\n\t\t\t\t\t\t\t\t\t\t\t (click)=\"startInlineEdit(row, column); $event.stopPropagation()\"\n\t\t\t\t\t\t\t\t\t\t\t (keydown.enter)=\"startInlineEdit(row, column); $event.stopPropagation()\">\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"xiri-chips-display\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t@for (chip of row[column.id]; track chip.label) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"xiri-chip-display\" [class]=\"chip.color || ''\">{{ chip.label }}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon class=\"xiri-edit-icon\">edit</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"xiri-chips-display\">\n\t\t\t\t\t\t\t\t\t\t\t\t@for (chip of row[column.id]; track chip.label) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"xiri-chip-display\" [class]=\"chip.color || ''\">{{ chip.label }}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@default {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\"\n\t\t\t\t\t\t\t\t\t [class.xiri-tree-td]=\"treeEnabled && column.id === treeColumnId\">\n\t\t\t\t\t\t\t\t\t\t@if (treeEnabled && column.id === treeColumnId) {\n\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"treePrefix; context: { $implicit: row }\"></ng-container>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t@if (isSaving(row, column.id)) {\n\t\t\t\t\t\t\t\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t\t\t\t\t\t\t\t} @else if (column.editable && options.editUrl && isEditing(row, column.id)) {\n\t\t\t\t\t\t\t\t\t\t\t@if (column.editableOptions || column.editableOptionsUrl || column.editableSearchUrl) {\n\t\t\t\t\t\t\t\t\t\t\t\t@if (editableOptionsLoading()) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-form-field class=\"xiri-inline-edit\" subscriptSizing=\"dynamic\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-select [(ngModel)]=\"row[column.id]\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t (keydown)=\"onInlineEditKeydown($event, row, column)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t (openedChange)=\"!$event && saveInlineEdit(row, column)\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@if (column.editableOptionsSearch || column.editableSearchUrl) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-option>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<ngx-mat-select-search [formControl]=\"inlineSearchControl\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t [searching]=\"inlineSearching()\"></ngx-mat-select-search>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</mat-option>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@for (opt of getEditableOptions(column); track opt.value) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-option [value]=\"opt.value\">{{ opt.label }}</mat-option>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</mat-select>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</mat-form-field>\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t\t<mat-form-field class=\"xiri-inline-edit\" subscriptSizing=\"dynamic\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<input matInput\n\t\t\t\t\t\t\t\t\t\t\t\t\t [(ngModel)]=\"row[column.id]\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t (blur)=\"saveInlineEdit(row, column)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t (keydown)=\"onInlineEditKeydown($event, row, column)\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<button matSuffix mat-icon-button class=\"xiri-inline-edit-confirm\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t (mousedown)=\"$event.preventDefault(); saveInlineEdit(row, column)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t tabindex=\"-1\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon>check</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t\t\t</mat-form-field>\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t} @else if (column.editable && options.editUrl) {\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"xiri-editable-cell\" role=\"button\" tabindex=\"0\"\n\t\t\t\t\t\t\t\t\t\t\t (click)=\"startInlineEdit(row, column); $event.stopPropagation()\"\n\t\t\t\t\t\t\t\t\t\t\t (keydown.enter)=\"startInlineEdit(row, column); $event.stopPropagation()\">\n\t\t\t\t\t\t\t\t\t\t\t\t{{ column.textPrefix }}{{ row[column.id] }}{{ column.textSuffix }}\n\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon class=\"xiri-edit-icon\">edit</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t{{ column.textPrefix }}{{ row[column.id] }}{{ column.textSuffix }}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t@if (treeEnabled && column.id === treeColumnId) {\n\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"treeSuffix; context: { $implicit: row }\"></ng-container>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t<td mat-footer-cell *matFooterCellDef [hidden]=\"!options.footer\"\n\t\t\t\t\t\t\t [style.width]=\"column.width\" [style.min-width]=\"column.minWidth\" class=\"bottomrow\"\n\t\t\t\t\t\t\t [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t@if ( footer[ column.id ] ) {\n\t\t\t\t\t\t\t\t\t\t{{ column.textPrefix }}{{ footer[ column.id ] }}{{ column.textSuffix }}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t\t@if (showSelectColumn) {\n\t\t\t\t\t\t<ng-container matColumnDef=\"select\" [sticky]=\"true\">\n\t\t\t\t\t\t\t<th mat-header-cell *matHeaderCellDef [style.width]=\"'65px'\">\n\t\t\t\t\t\t\t\t<mat-checkbox (change)=\"$event ? masterToggle() : null\"\n\t\t\t\t\t\t\t\t [checked]=\"selection.hasValue() && isAllSelected()\"\n\t\t\t\t\t\t\t\t [indeterminate]=\"selection.hasValue() && !isAllSelected()\">\n\t\t\t\t\t\t\t\t</mat-checkbox>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\">\n\t\t\t\t\t\t\t\t@if (isSelectable(row)) {\n\t\t\t\t\t\t\t\t\t<mat-checkbox\n\t\t\t\t\t\t\t\t\t\t\t(click)=\"$event.stopPropagation()\"\n\t\t\t\t\t\t\t\t\t\t\t(change)=\"$event ? toggleRow(row) : null\"\n\t\t\t\t\t\t\t\t\t\t\t[checked]=\"selection.isSelected(row)\">\n\t\t\t\t\t\t\t\t\t</mat-checkbox>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td mat-footer-cell *matFooterCellDef [style.width]=\"'65px'\" class=\"bottomrow\" [hidden]=\"!options.footer\">\n\t\t\t\t\t\t\t\t<mat-checkbox (change)=\"$event ? masterToggle() : null\"\n\t\t\t\t\t\t\t\t [checked]=\"selection.hasValue() && isAllSelected()\"\n\t\t\t\t\t\t\t\t [indeterminate]=\"selection.hasValue() && !isAllSelected()\">\n\t\t\t\t\t\t\t\t</mat-checkbox>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\n\t\t\t\t\t@if (extraHeaderFields.length > 0) {\n\t\t\t\t\t\t@for (column of extraHeaderFields; track column.id) {\n\t\t\t\t\t\t\t<ng-container matColumnDef=\"{{ column.id }}\" [sticky]=\"column.sticky\">\n\t\t\t\t\t\t\t\t<th mat-header-cell *matHeaderCellDef [attr.colspan]=\"column.headerSpan\">{{ column.name }}</th>\n\t\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t<tr mat-header-row *matHeaderRowDef=\"extraHeaders; sticky: true\" [class.dense]=\"options.dense\"></tr>\n\t\t\t\t\t}\n\n\t\t\t\t\t<tr mat-header-row *matHeaderRowDef=\"columnsToDisplay; sticky: true\" [class.dense]=\"options.dense\"></tr>\n\t\t\t\t\t<tr mat-row *matRowDef=\"let row; columns: columnsToDisplay;\" (click)=\"clicked(row)\"\n\t\t\t\t\t [class.xiri-tree-dimmed]=\"treeEnabled && row._tree?.dimmed\"></tr>\n\t\t\t\t\t<tr mat-footer-row *matFooterRowDef=\"columnsToDisplay; sticky: true\" [hidden]=\"!options.footer\"></tr>\n\t\t\t\t</table>\n\t\t\t</div>\n\t\t\t<div class=\"loader\" [hidden]=\"!loading()\" [class.has-bottombar]=\"(options.select || options.pagination) && !options.footer\">\n\t\t\t\t<mat-spinner diameter=\"30\"></mat-spinner>\n\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t@if (!loading()) {\n\t\t\t\t@if (!errorMsg && dataSource.filteredData.length === 0) {\n\t\t\t\t\t@if (options.emptyState) {\n\t\t\t\t\t\t<xiri-empty-state [settings]=\"options.emptyState\"></xiri-empty-state>\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<div class=\"nodata\">{{ options.textNoData }}</div>\n\t\t\t\t\t}\n\t\t\t\t} @else if (errorMsg) {\n\t\t\t\t\t<div class=\"alert alert-danger\">\n\t\t\t\t\t\t<span>{{ errorMsg }}</span>\n\t\t\t\t\t\t<button mat-button type=\"button\" data-testid=\"table-retry\" (click)=\"reload()\">\n\t\t\t\t\t\t\t<mat-icon>autorenew</mat-icon> Retry\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t<div class=\"xrow xsmall\" [class.bottomrow]=\"(options.select || options.pagination) && !options.footer\">\n\t\t\t\t@if (options.select) {\n\t\t\t\t\t<div class=\"xcol xcol-md-2 select-buttons\">\n\t\t\t\t\t\t@for (button of options.selectButtons; track button) {\n\t\t\t\t\t\t\t@switch (button.action) {\n\t\t\t\t\t\t\t\t@case ('dialog') {\n\t\t\t\t\t\t\t\t\t<button mat-icon-button\n\t\t\t\t\t\t\t\t\t (click)=\"openDialogSelection( $event, button )\"\n\t\t\t\t\t\t\t\t\t [disabled]=\"selection.isEmpty()\"\n\t\t\t\t\t\t\t\t\t [color]=\"button.color || 'primary'\"\n\t\t\t\t\t\t\t\t\t [matTooltip]=\"button.hint\"\n\t\t\t\t\t\t\t\t\t [matTooltipDisabled]=\"!button.hint\">\n\t\t\t\t\t\t\t\t\t\t<mat-icon>{{ button.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('api') {\n\t\t\t\t\t\t\t\t\t<button mat-icon-button\n\t\t\t\t\t\t\t\t\t (click)=\"apiCallSelection( $event, button )\"\n\t\t\t\t\t\t\t\t\t [disabled]=\"selection.isEmpty()\"\n\t\t\t\t\t\t\t\t\t [color]=\"button.color || 'primary'\"\n\t\t\t\t\t\t\t\t\t [matTooltip]=\"button.hint\"\n\t\t\t\t\t\t\t\t\t [matTooltipDisabled]=\"!button.hint\">\n\t\t\t\t\t\t\t\t\t\t<mat-icon>{{ button.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('download') {\n\t\t\t\t\t\t\t\t\t<button mat-icon-button\n\t\t\t\t\t\t\t\t\t (click)=\"downloadSelection( $event, button )\"\n\t\t\t\t\t\t\t\t\t [disabled]=\"selection.isEmpty()\"\n\t\t\t\t\t\t\t\t\t [color]=\"button.color || 'primary'\"\n\t\t\t\t\t\t\t\t\t [matTooltip]=\"button.hint\"\n\t\t\t\t\t\t\t\t\t [matTooltipDisabled]=\"!button.hint\">\n\t\t\t\t\t\t\t\t\t\t<mat-icon>{{ button.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t<div class=\"xcol xcol-right-md-10\">\n\t\t\t\t\t<mat-paginator [hidden]=\"!options.pagination\" [pageSizeOptions]=\"options.pageSizes || []\" showFirstLastButtons=\"true\"></mat-paginator>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</mat-card>\n\n@if (dynData.data) {\n\t<ng-container *ngTemplateOutlet=\"dyncomponent(); context: { $implicit: dynData }\"></ng-container>\n}\n\n<!-- Tree mode: indent + expand/collapse arrow rendered before the tree column's content -->\n<ng-template #treePrefix let-row>\n\t<span class=\"xiri-tree-prefix\" [style.padding-left.px]=\"(row._tree?.level || 0) * 24\">\n\t\t@if (row._tree?.hasChildren) {\n\t\t\t<button type=\"button\" class=\"xiri-tree-iconbtn xiri-tree-toggle\" (click)=\"toggleNode($event, row)\"\n\t\t\t tabindex=\"-1\" [attr.aria-label]=\"row._tree.expanded ? 'einklappen' : 'ausklappen'\">\n\t\t\t\t<mat-icon color=\"primary\">{{ row._tree.expanded ? 'expand_more' : 'chevron_right' }}</mat-icon>\n\t\t\t</button>\n\t\t} @else {\n\t\t\t<span class=\"xiri-tree-spacer\"></span>\n\t\t}\n\t</span>\n</ng-template>\n\n<!-- Tree mode: child-count badge (when collapsed) + optional \"+ sub\" button after the content -->\n<ng-template #treeSuffix let-row>\n\t@if (treeShowCounts && row._tree && !row._tree.expanded && row._tree.childCount > 0) {\n\t\t<span class=\"xiri-tree-count\">({{ row._tree.childCount }})</span>\n\t}\n\t@if (treeHasAddSub && treeCanAddSub(row)) {\n\t\t<button type=\"button\" class=\"xiri-tree-iconbtn xiri-tree-addsub\" (click)=\"addSub($event, row)\"\n\t\t tabindex=\"-1\" matTooltip=\"Sub-Eintrag hinzuf\u00FCgen\" aria-label=\"Sub-Eintrag hinzuf\u00FCgen\">\n\t\t\t<mat-icon color=\"primary\">add</mat-icon>\n\t\t</button>\n\t}\n</ng-template>\n", styles: ["mat-card.xiritablecard{padding:0;margin-bottom:var(--xiri-spacing-xl)}.xiritable{width:100%;overflow:auto}.xiritable.canbreak{word-break:break-all}.xiritable .table-full{display:inline-block;width:100%}.xiritable .table-full .xiri-bulk-bar{display:flex;align-items:center;gap:var(--xiri-spacing-sm);padding:var(--xiri-spacing-xs) var(--xiri-spacing-sm);background:var(--mat-sys-secondary-container, #e0e0e0);color:var(--mat-sys-on-secondary-container, inherit);border-radius:var(--xiri-radius-sm, 4px);margin-bottom:var(--xiri-spacing-xs)}.xiritable .table-full .xiri-bulk-bar.sticky{position:sticky;top:0;z-index:5}.xiritable .table-full .xiri-bulk-bar .xiri-bulk-count{font-weight:500}.xiritable .table-full .xiri-bulk-bar .xiri-bulk-spacer{flex:1 1 auto}.xiritable .table-full .tableout-wrap{position:relative}.xiritable .table-full .tableout{max-height:60vh;overflow-y:auto;width:100%;min-width:100%;max-width:100%}.xiritable .table-full .tableout.is-loading{min-height:100px}.xiritable .table-full .alert{padding:var(--xiri-spacing-md)}.xiritable .table-full mat-paginator{--mat-paginator-container-background-color: transparent;--mat-paginator-container-size: 51px;--mat-form-field-container-height: 32px;--mat-form-field-container-vertical-padding: 4px}.xiritable .table-full .bottomrow{border-top:1px solid var(--outline-variant, #C2C7CF)}.xiritable .table-full div.bottomrow{background-color:var(--surface-container, #F3F3F6);border-bottom-left-radius:var(--mat-card-elevated-container-shape, 12px);border-bottom-right-radius:var(--mat-card-elevated-container-shape, 12px)}.xiritable .header{background-color:var(--surface-container, #F3F3F6);display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;min-height:51px;padding:0 16px;border-bottom:1px solid var(--outline-variant, #C2C7CF);border-top-left-radius:var(--mat-card-elevated-container-shape, 12px);border-top-right-radius:var(--mat-card-elevated-container-shape, 12px)}.xiritable .header .buttons{padding:0 7px 0 .5rem;margin-left:-16px}.xiritable .header .buttons button{z-index:200}.xiritable .header .buttons.saveInput{padding-left:21px}.xiritable .header .middle{flex-grow:1;font-size:var(--xiri-font-size-title);display:flex;padding:0}.xiritable .header xiri-buttonline{padding:0 0 0 16px}.xiritable .header .autorefresh-indicator{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;font-size:var(--xiri-font-size-small, .8rem);color:var(--mat-sys-primary, var(--primary, #006398))}.xiritable .header .autorefresh-indicator mat-icon{font-size:18px;width:18px;height:18px;line-height:18px}.xiritable .header .autorefresh-indicator mat-icon.spin{animation:xiri-autorefresh-spin 1.5s linear infinite}.xiritable .header .lastupdated-indicator{display:inline-flex;align-items:center;padding:2px 8px;font-size:var(--xiri-font-size-small, .8rem);color:var(--on-surface-variant, #44474F);opacity:.75}@keyframes xiri-autorefresh-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.xiritable table{width:100%}.xiritable table.density-regular{--mat-table-header-container-height: 42px;--mat-table-footer-container-height: 42px;--mat-table-row-item-container-height: 42px}.xiritable table.density-compact{--mat-table-header-container-height: 32px;--mat-table-footer-container-height: 32px;--mat-table-row-item-container-height: 32px}.xiritable table.density-relaxed{--mat-table-header-container-height: 52px;--mat-table-footer-container-height: 52px;--mat-table-row-item-container-height: 52px}.xiritable table th.mat-mdc-header-cell:not(:first-of-type),.xiritable table td.mat-mdc-cell:not(:first-of-type),.xiritable table td.mat-mdc-footer-cell:not(:first-of-type){padding-left:5px}.xiritable table th.mat-mdc-header-cell:not(:last-of-type),.xiritable table td.mat-mdc-cell:not(:last-of-type),.xiritable table td.mat-mdc-footer-cell:not(:last-of-type){padding-right:7px}.xiritable table tr.mat-mdc-row{transition:background-color var(--xiri-duration-fast) var(--xiri-easing-standard)}.xiritable table tr.mat-mdc-row:hover{background:var(--surface-variant, #DEE3EB)}.xiritable table .tablelink{text-decoration:underline}.xiritable table td.buttons xiri-button,.xiritable table td.buttons xiri-buttonstyle,.xiritable table td.buttons .btnicon{margin-right:8px}.xiritable table td.buttons xiri-button:last-child,.xiritable table td.buttons xiri-buttonstyle:last-child,.xiritable table td.buttons .btnicon:last-child{margin-right:0}.xiritable table td.number,.xiritable table th.number,.xiritable table td.mat-mdc-footer-cell.number{text-align:right;font-variant-numeric:tabular-nums}.xiritable table td.right,.xiritable table td.align-right,.xiritable table th.right,.xiritable table th.align-right{text-align:right}.xiritable table td.center,.xiritable table td.align-center,.xiritable table th.center,.xiritable table th.align-center{text-align:center}.xiritable table td.left,.xiritable table td.align-left,.xiritable table th.left,.xiritable table th.align-left{text-align:left}.xiritable table td.vertical,.xiritable table th.vertical{writing-mode:sideways-rl;text-orientation:sideways}.xiritable table td.vertical div,.xiritable table th.vertical div{max-height:6rem}.xiritable table td.sideways,.xiritable table th.sideways{writing-mode:sideways-lr;text-orientation:sideways}.xiritable table td.sideways div,.xiritable table th.sideways div{max-height:6rem}.xiritable table td.upright,.xiritable table th.upright{writing-mode:vertical-rl;text-orientation:upright}.xiritable table.borders td+td{border-left:1px solid var(--outline-variant, #C2C7CF)}.xiritable table.bordersHeader th+th{border-left:1px solid var(--outline-variant, #C2C7CF)}.xiritable table td.mat-mdc-cell mat-form-field{--mat-form-field-container-height: 40px;--mat-form-field-container-vertical-padding: 8px}.xiritable .xiri-editable-cell{cursor:pointer;display:inline-flex;align-items:center;border-radius:var(--xiri-radius-xs);padding:2px 4px}.xiritable .xiri-editable-cell:hover,.xiritable .xiri-editable-cell:focus-visible{background-color:var(--surface-variant, #DEE3EB)}.xiritable .xiri-editable-cell:hover .xiri-edit-icon,.xiritable .xiri-editable-cell:focus-visible .xiri-edit-icon{opacity:1}.xiritable .xiri-edit-icon{opacity:0;font-size:14px;width:14px;height:14px;margin-left:4px;color:var(--on-surface-variant, #44474F);transition:opacity var(--xiri-duration-fast) var(--xiri-easing-standard)}.xiritable .xiri-inline-edit{--mat-form-field-container-height: 36px;--mat-form-field-container-vertical-padding: 6px;width:100%}.xiritable .xiri-inline-edit-confirm{--mdc-icon-button-icon-size: 18px;--mdc-icon-button-state-layer-size: 28px;width:28px;height:28px;padding:0;margin-right:5px;color:var(--primary, #1976d2);display:inline-flex;align-items:center;justify-content:center}.xiritable .xiri-inline-edit-confirm mat-icon{display:flex;align-items:center;justify-content:center;width:18px;height:18px;font-size:18px}.xiritable .mat-column-select{overflow:initial}.xiritable .select-buttons{padding:.3rem .8rem;display:flex;align-items:center}.xiritable .select-buttons button{margin-right:.5rem}.xiritable .xiri-cell-saved{animation:pulse .5s var(--xiri-easing-standard);border-radius:var(--xiri-radius-xs)}.xiritable .nodata{padding:.5rem 1.5rem;font-size:var(--xiri-font-size-label);background-color:var(--surface, #FFFFFF);animation:fadeInUp var(--xiri-duration-normal) var(--xiri-easing-decelerate)}.xiritable .loader{position:absolute;top:0;left:0;width:100%;bottom:0;display:flex;justify-content:center;align-items:center;background-color:var(--ripple, rgba(206, 212, 218, .5));z-index:200;border-bottom-left-radius:var(--mat-card-elevated-container-shape, 12px);border-bottom-right-radius:var(--mat-card-elevated-container-shape, 12px);animation:fadeIn var(--xiri-duration-fast) var(--xiri-easing-standard)}.xiritable .loader.has-bottombar{border-bottom-left-radius:0;border-bottom-right-radius:0}xiri-dyncomponent{margin-bottom:var(--xiri-spacing-xl)}[hidden]{display:none!important}.xiri-tree-actions{display:flex;align-items:center}td.xiri-tree-td{white-space:nowrap}td.xiri-tree-td .xiri-tree-prefix{display:inline-flex;align-items:center;vertical-align:middle}td.xiri-tree-td .xiri-tree-iconbtn{appearance:none;border:0;background:transparent;padding:0;margin:0;flex:0 0 24px;width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;border-radius:50%;cursor:pointer;-webkit-tap-highlight-color:transparent}td.xiri-tree-td .xiri-tree-iconbtn .mat-icon{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;font-size:20px;line-height:20px;margin:0}td.xiri-tree-td .xiri-tree-iconbtn:hover{background:#0000000f}td.xiri-tree-td .xiri-tree-iconbtn:focus-visible{outline:2px solid var(--mat-sys-primary, currentColor);outline-offset:-2px}td.xiri-tree-td .xiri-tree-spacer{width:24px;height:24px;flex:0 0 24px}td.xiri-tree-td .xiri-tree-count{margin-left:var(--xiri-spacing-xs, 4px);opacity:.6;font-size:.85em}td.xiri-tree-td .xiri-tree-addsub{margin-left:var(--xiri-spacing-xs, 4px);opacity:0;transition:opacity .15s ease-in-out}tr.mat-mdc-row:hover td.xiri-tree-td .xiri-tree-addsub,td.xiri-tree-td .xiri-tree-addsub:focus-visible{opacity:1}tr.xiri-tree-dimmed{opacity:.6}\n"], dependencies: [{ kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { 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"] }, { kind: "component", type: XiriButtonlineComponent, selector: "xiri-buttonline", inputs: ["settings", "disabled", "filterData"], outputs: ["result"] }, { kind: "component", type: XiriSearchComponent, selector: "xiri-search", inputs: ["placeholder", "open", "reset", "escape", "focus", "text"], outputs: ["changed"] }, { kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "directive", type: MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "component", type: MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "directive", type: MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "component", type: XiriButtonstyleComponent, selector: "xiri-buttonstyle", inputs: ["button", "disabled", "loading", "countdown", "pollText"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { 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: "ngmodule", type: FormsModule }, { 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.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { 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: "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: MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: XiriButtonComponent, selector: "xiri-button", inputs: ["button", "disabled", "filterData", "url"], outputs: ["result"] }, { kind: "directive", type: MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "component", type: MatFooterRow, selector: "mat-footer-row, tr[mat-footer-row]", exportAs: ["matFooterRow"] }, { kind: "directive", type: MatFooterRowDef, selector: "[matFooterRowDef]", inputs: ["matFooterRowDef", "matFooterRowDefSticky"] }, { kind: "directive", type: MatFooterCell, selector: "mat-footer-cell, td[mat-footer-cell]" }, { kind: "directive", type: MatFooterCellDef, selector: "[matFooterCellDef]" }, { kind: "component", type: MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { 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$1, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: XiriEmptyStateComponent, selector: "xiri-empty-state", inputs: ["settings"], outputs: ["buttonResult"] }, { kind: "pipe", type: DatePipe, name: "date" }, { kind: "pipe", type: SafehtmlPipe, name: "safeHtml" }, { kind: "pipe", type: XiriUrlPipe, name: "xiriUrl" }], encapsulation: i0.ViewEncapsulation.None }); }
5183
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: XiriTableComponent, isStandalone: true, selector: "xiri-table", inputs: { dyncomponent: { classPropertyName: "dyncomponent", publicName: "dyncomponent", isSignal: true, isRequired: false, transformFunction: null }, settings: { classPropertyName: "settings", publicName: "settings", isSignal: true, isRequired: true, transformFunction: null }, filterData: { classPropertyName: "filterData", publicName: "filterData", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clickedRow: "clickedRow" }, providers: [XiriTableInlineEditService, XiriTableTreeService], viewQueries: [{ propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true, isSignal: true }, { propertyName: "sort", first: true, predicate: MatSort, descendants: true, isSignal: true }, { propertyName: "table", first: true, predicate: MatTable, descendants: true, isSignal: true }], ngImport: i0, template: "<mat-card class=\"xiritablecard mat-mdc-elevation-specific mat-elevation-z3\">\n\t<div class=\"xiritable\" [class]=\"options.class\">\n\t\t<div class=\"table-full\">\n\t\t\t@if (bulkBarActive) {\n\t\t\t\t<div class=\"xiri-bulk-bar\" [class.sticky]=\"options.stickyBulkBar\" role=\"toolbar\"\n\t\t\t\t aria-label=\"Massenaktionen\" data-testid=\"table-bulk-bar\">\n\t\t\t\t\t<button mat-icon-button (click)=\"cancelBulk()\" matTooltip=\"Auswahl aufheben\"\n\t\t\t\t\t aria-label=\"Auswahl aufheben\">\n\t\t\t\t\t\t<mat-icon>close</mat-icon>\n\t\t\t\t\t</button>\n\t\t\t\t\t<span class=\"xiri-bulk-count\" aria-live=\"polite\" data-testid=\"table-bulk-count\">\n\t\t\t\t\t\t@if (bulkAllResults()) {\n\t\t\t\t\t\t\tAlle {{ bulkTotalCount() }} Ergebnisse ausgew\u00E4hlt\n\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t{{ selection.selected.length }} ausgew\u00E4hlt\n\t\t\t\t\t\t}\n\t\t\t\t\t</span>\n\t\t\t\t\t@if (canSelectAllResults()) {\n\t\t\t\t\t\t<button mat-button color=\"primary\" (click)=\"selectAllResults()\"\n\t\t\t\t\t\t data-testid=\"table-bulk-selectall\">\n\t\t\t\t\t\t\tAlle {{ bulkTotalCount() }} Ergebnisse ausw\u00E4hlen\n\t\t\t\t\t\t</button>\n\t\t\t\t\t}\n\t\t\t\t\t<span class=\"xiri-bulk-spacer\"></span>\n\t\t\t\t\t@for (button of options.bulkActions; track button) {\n\t\t\t\t\t\t@if (!button.hide) {\n\t\t\t\t\t\t\t<button mat-button [color]=\"button.color || 'primary'\"\n\t\t\t\t\t\t\t (click)=\"bulkAction($event, button)\"\n\t\t\t\t\t\t\t [matTooltip]=\"button.hint\" [matTooltipDisabled]=\"!button.hint\">\n\t\t\t\t\t\t\t\t@if (button.icon) {\n\t\t\t\t\t\t\t\t\t<mat-icon>{{ button.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t{{ button.text }}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t<div class=\"header\" [hidden]=\"bulkBarActive\">\n\t\t\t\t@if (options.reload) {\n\t\t\t\t\t<div class=\"buttons\">\n\t\t\t\t\t\t<button mat-icon-button (click)=\"reload()\" color=\"primary\" aria-label=\"Tabelle neu laden\">\n\t\t\t\t\t\t\t<mat-icon>autorenew</mat-icon>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t@if (autoRefresh()) {\n\t\t\t\t\t<div class=\"autorefresh-indicator\" role=\"status\" aria-live=\"polite\"\n\t\t\t\t\t matTooltip=\"Tabelle aktualisiert sich automatisch\">\n\t\t\t\t\t\t<mat-icon class=\"spin\">sync</mat-icon>\n\t\t\t\t\t\t<span>Auto-Refresh aktiv \u00B7 n\u00E4chste in {{ countdown() }}s</span>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t@if (lastUpdated(); as updated) {\n\t\t\t\t\t<div class=\"lastupdated-indicator\" data-testid=\"table-last-updated\" role=\"status\" aria-live=\"polite\">\n\t\t\t\t\t\tStand {{ updated | date:'HH:mm' }}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t@if (treeEnabled) {\n\t\t\t\t\t<div class=\"buttons xiri-tree-actions\">\n\t\t\t\t\t\t<button mat-icon-button (click)=\"expandAllNodes()\" color=\"primary\"\n\t\t\t\t\t\t matTooltip=\"Alle ausklappen\" aria-label=\"Alle ausklappen\">\n\t\t\t\t\t\t\t<mat-icon>unfold_more</mat-icon>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<button mat-icon-button (click)=\"collapseAllNodes()\" color=\"primary\"\n\t\t\t\t\t\t matTooltip=\"Alle einklappen\" aria-label=\"Alle einklappen\">\n\t\t\t\t\t\t\t<mat-icon>unfold_less</mat-icon>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t<div class=\"middle\" [class.hasButtons]=\"options.buttons\">{{ options.title }}</div>\n\t\t\t\t@if (options.buttons) {\n\t\t\t\t\t<xiri-buttonline [settings]=\"options.buttons\" (result)=\"buttonReturn($event)\"\n\t\t\t\t\t [filterData]=\"_filterData()\"></xiri-buttonline>\n\t\t\t\t}\n\t\t\t\t@if (options.search) {\n\t\t\t\t\t<xiri-search (changed)=\"searchDo($event)\" [placeholder]=\"''\" [text]=\"searchTextInit\"></xiri-search>\n\t\t\t\t}\n\t\t\t\t@if (options.saveInput) {\n\t\t\t\t\t<div class=\"buttons saveInput\">\n\t\t\t\t\t\t<button mat-raised-button (click)=\"saveInputData()\" color=\"primary\">\n\t\t\t\t\t\t\t{{ options.saveInput }}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t</div>\n\t\t\t<div class=\"tableout-wrap\">\n\t\t\t<div class=\"tableout\" [class.is-loading]=\"loading()\" [style.max-height]=\"options.scrollHeight || null\">\n\t\t\t\t<table mat-table [dataSource]=\"dataSource\" matSort [style.min-width]=\"options.minWidth ?? '100%'\"\n\t\t\t\t [class]=\"densityClass()\"\n\t\t\t\t [class.borders]=\"options.borders\" [class.bordersHeader]=\"options.bordersHeader\"\n\t\t\t\t [trackBy]=\"trackByRowId\">\n\n\t\t\t\t\t@for (column of displayedColumns; track column.id) {\n\t\t\t\t\t\t<ng-container [matColumnDef]=\"column.id\" [sticky]=\"column.sticky\">\n\t\t\t\t\t\t\t<th mat-header-cell *matHeaderCellDef mat-sort-header=\"{{ column.id }}\" [disabled]=\"!column.sort || !options.sort\" disableClear\n\t\t\t\t\t\t\t [style.width]=\"column.width\" [style.min-width]=\"column.minWidth\"\n\t\t\t\t\t\t\t [class]=\"column.display + ' ' + (column.header || '')\"> {{ column.name }}\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t@switch (column.format) {\n\t\t\t\t\t\t\t\t@case ('buttons') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t\t@for (button of column.buttons; track button; let i = $index) {\n\t\t\t\t\t\t\t\t\t\t\t@if (row[column.id][i] !== false && !button.hide) {\n\t\t\t\t\t\t\t\t\t\t\t\t@switch (button.action) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('link') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<xiri-button [button]=\"button\" [disabled]=\"false\" [url]=\"row[column.id][ i ]\"></xiri-button>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('href') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<xiri-button [button]=\"button\" [disabled]=\"false\" [url]=\"row[column.id][ i ]\"></xiri-button>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('download') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<xiri-button [button]=\"button\" [disabled]=\"false\" [url]=\"row[column.id][ i ]\"></xiri-button>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('dialog') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<xiri-buttonstyle [button]=\"button\" [disabled]=\"false\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t (click)=\"openDialog( $event, button, column.id, i, row)\"></xiri-buttonstyle>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('api') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<xiri-buttonstyle [button]=\"button\" [disabled]=\"false\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t (click)=\"apiCall( $event, row[column.id][ i ] )\"></xiri-buttonstyle>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('save') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<xiri-buttonstyle [button]=\"button\" (click)=\"saveCall( $event, button, row, row[column.id][ i ] )\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t [disabled]=\"!saveCallCheck( button, row )\"></xiri-buttonstyle>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('icon') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon class=\"btnicon\" [class]=\"button.color || 'primary'\" [matTooltip]=\"button.hint\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t [matTooltipDisabled]=\"!button.hint\">{{ button.icon }}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('menu') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<button mat-icon-button [matMenuTriggerFor]=\"menuRef\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t [class]=\"button.color || 'primary'\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t [matTooltip]=\"button.hint\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t [matTooltipDisabled]=\"!button.hint\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t [attr.aria-label]=\"button.hint || button.text\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t (click)=\"$event.stopPropagation()\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon>{{ button.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-menu #menuRef=\"matMenu\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@for (item of button.menuItems; track item; let j = $index) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@if (row[column.id][i][j] !== false) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@switch (item.action) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('link') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@let menuUrl = row[column.id][i][j] | xiriUrl;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<a mat-menu-item [routerLink]=\"menuUrl?.path\" [queryParams]=\"menuUrl?.queryParams\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon [class]=\"item.color || 'primary'\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span>{{ item.text }}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('href') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<a mat-menu-item [href]=\"row[column.id][i][j]\" target=\"_blank\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon [class]=\"item.color || 'primary'\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span>{{ item.text }}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('dialog') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<button mat-menu-item (click)=\"openMenuDialog($event, item, column.id, i, j, row)\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon [class]=\"item.color || 'primary'\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span>{{ item.text }}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</mat-menu>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('icon') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t\t@if (column.icons?.[ $any(row[ column.id ]) ]; as icon) {\n\t\t\t\t\t\t\t\t\t\t\t<mat-icon [class]=\"icon[ 'color' ] || 'primary'\"\n\t\t\t\t\t\t\t\t\t\t\t [matTooltip]=\"icon[ 'hint' ] || '' \"\n\t\t\t\t\t\t\t\t\t\t\t [matTooltipDisabled]=\"!icon[ 'hint' ]\">{{ icon['icon'] }}\n\t\t\t\t\t\t\t\t\t\t\t</mat-icon>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('html') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [innerHtml]=\"row[column.id] | safeHtml\" [class]=\"column.display\"></td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('link') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\"\n\t\t\t\t\t\t\t\t\t [class.xiri-tree-td]=\"treeEnabled && column.id === treeColumnId\">\n\t\t\t\t\t\t\t\t\t\t@if (treeEnabled && column.id === treeColumnId) {\n\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"treePrefix; context: { $implicit: row }\"></ng-container>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t@if (row[column.id + 'Link']) {\n\t\t\t\t\t\t\t\t\t\t\t@let cellUrl = row[column.id + 'Link'] | xiriUrl;\n\t\t\t\t\t\t\t\t\t\t\t<a [routerLink]=\"cellUrl?.path\" [queryParams]=\"cellUrl?.queryParams\" class=\"tablelink\">{{ row[column.id] }}</a>\n\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t<span>{{ row[column.id] }}</span>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t@if (treeEnabled && column.id === treeColumnId) {\n\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"treeSuffix; context: { $implicit: row }\"></ng-container>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('input') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t\t<mat-form-field subscriptSizing=\"dynamic\">\n\t\t\t\t\t\t\t\t\t\t\t<input matInput\n\t\t\t\t\t\t\t\t\t\t\t [type]=\"column.inputType || 'text'\"\n\t\t\t\t\t\t\t\t\t\t\t [(ngModel)]=\"row[ column.id ]\"\n\t\t\t\t\t\t\t\t\t\t\t [lang]=\"column.inputLang || ''\"\n\t\t\t\t\t\t\t\t\t\t\t [required]=\"column.inputRequired || true\"\n\t\t\t\t\t\t\t\t\t\t\t (paste)=\"pasteInput( $event, row, column )\">\n\t\t\t\t\t\t\t\t\t\t</mat-form-field>\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('text2') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t\t<div>{{ row[column.id][0] }}</div>\n\t\t\t\t\t\t\t\t\t\t<div>{{ row[column.id][1] }}</div>\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('textn') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t\t@for (line of row[column.id]; track $index) {\n\t\t\t\t\t\t\t\t\t\t\t<div>{{ line }}</div>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('number') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t\t{{ column.textPrefix }}{{ row[column.id][0] }}{{ column.textSuffix }}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('chips') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t\t@if (isSaving(row, column.id)) {\n\t\t\t\t\t\t\t\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t\t\t\t\t\t\t\t} @else if (column.editable && options.editUrl && isEditing(row, column.id)) {\n\t\t\t\t\t\t\t\t\t\t\t@if (editableOptionsLoading()) {\n\t\t\t\t\t\t\t\t\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t\t<mat-form-field class=\"xiri-inline-edit\" subscriptSizing=\"dynamic\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-select multiple\n\t\t\t\t\t\t\t\t\t\t\t\t\t [ngModel]=\"editingChipsValues()\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t (selectionChange)=\"onChipsSelectionChange(row, column, $event.value)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t (keydown)=\"onInlineEditKeydown($event, row, column)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t (openedChange)=\"!$event && saveInlineEdit(row, column)\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t@if (column.editableOptionsSearch || column.editableSearchUrl) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-option>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<ngx-mat-select-search [formControl]=\"inlineSearchControl\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t [searching]=\"inlineSearching()\"></ngx-mat-select-search>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</mat-option>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t@for (opt of getEditableOptions(column); track opt.value) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-option [value]=\"opt.value\">{{ opt.label }}</mat-option>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</mat-select>\n\t\t\t\t\t\t\t\t\t\t\t\t</mat-form-field>\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t} @else if (column.editable && options.editUrl) {\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"xiri-editable-cell\" role=\"button\" tabindex=\"0\"\n\t\t\t\t\t\t\t\t\t\t\t (click)=\"startInlineEdit(row, column); $event.stopPropagation()\"\n\t\t\t\t\t\t\t\t\t\t\t (keydown.enter)=\"startInlineEdit(row, column); $event.stopPropagation()\">\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"xiri-chips-display\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t@for (chip of row[column.id]; track chip.label) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"xiri-chip-display\" [class]=\"chip.color || ''\">{{ chip.label }}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon class=\"xiri-edit-icon\">edit</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"xiri-chips-display\">\n\t\t\t\t\t\t\t\t\t\t\t\t@for (chip of row[column.id]; track chip.label) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"xiri-chip-display\" [class]=\"chip.color || ''\">{{ chip.label }}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@default {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\"\n\t\t\t\t\t\t\t\t\t [class.xiri-tree-td]=\"treeEnabled && column.id === treeColumnId\">\n\t\t\t\t\t\t\t\t\t\t@if (treeEnabled && column.id === treeColumnId) {\n\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"treePrefix; context: { $implicit: row }\"></ng-container>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t@if (isSaving(row, column.id)) {\n\t\t\t\t\t\t\t\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t\t\t\t\t\t\t\t} @else if (column.editable && options.editUrl && isEditing(row, column.id)) {\n\t\t\t\t\t\t\t\t\t\t\t@if (column.editableOptions || column.editableOptionsUrl || column.editableSearchUrl) {\n\t\t\t\t\t\t\t\t\t\t\t\t@if (editableOptionsLoading()) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-form-field class=\"xiri-inline-edit\" subscriptSizing=\"dynamic\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-select [(ngModel)]=\"row[column.id]\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t (keydown)=\"onInlineEditKeydown($event, row, column)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t (openedChange)=\"!$event && saveInlineEdit(row, column)\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@if (column.editableOptionsSearch || column.editableSearchUrl) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-option>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<ngx-mat-select-search [formControl]=\"inlineSearchControl\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t [searching]=\"inlineSearching()\"></ngx-mat-select-search>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</mat-option>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@for (opt of getEditableOptions(column); track opt.value) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-option [value]=\"opt.value\">{{ opt.label }}</mat-option>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</mat-select>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</mat-form-field>\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t\t<mat-form-field class=\"xiri-inline-edit\" subscriptSizing=\"dynamic\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<input matInput\n\t\t\t\t\t\t\t\t\t\t\t\t\t [(ngModel)]=\"row[column.id]\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t (blur)=\"saveInlineEdit(row, column)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t (keydown)=\"onInlineEditKeydown($event, row, column)\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<button matSuffix mat-icon-button class=\"xiri-inline-edit-confirm\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t (mousedown)=\"$event.preventDefault(); saveInlineEdit(row, column)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t aria-label=\"\u00C4nderung speichern\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t tabindex=\"-1\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon>check</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t\t\t</mat-form-field>\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t} @else if (column.editable && options.editUrl) {\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"xiri-editable-cell\" role=\"button\" tabindex=\"0\"\n\t\t\t\t\t\t\t\t\t\t\t (click)=\"startInlineEdit(row, column); $event.stopPropagation()\"\n\t\t\t\t\t\t\t\t\t\t\t (keydown.enter)=\"startInlineEdit(row, column); $event.stopPropagation()\">\n\t\t\t\t\t\t\t\t\t\t\t\t{{ column.textPrefix }}{{ row[column.id] }}{{ column.textSuffix }}\n\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon class=\"xiri-edit-icon\">edit</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t{{ column.textPrefix }}{{ row[column.id] }}{{ column.textSuffix }}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t@if (treeEnabled && column.id === treeColumnId) {\n\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"treeSuffix; context: { $implicit: row }\"></ng-container>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t<td mat-footer-cell *matFooterCellDef [hidden]=\"!options.footer\"\n\t\t\t\t\t\t\t [style.width]=\"column.width\" [style.min-width]=\"column.minWidth\" class=\"bottomrow\"\n\t\t\t\t\t\t\t [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t@if ( footer[ column.id ] ) {\n\t\t\t\t\t\t\t\t\t\t{{ column.textPrefix }}{{ footer[ column.id ] }}{{ column.textSuffix }}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t\t@if (showSelectColumn) {\n\t\t\t\t\t\t<ng-container matColumnDef=\"select\" [sticky]=\"true\">\n\t\t\t\t\t\t\t<th mat-header-cell *matHeaderCellDef [style.width]=\"'65px'\">\n\t\t\t\t\t\t\t\t<mat-checkbox (change)=\"$event ? masterToggle() : null\"\n\t\t\t\t\t\t\t\t [checked]=\"selection.hasValue() && isAllSelected()\"\n\t\t\t\t\t\t\t\t [indeterminate]=\"selection.hasValue() && !isAllSelected()\">\n\t\t\t\t\t\t\t\t</mat-checkbox>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\">\n\t\t\t\t\t\t\t\t@if (isSelectable(row)) {\n\t\t\t\t\t\t\t\t\t<mat-checkbox\n\t\t\t\t\t\t\t\t\t\t\t(click)=\"$event.stopPropagation()\"\n\t\t\t\t\t\t\t\t\t\t\t(change)=\"$event ? toggleRow(row) : null\"\n\t\t\t\t\t\t\t\t\t\t\t[checked]=\"selection.isSelected(row)\">\n\t\t\t\t\t\t\t\t\t</mat-checkbox>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td mat-footer-cell *matFooterCellDef [style.width]=\"'65px'\" class=\"bottomrow\" [hidden]=\"!options.footer\">\n\t\t\t\t\t\t\t\t<mat-checkbox (change)=\"$event ? masterToggle() : null\"\n\t\t\t\t\t\t\t\t [checked]=\"selection.hasValue() && isAllSelected()\"\n\t\t\t\t\t\t\t\t [indeterminate]=\"selection.hasValue() && !isAllSelected()\">\n\t\t\t\t\t\t\t\t</mat-checkbox>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\n\t\t\t\t\t@if (extraHeaderFields.length > 0) {\n\t\t\t\t\t\t@for (column of extraHeaderFields; track column.id) {\n\t\t\t\t\t\t\t<ng-container matColumnDef=\"{{ column.id }}\" [sticky]=\"column.sticky\">\n\t\t\t\t\t\t\t\t<th mat-header-cell *matHeaderCellDef [attr.colspan]=\"column.headerSpan\">{{ column.name }}</th>\n\t\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t<tr mat-header-row *matHeaderRowDef=\"extraHeaders; sticky: true\" [class.dense]=\"options.dense\"></tr>\n\t\t\t\t\t}\n\n\t\t\t\t\t<tr mat-header-row *matHeaderRowDef=\"columnsToDisplay; sticky: true\" [class.dense]=\"options.dense\"></tr>\n\t\t\t\t\t<tr mat-row *matRowDef=\"let row; columns: columnsToDisplay;\" (click)=\"clicked(row)\"\n\t\t\t\t\t [class.xiri-tree-dimmed]=\"treeEnabled && row._tree?.dimmed\"></tr>\n\t\t\t\t\t<tr mat-footer-row *matFooterRowDef=\"columnsToDisplay; sticky: true\" [hidden]=\"!options.footer\"></tr>\n\t\t\t\t</table>\n\t\t\t</div>\n\t\t\t<div class=\"loader\" [hidden]=\"!loading()\" [class.has-bottombar]=\"(options.select || options.pagination) && !options.footer\">\n\t\t\t\t<mat-spinner diameter=\"30\"></mat-spinner>\n\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t@if (!loading()) {\n\t\t\t\t@if (!errorMsg && dataSource.filteredData.length === 0) {\n\t\t\t\t\t@if (options.emptyState) {\n\t\t\t\t\t\t<xiri-empty-state [settings]=\"options.emptyState\"></xiri-empty-state>\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<div class=\"nodata\">{{ options.textNoData }}</div>\n\t\t\t\t\t}\n\t\t\t\t} @else if (errorMsg) {\n\t\t\t\t\t<div class=\"alert alert-danger\">\n\t\t\t\t\t\t<span>{{ errorMsg }}</span>\n\t\t\t\t\t\t<button mat-button type=\"button\" data-testid=\"table-retry\" (click)=\"reload()\">\n\t\t\t\t\t\t\t<mat-icon>autorenew</mat-icon> Retry\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t<div class=\"xrow xsmall\" [class.bottomrow]=\"(options.select || options.pagination) && !options.footer\">\n\t\t\t\t@if (options.select) {\n\t\t\t\t\t<div class=\"xcol xcol-md-2 select-buttons\">\n\t\t\t\t\t\t@for (button of options.selectButtons; track button) {\n\t\t\t\t\t\t\t@if (!button.hide) {\n\t\t\t\t\t\t\t\t@switch (button.action) {\n\t\t\t\t\t\t\t\t\t@case ('dialog') {\n\t\t\t\t\t\t\t\t\t\t<button mat-icon-button\n\t\t\t\t\t\t\t\t\t\t (click)=\"openDialogSelection( $event, button )\"\n\t\t\t\t\t\t\t\t\t\t [disabled]=\"selection.isEmpty()\"\n\t\t\t\t\t\t\t\t\t\t [color]=\"button.color || 'primary'\"\n\t\t\t\t\t\t\t\t\t\t [matTooltip]=\"button.hint\"\n\t\t\t\t\t\t\t\t\t\t [matTooltipDisabled]=\"!button.hint\"\n\t\t\t\t\t\t\t\t\t\t [attr.aria-label]=\"button.hint || button.text\">\n\t\t\t\t\t\t\t\t\t\t\t<mat-icon>{{ button.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t@case ('api') {\n\t\t\t\t\t\t\t\t\t\t<button mat-icon-button\n\t\t\t\t\t\t\t\t\t\t (click)=\"apiCallSelection( $event, button )\"\n\t\t\t\t\t\t\t\t\t\t [disabled]=\"selection.isEmpty()\"\n\t\t\t\t\t\t\t\t\t\t [color]=\"button.color || 'primary'\"\n\t\t\t\t\t\t\t\t\t\t [matTooltip]=\"button.hint\"\n\t\t\t\t\t\t\t\t\t\t [matTooltipDisabled]=\"!button.hint\"\n\t\t\t\t\t\t\t\t\t\t [attr.aria-label]=\"button.hint || button.text\">\n\t\t\t\t\t\t\t\t\t\t\t<mat-icon>{{ button.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t@case ('download') {\n\t\t\t\t\t\t\t\t\t\t<button mat-icon-button\n\t\t\t\t\t\t\t\t\t\t (click)=\"downloadSelection( $event, button )\"\n\t\t\t\t\t\t\t\t\t\t [disabled]=\"selection.isEmpty()\"\n\t\t\t\t\t\t\t\t\t\t [color]=\"button.color || 'primary'\"\n\t\t\t\t\t\t\t\t\t\t [matTooltip]=\"button.hint\"\n\t\t\t\t\t\t\t\t\t\t [matTooltipDisabled]=\"!button.hint\"\n\t\t\t\t\t\t\t\t\t\t [attr.aria-label]=\"button.hint || button.text\">\n\t\t\t\t\t\t\t\t\t\t\t<mat-icon>{{ button.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t<div class=\"xcol xcol-right-md-10\">\n\t\t\t\t\t<mat-paginator [hidden]=\"!options.pagination\" [pageSizeOptions]=\"options.pageSizes || []\" showFirstLastButtons=\"true\"></mat-paginator>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</mat-card>\n\n@if (dynData.data) {\n\t<ng-container *ngTemplateOutlet=\"dyncomponent(); context: { $implicit: dynData }\"></ng-container>\n}\n\n<!-- Tree mode: indent + expand/collapse arrow rendered before the tree column's content -->\n<ng-template #treePrefix let-row>\n\t<span class=\"xiri-tree-prefix\" [style.padding-left.px]=\"(row._tree?.level || 0) * 24\">\n\t\t@if (row._tree?.hasChildren) {\n\t\t\t<button type=\"button\" class=\"xiri-tree-iconbtn xiri-tree-toggle\" (click)=\"toggleNode($event, row)\"\n\t\t\t tabindex=\"-1\" [attr.aria-label]=\"row._tree.expanded ? 'einklappen' : 'ausklappen'\">\n\t\t\t\t<mat-icon color=\"primary\">{{ row._tree.expanded ? 'expand_more' : 'chevron_right' }}</mat-icon>\n\t\t\t</button>\n\t\t} @else {\n\t\t\t<span class=\"xiri-tree-spacer\"></span>\n\t\t}\n\t</span>\n</ng-template>\n\n<!-- Tree mode: child-count badge (when collapsed) + optional \"+ sub\" button after the content -->\n<ng-template #treeSuffix let-row>\n\t@if (treeShowCounts && row._tree && !row._tree.expanded && row._tree.childCount > 0) {\n\t\t<span class=\"xiri-tree-count\">({{ row._tree.childCount }})</span>\n\t}\n\t@if (treeHasAddSub && treeCanAddSub(row)) {\n\t\t<button type=\"button\" class=\"xiri-tree-iconbtn xiri-tree-addsub\" (click)=\"addSub($event, row)\"\n\t\t tabindex=\"-1\" matTooltip=\"Sub-Eintrag hinzuf\u00FCgen\" aria-label=\"Sub-Eintrag hinzuf\u00FCgen\">\n\t\t\t<mat-icon color=\"primary\">add</mat-icon>\n\t\t</button>\n\t}\n</ng-template>\n", styles: ["mat-card.xiritablecard{padding:0;margin-bottom:var(--xiri-spacing-xl)}.xiritable{width:100%;overflow:auto}.xiritable.canbreak{word-break:break-all}.xiritable .table-full{display:inline-block;width:100%}.xiritable .table-full .xiri-bulk-bar{display:flex;align-items:center;gap:var(--xiri-spacing-sm);padding:var(--xiri-spacing-xs) var(--xiri-spacing-sm);background:var(--secondary-container, var(--mat-sys-secondary-container, #e0e0e0));color:var(--on-secondary-container, var(--mat-sys-on-secondary-container, inherit));border-radius:var(--xiri-radius-sm, 4px);margin-bottom:var(--xiri-spacing-xs)}.xiritable .table-full .xiri-bulk-bar.sticky{position:sticky;top:0;z-index:5}.xiritable .table-full .xiri-bulk-bar .xiri-bulk-count{font-weight:500}.xiritable .table-full .xiri-bulk-bar .xiri-bulk-spacer{flex:1 1 auto}.xiritable .table-full .tableout-wrap{position:relative}.xiritable .table-full .tableout{max-height:60vh;overflow-y:auto;width:100%;min-width:100%;max-width:100%}.xiritable .table-full .tableout.is-loading{min-height:100px}.xiritable .table-full .alert{padding:var(--xiri-spacing-md)}.xiritable .table-full mat-paginator{--mat-paginator-container-background-color: transparent;--mat-paginator-container-size: 51px;--mat-form-field-container-height: 32px;--mat-form-field-container-vertical-padding: 4px}.xiritable .table-full .bottomrow{border-top:1px solid var(--outline-variant, #C2C7CF)}.xiritable .table-full div.bottomrow{background-color:var(--surface-container, #F3F3F6);border-bottom-left-radius:var(--mat-card-elevated-container-shape, 12px);border-bottom-right-radius:var(--mat-card-elevated-container-shape, 12px)}.xiritable .header{background-color:var(--surface-container, #F3F3F6);display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;min-height:51px;padding:0 16px;border-bottom:1px solid var(--outline-variant, #C2C7CF);border-top-left-radius:var(--mat-card-elevated-container-shape, 12px);border-top-right-radius:var(--mat-card-elevated-container-shape, 12px)}.xiritable .header .buttons{padding:0 7px 0 .5rem;margin-left:-16px}.xiritable .header .buttons button{z-index:200}.xiritable .header .buttons.saveInput{padding-left:21px}.xiritable .header .middle{flex-grow:1;font-size:var(--xiri-font-size-title);display:flex;padding:0}.xiritable .header xiri-buttonline{padding:0 0 0 16px}.xiritable .header .autorefresh-indicator{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;font-size:var(--xiri-font-size-small, .8rem);color:var(--primary, var(--mat-sys-primary, #006398))}.xiritable .header .autorefresh-indicator mat-icon{font-size:18px;width:18px;height:18px;line-height:18px}.xiritable .header .autorefresh-indicator mat-icon.spin{animation:xiri-autorefresh-spin 1.5s linear infinite}.xiritable .header .lastupdated-indicator{display:inline-flex;align-items:center;padding:2px 8px;font-size:var(--xiri-font-size-small, .8rem);color:var(--on-surface-variant, #44474F);opacity:.75}@keyframes xiri-autorefresh-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.xiritable table{width:100%}.xiritable table.density-regular{--mat-table-header-container-height: 42px;--mat-table-footer-container-height: 42px;--mat-table-row-item-container-height: 42px}.xiritable table.density-compact{--mat-table-header-container-height: 32px;--mat-table-footer-container-height: 32px;--mat-table-row-item-container-height: 32px}.xiritable table.density-relaxed{--mat-table-header-container-height: 52px;--mat-table-footer-container-height: 52px;--mat-table-row-item-container-height: 52px}.xiritable table th.mat-mdc-header-cell:not(:first-of-type),.xiritable table td.mat-mdc-cell:not(:first-of-type),.xiritable table td.mat-mdc-footer-cell:not(:first-of-type){padding-left:5px}.xiritable table th.mat-mdc-header-cell:not(:last-of-type),.xiritable table td.mat-mdc-cell:not(:last-of-type),.xiritable table td.mat-mdc-footer-cell:not(:last-of-type){padding-right:7px}.xiritable table tr.mat-mdc-row{transition:background-color var(--xiri-duration-fast) var(--xiri-easing-standard)}.xiritable table tr.mat-mdc-row:hover{background:var(--surface-variant, #DEE3EB)}.xiritable table .tablelink{text-decoration:underline}.xiritable table td.buttons xiri-button,.xiritable table td.buttons xiri-buttonstyle,.xiritable table td.buttons .btnicon{margin-right:8px}.xiritable table td.buttons xiri-button:last-child,.xiritable table td.buttons xiri-buttonstyle:last-child,.xiritable table td.buttons .btnicon:last-child{margin-right:0}.xiritable table td.number,.xiritable table th.number,.xiritable table td.mat-mdc-footer-cell.number{text-align:right;font-variant-numeric:tabular-nums}.xiritable table td.right,.xiritable table td.align-right,.xiritable table th.right,.xiritable table th.align-right{text-align:right}.xiritable table td.center,.xiritable table td.align-center,.xiritable table th.center,.xiritable table th.align-center{text-align:center}.xiritable table td.left,.xiritable table td.align-left,.xiritable table th.left,.xiritable table th.align-left{text-align:left}.xiritable table td.vertical,.xiritable table th.vertical{writing-mode:sideways-rl;text-orientation:sideways}.xiritable table td.vertical div,.xiritable table th.vertical div{max-height:6rem}.xiritable table td.sideways,.xiritable table th.sideways{writing-mode:sideways-lr;text-orientation:sideways}.xiritable table td.sideways div,.xiritable table th.sideways div{max-height:6rem}.xiritable table td.upright,.xiritable table th.upright{writing-mode:vertical-rl;text-orientation:upright}.xiritable table.borders td+td{border-left:1px solid var(--outline-variant, #C2C7CF)}.xiritable table.bordersHeader th+th{border-left:1px solid var(--outline-variant, #C2C7CF)}.xiritable table td.mat-mdc-cell mat-form-field{--mat-form-field-container-height: 40px;--mat-form-field-container-vertical-padding: 8px}.xiritable .xiri-editable-cell{cursor:pointer;display:inline-flex;align-items:center;border-radius:var(--xiri-radius-xs);padding:2px 4px}.xiritable .xiri-editable-cell:hover,.xiritable .xiri-editable-cell:focus-visible{background-color:var(--surface-variant, #DEE3EB)}.xiritable .xiri-editable-cell:hover .xiri-edit-icon,.xiritable .xiri-editable-cell:focus-visible .xiri-edit-icon{opacity:1}.xiritable .xiri-edit-icon{opacity:0;font-size:14px;width:14px;height:14px;margin-left:4px;color:var(--on-surface-variant, #44474F);transition:opacity var(--xiri-duration-fast) var(--xiri-easing-standard)}.xiritable .xiri-inline-edit{--mat-form-field-container-height: 36px;--mat-form-field-container-vertical-padding: 6px;width:100%}.xiritable .xiri-inline-edit-confirm{--mdc-icon-button-icon-size: 18px;--mdc-icon-button-state-layer-size: 28px;width:28px;height:28px;padding:0;margin-right:5px;color:var(--primary, #1976d2);display:inline-flex;align-items:center;justify-content:center}.xiritable .xiri-inline-edit-confirm mat-icon{display:flex;align-items:center;justify-content:center;width:18px;height:18px;font-size:18px}.xiritable .mat-column-select{overflow:initial}.xiritable .select-buttons{padding:.3rem .8rem;display:flex;align-items:center}.xiritable .select-buttons button{margin-right:.5rem}.xiritable .xiri-cell-saved{animation:pulse .5s var(--xiri-easing-standard);border-radius:var(--xiri-radius-xs)}.xiritable .nodata{padding:.5rem 1.5rem;font-size:var(--xiri-font-size-label);background-color:var(--surface, #FFFFFF);animation:fadeInUp var(--xiri-duration-normal) var(--xiri-easing-decelerate)}.xiritable .loader{position:absolute;top:0;left:0;width:100%;bottom:0;display:flex;justify-content:center;align-items:center;background-color:var(--ripple, rgba(206, 212, 218, .5));z-index:200;border-bottom-left-radius:var(--mat-card-elevated-container-shape, 12px);border-bottom-right-radius:var(--mat-card-elevated-container-shape, 12px);animation:fadeIn var(--xiri-duration-fast) var(--xiri-easing-standard)}.xiritable .loader.has-bottombar{border-bottom-left-radius:0;border-bottom-right-radius:0}xiri-dyncomponent{margin-bottom:var(--xiri-spacing-xl)}[hidden]{display:none!important}.xiri-tree-actions{display:flex;align-items:center}td.xiri-tree-td{white-space:nowrap}td.xiri-tree-td .xiri-tree-prefix{display:inline-flex;align-items:center;vertical-align:middle}td.xiri-tree-td .xiri-tree-iconbtn{appearance:none;border:0;background:transparent;padding:0;margin:0;flex:0 0 24px;width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;border-radius:50%;cursor:pointer;-webkit-tap-highlight-color:transparent}td.xiri-tree-td .xiri-tree-iconbtn .mat-icon{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;font-size:20px;line-height:20px;margin:0}td.xiri-tree-td .xiri-tree-iconbtn:hover{background:#0000000f}td.xiri-tree-td .xiri-tree-iconbtn:focus-visible{outline:2px solid var(--primary, var(--mat-sys-primary, currentColor));outline-offset:-2px}td.xiri-tree-td .xiri-tree-spacer{width:24px;height:24px;flex:0 0 24px}td.xiri-tree-td .xiri-tree-count{margin-left:var(--xiri-spacing-xs, 4px);opacity:.6;font-size:.85em}td.xiri-tree-td .xiri-tree-addsub{margin-left:var(--xiri-spacing-xs, 4px);opacity:0;transition:opacity .15s ease-in-out}tr.mat-mdc-row:hover td.xiri-tree-td .xiri-tree-addsub,td.xiri-tree-td .xiri-tree-addsub:focus-visible{opacity:1}tr.xiri-tree-dimmed{opacity:.6}\n"], dependencies: [{ kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { 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"] }, { kind: "component", type: XiriButtonlineComponent, selector: "xiri-buttonline", inputs: ["settings", "disabled", "filterData"], outputs: ["result"] }, { kind: "component", type: XiriSearchComponent, selector: "xiri-search", inputs: ["placeholder", "open", "reset", "escape", "focus", "text"], outputs: ["changed"] }, { kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "directive", type: MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "component", type: MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "directive", type: MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "component", type: XiriButtonstyleComponent, selector: "xiri-buttonstyle", inputs: ["button", "disabled", "loading", "countdown", "pollText"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { 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: "ngmodule", type: FormsModule }, { 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.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { 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: "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: MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: XiriButtonComponent, selector: "xiri-button", inputs: ["button", "disabled", "filterData", "url"], outputs: ["result"] }, { kind: "directive", type: MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "component", type: MatFooterRow, selector: "mat-footer-row, tr[mat-footer-row]", exportAs: ["matFooterRow"] }, { kind: "directive", type: MatFooterRowDef, selector: "[matFooterRowDef]", inputs: ["matFooterRowDef", "matFooterRowDefSticky"] }, { kind: "directive", type: MatFooterCell, selector: "mat-footer-cell, td[mat-footer-cell]" }, { kind: "directive", type: MatFooterCellDef, selector: "[matFooterCellDef]" }, { kind: "component", type: MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { 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$1, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: XiriEmptyStateComponent, selector: "xiri-empty-state", inputs: ["settings"], outputs: ["buttonResult"] }, { kind: "pipe", type: DatePipe, name: "date" }, { kind: "pipe", type: SafehtmlPipe, name: "safeHtml" }, { kind: "pipe", type: XiriUrlPipe, name: "xiriUrl" }], encapsulation: i0.ViewEncapsulation.None }); }
5145
5184
  }
5146
5185
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriTableComponent, decorators: [{
5147
5186
  type: Component,
@@ -5176,7 +5215,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
5176
5215
  MatFooterRow, MatFooterRowDef, MatFooterCell, MatFooterCellDef,
5177
5216
  MatMenu, MatMenuItem, MatMenuTrigger,
5178
5217
  MatSelect, MatOption$1,
5179
- XiriEmptyStateComponent], template: "<mat-card class=\"xiritablecard mat-mdc-elevation-specific mat-elevation-z3\">\n\t<div class=\"xiritable\" [class]=\"options.class\">\n\t\t<div class=\"table-full\">\n\t\t\t@if (bulkBarActive) {\n\t\t\t\t<div class=\"xiri-bulk-bar\" [class.sticky]=\"options.stickyBulkBar\" role=\"toolbar\"\n\t\t\t\t aria-label=\"Massenaktionen\" data-testid=\"table-bulk-bar\">\n\t\t\t\t\t<button mat-icon-button (click)=\"cancelBulk()\" matTooltip=\"Auswahl aufheben\"\n\t\t\t\t\t aria-label=\"Auswahl aufheben\">\n\t\t\t\t\t\t<mat-icon>close</mat-icon>\n\t\t\t\t\t</button>\n\t\t\t\t\t<span class=\"xiri-bulk-count\" aria-live=\"polite\" data-testid=\"table-bulk-count\">\n\t\t\t\t\t\t@if (bulkAllResults()) {\n\t\t\t\t\t\t\tAlle {{ bulkTotalCount() }} Ergebnisse ausgew\u00E4hlt\n\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t{{ selection.selected.length }} ausgew\u00E4hlt\n\t\t\t\t\t\t}\n\t\t\t\t\t</span>\n\t\t\t\t\t@if (canSelectAllResults()) {\n\t\t\t\t\t\t<button mat-button color=\"primary\" (click)=\"selectAllResults()\"\n\t\t\t\t\t\t data-testid=\"table-bulk-selectall\">\n\t\t\t\t\t\t\tAlle {{ bulkTotalCount() }} Ergebnisse ausw\u00E4hlen\n\t\t\t\t\t\t</button>\n\t\t\t\t\t}\n\t\t\t\t\t<span class=\"xiri-bulk-spacer\"></span>\n\t\t\t\t\t@for (button of options.bulkActions; track button) {\n\t\t\t\t\t\t<button mat-button [color]=\"button.color || 'primary'\"\n\t\t\t\t\t\t (click)=\"bulkAction($event, button)\"\n\t\t\t\t\t\t [matTooltip]=\"button.hint\" [matTooltipDisabled]=\"!button.hint\">\n\t\t\t\t\t\t\t@if (button.icon) {\n\t\t\t\t\t\t\t\t<mat-icon>{{ button.icon }}</mat-icon>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t{{ button.text }}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t<div class=\"header\" [hidden]=\"bulkBarActive\">\n\t\t\t\t@if (options.reload) {\n\t\t\t\t\t<div class=\"buttons\">\n\t\t\t\t\t\t<button mat-icon-button (click)=\"reload()\" color=\"primary\" aria-label=\"Tabelle neu laden\">\n\t\t\t\t\t\t\t<mat-icon>autorenew</mat-icon>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t@if (autoRefresh()) {\n\t\t\t\t\t<div class=\"autorefresh-indicator\" role=\"status\" aria-live=\"polite\"\n\t\t\t\t\t matTooltip=\"Tabelle aktualisiert sich automatisch\">\n\t\t\t\t\t\t<mat-icon class=\"spin\">sync</mat-icon>\n\t\t\t\t\t\t<span>Auto-Refresh aktiv \u00B7 n\u00E4chste in {{ countdown() }}s</span>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t@if (lastUpdated(); as updated) {\n\t\t\t\t\t<div class=\"lastupdated-indicator\" data-testid=\"table-last-updated\" role=\"status\" aria-live=\"polite\">\n\t\t\t\t\t\tStand {{ updated | date:'HH:mm' }}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t@if (treeEnabled) {\n\t\t\t\t\t<div class=\"buttons xiri-tree-actions\">\n\t\t\t\t\t\t<button mat-icon-button (click)=\"expandAllNodes()\" color=\"primary\"\n\t\t\t\t\t\t matTooltip=\"Alle ausklappen\" aria-label=\"Alle ausklappen\">\n\t\t\t\t\t\t\t<mat-icon>unfold_more</mat-icon>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<button mat-icon-button (click)=\"collapseAllNodes()\" color=\"primary\"\n\t\t\t\t\t\t matTooltip=\"Alle einklappen\" aria-label=\"Alle einklappen\">\n\t\t\t\t\t\t\t<mat-icon>unfold_less</mat-icon>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t<div class=\"middle\" [class.hasButtons]=\"options.buttons\">{{ options.title }}</div>\n\t\t\t\t@if (options.buttons) {\n\t\t\t\t\t<xiri-buttonline [settings]=\"options.buttons\" (result)=\"buttonReturn($event)\"\n\t\t\t\t\t [filterData]=\"_filterData()\"></xiri-buttonline>\n\t\t\t\t}\n\t\t\t\t@if (options.search) {\n\t\t\t\t\t<xiri-search (changed)=\"searchDo($event)\" [placeholder]=\"''\" [text]=\"searchTextInit\"></xiri-search>\n\t\t\t\t}\n\t\t\t\t@if (options.saveInput) {\n\t\t\t\t\t<div class=\"buttons saveInput\">\n\t\t\t\t\t\t<button mat-raised-button (click)=\"saveInputData()\" color=\"primary\">\n\t\t\t\t\t\t\t{{ options.saveInput }}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t</div>\n\t\t\t<div class=\"tableout-wrap\">\n\t\t\t<div class=\"tableout\" [class.is-loading]=\"loading()\" [style.max-height]=\"options.scrollHeight || null\">\n\t\t\t\t<table mat-table [dataSource]=\"dataSource\" matSort [style.min-width]=\"options.minWidth ?? '100%'\"\n\t\t\t\t [class]=\"densityClass()\"\n\t\t\t\t [class.borders]=\"options.borders\" [class.bordersHeader]=\"options.bordersHeader\"\n\t\t\t\t [trackBy]=\"trackByRowId\">\n\n\t\t\t\t\t@for (column of displayedColumns; track column.id) {\n\t\t\t\t\t\t<ng-container [matColumnDef]=\"column.id\" [sticky]=\"column.sticky\">\n\t\t\t\t\t\t\t<th mat-header-cell *matHeaderCellDef mat-sort-header=\"{{ column.id }}\" [disabled]=\"!column.sort || !options.sort\" disableClear\n\t\t\t\t\t\t\t [style.width]=\"column.width\" [style.min-width]=\"column.minWidth\"\n\t\t\t\t\t\t\t [class]=\"column.display + ' ' + (column.header || '')\"> {{ column.name }}\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t@switch (column.format) {\n\t\t\t\t\t\t\t\t@case ('buttons') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t\t@for (button of column.buttons; track button; let i = $index) {\n\t\t\t\t\t\t\t\t\t\t\t@if (row[column.id][i] !== false) {\n\t\t\t\t\t\t\t\t\t\t\t\t@switch (button.action) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('link') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<xiri-button [button]=\"button\" [disabled]=\"false\" [url]=\"row[column.id][ i ]\"></xiri-button>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('href') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<xiri-button [button]=\"button\" [disabled]=\"false\" [url]=\"row[column.id][ i ]\"></xiri-button>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('download') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<xiri-button [button]=\"button\" [disabled]=\"false\" [url]=\"row[column.id][ i ]\"></xiri-button>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('dialog') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<xiri-buttonstyle [button]=\"button\" [disabled]=\"false\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t (click)=\"openDialog( $event, button, column.id, i, row)\"></xiri-buttonstyle>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('api') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<xiri-buttonstyle [button]=\"button\" [disabled]=\"false\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t (click)=\"apiCall( $event, row[column.id][ i ] )\"></xiri-buttonstyle>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('save') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<xiri-buttonstyle [button]=\"button\" (click)=\"saveCall( $event, button, row, row[column.id][ i ] )\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t [disabled]=\"!saveCallCheck( button, row )\"></xiri-buttonstyle>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('icon') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon class=\"btnicon\" [class]=\"button.color || 'primary'\" [matTooltip]=\"button.hint\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t [matTooltipDisabled]=\"!button.hint\">{{ button.icon }}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('menu') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<button mat-icon-button [matMenuTriggerFor]=\"menuRef\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t [class]=\"button.color || 'primary'\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t [matTooltip]=\"button.hint\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t [matTooltipDisabled]=\"!button.hint\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t (click)=\"$event.stopPropagation()\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon>{{ button.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-menu #menuRef=\"matMenu\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@for (item of button.menuItems; track item; let j = $index) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@if (row[column.id][i][j] !== false) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@switch (item.action) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('link') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@let menuUrl = row[column.id][i][j] | xiriUrl;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<a mat-menu-item [routerLink]=\"menuUrl?.path\" [queryParams]=\"menuUrl?.queryParams\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon [class]=\"item.color || 'primary'\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span>{{ item.text }}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('href') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<a mat-menu-item [href]=\"row[column.id][i][j]\" target=\"_blank\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon [class]=\"item.color || 'primary'\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span>{{ item.text }}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('dialog') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<button mat-menu-item (click)=\"openMenuDialog($event, item, column.id, i, j, row)\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon [class]=\"item.color || 'primary'\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span>{{ item.text }}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</mat-menu>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('icon') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t\t@if (column.icons?.[ $any(row[ column.id ]) ]; as icon) {\n\t\t\t\t\t\t\t\t\t\t\t<mat-icon [class]=\"icon[ 'color' ] || 'primary'\"\n\t\t\t\t\t\t\t\t\t\t\t [matTooltip]=\"icon[ 'hint' ] || '' \"\n\t\t\t\t\t\t\t\t\t\t\t [matTooltipDisabled]=\"!icon[ 'hint' ]\">{{ icon['icon'] }}\n\t\t\t\t\t\t\t\t\t\t\t</mat-icon>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('html') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [innerHtml]=\"row[column.id] | safeHtml\" [class]=\"column.display\"></td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('link') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\"\n\t\t\t\t\t\t\t\t\t [class.xiri-tree-td]=\"treeEnabled && column.id === treeColumnId\">\n\t\t\t\t\t\t\t\t\t\t@if (treeEnabled && column.id === treeColumnId) {\n\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"treePrefix; context: { $implicit: row }\"></ng-container>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t@if (row[column.id + 'Link']) {\n\t\t\t\t\t\t\t\t\t\t\t@let cellUrl = row[column.id + 'Link'] | xiriUrl;\n\t\t\t\t\t\t\t\t\t\t\t<a [routerLink]=\"cellUrl?.path\" [queryParams]=\"cellUrl?.queryParams\" class=\"tablelink\">{{ row[column.id] }}</a>\n\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t<span>{{ row[column.id] }}</span>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t@if (treeEnabled && column.id === treeColumnId) {\n\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"treeSuffix; context: { $implicit: row }\"></ng-container>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('input') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t\t<mat-form-field subscriptSizing=\"dynamic\">\n\t\t\t\t\t\t\t\t\t\t\t<input matInput\n\t\t\t\t\t\t\t\t\t\t\t [type]=\"column.inputType || 'text'\"\n\t\t\t\t\t\t\t\t\t\t\t [(ngModel)]=\"row[ column.id ]\"\n\t\t\t\t\t\t\t\t\t\t\t [lang]=\"column.inputLang || ''\"\n\t\t\t\t\t\t\t\t\t\t\t [required]=\"column.inputRequired || true\"\n\t\t\t\t\t\t\t\t\t\t\t (paste)=\"pasteInput( $event, row, column )\">\n\t\t\t\t\t\t\t\t\t\t</mat-form-field>\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('text2') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t\t<div>{{ row[column.id][0] }}</div>\n\t\t\t\t\t\t\t\t\t\t<div>{{ row[column.id][1] }}</div>\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('textn') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t\t@for (line of row[column.id]; track $index) {\n\t\t\t\t\t\t\t\t\t\t\t<div>{{ line }}</div>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('number') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t\t{{ column.textPrefix }}{{ row[column.id][0] }}{{ column.textSuffix }}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('chips') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t\t@if (isSaving(row, column.id)) {\n\t\t\t\t\t\t\t\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t\t\t\t\t\t\t\t} @else if (column.editable && options.editUrl && isEditing(row, column.id)) {\n\t\t\t\t\t\t\t\t\t\t\t@if (editableOptionsLoading()) {\n\t\t\t\t\t\t\t\t\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t\t<mat-form-field class=\"xiri-inline-edit\" subscriptSizing=\"dynamic\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-select multiple\n\t\t\t\t\t\t\t\t\t\t\t\t\t [ngModel]=\"editingChipsValues()\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t (selectionChange)=\"onChipsSelectionChange(row, column, $event.value)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t (keydown)=\"onInlineEditKeydown($event, row, column)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t (openedChange)=\"!$event && saveInlineEdit(row, column)\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t@if (column.editableOptionsSearch || column.editableSearchUrl) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-option>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<ngx-mat-select-search [formControl]=\"inlineSearchControl\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t [searching]=\"inlineSearching()\"></ngx-mat-select-search>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</mat-option>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t@for (opt of getEditableOptions(column); track opt.value) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-option [value]=\"opt.value\">{{ opt.label }}</mat-option>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</mat-select>\n\t\t\t\t\t\t\t\t\t\t\t\t</mat-form-field>\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t} @else if (column.editable && options.editUrl) {\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"xiri-editable-cell\" role=\"button\" tabindex=\"0\"\n\t\t\t\t\t\t\t\t\t\t\t (click)=\"startInlineEdit(row, column); $event.stopPropagation()\"\n\t\t\t\t\t\t\t\t\t\t\t (keydown.enter)=\"startInlineEdit(row, column); $event.stopPropagation()\">\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"xiri-chips-display\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t@for (chip of row[column.id]; track chip.label) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"xiri-chip-display\" [class]=\"chip.color || ''\">{{ chip.label }}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon class=\"xiri-edit-icon\">edit</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"xiri-chips-display\">\n\t\t\t\t\t\t\t\t\t\t\t\t@for (chip of row[column.id]; track chip.label) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"xiri-chip-display\" [class]=\"chip.color || ''\">{{ chip.label }}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@default {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\"\n\t\t\t\t\t\t\t\t\t [class.xiri-tree-td]=\"treeEnabled && column.id === treeColumnId\">\n\t\t\t\t\t\t\t\t\t\t@if (treeEnabled && column.id === treeColumnId) {\n\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"treePrefix; context: { $implicit: row }\"></ng-container>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t@if (isSaving(row, column.id)) {\n\t\t\t\t\t\t\t\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t\t\t\t\t\t\t\t} @else if (column.editable && options.editUrl && isEditing(row, column.id)) {\n\t\t\t\t\t\t\t\t\t\t\t@if (column.editableOptions || column.editableOptionsUrl || column.editableSearchUrl) {\n\t\t\t\t\t\t\t\t\t\t\t\t@if (editableOptionsLoading()) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-form-field class=\"xiri-inline-edit\" subscriptSizing=\"dynamic\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-select [(ngModel)]=\"row[column.id]\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t (keydown)=\"onInlineEditKeydown($event, row, column)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t (openedChange)=\"!$event && saveInlineEdit(row, column)\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@if (column.editableOptionsSearch || column.editableSearchUrl) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-option>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<ngx-mat-select-search [formControl]=\"inlineSearchControl\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t [searching]=\"inlineSearching()\"></ngx-mat-select-search>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</mat-option>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@for (opt of getEditableOptions(column); track opt.value) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-option [value]=\"opt.value\">{{ opt.label }}</mat-option>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</mat-select>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</mat-form-field>\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t\t<mat-form-field class=\"xiri-inline-edit\" subscriptSizing=\"dynamic\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<input matInput\n\t\t\t\t\t\t\t\t\t\t\t\t\t [(ngModel)]=\"row[column.id]\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t (blur)=\"saveInlineEdit(row, column)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t (keydown)=\"onInlineEditKeydown($event, row, column)\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<button matSuffix mat-icon-button class=\"xiri-inline-edit-confirm\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t (mousedown)=\"$event.preventDefault(); saveInlineEdit(row, column)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t tabindex=\"-1\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon>check</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t\t\t</mat-form-field>\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t} @else if (column.editable && options.editUrl) {\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"xiri-editable-cell\" role=\"button\" tabindex=\"0\"\n\t\t\t\t\t\t\t\t\t\t\t (click)=\"startInlineEdit(row, column); $event.stopPropagation()\"\n\t\t\t\t\t\t\t\t\t\t\t (keydown.enter)=\"startInlineEdit(row, column); $event.stopPropagation()\">\n\t\t\t\t\t\t\t\t\t\t\t\t{{ column.textPrefix }}{{ row[column.id] }}{{ column.textSuffix }}\n\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon class=\"xiri-edit-icon\">edit</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t{{ column.textPrefix }}{{ row[column.id] }}{{ column.textSuffix }}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t@if (treeEnabled && column.id === treeColumnId) {\n\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"treeSuffix; context: { $implicit: row }\"></ng-container>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t<td mat-footer-cell *matFooterCellDef [hidden]=\"!options.footer\"\n\t\t\t\t\t\t\t [style.width]=\"column.width\" [style.min-width]=\"column.minWidth\" class=\"bottomrow\"\n\t\t\t\t\t\t\t [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t@if ( footer[ column.id ] ) {\n\t\t\t\t\t\t\t\t\t\t{{ column.textPrefix }}{{ footer[ column.id ] }}{{ column.textSuffix }}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t\t@if (showSelectColumn) {\n\t\t\t\t\t\t<ng-container matColumnDef=\"select\" [sticky]=\"true\">\n\t\t\t\t\t\t\t<th mat-header-cell *matHeaderCellDef [style.width]=\"'65px'\">\n\t\t\t\t\t\t\t\t<mat-checkbox (change)=\"$event ? masterToggle() : null\"\n\t\t\t\t\t\t\t\t [checked]=\"selection.hasValue() && isAllSelected()\"\n\t\t\t\t\t\t\t\t [indeterminate]=\"selection.hasValue() && !isAllSelected()\">\n\t\t\t\t\t\t\t\t</mat-checkbox>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\">\n\t\t\t\t\t\t\t\t@if (isSelectable(row)) {\n\t\t\t\t\t\t\t\t\t<mat-checkbox\n\t\t\t\t\t\t\t\t\t\t\t(click)=\"$event.stopPropagation()\"\n\t\t\t\t\t\t\t\t\t\t\t(change)=\"$event ? toggleRow(row) : null\"\n\t\t\t\t\t\t\t\t\t\t\t[checked]=\"selection.isSelected(row)\">\n\t\t\t\t\t\t\t\t\t</mat-checkbox>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td mat-footer-cell *matFooterCellDef [style.width]=\"'65px'\" class=\"bottomrow\" [hidden]=\"!options.footer\">\n\t\t\t\t\t\t\t\t<mat-checkbox (change)=\"$event ? masterToggle() : null\"\n\t\t\t\t\t\t\t\t [checked]=\"selection.hasValue() && isAllSelected()\"\n\t\t\t\t\t\t\t\t [indeterminate]=\"selection.hasValue() && !isAllSelected()\">\n\t\t\t\t\t\t\t\t</mat-checkbox>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\n\t\t\t\t\t@if (extraHeaderFields.length > 0) {\n\t\t\t\t\t\t@for (column of extraHeaderFields; track column.id) {\n\t\t\t\t\t\t\t<ng-container matColumnDef=\"{{ column.id }}\" [sticky]=\"column.sticky\">\n\t\t\t\t\t\t\t\t<th mat-header-cell *matHeaderCellDef [attr.colspan]=\"column.headerSpan\">{{ column.name }}</th>\n\t\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t<tr mat-header-row *matHeaderRowDef=\"extraHeaders; sticky: true\" [class.dense]=\"options.dense\"></tr>\n\t\t\t\t\t}\n\n\t\t\t\t\t<tr mat-header-row *matHeaderRowDef=\"columnsToDisplay; sticky: true\" [class.dense]=\"options.dense\"></tr>\n\t\t\t\t\t<tr mat-row *matRowDef=\"let row; columns: columnsToDisplay;\" (click)=\"clicked(row)\"\n\t\t\t\t\t [class.xiri-tree-dimmed]=\"treeEnabled && row._tree?.dimmed\"></tr>\n\t\t\t\t\t<tr mat-footer-row *matFooterRowDef=\"columnsToDisplay; sticky: true\" [hidden]=\"!options.footer\"></tr>\n\t\t\t\t</table>\n\t\t\t</div>\n\t\t\t<div class=\"loader\" [hidden]=\"!loading()\" [class.has-bottombar]=\"(options.select || options.pagination) && !options.footer\">\n\t\t\t\t<mat-spinner diameter=\"30\"></mat-spinner>\n\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t@if (!loading()) {\n\t\t\t\t@if (!errorMsg && dataSource.filteredData.length === 0) {\n\t\t\t\t\t@if (options.emptyState) {\n\t\t\t\t\t\t<xiri-empty-state [settings]=\"options.emptyState\"></xiri-empty-state>\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<div class=\"nodata\">{{ options.textNoData }}</div>\n\t\t\t\t\t}\n\t\t\t\t} @else if (errorMsg) {\n\t\t\t\t\t<div class=\"alert alert-danger\">\n\t\t\t\t\t\t<span>{{ errorMsg }}</span>\n\t\t\t\t\t\t<button mat-button type=\"button\" data-testid=\"table-retry\" (click)=\"reload()\">\n\t\t\t\t\t\t\t<mat-icon>autorenew</mat-icon> Retry\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t<div class=\"xrow xsmall\" [class.bottomrow]=\"(options.select || options.pagination) && !options.footer\">\n\t\t\t\t@if (options.select) {\n\t\t\t\t\t<div class=\"xcol xcol-md-2 select-buttons\">\n\t\t\t\t\t\t@for (button of options.selectButtons; track button) {\n\t\t\t\t\t\t\t@switch (button.action) {\n\t\t\t\t\t\t\t\t@case ('dialog') {\n\t\t\t\t\t\t\t\t\t<button mat-icon-button\n\t\t\t\t\t\t\t\t\t (click)=\"openDialogSelection( $event, button )\"\n\t\t\t\t\t\t\t\t\t [disabled]=\"selection.isEmpty()\"\n\t\t\t\t\t\t\t\t\t [color]=\"button.color || 'primary'\"\n\t\t\t\t\t\t\t\t\t [matTooltip]=\"button.hint\"\n\t\t\t\t\t\t\t\t\t [matTooltipDisabled]=\"!button.hint\">\n\t\t\t\t\t\t\t\t\t\t<mat-icon>{{ button.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('api') {\n\t\t\t\t\t\t\t\t\t<button mat-icon-button\n\t\t\t\t\t\t\t\t\t (click)=\"apiCallSelection( $event, button )\"\n\t\t\t\t\t\t\t\t\t [disabled]=\"selection.isEmpty()\"\n\t\t\t\t\t\t\t\t\t [color]=\"button.color || 'primary'\"\n\t\t\t\t\t\t\t\t\t [matTooltip]=\"button.hint\"\n\t\t\t\t\t\t\t\t\t [matTooltipDisabled]=\"!button.hint\">\n\t\t\t\t\t\t\t\t\t\t<mat-icon>{{ button.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('download') {\n\t\t\t\t\t\t\t\t\t<button mat-icon-button\n\t\t\t\t\t\t\t\t\t (click)=\"downloadSelection( $event, button )\"\n\t\t\t\t\t\t\t\t\t [disabled]=\"selection.isEmpty()\"\n\t\t\t\t\t\t\t\t\t [color]=\"button.color || 'primary'\"\n\t\t\t\t\t\t\t\t\t [matTooltip]=\"button.hint\"\n\t\t\t\t\t\t\t\t\t [matTooltipDisabled]=\"!button.hint\">\n\t\t\t\t\t\t\t\t\t\t<mat-icon>{{ button.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t<div class=\"xcol xcol-right-md-10\">\n\t\t\t\t\t<mat-paginator [hidden]=\"!options.pagination\" [pageSizeOptions]=\"options.pageSizes || []\" showFirstLastButtons=\"true\"></mat-paginator>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</mat-card>\n\n@if (dynData.data) {\n\t<ng-container *ngTemplateOutlet=\"dyncomponent(); context: { $implicit: dynData }\"></ng-container>\n}\n\n<!-- Tree mode: indent + expand/collapse arrow rendered before the tree column's content -->\n<ng-template #treePrefix let-row>\n\t<span class=\"xiri-tree-prefix\" [style.padding-left.px]=\"(row._tree?.level || 0) * 24\">\n\t\t@if (row._tree?.hasChildren) {\n\t\t\t<button type=\"button\" class=\"xiri-tree-iconbtn xiri-tree-toggle\" (click)=\"toggleNode($event, row)\"\n\t\t\t tabindex=\"-1\" [attr.aria-label]=\"row._tree.expanded ? 'einklappen' : 'ausklappen'\">\n\t\t\t\t<mat-icon color=\"primary\">{{ row._tree.expanded ? 'expand_more' : 'chevron_right' }}</mat-icon>\n\t\t\t</button>\n\t\t} @else {\n\t\t\t<span class=\"xiri-tree-spacer\"></span>\n\t\t}\n\t</span>\n</ng-template>\n\n<!-- Tree mode: child-count badge (when collapsed) + optional \"+ sub\" button after the content -->\n<ng-template #treeSuffix let-row>\n\t@if (treeShowCounts && row._tree && !row._tree.expanded && row._tree.childCount > 0) {\n\t\t<span class=\"xiri-tree-count\">({{ row._tree.childCount }})</span>\n\t}\n\t@if (treeHasAddSub && treeCanAddSub(row)) {\n\t\t<button type=\"button\" class=\"xiri-tree-iconbtn xiri-tree-addsub\" (click)=\"addSub($event, row)\"\n\t\t tabindex=\"-1\" matTooltip=\"Sub-Eintrag hinzuf\u00FCgen\" aria-label=\"Sub-Eintrag hinzuf\u00FCgen\">\n\t\t\t<mat-icon color=\"primary\">add</mat-icon>\n\t\t</button>\n\t}\n</ng-template>\n", styles: ["mat-card.xiritablecard{padding:0;margin-bottom:var(--xiri-spacing-xl)}.xiritable{width:100%;overflow:auto}.xiritable.canbreak{word-break:break-all}.xiritable .table-full{display:inline-block;width:100%}.xiritable .table-full .xiri-bulk-bar{display:flex;align-items:center;gap:var(--xiri-spacing-sm);padding:var(--xiri-spacing-xs) var(--xiri-spacing-sm);background:var(--mat-sys-secondary-container, #e0e0e0);color:var(--mat-sys-on-secondary-container, inherit);border-radius:var(--xiri-radius-sm, 4px);margin-bottom:var(--xiri-spacing-xs)}.xiritable .table-full .xiri-bulk-bar.sticky{position:sticky;top:0;z-index:5}.xiritable .table-full .xiri-bulk-bar .xiri-bulk-count{font-weight:500}.xiritable .table-full .xiri-bulk-bar .xiri-bulk-spacer{flex:1 1 auto}.xiritable .table-full .tableout-wrap{position:relative}.xiritable .table-full .tableout{max-height:60vh;overflow-y:auto;width:100%;min-width:100%;max-width:100%}.xiritable .table-full .tableout.is-loading{min-height:100px}.xiritable .table-full .alert{padding:var(--xiri-spacing-md)}.xiritable .table-full mat-paginator{--mat-paginator-container-background-color: transparent;--mat-paginator-container-size: 51px;--mat-form-field-container-height: 32px;--mat-form-field-container-vertical-padding: 4px}.xiritable .table-full .bottomrow{border-top:1px solid var(--outline-variant, #C2C7CF)}.xiritable .table-full div.bottomrow{background-color:var(--surface-container, #F3F3F6);border-bottom-left-radius:var(--mat-card-elevated-container-shape, 12px);border-bottom-right-radius:var(--mat-card-elevated-container-shape, 12px)}.xiritable .header{background-color:var(--surface-container, #F3F3F6);display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;min-height:51px;padding:0 16px;border-bottom:1px solid var(--outline-variant, #C2C7CF);border-top-left-radius:var(--mat-card-elevated-container-shape, 12px);border-top-right-radius:var(--mat-card-elevated-container-shape, 12px)}.xiritable .header .buttons{padding:0 7px 0 .5rem;margin-left:-16px}.xiritable .header .buttons button{z-index:200}.xiritable .header .buttons.saveInput{padding-left:21px}.xiritable .header .middle{flex-grow:1;font-size:var(--xiri-font-size-title);display:flex;padding:0}.xiritable .header xiri-buttonline{padding:0 0 0 16px}.xiritable .header .autorefresh-indicator{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;font-size:var(--xiri-font-size-small, .8rem);color:var(--mat-sys-primary, var(--primary, #006398))}.xiritable .header .autorefresh-indicator mat-icon{font-size:18px;width:18px;height:18px;line-height:18px}.xiritable .header .autorefresh-indicator mat-icon.spin{animation:xiri-autorefresh-spin 1.5s linear infinite}.xiritable .header .lastupdated-indicator{display:inline-flex;align-items:center;padding:2px 8px;font-size:var(--xiri-font-size-small, .8rem);color:var(--on-surface-variant, #44474F);opacity:.75}@keyframes xiri-autorefresh-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.xiritable table{width:100%}.xiritable table.density-regular{--mat-table-header-container-height: 42px;--mat-table-footer-container-height: 42px;--mat-table-row-item-container-height: 42px}.xiritable table.density-compact{--mat-table-header-container-height: 32px;--mat-table-footer-container-height: 32px;--mat-table-row-item-container-height: 32px}.xiritable table.density-relaxed{--mat-table-header-container-height: 52px;--mat-table-footer-container-height: 52px;--mat-table-row-item-container-height: 52px}.xiritable table th.mat-mdc-header-cell:not(:first-of-type),.xiritable table td.mat-mdc-cell:not(:first-of-type),.xiritable table td.mat-mdc-footer-cell:not(:first-of-type){padding-left:5px}.xiritable table th.mat-mdc-header-cell:not(:last-of-type),.xiritable table td.mat-mdc-cell:not(:last-of-type),.xiritable table td.mat-mdc-footer-cell:not(:last-of-type){padding-right:7px}.xiritable table tr.mat-mdc-row{transition:background-color var(--xiri-duration-fast) var(--xiri-easing-standard)}.xiritable table tr.mat-mdc-row:hover{background:var(--surface-variant, #DEE3EB)}.xiritable table .tablelink{text-decoration:underline}.xiritable table td.buttons xiri-button,.xiritable table td.buttons xiri-buttonstyle,.xiritable table td.buttons .btnicon{margin-right:8px}.xiritable table td.buttons xiri-button:last-child,.xiritable table td.buttons xiri-buttonstyle:last-child,.xiritable table td.buttons .btnicon:last-child{margin-right:0}.xiritable table td.number,.xiritable table th.number,.xiritable table td.mat-mdc-footer-cell.number{text-align:right;font-variant-numeric:tabular-nums}.xiritable table td.right,.xiritable table td.align-right,.xiritable table th.right,.xiritable table th.align-right{text-align:right}.xiritable table td.center,.xiritable table td.align-center,.xiritable table th.center,.xiritable table th.align-center{text-align:center}.xiritable table td.left,.xiritable table td.align-left,.xiritable table th.left,.xiritable table th.align-left{text-align:left}.xiritable table td.vertical,.xiritable table th.vertical{writing-mode:sideways-rl;text-orientation:sideways}.xiritable table td.vertical div,.xiritable table th.vertical div{max-height:6rem}.xiritable table td.sideways,.xiritable table th.sideways{writing-mode:sideways-lr;text-orientation:sideways}.xiritable table td.sideways div,.xiritable table th.sideways div{max-height:6rem}.xiritable table td.upright,.xiritable table th.upright{writing-mode:vertical-rl;text-orientation:upright}.xiritable table.borders td+td{border-left:1px solid var(--outline-variant, #C2C7CF)}.xiritable table.bordersHeader th+th{border-left:1px solid var(--outline-variant, #C2C7CF)}.xiritable table td.mat-mdc-cell mat-form-field{--mat-form-field-container-height: 40px;--mat-form-field-container-vertical-padding: 8px}.xiritable .xiri-editable-cell{cursor:pointer;display:inline-flex;align-items:center;border-radius:var(--xiri-radius-xs);padding:2px 4px}.xiritable .xiri-editable-cell:hover,.xiritable .xiri-editable-cell:focus-visible{background-color:var(--surface-variant, #DEE3EB)}.xiritable .xiri-editable-cell:hover .xiri-edit-icon,.xiritable .xiri-editable-cell:focus-visible .xiri-edit-icon{opacity:1}.xiritable .xiri-edit-icon{opacity:0;font-size:14px;width:14px;height:14px;margin-left:4px;color:var(--on-surface-variant, #44474F);transition:opacity var(--xiri-duration-fast) var(--xiri-easing-standard)}.xiritable .xiri-inline-edit{--mat-form-field-container-height: 36px;--mat-form-field-container-vertical-padding: 6px;width:100%}.xiritable .xiri-inline-edit-confirm{--mdc-icon-button-icon-size: 18px;--mdc-icon-button-state-layer-size: 28px;width:28px;height:28px;padding:0;margin-right:5px;color:var(--primary, #1976d2);display:inline-flex;align-items:center;justify-content:center}.xiritable .xiri-inline-edit-confirm mat-icon{display:flex;align-items:center;justify-content:center;width:18px;height:18px;font-size:18px}.xiritable .mat-column-select{overflow:initial}.xiritable .select-buttons{padding:.3rem .8rem;display:flex;align-items:center}.xiritable .select-buttons button{margin-right:.5rem}.xiritable .xiri-cell-saved{animation:pulse .5s var(--xiri-easing-standard);border-radius:var(--xiri-radius-xs)}.xiritable .nodata{padding:.5rem 1.5rem;font-size:var(--xiri-font-size-label);background-color:var(--surface, #FFFFFF);animation:fadeInUp var(--xiri-duration-normal) var(--xiri-easing-decelerate)}.xiritable .loader{position:absolute;top:0;left:0;width:100%;bottom:0;display:flex;justify-content:center;align-items:center;background-color:var(--ripple, rgba(206, 212, 218, .5));z-index:200;border-bottom-left-radius:var(--mat-card-elevated-container-shape, 12px);border-bottom-right-radius:var(--mat-card-elevated-container-shape, 12px);animation:fadeIn var(--xiri-duration-fast) var(--xiri-easing-standard)}.xiritable .loader.has-bottombar{border-bottom-left-radius:0;border-bottom-right-radius:0}xiri-dyncomponent{margin-bottom:var(--xiri-spacing-xl)}[hidden]{display:none!important}.xiri-tree-actions{display:flex;align-items:center}td.xiri-tree-td{white-space:nowrap}td.xiri-tree-td .xiri-tree-prefix{display:inline-flex;align-items:center;vertical-align:middle}td.xiri-tree-td .xiri-tree-iconbtn{appearance:none;border:0;background:transparent;padding:0;margin:0;flex:0 0 24px;width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;border-radius:50%;cursor:pointer;-webkit-tap-highlight-color:transparent}td.xiri-tree-td .xiri-tree-iconbtn .mat-icon{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;font-size:20px;line-height:20px;margin:0}td.xiri-tree-td .xiri-tree-iconbtn:hover{background:#0000000f}td.xiri-tree-td .xiri-tree-iconbtn:focus-visible{outline:2px solid var(--mat-sys-primary, currentColor);outline-offset:-2px}td.xiri-tree-td .xiri-tree-spacer{width:24px;height:24px;flex:0 0 24px}td.xiri-tree-td .xiri-tree-count{margin-left:var(--xiri-spacing-xs, 4px);opacity:.6;font-size:.85em}td.xiri-tree-td .xiri-tree-addsub{margin-left:var(--xiri-spacing-xs, 4px);opacity:0;transition:opacity .15s ease-in-out}tr.mat-mdc-row:hover td.xiri-tree-td .xiri-tree-addsub,td.xiri-tree-td .xiri-tree-addsub:focus-visible{opacity:1}tr.xiri-tree-dimmed{opacity:.6}\n"] }]
5218
+ XiriEmptyStateComponent], template: "<mat-card class=\"xiritablecard mat-mdc-elevation-specific mat-elevation-z3\">\n\t<div class=\"xiritable\" [class]=\"options.class\">\n\t\t<div class=\"table-full\">\n\t\t\t@if (bulkBarActive) {\n\t\t\t\t<div class=\"xiri-bulk-bar\" [class.sticky]=\"options.stickyBulkBar\" role=\"toolbar\"\n\t\t\t\t aria-label=\"Massenaktionen\" data-testid=\"table-bulk-bar\">\n\t\t\t\t\t<button mat-icon-button (click)=\"cancelBulk()\" matTooltip=\"Auswahl aufheben\"\n\t\t\t\t\t aria-label=\"Auswahl aufheben\">\n\t\t\t\t\t\t<mat-icon>close</mat-icon>\n\t\t\t\t\t</button>\n\t\t\t\t\t<span class=\"xiri-bulk-count\" aria-live=\"polite\" data-testid=\"table-bulk-count\">\n\t\t\t\t\t\t@if (bulkAllResults()) {\n\t\t\t\t\t\t\tAlle {{ bulkTotalCount() }} Ergebnisse ausgew\u00E4hlt\n\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t{{ selection.selected.length }} ausgew\u00E4hlt\n\t\t\t\t\t\t}\n\t\t\t\t\t</span>\n\t\t\t\t\t@if (canSelectAllResults()) {\n\t\t\t\t\t\t<button mat-button color=\"primary\" (click)=\"selectAllResults()\"\n\t\t\t\t\t\t data-testid=\"table-bulk-selectall\">\n\t\t\t\t\t\t\tAlle {{ bulkTotalCount() }} Ergebnisse ausw\u00E4hlen\n\t\t\t\t\t\t</button>\n\t\t\t\t\t}\n\t\t\t\t\t<span class=\"xiri-bulk-spacer\"></span>\n\t\t\t\t\t@for (button of options.bulkActions; track button) {\n\t\t\t\t\t\t@if (!button.hide) {\n\t\t\t\t\t\t\t<button mat-button [color]=\"button.color || 'primary'\"\n\t\t\t\t\t\t\t (click)=\"bulkAction($event, button)\"\n\t\t\t\t\t\t\t [matTooltip]=\"button.hint\" [matTooltipDisabled]=\"!button.hint\">\n\t\t\t\t\t\t\t\t@if (button.icon) {\n\t\t\t\t\t\t\t\t\t<mat-icon>{{ button.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t{{ button.text }}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t<div class=\"header\" [hidden]=\"bulkBarActive\">\n\t\t\t\t@if (options.reload) {\n\t\t\t\t\t<div class=\"buttons\">\n\t\t\t\t\t\t<button mat-icon-button (click)=\"reload()\" color=\"primary\" aria-label=\"Tabelle neu laden\">\n\t\t\t\t\t\t\t<mat-icon>autorenew</mat-icon>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t@if (autoRefresh()) {\n\t\t\t\t\t<div class=\"autorefresh-indicator\" role=\"status\" aria-live=\"polite\"\n\t\t\t\t\t matTooltip=\"Tabelle aktualisiert sich automatisch\">\n\t\t\t\t\t\t<mat-icon class=\"spin\">sync</mat-icon>\n\t\t\t\t\t\t<span>Auto-Refresh aktiv \u00B7 n\u00E4chste in {{ countdown() }}s</span>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t@if (lastUpdated(); as updated) {\n\t\t\t\t\t<div class=\"lastupdated-indicator\" data-testid=\"table-last-updated\" role=\"status\" aria-live=\"polite\">\n\t\t\t\t\t\tStand {{ updated | date:'HH:mm' }}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t@if (treeEnabled) {\n\t\t\t\t\t<div class=\"buttons xiri-tree-actions\">\n\t\t\t\t\t\t<button mat-icon-button (click)=\"expandAllNodes()\" color=\"primary\"\n\t\t\t\t\t\t matTooltip=\"Alle ausklappen\" aria-label=\"Alle ausklappen\">\n\t\t\t\t\t\t\t<mat-icon>unfold_more</mat-icon>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<button mat-icon-button (click)=\"collapseAllNodes()\" color=\"primary\"\n\t\t\t\t\t\t matTooltip=\"Alle einklappen\" aria-label=\"Alle einklappen\">\n\t\t\t\t\t\t\t<mat-icon>unfold_less</mat-icon>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t<div class=\"middle\" [class.hasButtons]=\"options.buttons\">{{ options.title }}</div>\n\t\t\t\t@if (options.buttons) {\n\t\t\t\t\t<xiri-buttonline [settings]=\"options.buttons\" (result)=\"buttonReturn($event)\"\n\t\t\t\t\t [filterData]=\"_filterData()\"></xiri-buttonline>\n\t\t\t\t}\n\t\t\t\t@if (options.search) {\n\t\t\t\t\t<xiri-search (changed)=\"searchDo($event)\" [placeholder]=\"''\" [text]=\"searchTextInit\"></xiri-search>\n\t\t\t\t}\n\t\t\t\t@if (options.saveInput) {\n\t\t\t\t\t<div class=\"buttons saveInput\">\n\t\t\t\t\t\t<button mat-raised-button (click)=\"saveInputData()\" color=\"primary\">\n\t\t\t\t\t\t\t{{ options.saveInput }}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t</div>\n\t\t\t<div class=\"tableout-wrap\">\n\t\t\t<div class=\"tableout\" [class.is-loading]=\"loading()\" [style.max-height]=\"options.scrollHeight || null\">\n\t\t\t\t<table mat-table [dataSource]=\"dataSource\" matSort [style.min-width]=\"options.minWidth ?? '100%'\"\n\t\t\t\t [class]=\"densityClass()\"\n\t\t\t\t [class.borders]=\"options.borders\" [class.bordersHeader]=\"options.bordersHeader\"\n\t\t\t\t [trackBy]=\"trackByRowId\">\n\n\t\t\t\t\t@for (column of displayedColumns; track column.id) {\n\t\t\t\t\t\t<ng-container [matColumnDef]=\"column.id\" [sticky]=\"column.sticky\">\n\t\t\t\t\t\t\t<th mat-header-cell *matHeaderCellDef mat-sort-header=\"{{ column.id }}\" [disabled]=\"!column.sort || !options.sort\" disableClear\n\t\t\t\t\t\t\t [style.width]=\"column.width\" [style.min-width]=\"column.minWidth\"\n\t\t\t\t\t\t\t [class]=\"column.display + ' ' + (column.header || '')\"> {{ column.name }}\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t@switch (column.format) {\n\t\t\t\t\t\t\t\t@case ('buttons') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t\t@for (button of column.buttons; track button; let i = $index) {\n\t\t\t\t\t\t\t\t\t\t\t@if (row[column.id][i] !== false && !button.hide) {\n\t\t\t\t\t\t\t\t\t\t\t\t@switch (button.action) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('link') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<xiri-button [button]=\"button\" [disabled]=\"false\" [url]=\"row[column.id][ i ]\"></xiri-button>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('href') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<xiri-button [button]=\"button\" [disabled]=\"false\" [url]=\"row[column.id][ i ]\"></xiri-button>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('download') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<xiri-button [button]=\"button\" [disabled]=\"false\" [url]=\"row[column.id][ i ]\"></xiri-button>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('dialog') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<xiri-buttonstyle [button]=\"button\" [disabled]=\"false\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t (click)=\"openDialog( $event, button, column.id, i, row)\"></xiri-buttonstyle>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('api') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<xiri-buttonstyle [button]=\"button\" [disabled]=\"false\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t (click)=\"apiCall( $event, row[column.id][ i ] )\"></xiri-buttonstyle>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('save') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<xiri-buttonstyle [button]=\"button\" (click)=\"saveCall( $event, button, row, row[column.id][ i ] )\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t [disabled]=\"!saveCallCheck( button, row )\"></xiri-buttonstyle>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('icon') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon class=\"btnicon\" [class]=\"button.color || 'primary'\" [matTooltip]=\"button.hint\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t [matTooltipDisabled]=\"!button.hint\">{{ button.icon }}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('menu') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<button mat-icon-button [matMenuTriggerFor]=\"menuRef\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t [class]=\"button.color || 'primary'\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t [matTooltip]=\"button.hint\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t [matTooltipDisabled]=\"!button.hint\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t [attr.aria-label]=\"button.hint || button.text\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t (click)=\"$event.stopPropagation()\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon>{{ button.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-menu #menuRef=\"matMenu\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@for (item of button.menuItems; track item; let j = $index) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@if (row[column.id][i][j] !== false) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@switch (item.action) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('link') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@let menuUrl = row[column.id][i][j] | xiriUrl;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<a mat-menu-item [routerLink]=\"menuUrl?.path\" [queryParams]=\"menuUrl?.queryParams\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon [class]=\"item.color || 'primary'\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span>{{ item.text }}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('href') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<a mat-menu-item [href]=\"row[column.id][i][j]\" target=\"_blank\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon [class]=\"item.color || 'primary'\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span>{{ item.text }}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@case ('dialog') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<button mat-menu-item (click)=\"openMenuDialog($event, item, column.id, i, j, row)\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon [class]=\"item.color || 'primary'\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span>{{ item.text }}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</mat-menu>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('icon') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t\t@if (column.icons?.[ $any(row[ column.id ]) ]; as icon) {\n\t\t\t\t\t\t\t\t\t\t\t<mat-icon [class]=\"icon[ 'color' ] || 'primary'\"\n\t\t\t\t\t\t\t\t\t\t\t [matTooltip]=\"icon[ 'hint' ] || '' \"\n\t\t\t\t\t\t\t\t\t\t\t [matTooltipDisabled]=\"!icon[ 'hint' ]\">{{ icon['icon'] }}\n\t\t\t\t\t\t\t\t\t\t\t</mat-icon>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('html') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [innerHtml]=\"row[column.id] | safeHtml\" [class]=\"column.display\"></td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('link') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\"\n\t\t\t\t\t\t\t\t\t [class.xiri-tree-td]=\"treeEnabled && column.id === treeColumnId\">\n\t\t\t\t\t\t\t\t\t\t@if (treeEnabled && column.id === treeColumnId) {\n\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"treePrefix; context: { $implicit: row }\"></ng-container>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t@if (row[column.id + 'Link']) {\n\t\t\t\t\t\t\t\t\t\t\t@let cellUrl = row[column.id + 'Link'] | xiriUrl;\n\t\t\t\t\t\t\t\t\t\t\t<a [routerLink]=\"cellUrl?.path\" [queryParams]=\"cellUrl?.queryParams\" class=\"tablelink\">{{ row[column.id] }}</a>\n\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t<span>{{ row[column.id] }}</span>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t@if (treeEnabled && column.id === treeColumnId) {\n\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"treeSuffix; context: { $implicit: row }\"></ng-container>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('input') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t\t<mat-form-field subscriptSizing=\"dynamic\">\n\t\t\t\t\t\t\t\t\t\t\t<input matInput\n\t\t\t\t\t\t\t\t\t\t\t [type]=\"column.inputType || 'text'\"\n\t\t\t\t\t\t\t\t\t\t\t [(ngModel)]=\"row[ column.id ]\"\n\t\t\t\t\t\t\t\t\t\t\t [lang]=\"column.inputLang || ''\"\n\t\t\t\t\t\t\t\t\t\t\t [required]=\"column.inputRequired || true\"\n\t\t\t\t\t\t\t\t\t\t\t (paste)=\"pasteInput( $event, row, column )\">\n\t\t\t\t\t\t\t\t\t\t</mat-form-field>\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('text2') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t\t<div>{{ row[column.id][0] }}</div>\n\t\t\t\t\t\t\t\t\t\t<div>{{ row[column.id][1] }}</div>\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('textn') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t\t@for (line of row[column.id]; track $index) {\n\t\t\t\t\t\t\t\t\t\t\t<div>{{ line }}</div>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('number') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t\t{{ column.textPrefix }}{{ row[column.id][0] }}{{ column.textSuffix }}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@case ('chips') {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t\t@if (isSaving(row, column.id)) {\n\t\t\t\t\t\t\t\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t\t\t\t\t\t\t\t} @else if (column.editable && options.editUrl && isEditing(row, column.id)) {\n\t\t\t\t\t\t\t\t\t\t\t@if (editableOptionsLoading()) {\n\t\t\t\t\t\t\t\t\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t\t<mat-form-field class=\"xiri-inline-edit\" subscriptSizing=\"dynamic\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-select multiple\n\t\t\t\t\t\t\t\t\t\t\t\t\t [ngModel]=\"editingChipsValues()\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t (selectionChange)=\"onChipsSelectionChange(row, column, $event.value)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t (keydown)=\"onInlineEditKeydown($event, row, column)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t (openedChange)=\"!$event && saveInlineEdit(row, column)\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t@if (column.editableOptionsSearch || column.editableSearchUrl) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-option>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<ngx-mat-select-search [formControl]=\"inlineSearchControl\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t [searching]=\"inlineSearching()\"></ngx-mat-select-search>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</mat-option>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t@for (opt of getEditableOptions(column); track opt.value) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-option [value]=\"opt.value\">{{ opt.label }}</mat-option>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</mat-select>\n\t\t\t\t\t\t\t\t\t\t\t\t</mat-form-field>\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t} @else if (column.editable && options.editUrl) {\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"xiri-editable-cell\" role=\"button\" tabindex=\"0\"\n\t\t\t\t\t\t\t\t\t\t\t (click)=\"startInlineEdit(row, column); $event.stopPropagation()\"\n\t\t\t\t\t\t\t\t\t\t\t (keydown.enter)=\"startInlineEdit(row, column); $event.stopPropagation()\">\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"xiri-chips-display\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t@for (chip of row[column.id]; track chip.label) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"xiri-chip-display\" [class]=\"chip.color || ''\">{{ chip.label }}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon class=\"xiri-edit-icon\">edit</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"xiri-chips-display\">\n\t\t\t\t\t\t\t\t\t\t\t\t@for (chip of row[column.id]; track chip.label) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"xiri-chip-display\" [class]=\"chip.color || ''\">{{ chip.label }}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t@default {\n\t\t\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\" [class]=\"column.display\"\n\t\t\t\t\t\t\t\t\t [class.xiri-tree-td]=\"treeEnabled && column.id === treeColumnId\">\n\t\t\t\t\t\t\t\t\t\t@if (treeEnabled && column.id === treeColumnId) {\n\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"treePrefix; context: { $implicit: row }\"></ng-container>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t@if (isSaving(row, column.id)) {\n\t\t\t\t\t\t\t\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t\t\t\t\t\t\t\t} @else if (column.editable && options.editUrl && isEditing(row, column.id)) {\n\t\t\t\t\t\t\t\t\t\t\t@if (column.editableOptions || column.editableOptionsUrl || column.editableSearchUrl) {\n\t\t\t\t\t\t\t\t\t\t\t\t@if (editableOptionsLoading()) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-spinner diameter=\"20\"></mat-spinner>\n\t\t\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-form-field class=\"xiri-inline-edit\" subscriptSizing=\"dynamic\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-select [(ngModel)]=\"row[column.id]\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t (keydown)=\"onInlineEditKeydown($event, row, column)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t (openedChange)=\"!$event && saveInlineEdit(row, column)\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@if (column.editableOptionsSearch || column.editableSearchUrl) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-option>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<ngx-mat-select-search [formControl]=\"inlineSearchControl\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t [searching]=\"inlineSearching()\"></ngx-mat-select-search>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</mat-option>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t@for (opt of getEditableOptions(column); track opt.value) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-option [value]=\"opt.value\">{{ opt.label }}</mat-option>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</mat-select>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</mat-form-field>\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t\t<mat-form-field class=\"xiri-inline-edit\" subscriptSizing=\"dynamic\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<input matInput\n\t\t\t\t\t\t\t\t\t\t\t\t\t [(ngModel)]=\"row[column.id]\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t (blur)=\"saveInlineEdit(row, column)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t (keydown)=\"onInlineEditKeydown($event, row, column)\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<button matSuffix mat-icon-button class=\"xiri-inline-edit-confirm\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t (mousedown)=\"$event.preventDefault(); saveInlineEdit(row, column)\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t aria-label=\"\u00C4nderung speichern\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t tabindex=\"-1\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon>check</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t\t\t</mat-form-field>\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t} @else if (column.editable && options.editUrl) {\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"xiri-editable-cell\" role=\"button\" tabindex=\"0\"\n\t\t\t\t\t\t\t\t\t\t\t (click)=\"startInlineEdit(row, column); $event.stopPropagation()\"\n\t\t\t\t\t\t\t\t\t\t\t (keydown.enter)=\"startInlineEdit(row, column); $event.stopPropagation()\">\n\t\t\t\t\t\t\t\t\t\t\t\t{{ column.textPrefix }}{{ row[column.id] }}{{ column.textSuffix }}\n\t\t\t\t\t\t\t\t\t\t\t\t<mat-icon class=\"xiri-edit-icon\">edit</mat-icon>\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t\t{{ column.textPrefix }}{{ row[column.id] }}{{ column.textSuffix }}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t@if (treeEnabled && column.id === treeColumnId) {\n\t\t\t\t\t\t\t\t\t\t\t<ng-container *ngTemplateOutlet=\"treeSuffix; context: { $implicit: row }\"></ng-container>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t<td mat-footer-cell *matFooterCellDef [hidden]=\"!options.footer\"\n\t\t\t\t\t\t\t [style.width]=\"column.width\" [style.min-width]=\"column.minWidth\" class=\"bottomrow\"\n\t\t\t\t\t\t\t [class]=\"column.display\">\n\t\t\t\t\t\t\t\t\t@if ( footer[ column.id ] ) {\n\t\t\t\t\t\t\t\t\t\t{{ column.textPrefix }}{{ footer[ column.id ] }}{{ column.textSuffix }}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\t\t\t\t\t@if (showSelectColumn) {\n\t\t\t\t\t\t<ng-container matColumnDef=\"select\" [sticky]=\"true\">\n\t\t\t\t\t\t\t<th mat-header-cell *matHeaderCellDef [style.width]=\"'65px'\">\n\t\t\t\t\t\t\t\t<mat-checkbox (change)=\"$event ? masterToggle() : null\"\n\t\t\t\t\t\t\t\t [checked]=\"selection.hasValue() && isAllSelected()\"\n\t\t\t\t\t\t\t\t [indeterminate]=\"selection.hasValue() && !isAllSelected()\">\n\t\t\t\t\t\t\t\t</mat-checkbox>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<td mat-cell *matCellDef=\"let row\">\n\t\t\t\t\t\t\t\t@if (isSelectable(row)) {\n\t\t\t\t\t\t\t\t\t<mat-checkbox\n\t\t\t\t\t\t\t\t\t\t\t(click)=\"$event.stopPropagation()\"\n\t\t\t\t\t\t\t\t\t\t\t(change)=\"$event ? toggleRow(row) : null\"\n\t\t\t\t\t\t\t\t\t\t\t[checked]=\"selection.isSelected(row)\">\n\t\t\t\t\t\t\t\t\t</mat-checkbox>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td mat-footer-cell *matFooterCellDef [style.width]=\"'65px'\" class=\"bottomrow\" [hidden]=\"!options.footer\">\n\t\t\t\t\t\t\t\t<mat-checkbox (change)=\"$event ? masterToggle() : null\"\n\t\t\t\t\t\t\t\t [checked]=\"selection.hasValue() && isAllSelected()\"\n\t\t\t\t\t\t\t\t [indeterminate]=\"selection.hasValue() && !isAllSelected()\">\n\t\t\t\t\t\t\t\t</mat-checkbox>\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t}\n\n\t\t\t\t\t@if (extraHeaderFields.length > 0) {\n\t\t\t\t\t\t@for (column of extraHeaderFields; track column.id) {\n\t\t\t\t\t\t\t<ng-container matColumnDef=\"{{ column.id }}\" [sticky]=\"column.sticky\">\n\t\t\t\t\t\t\t\t<th mat-header-cell *matHeaderCellDef [attr.colspan]=\"column.headerSpan\">{{ column.name }}</th>\n\t\t\t\t\t\t\t</ng-container>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t<tr mat-header-row *matHeaderRowDef=\"extraHeaders; sticky: true\" [class.dense]=\"options.dense\"></tr>\n\t\t\t\t\t}\n\n\t\t\t\t\t<tr mat-header-row *matHeaderRowDef=\"columnsToDisplay; sticky: true\" [class.dense]=\"options.dense\"></tr>\n\t\t\t\t\t<tr mat-row *matRowDef=\"let row; columns: columnsToDisplay;\" (click)=\"clicked(row)\"\n\t\t\t\t\t [class.xiri-tree-dimmed]=\"treeEnabled && row._tree?.dimmed\"></tr>\n\t\t\t\t\t<tr mat-footer-row *matFooterRowDef=\"columnsToDisplay; sticky: true\" [hidden]=\"!options.footer\"></tr>\n\t\t\t\t</table>\n\t\t\t</div>\n\t\t\t<div class=\"loader\" [hidden]=\"!loading()\" [class.has-bottombar]=\"(options.select || options.pagination) && !options.footer\">\n\t\t\t\t<mat-spinner diameter=\"30\"></mat-spinner>\n\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t@if (!loading()) {\n\t\t\t\t@if (!errorMsg && dataSource.filteredData.length === 0) {\n\t\t\t\t\t@if (options.emptyState) {\n\t\t\t\t\t\t<xiri-empty-state [settings]=\"options.emptyState\"></xiri-empty-state>\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<div class=\"nodata\">{{ options.textNoData }}</div>\n\t\t\t\t\t}\n\t\t\t\t} @else if (errorMsg) {\n\t\t\t\t\t<div class=\"alert alert-danger\">\n\t\t\t\t\t\t<span>{{ errorMsg }}</span>\n\t\t\t\t\t\t<button mat-button type=\"button\" data-testid=\"table-retry\" (click)=\"reload()\">\n\t\t\t\t\t\t\t<mat-icon>autorenew</mat-icon> Retry\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t<div class=\"xrow xsmall\" [class.bottomrow]=\"(options.select || options.pagination) && !options.footer\">\n\t\t\t\t@if (options.select) {\n\t\t\t\t\t<div class=\"xcol xcol-md-2 select-buttons\">\n\t\t\t\t\t\t@for (button of options.selectButtons; track button) {\n\t\t\t\t\t\t\t@if (!button.hide) {\n\t\t\t\t\t\t\t\t@switch (button.action) {\n\t\t\t\t\t\t\t\t\t@case ('dialog') {\n\t\t\t\t\t\t\t\t\t\t<button mat-icon-button\n\t\t\t\t\t\t\t\t\t\t (click)=\"openDialogSelection( $event, button )\"\n\t\t\t\t\t\t\t\t\t\t [disabled]=\"selection.isEmpty()\"\n\t\t\t\t\t\t\t\t\t\t [color]=\"button.color || 'primary'\"\n\t\t\t\t\t\t\t\t\t\t [matTooltip]=\"button.hint\"\n\t\t\t\t\t\t\t\t\t\t [matTooltipDisabled]=\"!button.hint\"\n\t\t\t\t\t\t\t\t\t\t [attr.aria-label]=\"button.hint || button.text\">\n\t\t\t\t\t\t\t\t\t\t\t<mat-icon>{{ button.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t@case ('api') {\n\t\t\t\t\t\t\t\t\t\t<button mat-icon-button\n\t\t\t\t\t\t\t\t\t\t (click)=\"apiCallSelection( $event, button )\"\n\t\t\t\t\t\t\t\t\t\t [disabled]=\"selection.isEmpty()\"\n\t\t\t\t\t\t\t\t\t\t [color]=\"button.color || 'primary'\"\n\t\t\t\t\t\t\t\t\t\t [matTooltip]=\"button.hint\"\n\t\t\t\t\t\t\t\t\t\t [matTooltipDisabled]=\"!button.hint\"\n\t\t\t\t\t\t\t\t\t\t [attr.aria-label]=\"button.hint || button.text\">\n\t\t\t\t\t\t\t\t\t\t\t<mat-icon>{{ button.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t@case ('download') {\n\t\t\t\t\t\t\t\t\t\t<button mat-icon-button\n\t\t\t\t\t\t\t\t\t\t (click)=\"downloadSelection( $event, button )\"\n\t\t\t\t\t\t\t\t\t\t [disabled]=\"selection.isEmpty()\"\n\t\t\t\t\t\t\t\t\t\t [color]=\"button.color || 'primary'\"\n\t\t\t\t\t\t\t\t\t\t [matTooltip]=\"button.hint\"\n\t\t\t\t\t\t\t\t\t\t [matTooltipDisabled]=\"!button.hint\"\n\t\t\t\t\t\t\t\t\t\t [attr.aria-label]=\"button.hint || button.text\">\n\t\t\t\t\t\t\t\t\t\t\t<mat-icon>{{ button.icon }}</mat-icon>\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t<div class=\"xcol xcol-right-md-10\">\n\t\t\t\t\t<mat-paginator [hidden]=\"!options.pagination\" [pageSizeOptions]=\"options.pageSizes || []\" showFirstLastButtons=\"true\"></mat-paginator>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</mat-card>\n\n@if (dynData.data) {\n\t<ng-container *ngTemplateOutlet=\"dyncomponent(); context: { $implicit: dynData }\"></ng-container>\n}\n\n<!-- Tree mode: indent + expand/collapse arrow rendered before the tree column's content -->\n<ng-template #treePrefix let-row>\n\t<span class=\"xiri-tree-prefix\" [style.padding-left.px]=\"(row._tree?.level || 0) * 24\">\n\t\t@if (row._tree?.hasChildren) {\n\t\t\t<button type=\"button\" class=\"xiri-tree-iconbtn xiri-tree-toggle\" (click)=\"toggleNode($event, row)\"\n\t\t\t tabindex=\"-1\" [attr.aria-label]=\"row._tree.expanded ? 'einklappen' : 'ausklappen'\">\n\t\t\t\t<mat-icon color=\"primary\">{{ row._tree.expanded ? 'expand_more' : 'chevron_right' }}</mat-icon>\n\t\t\t</button>\n\t\t} @else {\n\t\t\t<span class=\"xiri-tree-spacer\"></span>\n\t\t}\n\t</span>\n</ng-template>\n\n<!-- Tree mode: child-count badge (when collapsed) + optional \"+ sub\" button after the content -->\n<ng-template #treeSuffix let-row>\n\t@if (treeShowCounts && row._tree && !row._tree.expanded && row._tree.childCount > 0) {\n\t\t<span class=\"xiri-tree-count\">({{ row._tree.childCount }})</span>\n\t}\n\t@if (treeHasAddSub && treeCanAddSub(row)) {\n\t\t<button type=\"button\" class=\"xiri-tree-iconbtn xiri-tree-addsub\" (click)=\"addSub($event, row)\"\n\t\t tabindex=\"-1\" matTooltip=\"Sub-Eintrag hinzuf\u00FCgen\" aria-label=\"Sub-Eintrag hinzuf\u00FCgen\">\n\t\t\t<mat-icon color=\"primary\">add</mat-icon>\n\t\t</button>\n\t}\n</ng-template>\n", styles: ["mat-card.xiritablecard{padding:0;margin-bottom:var(--xiri-spacing-xl)}.xiritable{width:100%;overflow:auto}.xiritable.canbreak{word-break:break-all}.xiritable .table-full{display:inline-block;width:100%}.xiritable .table-full .xiri-bulk-bar{display:flex;align-items:center;gap:var(--xiri-spacing-sm);padding:var(--xiri-spacing-xs) var(--xiri-spacing-sm);background:var(--secondary-container, var(--mat-sys-secondary-container, #e0e0e0));color:var(--on-secondary-container, var(--mat-sys-on-secondary-container, inherit));border-radius:var(--xiri-radius-sm, 4px);margin-bottom:var(--xiri-spacing-xs)}.xiritable .table-full .xiri-bulk-bar.sticky{position:sticky;top:0;z-index:5}.xiritable .table-full .xiri-bulk-bar .xiri-bulk-count{font-weight:500}.xiritable .table-full .xiri-bulk-bar .xiri-bulk-spacer{flex:1 1 auto}.xiritable .table-full .tableout-wrap{position:relative}.xiritable .table-full .tableout{max-height:60vh;overflow-y:auto;width:100%;min-width:100%;max-width:100%}.xiritable .table-full .tableout.is-loading{min-height:100px}.xiritable .table-full .alert{padding:var(--xiri-spacing-md)}.xiritable .table-full mat-paginator{--mat-paginator-container-background-color: transparent;--mat-paginator-container-size: 51px;--mat-form-field-container-height: 32px;--mat-form-field-container-vertical-padding: 4px}.xiritable .table-full .bottomrow{border-top:1px solid var(--outline-variant, #C2C7CF)}.xiritable .table-full div.bottomrow{background-color:var(--surface-container, #F3F3F6);border-bottom-left-radius:var(--mat-card-elevated-container-shape, 12px);border-bottom-right-radius:var(--mat-card-elevated-container-shape, 12px)}.xiritable .header{background-color:var(--surface-container, #F3F3F6);display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;min-height:51px;padding:0 16px;border-bottom:1px solid var(--outline-variant, #C2C7CF);border-top-left-radius:var(--mat-card-elevated-container-shape, 12px);border-top-right-radius:var(--mat-card-elevated-container-shape, 12px)}.xiritable .header .buttons{padding:0 7px 0 .5rem;margin-left:-16px}.xiritable .header .buttons button{z-index:200}.xiritable .header .buttons.saveInput{padding-left:21px}.xiritable .header .middle{flex-grow:1;font-size:var(--xiri-font-size-title);display:flex;padding:0}.xiritable .header xiri-buttonline{padding:0 0 0 16px}.xiritable .header .autorefresh-indicator{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;font-size:var(--xiri-font-size-small, .8rem);color:var(--primary, var(--mat-sys-primary, #006398))}.xiritable .header .autorefresh-indicator mat-icon{font-size:18px;width:18px;height:18px;line-height:18px}.xiritable .header .autorefresh-indicator mat-icon.spin{animation:xiri-autorefresh-spin 1.5s linear infinite}.xiritable .header .lastupdated-indicator{display:inline-flex;align-items:center;padding:2px 8px;font-size:var(--xiri-font-size-small, .8rem);color:var(--on-surface-variant, #44474F);opacity:.75}@keyframes xiri-autorefresh-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.xiritable table{width:100%}.xiritable table.density-regular{--mat-table-header-container-height: 42px;--mat-table-footer-container-height: 42px;--mat-table-row-item-container-height: 42px}.xiritable table.density-compact{--mat-table-header-container-height: 32px;--mat-table-footer-container-height: 32px;--mat-table-row-item-container-height: 32px}.xiritable table.density-relaxed{--mat-table-header-container-height: 52px;--mat-table-footer-container-height: 52px;--mat-table-row-item-container-height: 52px}.xiritable table th.mat-mdc-header-cell:not(:first-of-type),.xiritable table td.mat-mdc-cell:not(:first-of-type),.xiritable table td.mat-mdc-footer-cell:not(:first-of-type){padding-left:5px}.xiritable table th.mat-mdc-header-cell:not(:last-of-type),.xiritable table td.mat-mdc-cell:not(:last-of-type),.xiritable table td.mat-mdc-footer-cell:not(:last-of-type){padding-right:7px}.xiritable table tr.mat-mdc-row{transition:background-color var(--xiri-duration-fast) var(--xiri-easing-standard)}.xiritable table tr.mat-mdc-row:hover{background:var(--surface-variant, #DEE3EB)}.xiritable table .tablelink{text-decoration:underline}.xiritable table td.buttons xiri-button,.xiritable table td.buttons xiri-buttonstyle,.xiritable table td.buttons .btnicon{margin-right:8px}.xiritable table td.buttons xiri-button:last-child,.xiritable table td.buttons xiri-buttonstyle:last-child,.xiritable table td.buttons .btnicon:last-child{margin-right:0}.xiritable table td.number,.xiritable table th.number,.xiritable table td.mat-mdc-footer-cell.number{text-align:right;font-variant-numeric:tabular-nums}.xiritable table td.right,.xiritable table td.align-right,.xiritable table th.right,.xiritable table th.align-right{text-align:right}.xiritable table td.center,.xiritable table td.align-center,.xiritable table th.center,.xiritable table th.align-center{text-align:center}.xiritable table td.left,.xiritable table td.align-left,.xiritable table th.left,.xiritable table th.align-left{text-align:left}.xiritable table td.vertical,.xiritable table th.vertical{writing-mode:sideways-rl;text-orientation:sideways}.xiritable table td.vertical div,.xiritable table th.vertical div{max-height:6rem}.xiritable table td.sideways,.xiritable table th.sideways{writing-mode:sideways-lr;text-orientation:sideways}.xiritable table td.sideways div,.xiritable table th.sideways div{max-height:6rem}.xiritable table td.upright,.xiritable table th.upright{writing-mode:vertical-rl;text-orientation:upright}.xiritable table.borders td+td{border-left:1px solid var(--outline-variant, #C2C7CF)}.xiritable table.bordersHeader th+th{border-left:1px solid var(--outline-variant, #C2C7CF)}.xiritable table td.mat-mdc-cell mat-form-field{--mat-form-field-container-height: 40px;--mat-form-field-container-vertical-padding: 8px}.xiritable .xiri-editable-cell{cursor:pointer;display:inline-flex;align-items:center;border-radius:var(--xiri-radius-xs);padding:2px 4px}.xiritable .xiri-editable-cell:hover,.xiritable .xiri-editable-cell:focus-visible{background-color:var(--surface-variant, #DEE3EB)}.xiritable .xiri-editable-cell:hover .xiri-edit-icon,.xiritable .xiri-editable-cell:focus-visible .xiri-edit-icon{opacity:1}.xiritable .xiri-edit-icon{opacity:0;font-size:14px;width:14px;height:14px;margin-left:4px;color:var(--on-surface-variant, #44474F);transition:opacity var(--xiri-duration-fast) var(--xiri-easing-standard)}.xiritable .xiri-inline-edit{--mat-form-field-container-height: 36px;--mat-form-field-container-vertical-padding: 6px;width:100%}.xiritable .xiri-inline-edit-confirm{--mdc-icon-button-icon-size: 18px;--mdc-icon-button-state-layer-size: 28px;width:28px;height:28px;padding:0;margin-right:5px;color:var(--primary, #1976d2);display:inline-flex;align-items:center;justify-content:center}.xiritable .xiri-inline-edit-confirm mat-icon{display:flex;align-items:center;justify-content:center;width:18px;height:18px;font-size:18px}.xiritable .mat-column-select{overflow:initial}.xiritable .select-buttons{padding:.3rem .8rem;display:flex;align-items:center}.xiritable .select-buttons button{margin-right:.5rem}.xiritable .xiri-cell-saved{animation:pulse .5s var(--xiri-easing-standard);border-radius:var(--xiri-radius-xs)}.xiritable .nodata{padding:.5rem 1.5rem;font-size:var(--xiri-font-size-label);background-color:var(--surface, #FFFFFF);animation:fadeInUp var(--xiri-duration-normal) var(--xiri-easing-decelerate)}.xiritable .loader{position:absolute;top:0;left:0;width:100%;bottom:0;display:flex;justify-content:center;align-items:center;background-color:var(--ripple, rgba(206, 212, 218, .5));z-index:200;border-bottom-left-radius:var(--mat-card-elevated-container-shape, 12px);border-bottom-right-radius:var(--mat-card-elevated-container-shape, 12px);animation:fadeIn var(--xiri-duration-fast) var(--xiri-easing-standard)}.xiritable .loader.has-bottombar{border-bottom-left-radius:0;border-bottom-right-radius:0}xiri-dyncomponent{margin-bottom:var(--xiri-spacing-xl)}[hidden]{display:none!important}.xiri-tree-actions{display:flex;align-items:center}td.xiri-tree-td{white-space:nowrap}td.xiri-tree-td .xiri-tree-prefix{display:inline-flex;align-items:center;vertical-align:middle}td.xiri-tree-td .xiri-tree-iconbtn{appearance:none;border:0;background:transparent;padding:0;margin:0;flex:0 0 24px;width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;border-radius:50%;cursor:pointer;-webkit-tap-highlight-color:transparent}td.xiri-tree-td .xiri-tree-iconbtn .mat-icon{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;font-size:20px;line-height:20px;margin:0}td.xiri-tree-td .xiri-tree-iconbtn:hover{background:#0000000f}td.xiri-tree-td .xiri-tree-iconbtn:focus-visible{outline:2px solid var(--primary, var(--mat-sys-primary, currentColor));outline-offset:-2px}td.xiri-tree-td .xiri-tree-spacer{width:24px;height:24px;flex:0 0 24px}td.xiri-tree-td .xiri-tree-count{margin-left:var(--xiri-spacing-xs, 4px);opacity:.6;font-size:.85em}td.xiri-tree-td .xiri-tree-addsub{margin-left:var(--xiri-spacing-xs, 4px);opacity:0;transition:opacity .15s ease-in-out}tr.mat-mdc-row:hover td.xiri-tree-td .xiri-tree-addsub,td.xiri-tree-td .xiri-tree-addsub:focus-visible{opacity:1}tr.xiri-tree-dimmed{opacity:.6}\n"] }]
5180
5219
  }], ctorParameters: () => [], propDecorators: { dyncomponent: [{ type: i0.Input, args: [{ isSignal: true, alias: "dyncomponent", required: false }] }], settings: [{ type: i0.Input, args: [{ isSignal: true, alias: "settings", required: true }] }], filterData: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterData", required: false }] }], clickedRow: [{ type: i0.Output, args: ["clickedRow"] }], paginator: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatPaginator), { isSignal: true }] }], sort: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatSort), { isSignal: true }] }], table: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatTable), { isSignal: true }] }] } });
5181
5220
 
5182
5221
  class XiriFormService {
@@ -5500,7 +5539,7 @@ class XiriListComponent {
5500
5539
  item.isFavorite = !item.isFavorite;
5501
5540
  }
5502
5541
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5503
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: XiriListComponent, isStandalone: true, selector: "xiri-list", inputs: { settings: { classPropertyName: "settings", publicName: "settings", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "@for (section of settings().sections; track section) {\n\t@if (section.name) {\n\t\t<div mat-subheader>{{ section.name }}</div>\n\t}\n\t<mat-card class=\"card mat-mdc-elevation-specific mat-elevation-z2\">\n\t\t<mat-card-content>\n\t\t\t<mat-nav-list>\n\t\t\t\t@for (item of section.data; track item) {\n\t\t\t\t\t@let itemUrl = item.url | xiriUrl;\n\t\t\t\t\t<a mat-list-item [routerLink]=\"itemUrl?.path\" [queryParams]=\"itemUrl?.queryParams\" class=\"linelink\">\n\t\t\t\t\t\t<div matListItemIcon class=\"list-icon\" [class]=\"item.iconColor\">\n\t\t\t\t\t\t\t@if (item.iconSet) {\n\t\t\t\t\t\t\t\t<mat-icon [fontSet]=\"item.iconSet\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t<mat-icon>{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<span matListItemTitle>{{ item.name }}</span>\n\t\t\t\t\t\t<span matListItemLine>{{ item.info }}</span>\n\t\t\t\t\t\t@if (item.hasFavorite) {\n\t\t\t\t\t\t\t<div matListItemMeta class=\"list-fav\">\n\t\t\t\t\t\t\t\t<button mat-icon-button (click)=\"changeFavorite(item, $event)\" [matTooltip]=\"item.favoriteHint\">\n\t\t\t\t\t\t\t\t\t@if (item.isFavorite) {\n\t\t\t\t\t\t\t\t\t\t<mat-icon class=\"accent\">star</mat-icon>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t@if (!item.isFavorite) {\n\t\t\t\t\t\t\t\t\t\t<mat-icon class=\"gray\">star_outline</mat-icon>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t}\n\t\t\t\t\t</a>\n\t\t\t\t}\n\t\t\t</mat-nav-list>\n\t\t</mat-card-content>\n\t</mat-card>\n}\n", styles: [".card{background-color:var(--surface, #FFFFFF)}.card mat-card-content,.card mat-nav-list{padding:0}.card a+a{border-top:1px solid var(--outline-variant, #C2C7CF)}.card a.mat-mdc-list-item{align-items:center;border-radius:0}.card a.mat-mdc-list-item:before{border-radius:var(--xiri-radius-md)}.card a.mat-mdc-list-item.mdc-list-item--with-two-lines ::ng-deep .mdc-list-item__content{transform:translateY(-7px)}.card .list-icon{width:48px;height:48px;color:var(--on-primary, #FFFFFF);border-radius:50%;margin:0 16px;align-self:center;display:flex;justify-content:center;align-items:center}.card .list-icon mat-icon{text-align:center;font-size:var(--xiri-icon-size-lg);--mat-icon-color: var(--on-primary, white)}.card .list-icon.primary{background-color:var(--primary)}.card .list-icon.secondary{background-color:var(--secondary)}.card .list-icon.tertiary{background-color:var(--tertiary)}.card .list-icon.accent{background-color:var(--secondary)}.card .list-icon.warn,.card .list-icon.error{background-color:var(--error)}.card .list-icon.success{background-color:var(--color-success)}.card .list-icon.emerald{background-color:#2892d9}.card .list-icon.red{background-color:#e74c3c}.card .list-icon.yellow{background-color:#f1c40f}.card .list-icon.green{background-color:#2ecc71}.card .list-icon.blue{background-color:#3498db}.card .list-icon.purple{background-color:#9b59b6}.card .list-icon.gray{background-color:#95a5a6}.card .list-icon.lightgray{background-color:#bdc3c7}.card .list-icon.darkgray{background-color:#7f8c8d}.card .list-icon.orange{background-color:#e67e22}.card .list-icon.white{background-color:#fff}.card .list-icon.black{background-color:#000}.card .list-icon.inherit{background-color:inherit}.card .list-fav{display:flex;justify-content:center;align-items:center;height:100%}.card .list-fav mat-icon.gray{--mat-icon-color: var(--on-surface-variant, gray)}.card .list-fav mat-icon.accent{--mat-icon-color: var(--secondary, #6750A4)}\n"], dependencies: [{ kind: "directive", type: MatListSubheaderCssMatStyler, selector: "[mat-subheader], [matSubheader]" }, { kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: MatCardContent, selector: "mat-card-content" }, { kind: "component", type: MatNavList, selector: "mat-nav-list", exportAs: ["matNavList"] }, { kind: "component", type: MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "directive", type: MatListItemIcon, selector: "[matListItemIcon]" }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatListItemTitle, selector: "[matListItemTitle]" }, { kind: "directive", type: MatListItemLine, selector: "[matListItemLine]" }, { kind: "directive", type: MatListItemMeta, selector: "[matListItemMeta]" }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: XiriUrlPipe, name: "xiriUrl" }] }); }
5542
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: XiriListComponent, isStandalone: true, selector: "xiri-list", inputs: { settings: { classPropertyName: "settings", publicName: "settings", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "@for (section of settings().sections; track section) {\n\t@if (section.name) {\n\t\t<div mat-subheader>{{ section.name }}</div>\n\t}\n\t<mat-card class=\"card mat-mdc-elevation-specific mat-elevation-z2\">\n\t\t<mat-card-content>\n\t\t\t<mat-nav-list>\n\t\t\t\t@for (item of section.data; track item) {\n\t\t\t\t\t@let itemUrl = item.url | xiriUrl;\n\t\t\t\t\t<a mat-list-item [routerLink]=\"itemUrl?.path\" [queryParams]=\"itemUrl?.queryParams\" class=\"linelink\">\n\t\t\t\t\t\t<div matListItemIcon class=\"list-icon\" [class]=\"item.iconColor\">\n\t\t\t\t\t\t\t@if (item.iconSet) {\n\t\t\t\t\t\t\t\t<mat-icon [fontSet]=\"item.iconSet\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t<mat-icon>{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<span matListItemTitle>{{ item.name }}</span>\n\t\t\t\t\t\t<span matListItemLine>{{ item.info }}</span>\n\t\t\t\t\t\t@if (item.hasFavorite) {\n\t\t\t\t\t\t\t<div matListItemMeta class=\"list-fav\">\n\t\t\t\t\t\t\t\t<button mat-icon-button (click)=\"changeFavorite(item, $event)\" [matTooltip]=\"item.favoriteHint\"\n\t\t\t\t\t\t\t [attr.aria-label]=\"'Favorit: ' + item.name\"\n\t\t\t\t\t\t\t [attr.aria-pressed]=\"!!item.isFavorite\">\n\t\t\t\t\t\t\t\t\t@if (item.isFavorite) {\n\t\t\t\t\t\t\t\t\t\t<mat-icon class=\"accent\">star</mat-icon>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t@if (!item.isFavorite) {\n\t\t\t\t\t\t\t\t\t\t<mat-icon class=\"gray\">star_outline</mat-icon>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t}\n\t\t\t\t\t</a>\n\t\t\t\t}\n\t\t\t</mat-nav-list>\n\t\t</mat-card-content>\n\t</mat-card>\n}\n", styles: [".card{background-color:var(--surface, #FFFFFF)}.card mat-card-content,.card mat-nav-list{padding:0}.card a+a{border-top:1px solid var(--outline-variant, #C2C7CF)}.card a.mat-mdc-list-item{align-items:center;border-radius:0}.card a.mat-mdc-list-item:before{border-radius:var(--xiri-radius-md)}.card a.mat-mdc-list-item.mdc-list-item--with-two-lines ::ng-deep .mdc-list-item__content{transform:translateY(-7px)}.card .list-icon{width:48px;height:48px;color:var(--on-primary, #FFFFFF);border-radius:50%;margin:0 16px;align-self:center;display:flex;justify-content:center;align-items:center}.card .list-icon mat-icon{text-align:center;font-size:var(--xiri-icon-size-lg);--mat-icon-color: var(--on-primary, white)}.card .list-icon.primary{background-color:var(--primary)}.card .list-icon.secondary{background-color:var(--secondary)}.card .list-icon.tertiary{background-color:var(--tertiary)}.card .list-icon.accent{background-color:var(--secondary)}.card .list-icon.warn,.card .list-icon.error{background-color:var(--error)}.card .list-icon.success{background-color:var(--color-success)}.card .list-icon.emerald{background-color:#2892d9}.card .list-icon.red{background-color:#e74c3c}.card .list-icon.yellow{background-color:#f1c40f}.card .list-icon.green{background-color:#2ecc71}.card .list-icon.blue{background-color:#3498db}.card .list-icon.purple{background-color:#9b59b6}.card .list-icon.gray{background-color:#95a5a6}.card .list-icon.lightgray{background-color:#bdc3c7}.card .list-icon.darkgray{background-color:#7f8c8d}.card .list-icon.orange{background-color:#e67e22}.card .list-icon.white{background-color:#fff}.card .list-icon.black{background-color:#000}.card .list-icon.inherit{background-color:inherit}.card .list-fav{display:flex;justify-content:center;align-items:center;height:100%}.card .list-fav mat-icon.gray{--mat-icon-color: var(--on-surface-variant, gray)}.card .list-fav mat-icon.accent{--mat-icon-color: var(--secondary, #6750A4)}\n"], dependencies: [{ kind: "directive", type: MatListSubheaderCssMatStyler, selector: "[mat-subheader], [matSubheader]" }, { kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: MatCardContent, selector: "mat-card-content" }, { kind: "component", type: MatNavList, selector: "mat-nav-list", exportAs: ["matNavList"] }, { kind: "component", type: MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "directive", type: MatListItemIcon, selector: "[matListItemIcon]" }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatListItemTitle, selector: "[matListItemTitle]" }, { kind: "directive", type: MatListItemLine, selector: "[matListItemLine]" }, { kind: "directive", type: MatListItemMeta, selector: "[matListItemMeta]" }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: XiriUrlPipe, name: "xiriUrl" }] }); }
5504
5543
  }
5505
5544
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriListComponent, decorators: [{
5506
5545
  type: Component,
@@ -5519,7 +5558,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
5519
5558
  MatIconButton,
5520
5559
  MatTooltip,
5521
5560
  XiriUrlPipe,
5522
- ], template: "@for (section of settings().sections; track section) {\n\t@if (section.name) {\n\t\t<div mat-subheader>{{ section.name }}</div>\n\t}\n\t<mat-card class=\"card mat-mdc-elevation-specific mat-elevation-z2\">\n\t\t<mat-card-content>\n\t\t\t<mat-nav-list>\n\t\t\t\t@for (item of section.data; track item) {\n\t\t\t\t\t@let itemUrl = item.url | xiriUrl;\n\t\t\t\t\t<a mat-list-item [routerLink]=\"itemUrl?.path\" [queryParams]=\"itemUrl?.queryParams\" class=\"linelink\">\n\t\t\t\t\t\t<div matListItemIcon class=\"list-icon\" [class]=\"item.iconColor\">\n\t\t\t\t\t\t\t@if (item.iconSet) {\n\t\t\t\t\t\t\t\t<mat-icon [fontSet]=\"item.iconSet\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t<mat-icon>{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<span matListItemTitle>{{ item.name }}</span>\n\t\t\t\t\t\t<span matListItemLine>{{ item.info }}</span>\n\t\t\t\t\t\t@if (item.hasFavorite) {\n\t\t\t\t\t\t\t<div matListItemMeta class=\"list-fav\">\n\t\t\t\t\t\t\t\t<button mat-icon-button (click)=\"changeFavorite(item, $event)\" [matTooltip]=\"item.favoriteHint\">\n\t\t\t\t\t\t\t\t\t@if (item.isFavorite) {\n\t\t\t\t\t\t\t\t\t\t<mat-icon class=\"accent\">star</mat-icon>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t@if (!item.isFavorite) {\n\t\t\t\t\t\t\t\t\t\t<mat-icon class=\"gray\">star_outline</mat-icon>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t}\n\t\t\t\t\t</a>\n\t\t\t\t}\n\t\t\t</mat-nav-list>\n\t\t</mat-card-content>\n\t</mat-card>\n}\n", styles: [".card{background-color:var(--surface, #FFFFFF)}.card mat-card-content,.card mat-nav-list{padding:0}.card a+a{border-top:1px solid var(--outline-variant, #C2C7CF)}.card a.mat-mdc-list-item{align-items:center;border-radius:0}.card a.mat-mdc-list-item:before{border-radius:var(--xiri-radius-md)}.card a.mat-mdc-list-item.mdc-list-item--with-two-lines ::ng-deep .mdc-list-item__content{transform:translateY(-7px)}.card .list-icon{width:48px;height:48px;color:var(--on-primary, #FFFFFF);border-radius:50%;margin:0 16px;align-self:center;display:flex;justify-content:center;align-items:center}.card .list-icon mat-icon{text-align:center;font-size:var(--xiri-icon-size-lg);--mat-icon-color: var(--on-primary, white)}.card .list-icon.primary{background-color:var(--primary)}.card .list-icon.secondary{background-color:var(--secondary)}.card .list-icon.tertiary{background-color:var(--tertiary)}.card .list-icon.accent{background-color:var(--secondary)}.card .list-icon.warn,.card .list-icon.error{background-color:var(--error)}.card .list-icon.success{background-color:var(--color-success)}.card .list-icon.emerald{background-color:#2892d9}.card .list-icon.red{background-color:#e74c3c}.card .list-icon.yellow{background-color:#f1c40f}.card .list-icon.green{background-color:#2ecc71}.card .list-icon.blue{background-color:#3498db}.card .list-icon.purple{background-color:#9b59b6}.card .list-icon.gray{background-color:#95a5a6}.card .list-icon.lightgray{background-color:#bdc3c7}.card .list-icon.darkgray{background-color:#7f8c8d}.card .list-icon.orange{background-color:#e67e22}.card .list-icon.white{background-color:#fff}.card .list-icon.black{background-color:#000}.card .list-icon.inherit{background-color:inherit}.card .list-fav{display:flex;justify-content:center;align-items:center;height:100%}.card .list-fav mat-icon.gray{--mat-icon-color: var(--on-surface-variant, gray)}.card .list-fav mat-icon.accent{--mat-icon-color: var(--secondary, #6750A4)}\n"] }]
5561
+ ], template: "@for (section of settings().sections; track section) {\n\t@if (section.name) {\n\t\t<div mat-subheader>{{ section.name }}</div>\n\t}\n\t<mat-card class=\"card mat-mdc-elevation-specific mat-elevation-z2\">\n\t\t<mat-card-content>\n\t\t\t<mat-nav-list>\n\t\t\t\t@for (item of section.data; track item) {\n\t\t\t\t\t@let itemUrl = item.url | xiriUrl;\n\t\t\t\t\t<a mat-list-item [routerLink]=\"itemUrl?.path\" [queryParams]=\"itemUrl?.queryParams\" class=\"linelink\">\n\t\t\t\t\t\t<div matListItemIcon class=\"list-icon\" [class]=\"item.iconColor\">\n\t\t\t\t\t\t\t@if (item.iconSet) {\n\t\t\t\t\t\t\t\t<mat-icon [fontSet]=\"item.iconSet\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t<mat-icon>{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<span matListItemTitle>{{ item.name }}</span>\n\t\t\t\t\t\t<span matListItemLine>{{ item.info }}</span>\n\t\t\t\t\t\t@if (item.hasFavorite) {\n\t\t\t\t\t\t\t<div matListItemMeta class=\"list-fav\">\n\t\t\t\t\t\t\t\t<button mat-icon-button (click)=\"changeFavorite(item, $event)\" [matTooltip]=\"item.favoriteHint\"\n\t\t\t\t\t\t\t [attr.aria-label]=\"'Favorit: ' + item.name\"\n\t\t\t\t\t\t\t [attr.aria-pressed]=\"!!item.isFavorite\">\n\t\t\t\t\t\t\t\t\t@if (item.isFavorite) {\n\t\t\t\t\t\t\t\t\t\t<mat-icon class=\"accent\">star</mat-icon>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t@if (!item.isFavorite) {\n\t\t\t\t\t\t\t\t\t\t<mat-icon class=\"gray\">star_outline</mat-icon>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t}\n\t\t\t\t\t</a>\n\t\t\t\t}\n\t\t\t</mat-nav-list>\n\t\t</mat-card-content>\n\t</mat-card>\n}\n", styles: [".card{background-color:var(--surface, #FFFFFF)}.card mat-card-content,.card mat-nav-list{padding:0}.card a+a{border-top:1px solid var(--outline-variant, #C2C7CF)}.card a.mat-mdc-list-item{align-items:center;border-radius:0}.card a.mat-mdc-list-item:before{border-radius:var(--xiri-radius-md)}.card a.mat-mdc-list-item.mdc-list-item--with-two-lines ::ng-deep .mdc-list-item__content{transform:translateY(-7px)}.card .list-icon{width:48px;height:48px;color:var(--on-primary, #FFFFFF);border-radius:50%;margin:0 16px;align-self:center;display:flex;justify-content:center;align-items:center}.card .list-icon mat-icon{text-align:center;font-size:var(--xiri-icon-size-lg);--mat-icon-color: var(--on-primary, white)}.card .list-icon.primary{background-color:var(--primary)}.card .list-icon.secondary{background-color:var(--secondary)}.card .list-icon.tertiary{background-color:var(--tertiary)}.card .list-icon.accent{background-color:var(--secondary)}.card .list-icon.warn,.card .list-icon.error{background-color:var(--error)}.card .list-icon.success{background-color:var(--color-success)}.card .list-icon.emerald{background-color:#2892d9}.card .list-icon.red{background-color:#e74c3c}.card .list-icon.yellow{background-color:#f1c40f}.card .list-icon.green{background-color:#2ecc71}.card .list-icon.blue{background-color:#3498db}.card .list-icon.purple{background-color:#9b59b6}.card .list-icon.gray{background-color:#95a5a6}.card .list-icon.lightgray{background-color:#bdc3c7}.card .list-icon.darkgray{background-color:#7f8c8d}.card .list-icon.orange{background-color:#e67e22}.card .list-icon.white{background-color:#fff}.card .list-icon.black{background-color:#000}.card .list-icon.inherit{background-color:inherit}.card .list-fav{display:flex;justify-content:center;align-items:center;height:100%}.card .list-fav mat-icon.gray{--mat-icon-color: var(--on-surface-variant, gray)}.card .list-fav mat-icon.accent{--mat-icon-color: var(--secondary, #6750A4)}\n"] }]
5523
5562
  }], propDecorators: { settings: [{ type: i0.Input, args: [{ isSignal: true, alias: "settings", required: true }] }] } });
5524
5563
 
5525
5564
  class XiriHeaderComponent {
@@ -5914,11 +5953,11 @@ class XiriQueryComponent {
5914
5953
  });
5915
5954
  }
5916
5955
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriQueryComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5917
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: XiriQueryComponent, isStandalone: true, selector: "xiri-query", inputs: { settings: { classPropertyName: "settings", publicName: "settings", isSignal: true, isRequired: true, transformFunction: null }, dyncomponent: { classPropertyName: "dyncomponent", publicName: "dyncomponent", isSignal: true, isRequired: false, transformFunction: null }, count: { classPropertyName: "count", publicName: "count", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filterChange: "filterChange" }, ngImport: i0, template: "<div class=\"xrow\">\n\t<div class=\"xcol\">\n\t\t@if (settings().collapsed !== undefined) {\n\t\t\t<mat-expansion-panel [expanded]=\"!settings().collapsed\" class=\"query-expansion\">\n\t\t\t\t<mat-expansion-panel-header>\n\t\t\t\t\t<mat-panel-title>\n\t\t\t\t\t\t<mat-icon>filter_list</mat-icon> Filter\n\t\t\t\t\t</mat-panel-title>\n\t\t\t\t</mat-expansion-panel-header>\n\t\t\t\t<div class=\"query\">\n\t\t\t\t\t<xiri-form-fields [form]=\"formFields()\" (formChange)=\"formChanged($event)\" display=\"line\"></xiri-form-fields>\n\t\t\t\t\t<ng-container *ngTemplateOutlet=\"filterState\"></ng-container>\n\t\t\t\t\t@if (error()) {\n\t\t\t\t\t\t<div class=\"error\">\n\t\t\t\t\t\t\t<span>{{ error() }}</span>\n\t\t\t\t\t\t\t<button mat-button type=\"button\" data-testid=\"query-retry\" (click)=\"retry()\">\n\t\t\t\t\t\t\t\t<mat-icon>refresh</mat-icon> Retry\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t</mat-expansion-panel>\n\t\t} @else {\n\t\t\t<div class=\"query\">\n\t\t\t\t<xiri-form-fields [form]=\"formFields()\" (formChange)=\"formChanged($event)\" display=\"line\"></xiri-form-fields>\n\t\t\t\t<ng-container *ngTemplateOutlet=\"filterState\"></ng-container>\n\t\t\t\t@if (error()) {\n\t\t\t\t\t<div class=\"error\">\n\t\t\t\t\t\t<span>{{ error() }}</span>\n\t\t\t\t\t\t<button mat-button type=\"button\" data-testid=\"query-retry\" (click)=\"retry()\">\n\t\t\t\t\t\t\t<mat-icon>refresh</mat-icon> Retry\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t</div>\n\t@if (settings().buttonline; as buttonline) {\n\t\t<div class=\"xcol formbtnline\" [class]=\"buttonline.display\">\n\t\t\t<xiri-buttonline [settings]=\"$any(buttonline.data)\" [filterData]=\"filterData()\" [disabled]=\"!formValid()\"\n\t\t\t (result)=\"clickedButton($event)\"></xiri-buttonline>\n\t\t</div>\n\t\t@if (loading()) {\n\t\t\t<div class=\"xcol\">\n\t\t\t\t<mat-spinner diameter=\"30\"></mat-spinner>\n\t\t\t</div>\n\t\t}\n\t}\n\t@if (dynData.data) {\n\t\t<div class=\"xcol\">\n\t\t\t<ng-container *ngTemplateOutlet=\"dyncomponent(); context: { $implicit: dynData }\"></ng-container>\n\t\t</div>\n\t}\n\t@if (data()) {\n\t\t<div class=\"xcol\" [class.is-loading]=\"loading()\">\n\t\t\t<ng-container *ngTemplateOutlet=\"dyncomponent(); context: { $implicit: data() }\"></ng-container>\n\t\t</div>\n\t}\n</div>\n\n<ng-template #filterState>\n\t@if (settings().showActiveFilters && activeFilters().length) {\n\t\t<div class=\"query-filter-state\">\n\t\t\t<mat-chip-set aria-label=\"Aktive Filter\">\n\t\t\t\t@for (filter of activeFilters(); track filter.id) {\n\t\t\t\t\t<mat-chip data-testid=\"query-filter-chip\" (removed)=\"removeFilter(filter.id)\">\n\t\t\t\t\t\t<span class=\"chip-label\">{{ filter.label }}: {{ filter.value }}</span>\n\t\t\t\t\t\t<button matChipRemove type=\"button\"\n\t\t\t\t\t\t [attr.aria-label]=\"'Filter entfernen: ' + filter.label + ' ' + filter.value\">\n\t\t\t\t\t\t\t<mat-icon>cancel</mat-icon>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</mat-chip>\n\t\t\t\t}\n\t\t\t</mat-chip-set>\n\t\t\t<button mat-button type=\"button\" class=\"reset-filters\" data-testid=\"query-reset-filters\"\n\t\t\t (click)=\"resetFilters()\">\n\t\t\t\t<mat-icon>filter_list_off</mat-icon> Alle zur\u00FCcksetzen\n\t\t\t</button>\n\t\t</div>\n\t}\n\t@if (settings().showResultCount && resultCount(); as rc) {\n\t\t<div class=\"query-result-count\" data-testid=\"query-result-count\" aria-live=\"polite\">\n\t\t\t@if (rc.total !== undefined) {\n\t\t\t\t<span><strong>{{ rc.filtered }}</strong> von {{ rc.total }} Treffern</span>\n\t\t\t} @else {\n\t\t\t\t<span><strong>{{ rc.filtered }}</strong> Treffer</span>\n\t\t\t}\n\t\t</div>\n\t}\n</ng-template>\n", styles: [".query{padding-left:var(--xiri-spacing-md);padding-right:var(--xiri-spacing-md)}.is-loading{opacity:.5;transition:opacity .15s ease-in-out;pointer-events:none}.query-filter-state{display:flex;align-items:center;flex-wrap:wrap;gap:var(--xiri-spacing-sm);margin-top:var(--xiri-spacing-sm)}.query-filter-state .reset-filters mat-icon{margin-right:var(--xiri-spacing-xs)}.query-result-count{margin-top:var(--xiri-spacing-sm);color:var(--mat-sys-on-surface-variant, inherit);font-size:.9rem}.query-expansion .query{padding-left:0;padding-right:0}.query-expansion mat-panel-title mat-icon{margin-right:var(--xiri-spacing-sm)}\n"], dependencies: [{ kind: "component", type: XiriFormFieldsComponent, selector: "xiri-form-fields", inputs: ["form", "display", "disabled", "check"], outputs: ["formChange"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: XiriButtonlineComponent, selector: "xiri-buttonline", inputs: ["settings", "disabled", "filterData"], outputs: ["result"] }, { kind: "component", type: MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role", "tabIndex"] }, { kind: "component", type: MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "directive", type: MatChipRemove, selector: "[matChipRemove]" }] }); }
5956
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: XiriQueryComponent, isStandalone: true, selector: "xiri-query", inputs: { settings: { classPropertyName: "settings", publicName: "settings", isSignal: true, isRequired: true, transformFunction: null }, dyncomponent: { classPropertyName: "dyncomponent", publicName: "dyncomponent", isSignal: true, isRequired: false, transformFunction: null }, count: { classPropertyName: "count", publicName: "count", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filterChange: "filterChange" }, ngImport: i0, template: "<div class=\"xrow\">\n\t<div class=\"xcol\">\n\t\t@if (settings().collapsed !== undefined) {\n\t\t\t<mat-expansion-panel [expanded]=\"!settings().collapsed\" class=\"query-expansion\">\n\t\t\t\t<mat-expansion-panel-header>\n\t\t\t\t\t<mat-panel-title>\n\t\t\t\t\t\t<mat-icon>filter_list</mat-icon> Filter\n\t\t\t\t\t</mat-panel-title>\n\t\t\t\t</mat-expansion-panel-header>\n\t\t\t\t<div class=\"query\">\n\t\t\t\t\t<xiri-form-fields [form]=\"formFields()\" (formChange)=\"formChanged($event)\" display=\"line\"></xiri-form-fields>\n\t\t\t\t\t<ng-container *ngTemplateOutlet=\"filterState\"></ng-container>\n\t\t\t\t\t@if (error()) {\n\t\t\t\t\t\t<div class=\"error\">\n\t\t\t\t\t\t\t<span>{{ error() }}</span>\n\t\t\t\t\t\t\t<button mat-button type=\"button\" data-testid=\"query-retry\" (click)=\"retry()\">\n\t\t\t\t\t\t\t\t<mat-icon>refresh</mat-icon> Retry\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t</mat-expansion-panel>\n\t\t} @else {\n\t\t\t<div class=\"query\">\n\t\t\t\t<xiri-form-fields [form]=\"formFields()\" (formChange)=\"formChanged($event)\" display=\"line\"></xiri-form-fields>\n\t\t\t\t<ng-container *ngTemplateOutlet=\"filterState\"></ng-container>\n\t\t\t\t@if (error()) {\n\t\t\t\t\t<div class=\"error\">\n\t\t\t\t\t\t<span>{{ error() }}</span>\n\t\t\t\t\t\t<button mat-button type=\"button\" data-testid=\"query-retry\" (click)=\"retry()\">\n\t\t\t\t\t\t\t<mat-icon>refresh</mat-icon> Retry\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t</div>\n\t@if (settings().buttonline; as buttonline) {\n\t\t<div class=\"xcol formbtnline\" [class]=\"buttonline.display\">\n\t\t\t<xiri-buttonline [settings]=\"$any(buttonline.data)\" [filterData]=\"filterData()\" [disabled]=\"!formValid()\"\n\t\t\t (result)=\"clickedButton($event)\"></xiri-buttonline>\n\t\t</div>\n\t\t@if (loading()) {\n\t\t\t<div class=\"xcol\">\n\t\t\t\t<mat-spinner diameter=\"30\"></mat-spinner>\n\t\t\t</div>\n\t\t}\n\t}\n\t@if (dynData.data) {\n\t\t<div class=\"xcol\">\n\t\t\t<ng-container *ngTemplateOutlet=\"dyncomponent(); context: { $implicit: dynData }\"></ng-container>\n\t\t</div>\n\t}\n\t@if (data()) {\n\t\t<div class=\"xcol\" [class.is-loading]=\"loading()\">\n\t\t\t<ng-container *ngTemplateOutlet=\"dyncomponent(); context: { $implicit: data() }\"></ng-container>\n\t\t</div>\n\t}\n</div>\n\n<ng-template #filterState>\n\t@if (settings().showActiveFilters && activeFilters().length) {\n\t\t<div class=\"query-filter-state\">\n\t\t\t<mat-chip-set aria-label=\"Aktive Filter\">\n\t\t\t\t@for (filter of activeFilters(); track filter.id) {\n\t\t\t\t\t<mat-chip data-testid=\"query-filter-chip\" (removed)=\"removeFilter(filter.id)\">\n\t\t\t\t\t\t<span class=\"chip-label\">{{ filter.label }}: {{ filter.value }}</span>\n\t\t\t\t\t\t<button matChipRemove type=\"button\"\n\t\t\t\t\t\t [attr.aria-label]=\"'Filter entfernen: ' + filter.label + ' ' + filter.value\">\n\t\t\t\t\t\t\t<mat-icon>cancel</mat-icon>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</mat-chip>\n\t\t\t\t}\n\t\t\t</mat-chip-set>\n\t\t\t<button mat-button type=\"button\" class=\"reset-filters\" data-testid=\"query-reset-filters\"\n\t\t\t (click)=\"resetFilters()\">\n\t\t\t\t<mat-icon>filter_list_off</mat-icon> Alle zur\u00FCcksetzen\n\t\t\t</button>\n\t\t</div>\n\t}\n\t@if (settings().showResultCount && resultCount(); as rc) {\n\t\t<div class=\"query-result-count\" data-testid=\"query-result-count\" aria-live=\"polite\">\n\t\t\t@if (rc.total !== undefined) {\n\t\t\t\t<span><strong>{{ rc.filtered }}</strong> von {{ rc.total }} Treffern</span>\n\t\t\t} @else {\n\t\t\t\t<span><strong>{{ rc.filtered }}</strong> Treffer</span>\n\t\t\t}\n\t\t</div>\n\t}\n</ng-template>\n", styles: [".query{padding-left:var(--xiri-spacing-md);padding-right:var(--xiri-spacing-md)}.is-loading{opacity:.5;transition:opacity .15s ease-in-out;pointer-events:none}.query-filter-state{display:flex;align-items:center;flex-wrap:wrap;gap:var(--xiri-spacing-sm);margin-top:var(--xiri-spacing-sm)}.query-filter-state .reset-filters mat-icon{margin-right:var(--xiri-spacing-xs)}.query-result-count{margin-top:var(--xiri-spacing-sm);color:var(--on-surface-variant, var(--mat-sys-on-surface-variant, inherit));font-size:.9rem}.query-expansion .query{padding-left:0;padding-right:0}.query-expansion mat-panel-title mat-icon{margin-right:var(--xiri-spacing-sm)}\n"], dependencies: [{ kind: "component", type: XiriFormFieldsComponent, selector: "xiri-form-fields", inputs: ["form", "display", "disabled", "check"], outputs: ["formChange"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: XiriButtonlineComponent, selector: "xiri-buttonline", inputs: ["settings", "disabled", "filterData"], outputs: ["result"] }, { kind: "component", type: MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role", "tabIndex"] }, { kind: "component", type: MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "directive", type: MatChipRemove, selector: "[matChipRemove]" }] }); }
5918
5957
  }
5919
5958
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriQueryComponent, decorators: [{
5920
5959
  type: Component,
5921
- args: [{ selector: 'xiri-query', imports: [XiriFormFieldsComponent, NgTemplateOutlet, XiriButtonlineComponent, MatExpansionPanel, MatExpansionPanelHeader, MatExpansionPanelTitle, MatIcon, MatButton, MatProgressSpinner, MatChipSet, MatChip, MatChipRemove], template: "<div class=\"xrow\">\n\t<div class=\"xcol\">\n\t\t@if (settings().collapsed !== undefined) {\n\t\t\t<mat-expansion-panel [expanded]=\"!settings().collapsed\" class=\"query-expansion\">\n\t\t\t\t<mat-expansion-panel-header>\n\t\t\t\t\t<mat-panel-title>\n\t\t\t\t\t\t<mat-icon>filter_list</mat-icon> Filter\n\t\t\t\t\t</mat-panel-title>\n\t\t\t\t</mat-expansion-panel-header>\n\t\t\t\t<div class=\"query\">\n\t\t\t\t\t<xiri-form-fields [form]=\"formFields()\" (formChange)=\"formChanged($event)\" display=\"line\"></xiri-form-fields>\n\t\t\t\t\t<ng-container *ngTemplateOutlet=\"filterState\"></ng-container>\n\t\t\t\t\t@if (error()) {\n\t\t\t\t\t\t<div class=\"error\">\n\t\t\t\t\t\t\t<span>{{ error() }}</span>\n\t\t\t\t\t\t\t<button mat-button type=\"button\" data-testid=\"query-retry\" (click)=\"retry()\">\n\t\t\t\t\t\t\t\t<mat-icon>refresh</mat-icon> Retry\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t</mat-expansion-panel>\n\t\t} @else {\n\t\t\t<div class=\"query\">\n\t\t\t\t<xiri-form-fields [form]=\"formFields()\" (formChange)=\"formChanged($event)\" display=\"line\"></xiri-form-fields>\n\t\t\t\t<ng-container *ngTemplateOutlet=\"filterState\"></ng-container>\n\t\t\t\t@if (error()) {\n\t\t\t\t\t<div class=\"error\">\n\t\t\t\t\t\t<span>{{ error() }}</span>\n\t\t\t\t\t\t<button mat-button type=\"button\" data-testid=\"query-retry\" (click)=\"retry()\">\n\t\t\t\t\t\t\t<mat-icon>refresh</mat-icon> Retry\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t</div>\n\t@if (settings().buttonline; as buttonline) {\n\t\t<div class=\"xcol formbtnline\" [class]=\"buttonline.display\">\n\t\t\t<xiri-buttonline [settings]=\"$any(buttonline.data)\" [filterData]=\"filterData()\" [disabled]=\"!formValid()\"\n\t\t\t (result)=\"clickedButton($event)\"></xiri-buttonline>\n\t\t</div>\n\t\t@if (loading()) {\n\t\t\t<div class=\"xcol\">\n\t\t\t\t<mat-spinner diameter=\"30\"></mat-spinner>\n\t\t\t</div>\n\t\t}\n\t}\n\t@if (dynData.data) {\n\t\t<div class=\"xcol\">\n\t\t\t<ng-container *ngTemplateOutlet=\"dyncomponent(); context: { $implicit: dynData }\"></ng-container>\n\t\t</div>\n\t}\n\t@if (data()) {\n\t\t<div class=\"xcol\" [class.is-loading]=\"loading()\">\n\t\t\t<ng-container *ngTemplateOutlet=\"dyncomponent(); context: { $implicit: data() }\"></ng-container>\n\t\t</div>\n\t}\n</div>\n\n<ng-template #filterState>\n\t@if (settings().showActiveFilters && activeFilters().length) {\n\t\t<div class=\"query-filter-state\">\n\t\t\t<mat-chip-set aria-label=\"Aktive Filter\">\n\t\t\t\t@for (filter of activeFilters(); track filter.id) {\n\t\t\t\t\t<mat-chip data-testid=\"query-filter-chip\" (removed)=\"removeFilter(filter.id)\">\n\t\t\t\t\t\t<span class=\"chip-label\">{{ filter.label }}: {{ filter.value }}</span>\n\t\t\t\t\t\t<button matChipRemove type=\"button\"\n\t\t\t\t\t\t [attr.aria-label]=\"'Filter entfernen: ' + filter.label + ' ' + filter.value\">\n\t\t\t\t\t\t\t<mat-icon>cancel</mat-icon>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</mat-chip>\n\t\t\t\t}\n\t\t\t</mat-chip-set>\n\t\t\t<button mat-button type=\"button\" class=\"reset-filters\" data-testid=\"query-reset-filters\"\n\t\t\t (click)=\"resetFilters()\">\n\t\t\t\t<mat-icon>filter_list_off</mat-icon> Alle zur\u00FCcksetzen\n\t\t\t</button>\n\t\t</div>\n\t}\n\t@if (settings().showResultCount && resultCount(); as rc) {\n\t\t<div class=\"query-result-count\" data-testid=\"query-result-count\" aria-live=\"polite\">\n\t\t\t@if (rc.total !== undefined) {\n\t\t\t\t<span><strong>{{ rc.filtered }}</strong> von {{ rc.total }} Treffern</span>\n\t\t\t} @else {\n\t\t\t\t<span><strong>{{ rc.filtered }}</strong> Treffer</span>\n\t\t\t}\n\t\t</div>\n\t}\n</ng-template>\n", styles: [".query{padding-left:var(--xiri-spacing-md);padding-right:var(--xiri-spacing-md)}.is-loading{opacity:.5;transition:opacity .15s ease-in-out;pointer-events:none}.query-filter-state{display:flex;align-items:center;flex-wrap:wrap;gap:var(--xiri-spacing-sm);margin-top:var(--xiri-spacing-sm)}.query-filter-state .reset-filters mat-icon{margin-right:var(--xiri-spacing-xs)}.query-result-count{margin-top:var(--xiri-spacing-sm);color:var(--mat-sys-on-surface-variant, inherit);font-size:.9rem}.query-expansion .query{padding-left:0;padding-right:0}.query-expansion mat-panel-title mat-icon{margin-right:var(--xiri-spacing-sm)}\n"] }]
5960
+ args: [{ selector: 'xiri-query', imports: [XiriFormFieldsComponent, NgTemplateOutlet, XiriButtonlineComponent, MatExpansionPanel, MatExpansionPanelHeader, MatExpansionPanelTitle, MatIcon, MatButton, MatProgressSpinner, MatChipSet, MatChip, MatChipRemove], template: "<div class=\"xrow\">\n\t<div class=\"xcol\">\n\t\t@if (settings().collapsed !== undefined) {\n\t\t\t<mat-expansion-panel [expanded]=\"!settings().collapsed\" class=\"query-expansion\">\n\t\t\t\t<mat-expansion-panel-header>\n\t\t\t\t\t<mat-panel-title>\n\t\t\t\t\t\t<mat-icon>filter_list</mat-icon> Filter\n\t\t\t\t\t</mat-panel-title>\n\t\t\t\t</mat-expansion-panel-header>\n\t\t\t\t<div class=\"query\">\n\t\t\t\t\t<xiri-form-fields [form]=\"formFields()\" (formChange)=\"formChanged($event)\" display=\"line\"></xiri-form-fields>\n\t\t\t\t\t<ng-container *ngTemplateOutlet=\"filterState\"></ng-container>\n\t\t\t\t\t@if (error()) {\n\t\t\t\t\t\t<div class=\"error\">\n\t\t\t\t\t\t\t<span>{{ error() }}</span>\n\t\t\t\t\t\t\t<button mat-button type=\"button\" data-testid=\"query-retry\" (click)=\"retry()\">\n\t\t\t\t\t\t\t\t<mat-icon>refresh</mat-icon> Retry\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t</mat-expansion-panel>\n\t\t} @else {\n\t\t\t<div class=\"query\">\n\t\t\t\t<xiri-form-fields [form]=\"formFields()\" (formChange)=\"formChanged($event)\" display=\"line\"></xiri-form-fields>\n\t\t\t\t<ng-container *ngTemplateOutlet=\"filterState\"></ng-container>\n\t\t\t\t@if (error()) {\n\t\t\t\t\t<div class=\"error\">\n\t\t\t\t\t\t<span>{{ error() }}</span>\n\t\t\t\t\t\t<button mat-button type=\"button\" data-testid=\"query-retry\" (click)=\"retry()\">\n\t\t\t\t\t\t\t<mat-icon>refresh</mat-icon> Retry\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t</div>\n\t@if (settings().buttonline; as buttonline) {\n\t\t<div class=\"xcol formbtnline\" [class]=\"buttonline.display\">\n\t\t\t<xiri-buttonline [settings]=\"$any(buttonline.data)\" [filterData]=\"filterData()\" [disabled]=\"!formValid()\"\n\t\t\t (result)=\"clickedButton($event)\"></xiri-buttonline>\n\t\t</div>\n\t\t@if (loading()) {\n\t\t\t<div class=\"xcol\">\n\t\t\t\t<mat-spinner diameter=\"30\"></mat-spinner>\n\t\t\t</div>\n\t\t}\n\t}\n\t@if (dynData.data) {\n\t\t<div class=\"xcol\">\n\t\t\t<ng-container *ngTemplateOutlet=\"dyncomponent(); context: { $implicit: dynData }\"></ng-container>\n\t\t</div>\n\t}\n\t@if (data()) {\n\t\t<div class=\"xcol\" [class.is-loading]=\"loading()\">\n\t\t\t<ng-container *ngTemplateOutlet=\"dyncomponent(); context: { $implicit: data() }\"></ng-container>\n\t\t</div>\n\t}\n</div>\n\n<ng-template #filterState>\n\t@if (settings().showActiveFilters && activeFilters().length) {\n\t\t<div class=\"query-filter-state\">\n\t\t\t<mat-chip-set aria-label=\"Aktive Filter\">\n\t\t\t\t@for (filter of activeFilters(); track filter.id) {\n\t\t\t\t\t<mat-chip data-testid=\"query-filter-chip\" (removed)=\"removeFilter(filter.id)\">\n\t\t\t\t\t\t<span class=\"chip-label\">{{ filter.label }}: {{ filter.value }}</span>\n\t\t\t\t\t\t<button matChipRemove type=\"button\"\n\t\t\t\t\t\t [attr.aria-label]=\"'Filter entfernen: ' + filter.label + ' ' + filter.value\">\n\t\t\t\t\t\t\t<mat-icon>cancel</mat-icon>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</mat-chip>\n\t\t\t\t}\n\t\t\t</mat-chip-set>\n\t\t\t<button mat-button type=\"button\" class=\"reset-filters\" data-testid=\"query-reset-filters\"\n\t\t\t (click)=\"resetFilters()\">\n\t\t\t\t<mat-icon>filter_list_off</mat-icon> Alle zur\u00FCcksetzen\n\t\t\t</button>\n\t\t</div>\n\t}\n\t@if (settings().showResultCount && resultCount(); as rc) {\n\t\t<div class=\"query-result-count\" data-testid=\"query-result-count\" aria-live=\"polite\">\n\t\t\t@if (rc.total !== undefined) {\n\t\t\t\t<span><strong>{{ rc.filtered }}</strong> von {{ rc.total }} Treffern</span>\n\t\t\t} @else {\n\t\t\t\t<span><strong>{{ rc.filtered }}</strong> Treffer</span>\n\t\t\t}\n\t\t</div>\n\t}\n</ng-template>\n", styles: [".query{padding-left:var(--xiri-spacing-md);padding-right:var(--xiri-spacing-md)}.is-loading{opacity:.5;transition:opacity .15s ease-in-out;pointer-events:none}.query-filter-state{display:flex;align-items:center;flex-wrap:wrap;gap:var(--xiri-spacing-sm);margin-top:var(--xiri-spacing-sm)}.query-filter-state .reset-filters mat-icon{margin-right:var(--xiri-spacing-xs)}.query-result-count{margin-top:var(--xiri-spacing-sm);color:var(--on-surface-variant, var(--mat-sys-on-surface-variant, inherit));font-size:.9rem}.query-expansion .query{padding-left:0;padding-right:0}.query-expansion mat-panel-title mat-icon{margin-right:var(--xiri-spacing-sm)}\n"] }]
5922
5961
  }], propDecorators: { settings: [{ type: i0.Input, args: [{ isSignal: true, alias: "settings", required: true }] }], dyncomponent: [{ type: i0.Input, args: [{ isSignal: true, alias: "dyncomponent", required: false }] }], count: [{ type: i0.Input, args: [{ isSignal: true, alias: "count", required: false }] }], filterChange: [{ type: i0.Output, args: ["filterChange"] }] } });
5923
5962
  // A filter counts as active unless it is null/undefined, an empty string, an empty array,
5924
5963
  // a boolean false, or a range object with no bounds set.
@@ -5988,7 +6027,7 @@ class XiriLinksComponent {
5988
6027
  return true;
5989
6028
  }
5990
6029
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriLinksComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5991
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: XiriLinksComponent, isStandalone: true, selector: "xiri-links", inputs: { settings: { classPropertyName: "settings", publicName: "settings", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "class.compact": "compact()" } }, ngImport: i0, template: "@if (compact()) {\n\t<div class=\"card xiri-links-flat\">\n\t\t@if (settings().header || settings().headerIcon) {\n\t\t\t<div class=\"xiri-links-header\">\n\t\t\t\t@if (settings().headerIcon) {\n\t\t\t\t\t<div class=\"header-image\">\n\t\t\t\t\t\t<mat-icon [class]=\"settings().headerIconColor || 'primary'\">{{ settings().headerIcon }}</mat-icon>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t<div class=\"header-text\">\n\t\t\t\t\t@if (settings().header) {\n\t\t\t\t\t\t<div class=\"header-title\">{{ settings().header }}</div>\n\t\t\t\t\t}\n\t\t\t\t\t@if (settings().headerSub) {\n\t\t\t\t\t\t<div class=\"header-sub\">{{ settings().headerSub }}</div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t}\n\t\t<ng-container *ngTemplateOutlet=\"linkList\"></ng-container>\n\t</div>\n} @else {\n\t<mat-card class=\"card mat-mdc-elevation-specific mat-elevation-z2\">\n\t\t<mat-card-header>\n\t\t\t@if (settings().headerIcon) {\n\t\t\t\t<div mat-card-avatar class=\"header-image\">\n\t\t\t\t\t<mat-icon [class]=\"settings().headerIconColor || 'primary'\">{{ settings().headerIcon }}</mat-icon>\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@if (settings().headerSub) {\n\t\t\t\t<mat-card-subtitle>{{ settings().headerSub }}</mat-card-subtitle>\n\t\t\t}\n\t\t\t@if (settings().header) {\n\t\t\t\t<mat-card-title>{{ settings().header }}</mat-card-title>\n\t\t\t}\n\t\t</mat-card-header>\n\t\t<mat-card-content>\n\t\t\t<ng-container *ngTemplateOutlet=\"linkList\"></ng-container>\n\t\t</mat-card-content>\n\t</mat-card>\n}\n\n<ng-template #linkList>\n\t<mat-nav-list>\n\t\t@for (item of settings().data; track item) {\n\t\t\t@if (!item.action || item.action === 'link') {\n\t\t\t\t@let itemUrl = item.url | xiriUrl;\n\t\t\t\t<a mat-list-item [routerLink]=\"itemUrl?.path\" [queryParams]=\"itemUrl?.queryParams\">\n\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t<mat-icon matListItemIcon>{{ item.icon }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t\t<span matListItemTitle>{{ item.text }}</span>\n\t\t\t\t</a>\n\t\t\t} @else if (item.action === 'dialog') {\n\t\t\t\t<mat-list-item (click)=\"openDialog( item ) && $event.stopPropagation()\" (keydown.enter)=\"openDialog( item )\" (keydown.space)=\"openDialog( item ); $event.preventDefault()\">\n\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t<mat-icon matListItemIcon [class]=\"item.color || 'primary'\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t\t<span matListItemTitle>{{ item.text }}</span>\n\t\t\t\t</mat-list-item>\n\t\t\t}\n\t\t}\n\t</mat-nav-list>\n</ng-template>\n", styles: ["mat-card{margin-bottom:2rem}mat-card mat-card-content{margin:0 -1rem}mat-card mat-nav-list .mat-mdc-list-item{border-bottom:1px solid var(--outline-variant, #E7EBEE);text-decoration:underline}:host(.compact) .xiri-links-flat{background:transparent;box-shadow:none;padding:0;margin-bottom:0}:host(.compact) .xiri-links-header{display:flex;gap:var(--xiri-spacing-sm, 8px);align-items:center;margin-bottom:var(--xiri-spacing-sm, 8px)}:host(.compact) .xiri-links-header .header-title{font-size:var(--xiri-font-size-body);font-weight:500}:host(.compact) .xiri-links-header .header-sub{font-size:var(--xiri-font-size-label);color:var(--mat-sys-on-surface-variant, #555)}:host(.compact) mat-nav-list .mat-mdc-list-item{border-bottom:1px solid var(--outline-variant, #E7EBEE);text-decoration:underline}\n"], dependencies: [{ kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: MatCardAvatar, selector: "[mat-card-avatar], [matCardAvatar]" }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatCardSubtitle, selector: "mat-card-subtitle, [mat-card-subtitle], [matCardSubtitle]" }, { kind: "directive", type: MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "directive", type: MatCardContent, selector: "mat-card-content" }, { kind: "component", type: MatNavList, selector: "mat-nav-list", exportAs: ["matNavList"] }, { kind: "component", type: MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "directive", type: MatListItemIcon, selector: "[matListItemIcon]" }, { kind: "directive", type: MatListItemTitle, selector: "[matListItemTitle]" }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: XiriUrlPipe, name: "xiriUrl" }] }); }
6030
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: XiriLinksComponent, isStandalone: true, selector: "xiri-links", inputs: { settings: { classPropertyName: "settings", publicName: "settings", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "class.compact": "compact()" } }, ngImport: i0, template: "@if (compact()) {\n\t<div class=\"card xiri-links-flat\">\n\t\t@if (settings().header || settings().headerIcon) {\n\t\t\t<div class=\"xiri-links-header\">\n\t\t\t\t@if (settings().headerIcon) {\n\t\t\t\t\t<div class=\"header-image\">\n\t\t\t\t\t\t<mat-icon [class]=\"settings().headerIconColor || 'primary'\">{{ settings().headerIcon }}</mat-icon>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t<div class=\"header-text\">\n\t\t\t\t\t@if (settings().header) {\n\t\t\t\t\t\t<div class=\"header-title\">{{ settings().header }}</div>\n\t\t\t\t\t}\n\t\t\t\t\t@if (settings().headerSub) {\n\t\t\t\t\t\t<div class=\"header-sub\">{{ settings().headerSub }}</div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t}\n\t\t<ng-container *ngTemplateOutlet=\"linkList\"></ng-container>\n\t</div>\n} @else {\n\t<mat-card class=\"card mat-mdc-elevation-specific mat-elevation-z2\">\n\t\t<mat-card-header>\n\t\t\t@if (settings().headerIcon) {\n\t\t\t\t<div mat-card-avatar class=\"header-image\">\n\t\t\t\t\t<mat-icon [class]=\"settings().headerIconColor || 'primary'\">{{ settings().headerIcon }}</mat-icon>\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@if (settings().headerSub) {\n\t\t\t\t<mat-card-subtitle>{{ settings().headerSub }}</mat-card-subtitle>\n\t\t\t}\n\t\t\t@if (settings().header) {\n\t\t\t\t<mat-card-title>{{ settings().header }}</mat-card-title>\n\t\t\t}\n\t\t</mat-card-header>\n\t\t<mat-card-content>\n\t\t\t<ng-container *ngTemplateOutlet=\"linkList\"></ng-container>\n\t\t</mat-card-content>\n\t</mat-card>\n}\n\n<ng-template #linkList>\n\t<mat-nav-list>\n\t\t@for (item of settings().data; track item) {\n\t\t\t@if (!item.hide && (!item.action || item.action === 'link')) {\n\t\t\t\t@let itemUrl = item.url | xiriUrl;\n\t\t\t\t<a mat-list-item [routerLink]=\"itemUrl?.path\" [queryParams]=\"itemUrl?.queryParams\">\n\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t<mat-icon matListItemIcon>{{ item.icon }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t\t<span matListItemTitle>{{ item.text }}</span>\n\t\t\t\t</a>\n\t\t\t} @else if (!item.hide && item.action === 'dialog') {\n\t\t\t\t<mat-list-item (click)=\"openDialog( item ) && $event.stopPropagation()\" (keydown.enter)=\"openDialog( item )\" (keydown.space)=\"openDialog( item ); $event.preventDefault()\">\n\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t<mat-icon matListItemIcon [class]=\"item.color || 'primary'\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t\t<span matListItemTitle>{{ item.text }}</span>\n\t\t\t\t</mat-list-item>\n\t\t\t}\n\t\t}\n\t</mat-nav-list>\n</ng-template>\n", styles: ["mat-card{margin-bottom:2rem}mat-card mat-card-content{margin:0 -1rem}mat-card mat-nav-list .mat-mdc-list-item{border-bottom:1px solid var(--outline-variant, #E7EBEE);text-decoration:underline}:host(.compact) .xiri-links-flat{background:transparent;box-shadow:none;padding:0;margin-bottom:0}:host(.compact) .xiri-links-header{display:flex;gap:var(--xiri-spacing-sm, 8px);align-items:center;margin-bottom:var(--xiri-spacing-sm, 8px)}:host(.compact) .xiri-links-header .header-title{font-size:var(--xiri-font-size-body);font-weight:500}:host(.compact) .xiri-links-header .header-sub{font-size:var(--xiri-font-size-label);color:var(--on-surface-variant, var(--mat-sys-on-surface-variant, #555))}:host(.compact) mat-nav-list .mat-mdc-list-item{border-bottom:1px solid var(--outline-variant, #E7EBEE);text-decoration:underline}\n"], dependencies: [{ kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: MatCardAvatar, selector: "[mat-card-avatar], [matCardAvatar]" }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatCardSubtitle, selector: "mat-card-subtitle, [mat-card-subtitle], [matCardSubtitle]" }, { kind: "directive", type: MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "directive", type: MatCardContent, selector: "mat-card-content" }, { kind: "component", type: MatNavList, selector: "mat-nav-list", exportAs: ["matNavList"] }, { kind: "component", type: MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "directive", type: MatListItemIcon, selector: "[matListItemIcon]" }, { kind: "directive", type: MatListItemTitle, selector: "[matListItemTitle]" }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: XiriUrlPipe, name: "xiriUrl" }] }); }
5992
6031
  }
5993
6032
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriLinksComponent, decorators: [{
5994
6033
  type: Component,
@@ -6005,7 +6044,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
6005
6044
  MatListItemTitle,
6006
6045
  RouterLink,
6007
6046
  NgTemplateOutlet,
6008
- XiriUrlPipe], host: { '[class.compact]': 'compact()' }, template: "@if (compact()) {\n\t<div class=\"card xiri-links-flat\">\n\t\t@if (settings().header || settings().headerIcon) {\n\t\t\t<div class=\"xiri-links-header\">\n\t\t\t\t@if (settings().headerIcon) {\n\t\t\t\t\t<div class=\"header-image\">\n\t\t\t\t\t\t<mat-icon [class]=\"settings().headerIconColor || 'primary'\">{{ settings().headerIcon }}</mat-icon>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t<div class=\"header-text\">\n\t\t\t\t\t@if (settings().header) {\n\t\t\t\t\t\t<div class=\"header-title\">{{ settings().header }}</div>\n\t\t\t\t\t}\n\t\t\t\t\t@if (settings().headerSub) {\n\t\t\t\t\t\t<div class=\"header-sub\">{{ settings().headerSub }}</div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t}\n\t\t<ng-container *ngTemplateOutlet=\"linkList\"></ng-container>\n\t</div>\n} @else {\n\t<mat-card class=\"card mat-mdc-elevation-specific mat-elevation-z2\">\n\t\t<mat-card-header>\n\t\t\t@if (settings().headerIcon) {\n\t\t\t\t<div mat-card-avatar class=\"header-image\">\n\t\t\t\t\t<mat-icon [class]=\"settings().headerIconColor || 'primary'\">{{ settings().headerIcon }}</mat-icon>\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@if (settings().headerSub) {\n\t\t\t\t<mat-card-subtitle>{{ settings().headerSub }}</mat-card-subtitle>\n\t\t\t}\n\t\t\t@if (settings().header) {\n\t\t\t\t<mat-card-title>{{ settings().header }}</mat-card-title>\n\t\t\t}\n\t\t</mat-card-header>\n\t\t<mat-card-content>\n\t\t\t<ng-container *ngTemplateOutlet=\"linkList\"></ng-container>\n\t\t</mat-card-content>\n\t</mat-card>\n}\n\n<ng-template #linkList>\n\t<mat-nav-list>\n\t\t@for (item of settings().data; track item) {\n\t\t\t@if (!item.action || item.action === 'link') {\n\t\t\t\t@let itemUrl = item.url | xiriUrl;\n\t\t\t\t<a mat-list-item [routerLink]=\"itemUrl?.path\" [queryParams]=\"itemUrl?.queryParams\">\n\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t<mat-icon matListItemIcon>{{ item.icon }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t\t<span matListItemTitle>{{ item.text }}</span>\n\t\t\t\t</a>\n\t\t\t} @else if (item.action === 'dialog') {\n\t\t\t\t<mat-list-item (click)=\"openDialog( item ) && $event.stopPropagation()\" (keydown.enter)=\"openDialog( item )\" (keydown.space)=\"openDialog( item ); $event.preventDefault()\">\n\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t<mat-icon matListItemIcon [class]=\"item.color || 'primary'\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t\t<span matListItemTitle>{{ item.text }}</span>\n\t\t\t\t</mat-list-item>\n\t\t\t}\n\t\t}\n\t</mat-nav-list>\n</ng-template>\n", styles: ["mat-card{margin-bottom:2rem}mat-card mat-card-content{margin:0 -1rem}mat-card mat-nav-list .mat-mdc-list-item{border-bottom:1px solid var(--outline-variant, #E7EBEE);text-decoration:underline}:host(.compact) .xiri-links-flat{background:transparent;box-shadow:none;padding:0;margin-bottom:0}:host(.compact) .xiri-links-header{display:flex;gap:var(--xiri-spacing-sm, 8px);align-items:center;margin-bottom:var(--xiri-spacing-sm, 8px)}:host(.compact) .xiri-links-header .header-title{font-size:var(--xiri-font-size-body);font-weight:500}:host(.compact) .xiri-links-header .header-sub{font-size:var(--xiri-font-size-label);color:var(--mat-sys-on-surface-variant, #555)}:host(.compact) mat-nav-list .mat-mdc-list-item{border-bottom:1px solid var(--outline-variant, #E7EBEE);text-decoration:underline}\n"] }]
6047
+ XiriUrlPipe], host: { '[class.compact]': 'compact()' }, template: "@if (compact()) {\n\t<div class=\"card xiri-links-flat\">\n\t\t@if (settings().header || settings().headerIcon) {\n\t\t\t<div class=\"xiri-links-header\">\n\t\t\t\t@if (settings().headerIcon) {\n\t\t\t\t\t<div class=\"header-image\">\n\t\t\t\t\t\t<mat-icon [class]=\"settings().headerIconColor || 'primary'\">{{ settings().headerIcon }}</mat-icon>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t<div class=\"header-text\">\n\t\t\t\t\t@if (settings().header) {\n\t\t\t\t\t\t<div class=\"header-title\">{{ settings().header }}</div>\n\t\t\t\t\t}\n\t\t\t\t\t@if (settings().headerSub) {\n\t\t\t\t\t\t<div class=\"header-sub\">{{ settings().headerSub }}</div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t}\n\t\t<ng-container *ngTemplateOutlet=\"linkList\"></ng-container>\n\t</div>\n} @else {\n\t<mat-card class=\"card mat-mdc-elevation-specific mat-elevation-z2\">\n\t\t<mat-card-header>\n\t\t\t@if (settings().headerIcon) {\n\t\t\t\t<div mat-card-avatar class=\"header-image\">\n\t\t\t\t\t<mat-icon [class]=\"settings().headerIconColor || 'primary'\">{{ settings().headerIcon }}</mat-icon>\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@if (settings().headerSub) {\n\t\t\t\t<mat-card-subtitle>{{ settings().headerSub }}</mat-card-subtitle>\n\t\t\t}\n\t\t\t@if (settings().header) {\n\t\t\t\t<mat-card-title>{{ settings().header }}</mat-card-title>\n\t\t\t}\n\t\t</mat-card-header>\n\t\t<mat-card-content>\n\t\t\t<ng-container *ngTemplateOutlet=\"linkList\"></ng-container>\n\t\t</mat-card-content>\n\t</mat-card>\n}\n\n<ng-template #linkList>\n\t<mat-nav-list>\n\t\t@for (item of settings().data; track item) {\n\t\t\t@if (!item.hide && (!item.action || item.action === 'link')) {\n\t\t\t\t@let itemUrl = item.url | xiriUrl;\n\t\t\t\t<a mat-list-item [routerLink]=\"itemUrl?.path\" [queryParams]=\"itemUrl?.queryParams\">\n\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t<mat-icon matListItemIcon>{{ item.icon }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t\t<span matListItemTitle>{{ item.text }}</span>\n\t\t\t\t</a>\n\t\t\t} @else if (!item.hide && item.action === 'dialog') {\n\t\t\t\t<mat-list-item (click)=\"openDialog( item ) && $event.stopPropagation()\" (keydown.enter)=\"openDialog( item )\" (keydown.space)=\"openDialog( item ); $event.preventDefault()\">\n\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t<mat-icon matListItemIcon [class]=\"item.color || 'primary'\">{{ item.icon }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t\t<span matListItemTitle>{{ item.text }}</span>\n\t\t\t\t</mat-list-item>\n\t\t\t}\n\t\t}\n\t</mat-nav-list>\n</ng-template>\n", styles: ["mat-card{margin-bottom:2rem}mat-card mat-card-content{margin:0 -1rem}mat-card mat-nav-list .mat-mdc-list-item{border-bottom:1px solid var(--outline-variant, #E7EBEE);text-decoration:underline}:host(.compact) .xiri-links-flat{background:transparent;box-shadow:none;padding:0;margin-bottom:0}:host(.compact) .xiri-links-header{display:flex;gap:var(--xiri-spacing-sm, 8px);align-items:center;margin-bottom:var(--xiri-spacing-sm, 8px)}:host(.compact) .xiri-links-header .header-title{font-size:var(--xiri-font-size-body);font-weight:500}:host(.compact) .xiri-links-header .header-sub{font-size:var(--xiri-font-size-label);color:var(--on-surface-variant, var(--mat-sys-on-surface-variant, #555))}:host(.compact) mat-nav-list .mat-mdc-list-item{border-bottom:1px solid var(--outline-variant, #E7EBEE);text-decoration:underline}\n"] }]
6009
6048
  }], propDecorators: { settings: [{ type: i0.Input, args: [{ isSignal: true, alias: "settings", required: true }] }] } });
6010
6049
 
6011
6050
  class XiriCardlinkComponent {
@@ -6587,7 +6626,7 @@ class XiriSidepanelComponent {
6587
6626
  <xiri-dyncomponent [data]="$any(config().data)"></xiri-dyncomponent>
6588
6627
  }
6589
6628
  </div>
6590
- `, isInline: true, styles: [":host{display:flex;flex-direction:column;height:100%;background:var(--mat-sys-surface, #fff);box-shadow:var(--xiri-elevation-2, 0 0 16px rgba(0, 0, 0, .2))}.sidepanel-header{display:flex;align-items:center;justify-content:space-between;padding:var(--xiri-spacing-md);border-bottom:1px solid var(--xiri-border-color, rgba(0, 0, 0, .12))}.sidepanel-title{font-size:var(--xiri-font-size-title);font-weight:500}.sidepanel-content{flex:1 1 auto;overflow-y:auto;padding:var(--xiri-spacing-md)}\n"], dependencies: [{ 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"] }, { kind: "component", type: XiriDynComponentComponent, selector: "xiri-dyncomponent", inputs: ["data", "filterData", "dyncomponent"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6629
+ `, isInline: true, styles: [":host{display:flex;flex-direction:column;height:100%;background:var(--surface, var(--mat-sys-surface, #fff));box-shadow:var(--xiri-elevation-2, 0 0 16px rgba(0, 0, 0, .2))}.sidepanel-header{display:flex;align-items:center;justify-content:space-between;padding:var(--xiri-spacing-md);border-bottom:1px solid var(--xiri-border-color, rgba(0, 0, 0, .12))}.sidepanel-title{font-size:var(--xiri-font-size-title);font-weight:500}.sidepanel-content{flex:1 1 auto;overflow-y:auto;padding:var(--xiri-spacing-md)}\n"], dependencies: [{ 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"] }, { kind: "component", type: XiriDynComponentComponent, selector: "xiri-dyncomponent", inputs: ["data", "filterData", "dyncomponent"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6591
6630
  }
6592
6631
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriSidepanelComponent, decorators: [{
6593
6632
  type: Component,
@@ -6605,7 +6644,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
6605
6644
  <xiri-dyncomponent [data]="$any(config().data)"></xiri-dyncomponent>
6606
6645
  }
6607
6646
  </div>
6608
- `, styles: [":host{display:flex;flex-direction:column;height:100%;background:var(--mat-sys-surface, #fff);box-shadow:var(--xiri-elevation-2, 0 0 16px rgba(0, 0, 0, .2))}.sidepanel-header{display:flex;align-items:center;justify-content:space-between;padding:var(--xiri-spacing-md);border-bottom:1px solid var(--xiri-border-color, rgba(0, 0, 0, .12))}.sidepanel-title{font-size:var(--xiri-font-size-title);font-weight:500}.sidepanel-content{flex:1 1 auto;overflow-y:auto;padding:var(--xiri-spacing-md)}\n"] }]
6647
+ `, styles: [":host{display:flex;flex-direction:column;height:100%;background:var(--surface, var(--mat-sys-surface, #fff));box-shadow:var(--xiri-elevation-2, 0 0 16px rgba(0, 0, 0, .2))}.sidepanel-header{display:flex;align-items:center;justify-content:space-between;padding:var(--xiri-spacing-md);border-bottom:1px solid var(--xiri-border-color, rgba(0, 0, 0, .12))}.sidepanel-title{font-size:var(--xiri-font-size-title);font-weight:500}.sidepanel-content{flex:1 1 auto;overflow-y:auto;padding:var(--xiri-spacing-md)}\n"] }]
6609
6648
  }], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], ref: [{ type: i0.Input, args: [{ isSignal: true, alias: "ref", required: true }] }] } });
6610
6649
 
6611
6650
  class XiriSidepanelService {
@@ -6736,7 +6775,7 @@ class XiriImagetextComponent {
6736
6775
  ...(ngDevMode ? [{ debugName: "compact" }] : /* istanbul ignore next */ []));
6737
6776
  }
6738
6777
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriImagetextComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6739
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: XiriImagetextComponent, isStandalone: true, selector: "xiri-imagetext", inputs: { settings: { classPropertyName: "settings", publicName: "settings", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "class.compact": "compact()" } }, ngImport: i0, template: "@if (compact()) {\n\t<div class=\"card xiri-imagetext-flat\">\n\t\t@if (settings().header || settings().headerIcon) {\n\t\t\t<div class=\"xiri-imagetext-header align-items-center\">\n\t\t\t\t@if (settings().headerIcon) {\n\t\t\t\t\t<div class=\"header-image\">\n\t\t\t\t\t\t<mat-icon [class]=\"settings().headerIconColor || 'primary'\">{{ settings().headerIcon }}</mat-icon>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t<div class=\"header-text\">\n\t\t\t\t\t@if (settings().header) {\n\t\t\t\t\t\t<div class=\"header-title\">{{ settings().header }}</div>\n\t\t\t\t\t}\n\t\t\t\t\t@if (settings().headerSub) {\n\t\t\t\t\t\t<div class=\"header-sub\">{{ settings().headerSub }}</div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t}\n\t\t<div class=\"xiri-imagetext-content\">\n\t\t\t<mat-spinner [hidden]=\"!loading()\" diameter=\"30\"></mat-spinner>\n\t\t\t<img [hidden]=\"loading()\" (load)=\"loading.set(false)\" [src]=\"settings().url\" [alt]=\"settings().info\" id=\"ximg\"/>\n\t\t</div>\n\t</div>\n} @else {\n\t<mat-card class=\"card mat-mdc-elevation-specific mat-elevation-z2\">\n\t\t<mat-card-header class=\"align-items-center\">\n\t\t\t@if (settings().headerIcon) {\n\t\t\t\t<div mat-card-avatar class=\"header-image\">\n\t\t\t\t\t<mat-icon [class]=\"settings().headerIconColor || 'primary'\">{{ settings().headerIcon }}</mat-icon>\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@if (settings().header) {\n\t\t\t\t<mat-card-title>{{ settings().header }}</mat-card-title>\n\t\t\t}\n\t\t\t@if (settings().headerSub) {\n\t\t\t\t<mat-card-subtitle>{{ settings().headerSub }}</mat-card-subtitle>\n\t\t\t}\n\t\t</mat-card-header>\n\t\t<mat-card-content>\n\t\t\t<mat-spinner [hidden]=\"!loading()\" diameter=\"30\"></mat-spinner>\n\t\t\t<img [hidden]=\"loading()\" (load)=\"loading.set(false)\" [src]=\"settings().url\" [alt]=\"settings().info\" id=\"ximg\"/>\n\t\t</mat-card-content>\n\t</mat-card>\n}\n", styles: [".card{margin-bottom:2rem;text-align:center}#ximg{max-width:100%}[hidden]{display:none!important}:host(.compact) .xiri-imagetext-flat{background:transparent;box-shadow:none;padding:0;margin-bottom:0}:host(.compact) .xiri-imagetext-header{display:flex;gap:var(--xiri-spacing-sm, 8px);margin-bottom:var(--xiri-spacing-sm, 8px)}:host(.compact) .header-title{font-size:var(--xiri-font-size-body);font-weight:500}:host(.compact) .header-sub{font-size:var(--xiri-font-size-label);color:var(--mat-sys-on-surface-variant, #555)}\n"], dependencies: [{ kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: MatCardAvatar, selector: "[mat-card-avatar], [matCardAvatar]" }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "directive", type: MatCardSubtitle, selector: "mat-card-subtitle, [mat-card-subtitle], [matCardSubtitle]" }, { kind: "directive", type: MatCardContent, selector: "mat-card-content" }, { kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }] }); }
6778
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: XiriImagetextComponent, isStandalone: true, selector: "xiri-imagetext", inputs: { settings: { classPropertyName: "settings", publicName: "settings", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "class.compact": "compact()" } }, ngImport: i0, template: "@if (compact()) {\n\t<div class=\"card xiri-imagetext-flat\">\n\t\t@if (settings().header || settings().headerIcon) {\n\t\t\t<div class=\"xiri-imagetext-header align-items-center\">\n\t\t\t\t@if (settings().headerIcon) {\n\t\t\t\t\t<div class=\"header-image\">\n\t\t\t\t\t\t<mat-icon [class]=\"settings().headerIconColor || 'primary'\">{{ settings().headerIcon }}</mat-icon>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t<div class=\"header-text\">\n\t\t\t\t\t@if (settings().header) {\n\t\t\t\t\t\t<div class=\"header-title\">{{ settings().header }}</div>\n\t\t\t\t\t}\n\t\t\t\t\t@if (settings().headerSub) {\n\t\t\t\t\t\t<div class=\"header-sub\">{{ settings().headerSub }}</div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t}\n\t\t<div class=\"xiri-imagetext-content\">\n\t\t\t<mat-spinner [hidden]=\"!loading()\" diameter=\"30\"></mat-spinner>\n\t\t\t<img [hidden]=\"loading()\" (load)=\"loading.set(false)\" [src]=\"settings().url\" [alt]=\"settings().info\" id=\"ximg\"/>\n\t\t</div>\n\t</div>\n} @else {\n\t<mat-card class=\"card mat-mdc-elevation-specific mat-elevation-z2\">\n\t\t<mat-card-header class=\"align-items-center\">\n\t\t\t@if (settings().headerIcon) {\n\t\t\t\t<div mat-card-avatar class=\"header-image\">\n\t\t\t\t\t<mat-icon [class]=\"settings().headerIconColor || 'primary'\">{{ settings().headerIcon }}</mat-icon>\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@if (settings().header) {\n\t\t\t\t<mat-card-title>{{ settings().header }}</mat-card-title>\n\t\t\t}\n\t\t\t@if (settings().headerSub) {\n\t\t\t\t<mat-card-subtitle>{{ settings().headerSub }}</mat-card-subtitle>\n\t\t\t}\n\t\t</mat-card-header>\n\t\t<mat-card-content>\n\t\t\t<mat-spinner [hidden]=\"!loading()\" diameter=\"30\"></mat-spinner>\n\t\t\t<img [hidden]=\"loading()\" (load)=\"loading.set(false)\" [src]=\"settings().url\" [alt]=\"settings().info\" id=\"ximg\"/>\n\t\t</mat-card-content>\n\t</mat-card>\n}\n", styles: [".card{margin-bottom:2rem;text-align:center}#ximg{max-width:100%}[hidden]{display:none!important}:host(.compact) .xiri-imagetext-flat{background:transparent;box-shadow:none;padding:0;margin-bottom:0}:host(.compact) .xiri-imagetext-header{display:flex;gap:var(--xiri-spacing-sm, 8px);margin-bottom:var(--xiri-spacing-sm, 8px)}:host(.compact) .header-title{font-size:var(--xiri-font-size-body);font-weight:500}:host(.compact) .header-sub{font-size:var(--xiri-font-size-label);color:var(--on-surface-variant, var(--mat-sys-on-surface-variant, #555))}\n"], dependencies: [{ kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: MatCardAvatar, selector: "[mat-card-avatar], [matCardAvatar]" }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "directive", type: MatCardSubtitle, selector: "mat-card-subtitle, [mat-card-subtitle], [matCardSubtitle]" }, { kind: "directive", type: MatCardContent, selector: "mat-card-content" }, { kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }] }); }
6740
6779
  }
6741
6780
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriImagetextComponent, decorators: [{
6742
6781
  type: Component,
@@ -6747,7 +6786,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
6747
6786
  MatCardTitle,
6748
6787
  MatCardSubtitle,
6749
6788
  MatCardContent,
6750
- MatProgressSpinner], host: { '[class.compact]': 'compact()' }, template: "@if (compact()) {\n\t<div class=\"card xiri-imagetext-flat\">\n\t\t@if (settings().header || settings().headerIcon) {\n\t\t\t<div class=\"xiri-imagetext-header align-items-center\">\n\t\t\t\t@if (settings().headerIcon) {\n\t\t\t\t\t<div class=\"header-image\">\n\t\t\t\t\t\t<mat-icon [class]=\"settings().headerIconColor || 'primary'\">{{ settings().headerIcon }}</mat-icon>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t<div class=\"header-text\">\n\t\t\t\t\t@if (settings().header) {\n\t\t\t\t\t\t<div class=\"header-title\">{{ settings().header }}</div>\n\t\t\t\t\t}\n\t\t\t\t\t@if (settings().headerSub) {\n\t\t\t\t\t\t<div class=\"header-sub\">{{ settings().headerSub }}</div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t}\n\t\t<div class=\"xiri-imagetext-content\">\n\t\t\t<mat-spinner [hidden]=\"!loading()\" diameter=\"30\"></mat-spinner>\n\t\t\t<img [hidden]=\"loading()\" (load)=\"loading.set(false)\" [src]=\"settings().url\" [alt]=\"settings().info\" id=\"ximg\"/>\n\t\t</div>\n\t</div>\n} @else {\n\t<mat-card class=\"card mat-mdc-elevation-specific mat-elevation-z2\">\n\t\t<mat-card-header class=\"align-items-center\">\n\t\t\t@if (settings().headerIcon) {\n\t\t\t\t<div mat-card-avatar class=\"header-image\">\n\t\t\t\t\t<mat-icon [class]=\"settings().headerIconColor || 'primary'\">{{ settings().headerIcon }}</mat-icon>\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@if (settings().header) {\n\t\t\t\t<mat-card-title>{{ settings().header }}</mat-card-title>\n\t\t\t}\n\t\t\t@if (settings().headerSub) {\n\t\t\t\t<mat-card-subtitle>{{ settings().headerSub }}</mat-card-subtitle>\n\t\t\t}\n\t\t</mat-card-header>\n\t\t<mat-card-content>\n\t\t\t<mat-spinner [hidden]=\"!loading()\" diameter=\"30\"></mat-spinner>\n\t\t\t<img [hidden]=\"loading()\" (load)=\"loading.set(false)\" [src]=\"settings().url\" [alt]=\"settings().info\" id=\"ximg\"/>\n\t\t</mat-card-content>\n\t</mat-card>\n}\n", styles: [".card{margin-bottom:2rem;text-align:center}#ximg{max-width:100%}[hidden]{display:none!important}:host(.compact) .xiri-imagetext-flat{background:transparent;box-shadow:none;padding:0;margin-bottom:0}:host(.compact) .xiri-imagetext-header{display:flex;gap:var(--xiri-spacing-sm, 8px);margin-bottom:var(--xiri-spacing-sm, 8px)}:host(.compact) .header-title{font-size:var(--xiri-font-size-body);font-weight:500}:host(.compact) .header-sub{font-size:var(--xiri-font-size-label);color:var(--mat-sys-on-surface-variant, #555)}\n"] }]
6789
+ MatProgressSpinner], host: { '[class.compact]': 'compact()' }, template: "@if (compact()) {\n\t<div class=\"card xiri-imagetext-flat\">\n\t\t@if (settings().header || settings().headerIcon) {\n\t\t\t<div class=\"xiri-imagetext-header align-items-center\">\n\t\t\t\t@if (settings().headerIcon) {\n\t\t\t\t\t<div class=\"header-image\">\n\t\t\t\t\t\t<mat-icon [class]=\"settings().headerIconColor || 'primary'\">{{ settings().headerIcon }}</mat-icon>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\t<div class=\"header-text\">\n\t\t\t\t\t@if (settings().header) {\n\t\t\t\t\t\t<div class=\"header-title\">{{ settings().header }}</div>\n\t\t\t\t\t}\n\t\t\t\t\t@if (settings().headerSub) {\n\t\t\t\t\t\t<div class=\"header-sub\">{{ settings().headerSub }}</div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t}\n\t\t<div class=\"xiri-imagetext-content\">\n\t\t\t<mat-spinner [hidden]=\"!loading()\" diameter=\"30\"></mat-spinner>\n\t\t\t<img [hidden]=\"loading()\" (load)=\"loading.set(false)\" [src]=\"settings().url\" [alt]=\"settings().info\" id=\"ximg\"/>\n\t\t</div>\n\t</div>\n} @else {\n\t<mat-card class=\"card mat-mdc-elevation-specific mat-elevation-z2\">\n\t\t<mat-card-header class=\"align-items-center\">\n\t\t\t@if (settings().headerIcon) {\n\t\t\t\t<div mat-card-avatar class=\"header-image\">\n\t\t\t\t\t<mat-icon [class]=\"settings().headerIconColor || 'primary'\">{{ settings().headerIcon }}</mat-icon>\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t@if (settings().header) {\n\t\t\t\t<mat-card-title>{{ settings().header }}</mat-card-title>\n\t\t\t}\n\t\t\t@if (settings().headerSub) {\n\t\t\t\t<mat-card-subtitle>{{ settings().headerSub }}</mat-card-subtitle>\n\t\t\t}\n\t\t</mat-card-header>\n\t\t<mat-card-content>\n\t\t\t<mat-spinner [hidden]=\"!loading()\" diameter=\"30\"></mat-spinner>\n\t\t\t<img [hidden]=\"loading()\" (load)=\"loading.set(false)\" [src]=\"settings().url\" [alt]=\"settings().info\" id=\"ximg\"/>\n\t\t</mat-card-content>\n\t</mat-card>\n}\n", styles: [".card{margin-bottom:2rem;text-align:center}#ximg{max-width:100%}[hidden]{display:none!important}:host(.compact) .xiri-imagetext-flat{background:transparent;box-shadow:none;padding:0;margin-bottom:0}:host(.compact) .xiri-imagetext-header{display:flex;gap:var(--xiri-spacing-sm, 8px);margin-bottom:var(--xiri-spacing-sm, 8px)}:host(.compact) .header-title{font-size:var(--xiri-font-size-body);font-weight:500}:host(.compact) .header-sub{font-size:var(--xiri-font-size-label);color:var(--on-surface-variant, var(--mat-sys-on-surface-variant, #555))}\n"] }]
6751
6790
  }], propDecorators: { settings: [{ type: i0.Input, args: [{ isSignal: true, alias: "settings", required: true }] }] } });
6752
6791
 
6753
6792
  var imagetext_component = /*#__PURE__*/Object.freeze({
@@ -6804,6 +6843,11 @@ class XiriSidenavComponent {
6804
6843
  this.cdr.markForCheck();
6805
6844
  }
6806
6845
  checkField(field, url) {
6846
+ // A hidden entry is not rendered, so it must not activate or expand its parent either.
6847
+ if (field.hide) {
6848
+ field.active = false;
6849
+ return false;
6850
+ }
6807
6851
  const matchesSelf = (field.link != null && field.link == url) || (field.regex != null && field.regex.test(url));
6808
6852
  if (field.menu) {
6809
6853
  let found = false;
@@ -6821,7 +6865,7 @@ class XiriSidenavComponent {
6821
6865
  return field.active;
6822
6866
  }
6823
6867
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriSidenavComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6824
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: XiriSidenavComponent, isStandalone: true, selector: "xiri-sidenav", inputs: { settings: { classPropertyName: "settings", publicName: "settings", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (loading) {\n\t<div class=\"loading\">\n\t\t<mat-spinner diameter=\"30\"></mat-spinner>\n\t</div>\n}\n\n@for (nav of fields; track nav) {\n\n\t@if ( nav.link ) {\n\t\t@let navUrl = nav.link | xiriUrl;\n\t\t<a mat-list-item [routerLink]=\"navUrl?.path\" [queryParams]=\"navUrl?.queryParams\" [class.active]=\"nav.active\">\n\t\t\t@if (nav.iconSet) {\n\t\t\t\t<mat-icon matListItemIcon [fontSet]=\"nav.iconSet\" [class]=\"nav.active ? 'primary' : 'accent'\">{{ nav.icon }}</mat-icon>\n\t\t\t} @else {\n\t\t\t\t<mat-icon matListItemIcon [class]=\"nav.active ? 'primary' : 'accent'\">{{ nav.icon }}</mat-icon>\n\t\t\t}\n\t\t\t<span matListItemTitle>{{ nav.name }}</span>\n\t\t</a>\n\t} @else if (nav.menu) {\n\t\t<mat-list-item (click)=\"nav.showSubmenu = !nav.showSubmenu\" (keydown.enter)=\"nav.showSubmenu = !nav.showSubmenu\" (keydown.space)=\"nav.showSubmenu = !nav.showSubmenu; $event.preventDefault()\" [attr.aria-expanded]=\"nav.showSubmenu\" class=\"parent\">\n\t\t\t@if (nav.iconSet) {\n\t\t\t\t<mat-icon matListItemIcon [fontSet]=\"nav.iconSet\" [class]=\"nav.active ? 'primary' : 'accent'\">{{ nav.icon }}</mat-icon>\n\t\t\t} @else {\n\t\t\t\t<mat-icon matListItemIcon [class]=\"nav.active ? 'primary' : 'accent'\">{{ nav.icon }}</mat-icon>\n\t\t\t}\n\t\t\t<span matListItemTitle>{{ nav.name }}</span>\n\t\t\t<span matListItemMeta>\n\t\t\t\t<mat-icon class=\"menu-button\" [class.rotated]=\"nav.showSubmenu\">expand_more</mat-icon>\n\t\t\t</span>\n\t\t</mat-list-item>\n\t\t<div class=\"submenu\" [class.expanded]=\"nav.showSubmenu\">\n\t\t\t@for (subnav of nav.sub; track subnav) {\n\t\t\t\t@if (subnav.link) {\n\t\t\t\t\t@let subnavUrl = subnav.link | xiriUrl;\n\t\t\t\t\t<a mat-list-item [routerLink]=\"subnavUrl?.path\" [queryParams]=\"subnavUrl?.queryParams\" [class.active]=\"subnav.active\">{{ subnav.name }}</a>\n\t\t\t\t} @else if (subnav.menu) {\n\t\t\t\t\t<mat-list-item (click)=\"subnav.showSubmenu = !subnav.showSubmenu\" (keydown.enter)=\"subnav.showSubmenu = !subnav.showSubmenu\" (keydown.space)=\"subnav.showSubmenu = !subnav.showSubmenu; $event.preventDefault()\" [attr.aria-expanded]=\"subnav.showSubmenu\" class=\"parent\">\n\t\t\t\t\t\t<span matListItemTitle>{{ subnav.name }}</span>\n\t\t\t\t\t\t<span matListItemMeta>\n\t\t\t\t\t\t\t<mat-icon class=\"menu-button\" [class.rotated]=\"subnav.showSubmenu\">expand_more</mat-icon>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</mat-list-item>\n\t\t\t\t\t<div class=\"submenu submenu-nested\" [class.expanded]=\"subnav.showSubmenu\">\n\t\t\t\t\t\t@for (subsubnav of subnav.sub; track subsubnav) {\n\t\t\t\t\t\t\t@if (subsubnav.link) {\n\t\t\t\t\t\t\t\t@let subsubnavUrl = subsubnav.link | xiriUrl;\n\t\t\t\t\t\t\t<a mat-list-item [routerLink]=\"subsubnavUrl?.path\" [queryParams]=\"subsubnavUrl?.queryParams\" [class.active]=\"subsubnav.active\">{{ subsubnav.name }}</a>\n\t\t\t\t\t\t\t} @else if (subsubnav.extern) {\n\t\t\t\t\t\t\t\t<a mat-list-item [href]=\"subsubnav.extern\">{{ subsubnav.name }}</a>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t} @else if (subnav.extern) {\n\t\t\t\t\t<a mat-list-item [href]=\"subnav.extern\">{{ subnav.name }}</a>\n\t\t\t\t}\n\t\t\t}\n\t\t</div>\n\t} @else if (nav.extern) {\n\t\t<a mat-list-item [href]=\"nav.extern\">\n\t\t\t@if (nav.iconSet) {\n\t\t\t\t<mat-icon matListItemIcon [fontSet]=\"nav.iconSet\" class=\"accent\">{{ nav.icon }}</mat-icon>\n\t\t\t} @else {\n\t\t\t\t<mat-icon matListItemIcon class=\"accent\">{{ nav.icon }}</mat-icon>\n\t\t\t}\n\t\t\t<span matListItemTitle>{{ nav.name }}</span>\n\t\t</a>\n\t}\n}\n", styles: [":host{min-width:160px}.loading{margin:var(--xiri-spacing-md)}.mat-mdc-list-item{--mat-list-list-item-label-text-size: .9rem;--mat-list-list-item-label-text-weight: 400}.mat-mdc-list-item mat-icon{display:flex;align-items:center;justify-content:center}.mat-mdc-list-item mat-icon.mat-mdc-list-item-icon{color:var(--xiri-sidenav-icon-color, var(--secondary, #51606F))}.mat-mdc-list-item .mdc-list-item__start{margin-right:var(--xiri-spacing-md)}.mat-mdc-list-item .menu-button{font-size:var(--xiri-font-size-title);transition:var(--xiri-duration-slow) var(--xiri-easing-standard);transform:rotate(0)}.mat-mdc-list-item .menu-button.rotated{transform:rotate(180deg)}.mat-mdc-list-item.active{text-decoration:var(--xiri-sidenav-active-decoration, none);background-color:var(--xiri-sidenav-active-color, transparent)}.mat-mdc-list-item.active mat-icon.mat-mdc-list-item-icon{color:var(--xiri-sidenav-active-icon-color, var(--primary))}.submenu{overflow-y:hidden;transition:max-height var(--xiri-duration-slow) var(--xiri-easing-decelerate);max-height:0;padding-left:var(--xiri-spacing-xl)}.submenu.expanded{transition:max-height var(--xiri-duration-slow) var(--xiri-easing-standard);max-height:1000px}.submenu-nested{padding-left:var(--xiri-spacing-md)}\n"], dependencies: [{ kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatListItemIcon, selector: "[matListItemIcon]" }, { kind: "directive", type: MatListItemTitle, selector: "[matListItemTitle]" }, { kind: "directive", type: MatListItemMeta, selector: "[matListItemMeta]" }, { kind: "pipe", type: XiriUrlPipe, name: "xiriUrl" }] }); }
6868
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: XiriSidenavComponent, isStandalone: true, selector: "xiri-sidenav", inputs: { settings: { classPropertyName: "settings", publicName: "settings", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (loading) {\n\t<div class=\"loading\">\n\t\t<mat-spinner diameter=\"30\"></mat-spinner>\n\t</div>\n}\n\n@for (nav of fields; track nav) {\n\n\t<!-- One guard per level, not per branch: a hidden entry can never slip through\n\t link/menu/extern. Structural, so no routerLink is left in the DOM. -->\n\t@if (!nav.hide) {\n\t\t@if ( nav.link ) {\n\t\t\t@let navUrl = nav.link | xiriUrl;\n\t\t\t<a mat-list-item [routerLink]=\"navUrl?.path\" [queryParams]=\"navUrl?.queryParams\" [class.active]=\"nav.active\">\n\t\t\t\t@if (nav.iconSet) {\n\t\t\t\t\t<mat-icon matListItemIcon [fontSet]=\"nav.iconSet\" [class]=\"nav.active ? 'primary' : 'accent'\">{{ nav.icon }}</mat-icon>\n\t\t\t\t} @else {\n\t\t\t\t\t<mat-icon matListItemIcon [class]=\"nav.active ? 'primary' : 'accent'\">{{ nav.icon }}</mat-icon>\n\t\t\t\t}\n\t\t\t\t<span matListItemTitle>{{ nav.name }}</span>\n\t\t\t</a>\n\t\t} @else if (nav.menu) {\n\t\t\t<mat-list-item (click)=\"nav.showSubmenu = !nav.showSubmenu\" (keydown.enter)=\"nav.showSubmenu = !nav.showSubmenu\" (keydown.space)=\"nav.showSubmenu = !nav.showSubmenu; $event.preventDefault()\" [attr.aria-expanded]=\"nav.showSubmenu\" class=\"parent\">\n\t\t\t\t@if (nav.iconSet) {\n\t\t\t\t\t<mat-icon matListItemIcon [fontSet]=\"nav.iconSet\" [class]=\"nav.active ? 'primary' : 'accent'\">{{ nav.icon }}</mat-icon>\n\t\t\t\t} @else {\n\t\t\t\t\t<mat-icon matListItemIcon [class]=\"nav.active ? 'primary' : 'accent'\">{{ nav.icon }}</mat-icon>\n\t\t\t\t}\n\t\t\t\t<span matListItemTitle>{{ nav.name }}</span>\n\t\t\t\t<span matListItemMeta>\n\t\t\t\t\t<mat-icon class=\"menu-button\" [class.rotated]=\"nav.showSubmenu\">expand_more</mat-icon>\n\t\t\t\t</span>\n\t\t\t</mat-list-item>\n\t\t\t<div class=\"submenu\" [class.expanded]=\"nav.showSubmenu\">\n\t\t\t\t@for (subnav of nav.sub; track subnav) {\n\t\t\t\t\t@if (!subnav.hide) {\n\t\t\t\t\t\t@if (subnav.link) {\n\t\t\t\t\t\t\t@let subnavUrl = subnav.link | xiriUrl;\n\t\t\t\t\t\t\t<a mat-list-item [routerLink]=\"subnavUrl?.path\" [queryParams]=\"subnavUrl?.queryParams\" [class.active]=\"subnav.active\">{{ subnav.name }}</a>\n\t\t\t\t\t\t} @else if (subnav.menu) {\n\t\t\t\t\t\t\t<mat-list-item (click)=\"subnav.showSubmenu = !subnav.showSubmenu\" (keydown.enter)=\"subnav.showSubmenu = !subnav.showSubmenu\" (keydown.space)=\"subnav.showSubmenu = !subnav.showSubmenu; $event.preventDefault()\" [attr.aria-expanded]=\"subnav.showSubmenu\" class=\"parent\">\n\t\t\t\t\t\t\t\t<span matListItemTitle>{{ subnav.name }}</span>\n\t\t\t\t\t\t\t\t<span matListItemMeta>\n\t\t\t\t\t\t\t\t\t<mat-icon class=\"menu-button\" [class.rotated]=\"subnav.showSubmenu\">expand_more</mat-icon>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</mat-list-item>\n\t\t\t\t\t\t\t<div class=\"submenu submenu-nested\" [class.expanded]=\"subnav.showSubmenu\">\n\t\t\t\t\t\t\t\t@for (subsubnav of subnav.sub; track subsubnav) {\n\t\t\t\t\t\t\t\t\t@if (!subsubnav.hide) {\n\t\t\t\t\t\t\t\t\t\t@if (subsubnav.link) {\n\t\t\t\t\t\t\t\t\t\t\t@let subsubnavUrl = subsubnav.link | xiriUrl;\n\t\t\t\t\t\t\t\t\t\t\t<a mat-list-item [routerLink]=\"subsubnavUrl?.path\" [queryParams]=\"subsubnavUrl?.queryParams\" [class.active]=\"subsubnav.active\">{{ subsubnav.name }}</a>\n\t\t\t\t\t\t\t\t\t\t} @else if (subsubnav.extern) {\n\t\t\t\t\t\t\t\t\t\t\t<a mat-list-item [href]=\"subsubnav.extern\">{{ subsubnav.name }}</a>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t} @else if (subnav.extern) {\n\t\t\t\t\t\t\t<a mat-list-item [href]=\"subnav.extern\">{{ subnav.name }}</a>\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t</div>\n\t\t} @else if (nav.extern) {\n\t\t\t<a mat-list-item [href]=\"nav.extern\">\n\t\t\t\t@if (nav.iconSet) {\n\t\t\t\t\t<mat-icon matListItemIcon [fontSet]=\"nav.iconSet\" class=\"accent\">{{ nav.icon }}</mat-icon>\n\t\t\t\t} @else {\n\t\t\t\t\t<mat-icon matListItemIcon class=\"accent\">{{ nav.icon }}</mat-icon>\n\t\t\t\t}\n\t\t\t\t<span matListItemTitle>{{ nav.name }}</span>\n\t\t\t</a>\n\t\t}\n\t}\n}\n", styles: [":host{min-width:160px}.loading{margin:var(--xiri-spacing-md)}.mat-mdc-list-item{--mat-list-list-item-label-text-size: .9rem;--mat-list-list-item-label-text-weight: 400}.mat-mdc-list-item mat-icon{display:flex;align-items:center;justify-content:center}.mat-mdc-list-item mat-icon.mat-mdc-list-item-icon{color:var(--xiri-sidenav-icon-color, var(--secondary, #51606F))}.mat-mdc-list-item .mdc-list-item__start{margin-right:var(--xiri-spacing-md)}.mat-mdc-list-item .menu-button{font-size:var(--xiri-font-size-title);transition:var(--xiri-duration-slow) var(--xiri-easing-standard);transform:rotate(0)}.mat-mdc-list-item .menu-button.rotated{transform:rotate(180deg)}.mat-mdc-list-item.active{text-decoration:var(--xiri-sidenav-active-decoration, none);background-color:var(--xiri-sidenav-active-color, transparent)}.mat-mdc-list-item.active mat-icon.mat-mdc-list-item-icon{color:var(--xiri-sidenav-active-icon-color, var(--primary))}.submenu{overflow-y:hidden;transition:max-height var(--xiri-duration-slow) var(--xiri-easing-decelerate);max-height:0;padding-left:var(--xiri-spacing-xl)}.submenu.expanded{transition:max-height var(--xiri-duration-slow) var(--xiri-easing-standard);max-height:1000px}.submenu-nested{padding-left:var(--xiri-spacing-md)}\n"], dependencies: [{ kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatListItemIcon, selector: "[matListItemIcon]" }, { kind: "directive", type: MatListItemTitle, selector: "[matListItemTitle]" }, { kind: "directive", type: MatListItemMeta, selector: "[matListItemMeta]" }, { kind: "pipe", type: XiriUrlPipe, name: "xiriUrl" }] }); }
6825
6869
  }
6826
6870
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriSidenavComponent, decorators: [{
6827
6871
  type: Component,
@@ -6834,7 +6878,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
6834
6878
  MatListItemTitle,
6835
6879
  MatListItemMeta,
6836
6880
  XiriUrlPipe,
6837
- ], template: "@if (loading) {\n\t<div class=\"loading\">\n\t\t<mat-spinner diameter=\"30\"></mat-spinner>\n\t</div>\n}\n\n@for (nav of fields; track nav) {\n\n\t@if ( nav.link ) {\n\t\t@let navUrl = nav.link | xiriUrl;\n\t\t<a mat-list-item [routerLink]=\"navUrl?.path\" [queryParams]=\"navUrl?.queryParams\" [class.active]=\"nav.active\">\n\t\t\t@if (nav.iconSet) {\n\t\t\t\t<mat-icon matListItemIcon [fontSet]=\"nav.iconSet\" [class]=\"nav.active ? 'primary' : 'accent'\">{{ nav.icon }}</mat-icon>\n\t\t\t} @else {\n\t\t\t\t<mat-icon matListItemIcon [class]=\"nav.active ? 'primary' : 'accent'\">{{ nav.icon }}</mat-icon>\n\t\t\t}\n\t\t\t<span matListItemTitle>{{ nav.name }}</span>\n\t\t</a>\n\t} @else if (nav.menu) {\n\t\t<mat-list-item (click)=\"nav.showSubmenu = !nav.showSubmenu\" (keydown.enter)=\"nav.showSubmenu = !nav.showSubmenu\" (keydown.space)=\"nav.showSubmenu = !nav.showSubmenu; $event.preventDefault()\" [attr.aria-expanded]=\"nav.showSubmenu\" class=\"parent\">\n\t\t\t@if (nav.iconSet) {\n\t\t\t\t<mat-icon matListItemIcon [fontSet]=\"nav.iconSet\" [class]=\"nav.active ? 'primary' : 'accent'\">{{ nav.icon }}</mat-icon>\n\t\t\t} @else {\n\t\t\t\t<mat-icon matListItemIcon [class]=\"nav.active ? 'primary' : 'accent'\">{{ nav.icon }}</mat-icon>\n\t\t\t}\n\t\t\t<span matListItemTitle>{{ nav.name }}</span>\n\t\t\t<span matListItemMeta>\n\t\t\t\t<mat-icon class=\"menu-button\" [class.rotated]=\"nav.showSubmenu\">expand_more</mat-icon>\n\t\t\t</span>\n\t\t</mat-list-item>\n\t\t<div class=\"submenu\" [class.expanded]=\"nav.showSubmenu\">\n\t\t\t@for (subnav of nav.sub; track subnav) {\n\t\t\t\t@if (subnav.link) {\n\t\t\t\t\t@let subnavUrl = subnav.link | xiriUrl;\n\t\t\t\t\t<a mat-list-item [routerLink]=\"subnavUrl?.path\" [queryParams]=\"subnavUrl?.queryParams\" [class.active]=\"subnav.active\">{{ subnav.name }}</a>\n\t\t\t\t} @else if (subnav.menu) {\n\t\t\t\t\t<mat-list-item (click)=\"subnav.showSubmenu = !subnav.showSubmenu\" (keydown.enter)=\"subnav.showSubmenu = !subnav.showSubmenu\" (keydown.space)=\"subnav.showSubmenu = !subnav.showSubmenu; $event.preventDefault()\" [attr.aria-expanded]=\"subnav.showSubmenu\" class=\"parent\">\n\t\t\t\t\t\t<span matListItemTitle>{{ subnav.name }}</span>\n\t\t\t\t\t\t<span matListItemMeta>\n\t\t\t\t\t\t\t<mat-icon class=\"menu-button\" [class.rotated]=\"subnav.showSubmenu\">expand_more</mat-icon>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</mat-list-item>\n\t\t\t\t\t<div class=\"submenu submenu-nested\" [class.expanded]=\"subnav.showSubmenu\">\n\t\t\t\t\t\t@for (subsubnav of subnav.sub; track subsubnav) {\n\t\t\t\t\t\t\t@if (subsubnav.link) {\n\t\t\t\t\t\t\t\t@let subsubnavUrl = subsubnav.link | xiriUrl;\n\t\t\t\t\t\t\t<a mat-list-item [routerLink]=\"subsubnavUrl?.path\" [queryParams]=\"subsubnavUrl?.queryParams\" [class.active]=\"subsubnav.active\">{{ subsubnav.name }}</a>\n\t\t\t\t\t\t\t} @else if (subsubnav.extern) {\n\t\t\t\t\t\t\t\t<a mat-list-item [href]=\"subsubnav.extern\">{{ subsubnav.name }}</a>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t</div>\n\t\t\t\t} @else if (subnav.extern) {\n\t\t\t\t\t<a mat-list-item [href]=\"subnav.extern\">{{ subnav.name }}</a>\n\t\t\t\t}\n\t\t\t}\n\t\t</div>\n\t} @else if (nav.extern) {\n\t\t<a mat-list-item [href]=\"nav.extern\">\n\t\t\t@if (nav.iconSet) {\n\t\t\t\t<mat-icon matListItemIcon [fontSet]=\"nav.iconSet\" class=\"accent\">{{ nav.icon }}</mat-icon>\n\t\t\t} @else {\n\t\t\t\t<mat-icon matListItemIcon class=\"accent\">{{ nav.icon }}</mat-icon>\n\t\t\t}\n\t\t\t<span matListItemTitle>{{ nav.name }}</span>\n\t\t</a>\n\t}\n}\n", styles: [":host{min-width:160px}.loading{margin:var(--xiri-spacing-md)}.mat-mdc-list-item{--mat-list-list-item-label-text-size: .9rem;--mat-list-list-item-label-text-weight: 400}.mat-mdc-list-item mat-icon{display:flex;align-items:center;justify-content:center}.mat-mdc-list-item mat-icon.mat-mdc-list-item-icon{color:var(--xiri-sidenav-icon-color, var(--secondary, #51606F))}.mat-mdc-list-item .mdc-list-item__start{margin-right:var(--xiri-spacing-md)}.mat-mdc-list-item .menu-button{font-size:var(--xiri-font-size-title);transition:var(--xiri-duration-slow) var(--xiri-easing-standard);transform:rotate(0)}.mat-mdc-list-item .menu-button.rotated{transform:rotate(180deg)}.mat-mdc-list-item.active{text-decoration:var(--xiri-sidenav-active-decoration, none);background-color:var(--xiri-sidenav-active-color, transparent)}.mat-mdc-list-item.active mat-icon.mat-mdc-list-item-icon{color:var(--xiri-sidenav-active-icon-color, var(--primary))}.submenu{overflow-y:hidden;transition:max-height var(--xiri-duration-slow) var(--xiri-easing-decelerate);max-height:0;padding-left:var(--xiri-spacing-xl)}.submenu.expanded{transition:max-height var(--xiri-duration-slow) var(--xiri-easing-standard);max-height:1000px}.submenu-nested{padding-left:var(--xiri-spacing-md)}\n"] }]
6881
+ ], template: "@if (loading) {\n\t<div class=\"loading\">\n\t\t<mat-spinner diameter=\"30\"></mat-spinner>\n\t</div>\n}\n\n@for (nav of fields; track nav) {\n\n\t<!-- One guard per level, not per branch: a hidden entry can never slip through\n\t link/menu/extern. Structural, so no routerLink is left in the DOM. -->\n\t@if (!nav.hide) {\n\t\t@if ( nav.link ) {\n\t\t\t@let navUrl = nav.link | xiriUrl;\n\t\t\t<a mat-list-item [routerLink]=\"navUrl?.path\" [queryParams]=\"navUrl?.queryParams\" [class.active]=\"nav.active\">\n\t\t\t\t@if (nav.iconSet) {\n\t\t\t\t\t<mat-icon matListItemIcon [fontSet]=\"nav.iconSet\" [class]=\"nav.active ? 'primary' : 'accent'\">{{ nav.icon }}</mat-icon>\n\t\t\t\t} @else {\n\t\t\t\t\t<mat-icon matListItemIcon [class]=\"nav.active ? 'primary' : 'accent'\">{{ nav.icon }}</mat-icon>\n\t\t\t\t}\n\t\t\t\t<span matListItemTitle>{{ nav.name }}</span>\n\t\t\t</a>\n\t\t} @else if (nav.menu) {\n\t\t\t<mat-list-item (click)=\"nav.showSubmenu = !nav.showSubmenu\" (keydown.enter)=\"nav.showSubmenu = !nav.showSubmenu\" (keydown.space)=\"nav.showSubmenu = !nav.showSubmenu; $event.preventDefault()\" [attr.aria-expanded]=\"nav.showSubmenu\" class=\"parent\">\n\t\t\t\t@if (nav.iconSet) {\n\t\t\t\t\t<mat-icon matListItemIcon [fontSet]=\"nav.iconSet\" [class]=\"nav.active ? 'primary' : 'accent'\">{{ nav.icon }}</mat-icon>\n\t\t\t\t} @else {\n\t\t\t\t\t<mat-icon matListItemIcon [class]=\"nav.active ? 'primary' : 'accent'\">{{ nav.icon }}</mat-icon>\n\t\t\t\t}\n\t\t\t\t<span matListItemTitle>{{ nav.name }}</span>\n\t\t\t\t<span matListItemMeta>\n\t\t\t\t\t<mat-icon class=\"menu-button\" [class.rotated]=\"nav.showSubmenu\">expand_more</mat-icon>\n\t\t\t\t</span>\n\t\t\t</mat-list-item>\n\t\t\t<div class=\"submenu\" [class.expanded]=\"nav.showSubmenu\">\n\t\t\t\t@for (subnav of nav.sub; track subnav) {\n\t\t\t\t\t@if (!subnav.hide) {\n\t\t\t\t\t\t@if (subnav.link) {\n\t\t\t\t\t\t\t@let subnavUrl = subnav.link | xiriUrl;\n\t\t\t\t\t\t\t<a mat-list-item [routerLink]=\"subnavUrl?.path\" [queryParams]=\"subnavUrl?.queryParams\" [class.active]=\"subnav.active\">{{ subnav.name }}</a>\n\t\t\t\t\t\t} @else if (subnav.menu) {\n\t\t\t\t\t\t\t<mat-list-item (click)=\"subnav.showSubmenu = !subnav.showSubmenu\" (keydown.enter)=\"subnav.showSubmenu = !subnav.showSubmenu\" (keydown.space)=\"subnav.showSubmenu = !subnav.showSubmenu; $event.preventDefault()\" [attr.aria-expanded]=\"subnav.showSubmenu\" class=\"parent\">\n\t\t\t\t\t\t\t\t<span matListItemTitle>{{ subnav.name }}</span>\n\t\t\t\t\t\t\t\t<span matListItemMeta>\n\t\t\t\t\t\t\t\t\t<mat-icon class=\"menu-button\" [class.rotated]=\"subnav.showSubmenu\">expand_more</mat-icon>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</mat-list-item>\n\t\t\t\t\t\t\t<div class=\"submenu submenu-nested\" [class.expanded]=\"subnav.showSubmenu\">\n\t\t\t\t\t\t\t\t@for (subsubnav of subnav.sub; track subsubnav) {\n\t\t\t\t\t\t\t\t\t@if (!subsubnav.hide) {\n\t\t\t\t\t\t\t\t\t\t@if (subsubnav.link) {\n\t\t\t\t\t\t\t\t\t\t\t@let subsubnavUrl = subsubnav.link | xiriUrl;\n\t\t\t\t\t\t\t\t\t\t\t<a mat-list-item [routerLink]=\"subsubnavUrl?.path\" [queryParams]=\"subsubnavUrl?.queryParams\" [class.active]=\"subsubnav.active\">{{ subsubnav.name }}</a>\n\t\t\t\t\t\t\t\t\t\t} @else if (subsubnav.extern) {\n\t\t\t\t\t\t\t\t\t\t\t<a mat-list-item [href]=\"subsubnav.extern\">{{ subsubnav.name }}</a>\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t} @else if (subnav.extern) {\n\t\t\t\t\t\t\t<a mat-list-item [href]=\"subnav.extern\">{{ subnav.name }}</a>\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t</div>\n\t\t} @else if (nav.extern) {\n\t\t\t<a mat-list-item [href]=\"nav.extern\">\n\t\t\t\t@if (nav.iconSet) {\n\t\t\t\t\t<mat-icon matListItemIcon [fontSet]=\"nav.iconSet\" class=\"accent\">{{ nav.icon }}</mat-icon>\n\t\t\t\t} @else {\n\t\t\t\t\t<mat-icon matListItemIcon class=\"accent\">{{ nav.icon }}</mat-icon>\n\t\t\t\t}\n\t\t\t\t<span matListItemTitle>{{ nav.name }}</span>\n\t\t\t</a>\n\t\t}\n\t}\n}\n", styles: [":host{min-width:160px}.loading{margin:var(--xiri-spacing-md)}.mat-mdc-list-item{--mat-list-list-item-label-text-size: .9rem;--mat-list-list-item-label-text-weight: 400}.mat-mdc-list-item mat-icon{display:flex;align-items:center;justify-content:center}.mat-mdc-list-item mat-icon.mat-mdc-list-item-icon{color:var(--xiri-sidenav-icon-color, var(--secondary, #51606F))}.mat-mdc-list-item .mdc-list-item__start{margin-right:var(--xiri-spacing-md)}.mat-mdc-list-item .menu-button{font-size:var(--xiri-font-size-title);transition:var(--xiri-duration-slow) var(--xiri-easing-standard);transform:rotate(0)}.mat-mdc-list-item .menu-button.rotated{transform:rotate(180deg)}.mat-mdc-list-item.active{text-decoration:var(--xiri-sidenav-active-decoration, none);background-color:var(--xiri-sidenav-active-color, transparent)}.mat-mdc-list-item.active mat-icon.mat-mdc-list-item-icon{color:var(--xiri-sidenav-active-icon-color, var(--primary))}.submenu{overflow-y:hidden;transition:max-height var(--xiri-duration-slow) var(--xiri-easing-decelerate);max-height:0;padding-left:var(--xiri-spacing-xl)}.submenu.expanded{transition:max-height var(--xiri-duration-slow) var(--xiri-easing-standard);max-height:1000px}.submenu-nested{padding-left:var(--xiri-spacing-md)}\n"] }]
6838
6882
  }], ctorParameters: () => [], propDecorators: { settings: [{ type: i0.Input, args: [{ isSignal: true, alias: "settings", required: false }] }] } });
6839
6883
 
6840
6884
  class XiriBreadcrumbComponent {
@@ -6843,11 +6887,11 @@ class XiriBreadcrumbComponent {
6843
6887
  ...(ngDevMode ? [{ debugName: "settings" }] : /* istanbul ignore next */ []));
6844
6888
  }
6845
6889
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriBreadcrumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6846
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: XiriBreadcrumbComponent, isStandalone: true, selector: "xiri-breadcrumb", inputs: { settings: { classPropertyName: "settings", publicName: "settings", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<nav class=\"breadcrumb\" aria-label=\"Breadcrumb\">\n\t<ol>\n\t\t@for (item of settings(); track $index; let last = $last) {\n\t\t\t<li [class.active]=\"last\">\n\t\t\t\t@if (item.link) {\n\t\t\t\t\t@if (item.extern) {\n\t\t\t\t\t\t<a [href]=\"item.link\" target=\"_blank\" rel=\"noopener\">\n\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t<mat-icon>{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t{{ item.label }}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t@let itemUrl = item.link | xiriUrl;\n\t\t\t\t\t\t<a [routerLink]=\"itemUrl?.path\" [queryParams]=\"itemUrl?.queryParams\">\n\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t<mat-icon>{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t{{ item.label }}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t}\n\t\t\t\t} @else {\n\t\t\t\t\t<span>\n\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t<mat-icon>{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t{{ item.label }}\n\t\t\t\t\t</span>\n\t\t\t\t}\n\t\t\t\t@if (!last) {\n\t\t\t\t\t<mat-icon class=\"separator\">chevron_right</mat-icon>\n\t\t\t\t}\n\t\t\t</li>\n\t\t}\n\t</ol>\n</nav>\n", styles: [".breadcrumb ol{display:flex;flex-wrap:wrap;align-items:center;list-style:none;padding:0;margin:0;gap:var(--xiri-spacing-xs)}.breadcrumb li{display:flex;align-items:center;gap:var(--xiri-spacing-xs);font-size:var(--xiri-font-size-body, .875rem);color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6))}.breadcrumb li a{display:flex;align-items:center;gap:.25rem;color:var(--primary, #2892D9);text-decoration:none;border-radius:var(--xiri-radius-xs);padding:.125rem .25rem;margin:-.125rem -.25rem}.breadcrumb li a:hover{text-decoration:underline;background:color-mix(in srgb,var(--primary, #2892D9) 8%,transparent)}.breadcrumb li a mat-icon{font-size:1.125rem;width:1.125rem;height:1.125rem}.breadcrumb li span{display:flex;align-items:center;gap:var(--xiri-spacing-xs)}.breadcrumb li span mat-icon{font-size:1.125rem;width:1.125rem;height:1.125rem}.breadcrumb li.active{font-weight:500;color:var(--mat-sys-on-surface, rgba(0, 0, 0, .87))}.breadcrumb li .separator{font-size:1.125rem;width:1.125rem;height:1.125rem;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6))}\n"], dependencies: [{ kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "pipe", type: XiriUrlPipe, name: "xiriUrl" }] }); }
6890
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: XiriBreadcrumbComponent, isStandalone: true, selector: "xiri-breadcrumb", inputs: { settings: { classPropertyName: "settings", publicName: "settings", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<nav class=\"breadcrumb\" aria-label=\"Breadcrumb\">\n\t<ol>\n\t\t@for (item of settings(); track $index; let last = $last) {\n\t\t\t<li [class.active]=\"last\">\n\t\t\t\t@if (item.link) {\n\t\t\t\t\t@if (item.extern) {\n\t\t\t\t\t\t<a [href]=\"item.link\" target=\"_blank\" rel=\"noopener\">\n\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t<mat-icon>{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t{{ item.label }}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t@let itemUrl = item.link | xiriUrl;\n\t\t\t\t\t\t<a [routerLink]=\"itemUrl?.path\" [queryParams]=\"itemUrl?.queryParams\">\n\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t<mat-icon>{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t{{ item.label }}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t}\n\t\t\t\t} @else {\n\t\t\t\t\t<span>\n\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t<mat-icon>{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t{{ item.label }}\n\t\t\t\t\t</span>\n\t\t\t\t}\n\t\t\t\t@if (!last) {\n\t\t\t\t\t<mat-icon class=\"separator\">chevron_right</mat-icon>\n\t\t\t\t}\n\t\t\t</li>\n\t\t}\n\t</ol>\n</nav>\n", styles: [".breadcrumb ol{display:flex;flex-wrap:wrap;align-items:center;list-style:none;padding:0;margin:0;gap:var(--xiri-spacing-xs)}.breadcrumb li{display:flex;align-items:center;gap:var(--xiri-spacing-xs);font-size:var(--xiri-font-size-body, .875rem);color:var(--on-surface-variant, var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6)))}.breadcrumb li a{display:flex;align-items:center;gap:.25rem;color:var(--primary, #2892D9);text-decoration:none;border-radius:var(--xiri-radius-xs);padding:.125rem .25rem;margin:-.125rem -.25rem}.breadcrumb li a:hover{text-decoration:underline;background:color-mix(in srgb,var(--primary, #2892D9) 8%,transparent)}.breadcrumb li a mat-icon{font-size:1.125rem;width:1.125rem;height:1.125rem}.breadcrumb li span{display:flex;align-items:center;gap:var(--xiri-spacing-xs)}.breadcrumb li span mat-icon{font-size:1.125rem;width:1.125rem;height:1.125rem}.breadcrumb li.active{font-weight:500;color:var(--on-surface, var(--mat-sys-on-surface, rgba(0, 0, 0, .87)))}.breadcrumb li .separator{font-size:1.125rem;width:1.125rem;height:1.125rem;color:var(--on-surface-variant, var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6)))}\n"], dependencies: [{ kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "pipe", type: XiriUrlPipe, name: "xiriUrl" }] }); }
6847
6891
  }
6848
6892
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriBreadcrumbComponent, decorators: [{
6849
6893
  type: Component,
6850
- args: [{ selector: 'xiri-breadcrumb', imports: [MatIcon, RouterLink, XiriUrlPipe], template: "<nav class=\"breadcrumb\" aria-label=\"Breadcrumb\">\n\t<ol>\n\t\t@for (item of settings(); track $index; let last = $last) {\n\t\t\t<li [class.active]=\"last\">\n\t\t\t\t@if (item.link) {\n\t\t\t\t\t@if (item.extern) {\n\t\t\t\t\t\t<a [href]=\"item.link\" target=\"_blank\" rel=\"noopener\">\n\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t<mat-icon>{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t{{ item.label }}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t@let itemUrl = item.link | xiriUrl;\n\t\t\t\t\t\t<a [routerLink]=\"itemUrl?.path\" [queryParams]=\"itemUrl?.queryParams\">\n\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t<mat-icon>{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t{{ item.label }}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t}\n\t\t\t\t} @else {\n\t\t\t\t\t<span>\n\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t<mat-icon>{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t{{ item.label }}\n\t\t\t\t\t</span>\n\t\t\t\t}\n\t\t\t\t@if (!last) {\n\t\t\t\t\t<mat-icon class=\"separator\">chevron_right</mat-icon>\n\t\t\t\t}\n\t\t\t</li>\n\t\t}\n\t</ol>\n</nav>\n", styles: [".breadcrumb ol{display:flex;flex-wrap:wrap;align-items:center;list-style:none;padding:0;margin:0;gap:var(--xiri-spacing-xs)}.breadcrumb li{display:flex;align-items:center;gap:var(--xiri-spacing-xs);font-size:var(--xiri-font-size-body, .875rem);color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6))}.breadcrumb li a{display:flex;align-items:center;gap:.25rem;color:var(--primary, #2892D9);text-decoration:none;border-radius:var(--xiri-radius-xs);padding:.125rem .25rem;margin:-.125rem -.25rem}.breadcrumb li a:hover{text-decoration:underline;background:color-mix(in srgb,var(--primary, #2892D9) 8%,transparent)}.breadcrumb li a mat-icon{font-size:1.125rem;width:1.125rem;height:1.125rem}.breadcrumb li span{display:flex;align-items:center;gap:var(--xiri-spacing-xs)}.breadcrumb li span mat-icon{font-size:1.125rem;width:1.125rem;height:1.125rem}.breadcrumb li.active{font-weight:500;color:var(--mat-sys-on-surface, rgba(0, 0, 0, .87))}.breadcrumb li .separator{font-size:1.125rem;width:1.125rem;height:1.125rem;color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6))}\n"] }]
6894
+ args: [{ selector: 'xiri-breadcrumb', imports: [MatIcon, RouterLink, XiriUrlPipe], template: "<nav class=\"breadcrumb\" aria-label=\"Breadcrumb\">\n\t<ol>\n\t\t@for (item of settings(); track $index; let last = $last) {\n\t\t\t<li [class.active]=\"last\">\n\t\t\t\t@if (item.link) {\n\t\t\t\t\t@if (item.extern) {\n\t\t\t\t\t\t<a [href]=\"item.link\" target=\"_blank\" rel=\"noopener\">\n\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t<mat-icon>{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t{{ item.label }}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t@let itemUrl = item.link | xiriUrl;\n\t\t\t\t\t\t<a [routerLink]=\"itemUrl?.path\" [queryParams]=\"itemUrl?.queryParams\">\n\t\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t\t<mat-icon>{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t{{ item.label }}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t}\n\t\t\t\t} @else {\n\t\t\t\t\t<span>\n\t\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t\t<mat-icon>{{ item.icon }}</mat-icon>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t{{ item.label }}\n\t\t\t\t\t</span>\n\t\t\t\t}\n\t\t\t\t@if (!last) {\n\t\t\t\t\t<mat-icon class=\"separator\">chevron_right</mat-icon>\n\t\t\t\t}\n\t\t\t</li>\n\t\t}\n\t</ol>\n</nav>\n", styles: [".breadcrumb ol{display:flex;flex-wrap:wrap;align-items:center;list-style:none;padding:0;margin:0;gap:var(--xiri-spacing-xs)}.breadcrumb li{display:flex;align-items:center;gap:var(--xiri-spacing-xs);font-size:var(--xiri-font-size-body, .875rem);color:var(--on-surface-variant, var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6)))}.breadcrumb li a{display:flex;align-items:center;gap:.25rem;color:var(--primary, #2892D9);text-decoration:none;border-radius:var(--xiri-radius-xs);padding:.125rem .25rem;margin:-.125rem -.25rem}.breadcrumb li a:hover{text-decoration:underline;background:color-mix(in srgb,var(--primary, #2892D9) 8%,transparent)}.breadcrumb li a mat-icon{font-size:1.125rem;width:1.125rem;height:1.125rem}.breadcrumb li span{display:flex;align-items:center;gap:var(--xiri-spacing-xs)}.breadcrumb li span mat-icon{font-size:1.125rem;width:1.125rem;height:1.125rem}.breadcrumb li.active{font-weight:500;color:var(--on-surface, var(--mat-sys-on-surface, rgba(0, 0, 0, .87)))}.breadcrumb li .separator{font-size:1.125rem;width:1.125rem;height:1.125rem;color:var(--on-surface-variant, var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6)))}\n"] }]
6851
6895
  }], propDecorators: { settings: [{ type: i0.Input, args: [{ isSignal: true, alias: "settings", required: true }] }] } });
6852
6896
 
6853
6897
  class XiriTimelineComponent {
@@ -6856,11 +6900,11 @@ class XiriTimelineComponent {
6856
6900
  ...(ngDevMode ? [{ debugName: "settings" }] : /* istanbul ignore next */ []));
6857
6901
  }
6858
6902
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriTimelineComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6859
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: XiriTimelineComponent, isStandalone: true, selector: "xiri-timeline", inputs: { settings: { classPropertyName: "settings", publicName: "settings", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"timeline\" [class.horizontal]=\"settings().orientation === 'horizontal'\">\n\t@for (item of settings().items; track $index; let last = $last; let first = $first) {\n\t\t<div class=\"timeline-item\" [class.last]=\"last\" [class.first]=\"first\">\n\t\t\t<div class=\"timeline-marker\">\n\t\t\t\t<div class=\"timeline-line line-before\"></div>\n\t\t\t\t<div class=\"timeline-dot\" [class]=\"item.iconColor || 'primary'\">\n\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t<mat-icon>{{ item.icon }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t\t<div class=\"timeline-line line-after\"></div>\n\t\t\t</div>\n\t\t\t<div class=\"timeline-content\">\n\t\t\t\t<div class=\"timeline-header\">\n\t\t\t\t\t<span class=\"timeline-title\">{{ item.title }}</span>\n\t\t\t\t\t@if (item.datetime) {\n\t\t\t\t\t\t<span class=\"timeline-datetime\">{{ item.datetime }}</span>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t\t@if (item.description && settings().orientation !== 'horizontal') {\n\t\t\t\t\t<div class=\"timeline-description\">{{ item.description }}</div>\n\t\t\t\t}\n\t\t\t</div>\n\t\t</div>\n\t}\n</div>\n", styles: [":host{display:block;container-type:inline-size}.timeline{display:flex;flex-direction:column}.timeline-item{display:flex;gap:var(--xiri-spacing-md);animation:fadeInUp var(--xiri-duration-normal, .3s) var(--xiri-easing-decelerate, cubic-bezier(0, 0, .2, 1)) both}.timeline-item:nth-child(1){animation-delay:0ms}.timeline-item:nth-child(2){animation-delay:50ms}.timeline-item:nth-child(3){animation-delay:.1s}.timeline-item:nth-child(4){animation-delay:.15s}.timeline-item:nth-child(5){animation-delay:.2s}.timeline-item:nth-child(6){animation-delay:.25s}.timeline-item:nth-child(7){animation-delay:.3s}.timeline-item:nth-child(8){animation-delay:.35s}.timeline-item:nth-child(9){animation-delay:.4s}.timeline-item:nth-child(10){animation-delay:.45s}.timeline-item:nth-child(11){animation-delay:.5s}.timeline-item:nth-child(12){animation-delay:.55s}.timeline-item:nth-child(13){animation-delay:.6s}.timeline-item:nth-child(14){animation-delay:.65s}.timeline-item:nth-child(15){animation-delay:.7s}.timeline-item:nth-child(16){animation-delay:.75s}.timeline-item:nth-child(17){animation-delay:.8s}.timeline-item:nth-child(18){animation-delay:.85s}.timeline-item:nth-child(19){animation-delay:.9s}.timeline-item:nth-child(20){animation-delay:.95s}.timeline-item .timeline-line.line-before,.timeline-item.last .timeline-line.line-after{display:none}.timeline-marker{display:flex;flex-direction:column;align-items:center;flex-shrink:0;width:2.5rem}.timeline-dot{width:2.5rem;height:2.5rem;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;background:var(--primary, #2892D9);color:var(--on-primary, white)}.timeline-dot mat-icon{font-size:1.25rem;width:1.25rem;height:1.25rem}.timeline-dot.primary{background:var(--primary)}.timeline-dot.secondary{background:var(--secondary)}.timeline-dot.tertiary{background:var(--tertiary)}.timeline-dot.accent{background:var(--secondary)}.timeline-dot.warn,.timeline-dot.error{background:var(--error)}.timeline-dot.success{background:var(--color-success)}.timeline-dot.emerald{background:#2892d9}.timeline-dot.red{background:#e74c3c}.timeline-dot.yellow{background:#f1c40f}.timeline-dot.green{background:#2ecc71}.timeline-dot.blue{background:#3498db}.timeline-dot.purple{background:#9b59b6}.timeline-dot.gray{background:#95a5a6}.timeline-dot.lightgray{background:#bdc3c7}.timeline-dot.darkgray{background:#7f8c8d}.timeline-dot.orange{background:#e67e22}.timeline-dot.white{background:#fff}.timeline-dot.black{background:#000}.timeline-dot.inherit{background:inherit}.timeline-line{width:2px;flex:1;min-height:var(--xiri-spacing-lg);background:var(--mat-sys-outline-variant, rgba(0, 0, 0, .12))}.timeline-content{padding-bottom:var(--xiri-spacing-lg);flex:1;min-width:0}.timeline-header{display:flex;align-items:baseline;gap:.75rem;flex-wrap:wrap;min-height:2.5rem;align-content:center}.timeline-title{font-weight:500;font-size:var(--xiri-font-size-body, .875rem);color:var(--mat-sys-on-surface, rgba(0, 0, 0, .87))}.timeline-datetime{font-size:var(--xiri-font-size-helper, .75rem);color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6))}.timeline-description{margin-top:.25rem;font-size:var(--xiri-font-size-body, .875rem);color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));line-height:1.5}@container (min-width: 481px){.timeline.horizontal{flex-direction:row}.timeline.horizontal .timeline-item{flex:1;min-width:0;flex-direction:column;align-items:center;gap:var(--xiri-spacing-xs);padding-bottom:0}.timeline.horizontal .timeline-item .timeline-line.line-before{display:block}.timeline.horizontal .timeline-item.first .timeline-line.line-before{visibility:hidden}.timeline.horizontal .timeline-item.last .timeline-line.line-after{display:block;visibility:hidden}.timeline.horizontal .timeline-content,.timeline.horizontal .timeline-header{display:contents}.timeline.horizontal .timeline-title{order:-2;text-align:center;min-height:2.5em;display:flex;align-items:center;justify-content:center;padding:0 var(--xiri-spacing-xs)}.timeline.horizontal .timeline-marker{order:-1;width:100%;flex-direction:row;align-items:center;gap:0}.timeline.horizontal .timeline-datetime{order:1;text-align:center;min-height:1.5em;display:flex;align-items:center;justify-content:center}.timeline.horizontal .timeline-line{flex:1;width:auto;height:2px;min-height:0}}\n"], dependencies: [{ kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] }); }
6903
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: XiriTimelineComponent, isStandalone: true, selector: "xiri-timeline", inputs: { settings: { classPropertyName: "settings", publicName: "settings", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"timeline\" [class.horizontal]=\"settings().orientation === 'horizontal'\">\n\t@for (item of settings().items; track $index; let last = $last; let first = $first) {\n\t\t<div class=\"timeline-item\" [class.last]=\"last\" [class.first]=\"first\">\n\t\t\t<div class=\"timeline-marker\">\n\t\t\t\t<div class=\"timeline-line line-before\"></div>\n\t\t\t\t<div class=\"timeline-dot\" [class]=\"item.iconColor || 'primary'\">\n\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t<mat-icon>{{ item.icon }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t\t<div class=\"timeline-line line-after\"></div>\n\t\t\t</div>\n\t\t\t<div class=\"timeline-content\">\n\t\t\t\t<div class=\"timeline-header\">\n\t\t\t\t\t<span class=\"timeline-title\">{{ item.title }}</span>\n\t\t\t\t\t@if (item.datetime) {\n\t\t\t\t\t\t<span class=\"timeline-datetime\">{{ item.datetime }}</span>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t\t@if (item.description && settings().orientation !== 'horizontal') {\n\t\t\t\t\t<div class=\"timeline-description\">{{ item.description }}</div>\n\t\t\t\t}\n\t\t\t</div>\n\t\t</div>\n\t}\n</div>\n", styles: [":host{display:block;container-type:inline-size}.timeline{display:flex;flex-direction:column}.timeline-item{display:flex;gap:var(--xiri-spacing-md);animation:fadeInUp var(--xiri-duration-normal, .3s) var(--xiri-easing-decelerate, cubic-bezier(0, 0, .2, 1)) both}.timeline-item:nth-child(1){animation-delay:0ms}.timeline-item:nth-child(2){animation-delay:50ms}.timeline-item:nth-child(3){animation-delay:.1s}.timeline-item:nth-child(4){animation-delay:.15s}.timeline-item:nth-child(5){animation-delay:.2s}.timeline-item:nth-child(6){animation-delay:.25s}.timeline-item:nth-child(7){animation-delay:.3s}.timeline-item:nth-child(8){animation-delay:.35s}.timeline-item:nth-child(9){animation-delay:.4s}.timeline-item:nth-child(10){animation-delay:.45s}.timeline-item:nth-child(11){animation-delay:.5s}.timeline-item:nth-child(12){animation-delay:.55s}.timeline-item:nth-child(13){animation-delay:.6s}.timeline-item:nth-child(14){animation-delay:.65s}.timeline-item:nth-child(15){animation-delay:.7s}.timeline-item:nth-child(16){animation-delay:.75s}.timeline-item:nth-child(17){animation-delay:.8s}.timeline-item:nth-child(18){animation-delay:.85s}.timeline-item:nth-child(19){animation-delay:.9s}.timeline-item:nth-child(20){animation-delay:.95s}.timeline-item .timeline-line.line-before,.timeline-item.last .timeline-line.line-after{display:none}.timeline-marker{display:flex;flex-direction:column;align-items:center;flex-shrink:0;width:2.5rem}.timeline-dot{width:2.5rem;height:2.5rem;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;background:var(--primary, #2892D9);color:var(--on-primary, white)}.timeline-dot mat-icon{font-size:1.25rem;width:1.25rem;height:1.25rem}.timeline-dot.primary{background:var(--primary)}.timeline-dot.secondary{background:var(--secondary)}.timeline-dot.tertiary{background:var(--tertiary)}.timeline-dot.accent{background:var(--secondary)}.timeline-dot.warn,.timeline-dot.error{background:var(--error)}.timeline-dot.success{background:var(--color-success)}.timeline-dot.emerald{background:#2892d9}.timeline-dot.red{background:#e74c3c}.timeline-dot.yellow{background:#f1c40f}.timeline-dot.green{background:#2ecc71}.timeline-dot.blue{background:#3498db}.timeline-dot.purple{background:#9b59b6}.timeline-dot.gray{background:#95a5a6}.timeline-dot.lightgray{background:#bdc3c7}.timeline-dot.darkgray{background:#7f8c8d}.timeline-dot.orange{background:#e67e22}.timeline-dot.white{background:#fff}.timeline-dot.black{background:#000}.timeline-dot.inherit{background:inherit}.timeline-line{width:2px;flex:1;min-height:var(--xiri-spacing-lg);background:var(--outline-variant, var(--mat-sys-outline-variant, rgba(0, 0, 0, .12)))}.timeline-content{padding-bottom:var(--xiri-spacing-lg);flex:1;min-width:0}.timeline-header{display:flex;align-items:baseline;gap:.75rem;flex-wrap:wrap;min-height:2.5rem;align-content:center}.timeline-title{font-weight:500;font-size:var(--xiri-font-size-body, .875rem);color:var(--on-surface, var(--mat-sys-on-surface, rgba(0, 0, 0, .87)))}.timeline-datetime{font-size:var(--xiri-font-size-helper, .75rem);color:var(--on-surface-variant, var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6)))}.timeline-description{margin-top:.25rem;font-size:var(--xiri-font-size-body, .875rem);color:var(--on-surface-variant, var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6)));line-height:1.5}@container (min-width: 481px){.timeline.horizontal{flex-direction:row}.timeline.horizontal .timeline-item{flex:1;min-width:0;flex-direction:column;align-items:center;gap:var(--xiri-spacing-xs);padding-bottom:0}.timeline.horizontal .timeline-item .timeline-line.line-before{display:block}.timeline.horizontal .timeline-item.first .timeline-line.line-before{visibility:hidden}.timeline.horizontal .timeline-item.last .timeline-line.line-after{display:block;visibility:hidden}.timeline.horizontal .timeline-content,.timeline.horizontal .timeline-header{display:contents}.timeline.horizontal .timeline-title{order:-2;text-align:center;min-height:2.5em;display:flex;align-items:center;justify-content:center;padding:0 var(--xiri-spacing-xs)}.timeline.horizontal .timeline-marker{order:-1;width:100%;flex-direction:row;align-items:center;gap:0}.timeline.horizontal .timeline-datetime{order:1;text-align:center;min-height:1.5em;display:flex;align-items:center;justify-content:center}.timeline.horizontal .timeline-line{flex:1;width:auto;height:2px;min-height:0}}\n"], dependencies: [{ kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] }); }
6860
6904
  }
6861
6905
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriTimelineComponent, decorators: [{
6862
6906
  type: Component,
6863
- args: [{ selector: 'xiri-timeline', imports: [MatIcon], template: "<div class=\"timeline\" [class.horizontal]=\"settings().orientation === 'horizontal'\">\n\t@for (item of settings().items; track $index; let last = $last; let first = $first) {\n\t\t<div class=\"timeline-item\" [class.last]=\"last\" [class.first]=\"first\">\n\t\t\t<div class=\"timeline-marker\">\n\t\t\t\t<div class=\"timeline-line line-before\"></div>\n\t\t\t\t<div class=\"timeline-dot\" [class]=\"item.iconColor || 'primary'\">\n\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t<mat-icon>{{ item.icon }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t\t<div class=\"timeline-line line-after\"></div>\n\t\t\t</div>\n\t\t\t<div class=\"timeline-content\">\n\t\t\t\t<div class=\"timeline-header\">\n\t\t\t\t\t<span class=\"timeline-title\">{{ item.title }}</span>\n\t\t\t\t\t@if (item.datetime) {\n\t\t\t\t\t\t<span class=\"timeline-datetime\">{{ item.datetime }}</span>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t\t@if (item.description && settings().orientation !== 'horizontal') {\n\t\t\t\t\t<div class=\"timeline-description\">{{ item.description }}</div>\n\t\t\t\t}\n\t\t\t</div>\n\t\t</div>\n\t}\n</div>\n", styles: [":host{display:block;container-type:inline-size}.timeline{display:flex;flex-direction:column}.timeline-item{display:flex;gap:var(--xiri-spacing-md);animation:fadeInUp var(--xiri-duration-normal, .3s) var(--xiri-easing-decelerate, cubic-bezier(0, 0, .2, 1)) both}.timeline-item:nth-child(1){animation-delay:0ms}.timeline-item:nth-child(2){animation-delay:50ms}.timeline-item:nth-child(3){animation-delay:.1s}.timeline-item:nth-child(4){animation-delay:.15s}.timeline-item:nth-child(5){animation-delay:.2s}.timeline-item:nth-child(6){animation-delay:.25s}.timeline-item:nth-child(7){animation-delay:.3s}.timeline-item:nth-child(8){animation-delay:.35s}.timeline-item:nth-child(9){animation-delay:.4s}.timeline-item:nth-child(10){animation-delay:.45s}.timeline-item:nth-child(11){animation-delay:.5s}.timeline-item:nth-child(12){animation-delay:.55s}.timeline-item:nth-child(13){animation-delay:.6s}.timeline-item:nth-child(14){animation-delay:.65s}.timeline-item:nth-child(15){animation-delay:.7s}.timeline-item:nth-child(16){animation-delay:.75s}.timeline-item:nth-child(17){animation-delay:.8s}.timeline-item:nth-child(18){animation-delay:.85s}.timeline-item:nth-child(19){animation-delay:.9s}.timeline-item:nth-child(20){animation-delay:.95s}.timeline-item .timeline-line.line-before,.timeline-item.last .timeline-line.line-after{display:none}.timeline-marker{display:flex;flex-direction:column;align-items:center;flex-shrink:0;width:2.5rem}.timeline-dot{width:2.5rem;height:2.5rem;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;background:var(--primary, #2892D9);color:var(--on-primary, white)}.timeline-dot mat-icon{font-size:1.25rem;width:1.25rem;height:1.25rem}.timeline-dot.primary{background:var(--primary)}.timeline-dot.secondary{background:var(--secondary)}.timeline-dot.tertiary{background:var(--tertiary)}.timeline-dot.accent{background:var(--secondary)}.timeline-dot.warn,.timeline-dot.error{background:var(--error)}.timeline-dot.success{background:var(--color-success)}.timeline-dot.emerald{background:#2892d9}.timeline-dot.red{background:#e74c3c}.timeline-dot.yellow{background:#f1c40f}.timeline-dot.green{background:#2ecc71}.timeline-dot.blue{background:#3498db}.timeline-dot.purple{background:#9b59b6}.timeline-dot.gray{background:#95a5a6}.timeline-dot.lightgray{background:#bdc3c7}.timeline-dot.darkgray{background:#7f8c8d}.timeline-dot.orange{background:#e67e22}.timeline-dot.white{background:#fff}.timeline-dot.black{background:#000}.timeline-dot.inherit{background:inherit}.timeline-line{width:2px;flex:1;min-height:var(--xiri-spacing-lg);background:var(--mat-sys-outline-variant, rgba(0, 0, 0, .12))}.timeline-content{padding-bottom:var(--xiri-spacing-lg);flex:1;min-width:0}.timeline-header{display:flex;align-items:baseline;gap:.75rem;flex-wrap:wrap;min-height:2.5rem;align-content:center}.timeline-title{font-weight:500;font-size:var(--xiri-font-size-body, .875rem);color:var(--mat-sys-on-surface, rgba(0, 0, 0, .87))}.timeline-datetime{font-size:var(--xiri-font-size-helper, .75rem);color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6))}.timeline-description{margin-top:.25rem;font-size:var(--xiri-font-size-body, .875rem);color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));line-height:1.5}@container (min-width: 481px){.timeline.horizontal{flex-direction:row}.timeline.horizontal .timeline-item{flex:1;min-width:0;flex-direction:column;align-items:center;gap:var(--xiri-spacing-xs);padding-bottom:0}.timeline.horizontal .timeline-item .timeline-line.line-before{display:block}.timeline.horizontal .timeline-item.first .timeline-line.line-before{visibility:hidden}.timeline.horizontal .timeline-item.last .timeline-line.line-after{display:block;visibility:hidden}.timeline.horizontal .timeline-content,.timeline.horizontal .timeline-header{display:contents}.timeline.horizontal .timeline-title{order:-2;text-align:center;min-height:2.5em;display:flex;align-items:center;justify-content:center;padding:0 var(--xiri-spacing-xs)}.timeline.horizontal .timeline-marker{order:-1;width:100%;flex-direction:row;align-items:center;gap:0}.timeline.horizontal .timeline-datetime{order:1;text-align:center;min-height:1.5em;display:flex;align-items:center;justify-content:center}.timeline.horizontal .timeline-line{flex:1;width:auto;height:2px;min-height:0}}\n"] }]
6907
+ args: [{ selector: 'xiri-timeline', imports: [MatIcon], template: "<div class=\"timeline\" [class.horizontal]=\"settings().orientation === 'horizontal'\">\n\t@for (item of settings().items; track $index; let last = $last; let first = $first) {\n\t\t<div class=\"timeline-item\" [class.last]=\"last\" [class.first]=\"first\">\n\t\t\t<div class=\"timeline-marker\">\n\t\t\t\t<div class=\"timeline-line line-before\"></div>\n\t\t\t\t<div class=\"timeline-dot\" [class]=\"item.iconColor || 'primary'\">\n\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t<mat-icon>{{ item.icon }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t\t<div class=\"timeline-line line-after\"></div>\n\t\t\t</div>\n\t\t\t<div class=\"timeline-content\">\n\t\t\t\t<div class=\"timeline-header\">\n\t\t\t\t\t<span class=\"timeline-title\">{{ item.title }}</span>\n\t\t\t\t\t@if (item.datetime) {\n\t\t\t\t\t\t<span class=\"timeline-datetime\">{{ item.datetime }}</span>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t\t@if (item.description && settings().orientation !== 'horizontal') {\n\t\t\t\t\t<div class=\"timeline-description\">{{ item.description }}</div>\n\t\t\t\t}\n\t\t\t</div>\n\t\t</div>\n\t}\n</div>\n", styles: [":host{display:block;container-type:inline-size}.timeline{display:flex;flex-direction:column}.timeline-item{display:flex;gap:var(--xiri-spacing-md);animation:fadeInUp var(--xiri-duration-normal, .3s) var(--xiri-easing-decelerate, cubic-bezier(0, 0, .2, 1)) both}.timeline-item:nth-child(1){animation-delay:0ms}.timeline-item:nth-child(2){animation-delay:50ms}.timeline-item:nth-child(3){animation-delay:.1s}.timeline-item:nth-child(4){animation-delay:.15s}.timeline-item:nth-child(5){animation-delay:.2s}.timeline-item:nth-child(6){animation-delay:.25s}.timeline-item:nth-child(7){animation-delay:.3s}.timeline-item:nth-child(8){animation-delay:.35s}.timeline-item:nth-child(9){animation-delay:.4s}.timeline-item:nth-child(10){animation-delay:.45s}.timeline-item:nth-child(11){animation-delay:.5s}.timeline-item:nth-child(12){animation-delay:.55s}.timeline-item:nth-child(13){animation-delay:.6s}.timeline-item:nth-child(14){animation-delay:.65s}.timeline-item:nth-child(15){animation-delay:.7s}.timeline-item:nth-child(16){animation-delay:.75s}.timeline-item:nth-child(17){animation-delay:.8s}.timeline-item:nth-child(18){animation-delay:.85s}.timeline-item:nth-child(19){animation-delay:.9s}.timeline-item:nth-child(20){animation-delay:.95s}.timeline-item .timeline-line.line-before,.timeline-item.last .timeline-line.line-after{display:none}.timeline-marker{display:flex;flex-direction:column;align-items:center;flex-shrink:0;width:2.5rem}.timeline-dot{width:2.5rem;height:2.5rem;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;background:var(--primary, #2892D9);color:var(--on-primary, white)}.timeline-dot mat-icon{font-size:1.25rem;width:1.25rem;height:1.25rem}.timeline-dot.primary{background:var(--primary)}.timeline-dot.secondary{background:var(--secondary)}.timeline-dot.tertiary{background:var(--tertiary)}.timeline-dot.accent{background:var(--secondary)}.timeline-dot.warn,.timeline-dot.error{background:var(--error)}.timeline-dot.success{background:var(--color-success)}.timeline-dot.emerald{background:#2892d9}.timeline-dot.red{background:#e74c3c}.timeline-dot.yellow{background:#f1c40f}.timeline-dot.green{background:#2ecc71}.timeline-dot.blue{background:#3498db}.timeline-dot.purple{background:#9b59b6}.timeline-dot.gray{background:#95a5a6}.timeline-dot.lightgray{background:#bdc3c7}.timeline-dot.darkgray{background:#7f8c8d}.timeline-dot.orange{background:#e67e22}.timeline-dot.white{background:#fff}.timeline-dot.black{background:#000}.timeline-dot.inherit{background:inherit}.timeline-line{width:2px;flex:1;min-height:var(--xiri-spacing-lg);background:var(--outline-variant, var(--mat-sys-outline-variant, rgba(0, 0, 0, .12)))}.timeline-content{padding-bottom:var(--xiri-spacing-lg);flex:1;min-width:0}.timeline-header{display:flex;align-items:baseline;gap:.75rem;flex-wrap:wrap;min-height:2.5rem;align-content:center}.timeline-title{font-weight:500;font-size:var(--xiri-font-size-body, .875rem);color:var(--on-surface, var(--mat-sys-on-surface, rgba(0, 0, 0, .87)))}.timeline-datetime{font-size:var(--xiri-font-size-helper, .75rem);color:var(--on-surface-variant, var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6)))}.timeline-description{margin-top:.25rem;font-size:var(--xiri-font-size-body, .875rem);color:var(--on-surface-variant, var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6)));line-height:1.5}@container (min-width: 481px){.timeline.horizontal{flex-direction:row}.timeline.horizontal .timeline-item{flex:1;min-width:0;flex-direction:column;align-items:center;gap:var(--xiri-spacing-xs);padding-bottom:0}.timeline.horizontal .timeline-item .timeline-line.line-before{display:block}.timeline.horizontal .timeline-item.first .timeline-line.line-before{visibility:hidden}.timeline.horizontal .timeline-item.last .timeline-line.line-after{display:block;visibility:hidden}.timeline.horizontal .timeline-content,.timeline.horizontal .timeline-header{display:contents}.timeline.horizontal .timeline-title{order:-2;text-align:center;min-height:2.5em;display:flex;align-items:center;justify-content:center;padding:0 var(--xiri-spacing-xs)}.timeline.horizontal .timeline-marker{order:-1;width:100%;flex-direction:row;align-items:center;gap:0}.timeline.horizontal .timeline-datetime{order:1;text-align:center;min-height:1.5em;display:flex;align-items:center;justify-content:center}.timeline.horizontal .timeline-line{flex:1;width:auto;height:2px;min-height:0}}\n"] }]
6864
6908
  }], propDecorators: { settings: [{ type: i0.Input, args: [{ isSignal: true, alias: "settings", required: true }] }] } });
6865
6909
 
6866
6910
  var timeline_component = /*#__PURE__*/Object.freeze({
@@ -6964,26 +7008,28 @@ class XiriEchartsHostComponent {
6964
7008
  this.chart.setOption(opt, true);
6965
7009
  }
6966
7010
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriEchartsHostComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6967
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: XiriEchartsHostComponent, isStandalone: true, selector: "xiri-echarts-host", inputs: { option: { classPropertyName: "option", publicName: "option", isSignal: true, isRequired: true, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, headerIcon: { classPropertyName: "headerIcon", publicName: "headerIcon", isSignal: true, isRequired: false, transformFunction: null }, headerIconColor: { classPropertyName: "headerIconColor", publicName: "headerIconColor", isSignal: true, isRequired: false, transformFunction: null }, chartHeight: { classPropertyName: "chartHeight", publicName: "chartHeight", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemClick: "itemClick" }, host: { properties: { "class.compact": "compact()" } }, viewQueries: [{ propertyName: "chartHostRef", first: true, predicate: ["chartHost"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (compact()) {\n\t<div class=\"xiri-echarts xiri-echarts-flat\">\n\t\t@if (hasHeader()) {\n\t\t\t<div class=\"xiri-echarts-header\">\n\t\t\t\t@if (headerIcon()) {\n\t\t\t\t\t<mat-icon [class]=\"headerIconColor() || 'primary'\">{{ headerIcon() }}</mat-icon>\n\t\t\t\t}\n\t\t\t\t@if (title()) {\n\t\t\t\t\t<div class=\"xiri-echarts-title\">{{ title() }}</div>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t\t<div #chartHost class=\"xiri-echarts-host\" [style.height]=\"chartHeight()\"></div>\n\t\t@if (error()) {\n\t\t\t<div class=\"xiri-echarts-error\">{{ error() }}</div>\n\t\t}\n\t</div>\n} @else {\n\t<mat-card class=\"xiri-echarts mat-mdc-elevation-specific mat-elevation-z2\">\n\t\t<mat-card-content>\n\t\t\t@if (hasHeader()) {\n\t\t\t\t<div class=\"xiri-echarts-header\">\n\t\t\t\t\t@if (headerIcon()) {\n\t\t\t\t\t\t<mat-icon [class]=\"headerIconColor() || 'primary'\">{{ headerIcon() }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t\t@if (title()) {\n\t\t\t\t\t\t<div class=\"xiri-echarts-title\">{{ title() }}</div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t<div #chartHost class=\"xiri-echarts-host\" [style.height]=\"chartHeight()\"></div>\n\t\t\t@if (error()) {\n\t\t\t\t<div class=\"xiri-echarts-error\">{{ error() }}</div>\n\t\t\t}\n\t\t</mat-card-content>\n\t</mat-card>\n}\n", styles: [".xiri-echarts{height:100%}.xiri-echarts .xiri-echarts-header{display:flex;align-items:center;gap:8px;margin-bottom:8px}.xiri-echarts .xiri-echarts-header mat-icon{font-size:var(--xiri-icon-size-md, 24px);width:var(--xiri-icon-size-md, 24px);height:var(--xiri-icon-size-md, 24px)}.xiri-echarts .xiri-echarts-title{font-size:14px;font-weight:500;color:var(--mat-sys-on-surface-variant, #555)}.xiri-echarts .xiri-echarts-host{width:100%;min-height:160px}.xiri-echarts .xiri-echarts-error{font-size:12px;color:var(--mat-sys-error, #b00020);padding:8px 0}.xiri-echarts-flat{background:transparent;box-shadow:none;padding:0}\n"], dependencies: [{ kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: MatCardContent, selector: "mat-card-content" }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], encapsulation: i0.ViewEncapsulation.None }); }
7011
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: XiriEchartsHostComponent, isStandalone: true, selector: "xiri-echarts-host", inputs: { option: { classPropertyName: "option", publicName: "option", isSignal: true, isRequired: true, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, headerIcon: { classPropertyName: "headerIcon", publicName: "headerIcon", isSignal: true, isRequired: false, transformFunction: null }, headerIconColor: { classPropertyName: "headerIconColor", publicName: "headerIconColor", isSignal: true, isRequired: false, transformFunction: null }, chartHeight: { classPropertyName: "chartHeight", publicName: "chartHeight", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemClick: "itemClick" }, host: { properties: { "class.compact": "compact()" } }, viewQueries: [{ propertyName: "chartHostRef", first: true, predicate: ["chartHost"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (compact()) {\n\t<div class=\"xiri-echarts xiri-echarts-flat\">\n\t\t@if (hasHeader()) {\n\t\t\t<div class=\"xiri-echarts-header\">\n\t\t\t\t@if (headerIcon()) {\n\t\t\t\t\t<mat-icon [class]=\"headerIconColor() || 'primary'\">{{ headerIcon() }}</mat-icon>\n\t\t\t\t}\n\t\t\t\t@if (title()) {\n\t\t\t\t\t<div class=\"xiri-echarts-title\">{{ title() }}</div>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t\t<div #chartHost class=\"xiri-echarts-host\" [style.height]=\"chartHeight()\"></div>\n\t\t@if (error()) {\n\t\t\t<div class=\"xiri-echarts-error\">{{ error() }}</div>\n\t\t}\n\t</div>\n} @else {\n\t<mat-card class=\"xiri-echarts mat-mdc-elevation-specific mat-elevation-z2\">\n\t\t<mat-card-content>\n\t\t\t@if (hasHeader()) {\n\t\t\t\t<div class=\"xiri-echarts-header\">\n\t\t\t\t\t@if (headerIcon()) {\n\t\t\t\t\t\t<mat-icon [class]=\"headerIconColor() || 'primary'\">{{ headerIcon() }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t\t@if (title()) {\n\t\t\t\t\t\t<div class=\"xiri-echarts-title\">{{ title() }}</div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t<div #chartHost class=\"xiri-echarts-host\" [style.height]=\"chartHeight()\"></div>\n\t\t\t@if (error()) {\n\t\t\t\t<div class=\"xiri-echarts-error\">{{ error() }}</div>\n\t\t\t}\n\t\t</mat-card-content>\n\t</mat-card>\n}\n", styles: [".xiri-echarts{height:100%}.xiri-echarts .xiri-echarts-header{display:flex;align-items:center;gap:8px;margin-bottom:8px}.xiri-echarts .xiri-echarts-header mat-icon{font-size:var(--xiri-icon-size-md, 24px);width:var(--xiri-icon-size-md, 24px);height:var(--xiri-icon-size-md, 24px)}.xiri-echarts .xiri-echarts-title{font-size:14px;font-weight:500;color:var(--on-surface-variant, var(--mat-sys-on-surface-variant, #555))}.xiri-echarts .xiri-echarts-host{width:100%;min-height:160px}.xiri-echarts .xiri-echarts-error{font-size:12px;color:var(--error, var(--mat-sys-error, #b00020));padding:8px 0}.xiri-echarts-flat{background:transparent;box-shadow:none;padding:0}\n"], dependencies: [{ kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: MatCardContent, selector: "mat-card-content" }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], encapsulation: i0.ViewEncapsulation.None }); }
6968
7012
  }
6969
7013
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: XiriEchartsHostComponent, decorators: [{
6970
7014
  type: Component,
6971
- args: [{ selector: 'xiri-echarts-host', encapsulation: ViewEncapsulation.None, imports: [MatCard, MatCardContent, MatIcon], host: { '[class.compact]': 'compact()' }, template: "@if (compact()) {\n\t<div class=\"xiri-echarts xiri-echarts-flat\">\n\t\t@if (hasHeader()) {\n\t\t\t<div class=\"xiri-echarts-header\">\n\t\t\t\t@if (headerIcon()) {\n\t\t\t\t\t<mat-icon [class]=\"headerIconColor() || 'primary'\">{{ headerIcon() }}</mat-icon>\n\t\t\t\t}\n\t\t\t\t@if (title()) {\n\t\t\t\t\t<div class=\"xiri-echarts-title\">{{ title() }}</div>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t\t<div #chartHost class=\"xiri-echarts-host\" [style.height]=\"chartHeight()\"></div>\n\t\t@if (error()) {\n\t\t\t<div class=\"xiri-echarts-error\">{{ error() }}</div>\n\t\t}\n\t</div>\n} @else {\n\t<mat-card class=\"xiri-echarts mat-mdc-elevation-specific mat-elevation-z2\">\n\t\t<mat-card-content>\n\t\t\t@if (hasHeader()) {\n\t\t\t\t<div class=\"xiri-echarts-header\">\n\t\t\t\t\t@if (headerIcon()) {\n\t\t\t\t\t\t<mat-icon [class]=\"headerIconColor() || 'primary'\">{{ headerIcon() }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t\t@if (title()) {\n\t\t\t\t\t\t<div class=\"xiri-echarts-title\">{{ title() }}</div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t<div #chartHost class=\"xiri-echarts-host\" [style.height]=\"chartHeight()\"></div>\n\t\t\t@if (error()) {\n\t\t\t\t<div class=\"xiri-echarts-error\">{{ error() }}</div>\n\t\t\t}\n\t\t</mat-card-content>\n\t</mat-card>\n}\n", styles: [".xiri-echarts{height:100%}.xiri-echarts .xiri-echarts-header{display:flex;align-items:center;gap:8px;margin-bottom:8px}.xiri-echarts .xiri-echarts-header mat-icon{font-size:var(--xiri-icon-size-md, 24px);width:var(--xiri-icon-size-md, 24px);height:var(--xiri-icon-size-md, 24px)}.xiri-echarts .xiri-echarts-title{font-size:14px;font-weight:500;color:var(--mat-sys-on-surface-variant, #555)}.xiri-echarts .xiri-echarts-host{width:100%;min-height:160px}.xiri-echarts .xiri-echarts-error{font-size:12px;color:var(--mat-sys-error, #b00020);padding:8px 0}.xiri-echarts-flat{background:transparent;box-shadow:none;padding:0}\n"] }]
7015
+ args: [{ selector: 'xiri-echarts-host', encapsulation: ViewEncapsulation.None, imports: [MatCard, MatCardContent, MatIcon], host: { '[class.compact]': 'compact()' }, template: "@if (compact()) {\n\t<div class=\"xiri-echarts xiri-echarts-flat\">\n\t\t@if (hasHeader()) {\n\t\t\t<div class=\"xiri-echarts-header\">\n\t\t\t\t@if (headerIcon()) {\n\t\t\t\t\t<mat-icon [class]=\"headerIconColor() || 'primary'\">{{ headerIcon() }}</mat-icon>\n\t\t\t\t}\n\t\t\t\t@if (title()) {\n\t\t\t\t\t<div class=\"xiri-echarts-title\">{{ title() }}</div>\n\t\t\t\t}\n\t\t\t</div>\n\t\t}\n\t\t<div #chartHost class=\"xiri-echarts-host\" [style.height]=\"chartHeight()\"></div>\n\t\t@if (error()) {\n\t\t\t<div class=\"xiri-echarts-error\">{{ error() }}</div>\n\t\t}\n\t</div>\n} @else {\n\t<mat-card class=\"xiri-echarts mat-mdc-elevation-specific mat-elevation-z2\">\n\t\t<mat-card-content>\n\t\t\t@if (hasHeader()) {\n\t\t\t\t<div class=\"xiri-echarts-header\">\n\t\t\t\t\t@if (headerIcon()) {\n\t\t\t\t\t\t<mat-icon [class]=\"headerIconColor() || 'primary'\">{{ headerIcon() }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t\t@if (title()) {\n\t\t\t\t\t\t<div class=\"xiri-echarts-title\">{{ title() }}</div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t<div #chartHost class=\"xiri-echarts-host\" [style.height]=\"chartHeight()\"></div>\n\t\t\t@if (error()) {\n\t\t\t\t<div class=\"xiri-echarts-error\">{{ error() }}</div>\n\t\t\t}\n\t\t</mat-card-content>\n\t</mat-card>\n}\n", styles: [".xiri-echarts{height:100%}.xiri-echarts .xiri-echarts-header{display:flex;align-items:center;gap:8px;margin-bottom:8px}.xiri-echarts .xiri-echarts-header mat-icon{font-size:var(--xiri-icon-size-md, 24px);width:var(--xiri-icon-size-md, 24px);height:var(--xiri-icon-size-md, 24px)}.xiri-echarts .xiri-echarts-title{font-size:14px;font-weight:500;color:var(--on-surface-variant, var(--mat-sys-on-surface-variant, #555))}.xiri-echarts .xiri-echarts-host{width:100%;min-height:160px}.xiri-echarts .xiri-echarts-error{font-size:12px;color:var(--error, var(--mat-sys-error, #b00020));padding:8px 0}.xiri-echarts-flat{background:transparent;box-shadow:none;padding:0}\n"] }]
6972
7016
  }], ctorParameters: () => [], propDecorators: { option: [{ type: i0.Input, args: [{ isSignal: true, alias: "option", required: true }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], headerIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerIcon", required: false }] }], headerIconColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerIconColor", required: false }] }], chartHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "chartHeight", required: false }] }], itemClick: [{ type: i0.Output, args: ["itemClick"] }], chartHostRef: [{ type: i0.ViewChild, args: ['chartHost', { isSignal: true }] }] } });
6973
7017
 
6974
7018
  /**
6975
- * Maps semantic XiriColor names to concrete CSS color values.
7019
+ * Maps semantic XiriColor names to CSS color values.
6976
7020
  *
6977
- * Theme tokens use Material 3 system variables; extended tokens use
6978
- * fixed brand colors that work both in light and dark themes.
7021
+ * Theme tokens reference the theme variables written by `xirimat.theming()`;
7022
+ * extended tokens are fixed brand colors that work in light and dark alike.
7023
+ * Anything referencing a variable is resolved by `resolveColor()` before it
7024
+ * reaches echarts — see there for why.
6979
7025
  */
6980
7026
  const COLOR_CSS_VAR = {
6981
- primary: 'var(--mat-sys-primary)',
6982
- secondary: 'var(--mat-sys-secondary)',
6983
- tertiary: 'var(--mat-sys-tertiary)',
6984
- accent: 'var(--mat-sys-tertiary)',
7027
+ primary: 'var(--primary)',
7028
+ secondary: 'var(--secondary)',
7029
+ tertiary: 'var(--tertiary)',
7030
+ accent: 'var(--tertiary)',
6985
7031
  warn: '#f5a623',
6986
- error: 'var(--mat-sys-error)',
7032
+ error: 'var(--error)',
6987
7033
  success: '#2e7d32',
6988
7034
  emerald: '#10b981',
6989
7035
  red: '#e53935',
@@ -7000,13 +7046,51 @@ const COLOR_CSS_VAR = {
7000
7046
  inherit: 'currentColor'
7001
7047
  };
7002
7048
  /**
7003
- * Resolves a XiriColor token (or a freeform CSS color) to a CSS-color string
7004
- * usable in echarts options. Unknown tokens fall back to the given fallback.
7049
+ * Bumped whenever the active theme changes. `resolveColor()` reads it, so the
7050
+ * `computed()` that builds a chart option re-evaluates on a theme switch and
7051
+ * the chart is re-rendered with the new colors — without every chart component
7052
+ * having to know about the theme.
7053
+ */
7054
+ const themeEpoch = signal(0, /* @ts-ignore */
7055
+ ...(ngDevMode ? [{ debugName: "themeEpoch" }] : /* istanbul ignore next */ []));
7056
+ /** Called by XiriThemeService after it applied a theme class. */
7057
+ function notifyThemeChanged() {
7058
+ themeEpoch.update(v => v + 1);
7059
+ }
7060
+ /**
7061
+ * Reads a `var(--x)` / `var(--x, y)` expression off the document root.
7062
+ * Returns undefined when there is no document (SSR) or the variable is unset.
7063
+ */
7064
+ function readCssVar(expression) {
7065
+ if (typeof document === 'undefined')
7066
+ return undefined;
7067
+ const name = expression.slice(4, -1).split(',')[0].trim();
7068
+ const value = getComputedStyle(document.documentElement).getPropertyValue(name).trim();
7069
+ return value || undefined;
7070
+ }
7071
+ /**
7072
+ * Resolves a XiriColor token to a concrete CSS color usable in echarts options.
7073
+ *
7074
+ * echarts draws on a canvas, where neither `var(--x)` nor `currentColor` is a
7075
+ * valid color — both have to be resolved to a literal first, or the series ends
7076
+ * up with no color at all. Unknown tokens fall back to the given fallback.
7005
7077
  */
7006
7078
  function resolveColor(color, fallback = '#8b5cf6') {
7079
+ themeEpoch(); // track theme changes, see notifyThemeChanged()
7007
7080
  if (!color)
7008
7081
  return fallback;
7009
- return COLOR_CSS_VAR[color] ?? fallback;
7082
+ const mapped = COLOR_CSS_VAR[color];
7083
+ if (mapped === undefined)
7084
+ return fallback;
7085
+ if (mapped.startsWith('var('))
7086
+ return readCssVar(mapped) ?? fallback;
7087
+ // "inherit" means the surrounding text color, which a canvas cannot inherit.
7088
+ if (mapped === 'currentColor') {
7089
+ if (typeof document === 'undefined')
7090
+ return fallback;
7091
+ return getComputedStyle(document.documentElement).color || fallback;
7092
+ }
7093
+ return mapped;
7010
7094
  }
7011
7095
  /**
7012
7096
  * Default categorical palette used by charts (line/pie/sankey) to color series
@@ -8308,6 +8392,9 @@ class ThemeService {
8308
8392
  root.classList.add('dark-theme');
8309
8393
  }
8310
8394
  // 'auto' mode: no class needed, CSS media query handles it
8395
+ // Charts resolve theme colors to literals (a canvas cannot read CSS
8396
+ // variables), so they have to be told to re-resolve.
8397
+ notifyThemeChanged();
8311
8398
  }
8312
8399
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ThemeService, deps: [], target: i0.ɵɵFactoryTarget.Service }); }
8313
8400
  static { this.ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.0.7", ngImport: i0, type: ThemeService }); }
@@ -8334,5 +8421,5 @@ function provideXiriServices(config) {
8334
8421
  * Generated bundle index. Do not edit.
8335
8422
  */
8336
8423
 
8337
- export { COLOR_CSS_VAR, DEFAULT_COMPARE, DEFAULT_PREDICATE, FALLBACK_COLORS, SafehtmlPipe, ThemeService, XiriAlertComponent, XiriBarChartComponent, XiriBreadcrumbComponent, XiriBulletChartComponent, XiriButtonComponent, XiriButtonlineComponent, XiriButtonstyleComponent, XiriCalendarComponent, XiriCalloutComponent, XiriCardComponent, XiriCardlinkComponent, XiriColsDirective, XiriDataService, XiriDataServiceConfig, XiriDescriptionListComponent, XiriDialogComponent, XiriDividerComponent, XiriDoneComponent, XiriDownloadService, XiriDynComponentComponent, XiriEchartsHostComponent, XiriEmptyStateComponent, XiriErrorComponent, XiriExpansionComponent, XiriFormComponent, XiriFormFieldsComponent, XiriFormService, XiriGanttComponent, XiriGaugeChartComponent, XiriHeaderComponent, XiriHeatmapComponent, XiriImagetextComponent, XiriInfopointComponent, XiriLineChartComponent, XiriLinksComponent, XiriListComponent, XiriLocalStorageService, XiriLocaleService, XiriMultiStatComponent, XiriMultiprogressComponent, XiriPageHeaderComponent, XiriPieChartComponent, XiriProgressComponent, XiriQueryComponent, XiriRawTableComponent, XiriResponseHandlerService, XiriSankeyComponent, XiriSearchComponent, XiriSectionComponent, XiriSelectDirective, XiriSessionStorageService, XiriSidenavComponent, XiriSidepanelComponent, XiriSidepanelRef, XiriSidepanelService, XiriSkeletonComponent, XiriSnackbarService, XiriStatComponent, XiriStatGridComponent, XiriStatusComponent, XiriStepperComponent, XiriTableComponent, XiriTabsComponent, XiriTimelineComponent, XiriToolbarComponent, XiriTreeComponent, XiriUrlPipe, colsToClasses, defaultXiriDataServiceConfig, escapeHtml, provideXiriServices, resolveColor };
8424
+ export { COLOR_CSS_VAR, DEFAULT_COMPARE, DEFAULT_PREDICATE, FALLBACK_COLORS, SafehtmlPipe, ThemeService, XiriAlertComponent, XiriBarChartComponent, XiriBreadcrumbComponent, XiriBulletChartComponent, XiriButtonComponent, XiriButtonlineComponent, XiriButtonstyleComponent, XiriCalendarComponent, XiriCalloutComponent, XiriCardComponent, XiriCardlinkComponent, XiriColsDirective, XiriDataService, XiriDataServiceConfig, XiriDescriptionListComponent, XiriDialogComponent, XiriDividerComponent, XiriDoneComponent, XiriDownloadService, XiriDynComponentComponent, XiriEchartsHostComponent, XiriEmptyStateComponent, XiriErrorComponent, XiriExpansionComponent, XiriFormComponent, XiriFormFieldsComponent, XiriFormService, XiriGanttComponent, XiriGaugeChartComponent, XiriHeaderComponent, XiriHeatmapComponent, XiriImagetextComponent, XiriInfopointComponent, XiriLineChartComponent, XiriLinksComponent, XiriListComponent, XiriLocalStorageService, XiriLocaleService, XiriMultiStatComponent, XiriMultiprogressComponent, XiriPageHeaderComponent, XiriPieChartComponent, XiriProgressComponent, XiriQueryComponent, XiriRawTableComponent, XiriResponseHandlerService, XiriSankeyComponent, XiriSearchComponent, XiriSectionComponent, XiriSelectDirective, XiriSessionStorageService, XiriSidenavComponent, XiriSidepanelComponent, XiriSidepanelRef, XiriSidepanelService, XiriSkeletonComponent, XiriSnackbarService, XiriStatComponent, XiriStatGridComponent, XiriStatusComponent, XiriStepperComponent, XiriTableComponent, XiriTabsComponent, XiriTimelineComponent, XiriToolbarComponent, XiriTreeComponent, XiriUrlPipe, colsToClasses, defaultXiriDataServiceConfig, escapeHtml, notifyThemeChanged, provideXiriServices, resolveColor };
8338
8425
  //# sourceMappingURL=xiriframework-xiri-ng.mjs.map