import * as i0 from '@angular/core';
import { Injectable, input, booleanAttribute, output, signal, computed, inject, ElementRef, Component, DestroyRef, viewChild, ChangeDetectorRef, DOCUMENT, NgModule, model } from '@angular/core';
import { SiCardComponent } from '@siemens/element-ng/card';
import { SiContentActionBarComponent } from '@siemens/element-ng/content-action-bar';
import { addIcons, elementZoom, elementPinch, elementRight2, SiIconComponent, elementSortUp, elementSortDown, SiStatusIconComponent } from '@siemens/element-ng/icon';
import { t, SiTranslatePipe } from '@siemens/element-translate-ng/translate';
import { BehaviorSubject } from 'rxjs';
import * as i1 from '@angular/cdk/portal';
import { CdkPortalOutlet, DomPortal, PortalModule } from '@angular/cdk/portal';
import { ViewportScroller, NgClass } from '@angular/common';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { ScrollbarHelper } from '@siemens/element-ng/common';
import { ResizeObserverService, BOOTSTRAP_BREAKPOINTS } from '@siemens/element-ng/resize-observer';
import { SiLinkDirective } from '@siemens/element-ng/link';
import * as i1$1 from '@angular/forms';
import { FormsModule } from '@angular/forms';
import { SiSearchBarComponent } from '@siemens/element-ng/search-bar';
import { A11yModule } from '@angular/cdk/a11y';
import { CdkMenuTrigger } from '@angular/cdk/menu';
import { ActivatedRoute, RouterLink } from '@angular/router';
import * as i1$2 from '@siemens/element-ng/menu';
import { SiMenuModule } from '@siemens/element-ng/menu';

/**
 * Copyright (c) Siemens 2016 - 2025
 * SPDX-License-Identifier: MIT
 */
class SiDashboardService {
    cards = new BehaviorSubject([]);
    /**
     * Subject containing the current dashboard cards as a list.
     *
     * @defaultValue this.cards.asObservable()
     */
    cards$ = this.cards.asObservable();
    /**
     * Registers a new dashboard card.
     */
    register(card) {
        const nextCards = this.cards.value;
        nextCards.push(card);
        this.cards.next(nextCards);
    }
    /**
     * Removes a registered dashboard card.
     */
    unregister(card) {
        const nextCards = this.cards.value;
        const index = nextCards.indexOf(card);
        if (index > -1) {
            nextCards.splice(index, 1);
            this.cards.next(nextCards);
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiDashboardService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
    static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiDashboardService });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiDashboardService, decorators: [{
            type: Injectable
        }] });

/**
 * Copyright (c) Siemens 2016 - 2025
 * SPDX-License-Identifier: MIT
 */
class SiDashboardCardComponent extends SiCardComponent {
    /**
     * Description of cancel button & action.
     *
     * @defaultValue
     * ```
     * t(() => $localize`:@@SI_DASHBOARD.RESTORE:Restore`)
     * ```
     */
    restoreText = input(t(() => $localize `:@@SI_DASHBOARD.RESTORE:Restore`));
    /**
     * Description of expand button & action.
     *
     * @defaultValue
     * ```
     * t(() => $localize`:@@SI_DASHBOARD.EXPAND:Expand`)
     * ```
     */
    expandText = input(t(() => $localize `:@@SI_DASHBOARD.EXPAND:Expand`));
    /**
     * Option to enable and show the UI controls for card expand functionality.
     * `Expand` and `restore` action items will be added to the content action bar.
     * The expand resizing has to be implemented by the container of the card.
     *
     * @defaultValue false
     */
    enableExpandInteraction = input(false, { transform: booleanAttribute });
    /**
     * Used in combination with si-dashboard to show filters when a card is expanded or not.
     *
     * @defaultValue true
     */
    showMenubar = input(true, { transform: booleanAttribute });
    /**
     * Emitter for size state change
     */
    expandChange = output();
    /**
     * Whether the card is currently expanded.
     *
     * @defaultValue false
     */
    isExpanded = signal(false);
    /** @internal */
    hide = false;
    /** @internal */
    enableExpandInteractionInternal = signal(false);
    enableExpandInteractionComputed = computed(() => this.enableExpandInteraction() || this.enableExpandInteractionInternal());
    /** @internal */
    element = inject(ElementRef);
    displayContentActionBar = computed(() => this.primaryActionsComputed()?.length > 0 || this.secondaryActions()?.length > 0);
    actionBarViewTypeComputed = computed(() => {
        if (!this.hasContentBarActions()) {
            if (this.enableExpandInteractionComputed()) {
                return 'expanded';
            }
            else {
                return this.actionBarViewType();
            }
        }
        else {
            return this.actionBarViewType();
        }
    });
    actionBarTitleComputed = computed(() => {
        if (!this.hasContentBarActions()) {
            if (this.enableExpandInteractionComputed()) {
                return this.expandRestoreIconTooltip();
            }
            else {
                return this.actionBarTitle();
            }
        }
        else {
            return this.actionBarTitle();
        }
    });
    primaryActionsComputed = computed(() => {
        const expandRestoreButtonActions = [
            {
                type: 'action',
                label: this.isExpanded() ? this.restoreText() : this.expandText(),
                icon: this.isExpanded() ? this.icons.elementPinch : this.icons.elementZoom,
                iconOnly: true,
                action: () => this.expandCard(!this.isExpanded())
            }
        ];
        if (!this.hasContentBarActions()) {
            if (this.enableExpandInteractionComputed()) {
                return expandRestoreButtonActions;
            }
            else {
                return [];
            }
        }
        else {
            if (!this.enableExpandInteractionComputed()) {
                return this.primaryActions();
            }
            else {
                const action = this.isExpanded() ? this.restoreActionItem() : this.expandActionItem();
                if (this.primaryActions() && this.primaryActions().length > 0) {
                    return [...this.primaryActions(), action];
                }
                else {
                    return [action];
                }
            }
        }
    });
    icons = addIcons({
        elementPinch,
        elementZoom
    });
    expandRestoreIconTooltip = computed(() => {
        return this.isExpanded() ? this.restoreText() : this.expandText();
    });
    expandActionItem = computed(() => {
        return {
            type: 'action',
            label: this.expandText(),
            icon: this.icons.elementZoom,
            iconOnly: true,
            action: () => this.expandCard(true)
        };
    });
    restoreActionItem = computed(() => {
        return {
            type: 'action',
            label: this.restoreText(),
            icon: this.icons.elementPinch,
            iconOnly: true,
            action: () => this.expandCard(false)
        };
    });
    hasContentBarActions = computed(() => {
        return this.primaryActions()?.length > 0 || this.secondaryActions()?.length > 0;
    });
    dashboardService = inject(SiDashboardService, { optional: true });
    constructor() {
        super();
        this.dashboardService?.register(this);
    }
    ngOnDestroy() {
        this.dashboardService?.unregister(this);
    }
    /**
     * Expand the dashboard card.
     */
    expand() {
        this.expandCard(true);
    }
    /**
     * Restore the dashboard card to the original, non-expanded state.
     */
    restore() {
        this.expandCard(false);
    }
    expandCard(expand) {
        this.isExpanded.set(expand);
        this.expandChange.emit(expand);
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiDashboardCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: SiDashboardCardComponent, isStandalone: true, selector: "si-dashboard-card", inputs: { restoreText: { classPropertyName: "restoreText", publicName: "restoreText", isSignal: true, isRequired: false, transformFunction: null }, expandText: { classPropertyName: "expandText", publicName: "expandText", isSignal: true, isRequired: false, transformFunction: null }, enableExpandInteraction: { classPropertyName: "enableExpandInteraction", publicName: "enableExpandInteraction", isSignal: true, isRequired: false, transformFunction: null }, showMenubar: { classPropertyName: "showMenubar", publicName: "showMenubar", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { expandChange: "expandChange" }, host: { properties: { "class.elevation-2": "isExpanded()", "class.expanded": "isExpanded()", "class.d-none": "hide" } }, usesInheritance: true, ngImport: i0, template: "@if (imgSrc()) {\n  <img\n    class=\"card-content-split\"\n    [class.card-img-top]=\"imgDir() !== 'horizontal'\"\n    [class.card-img-start]=\"imgDir() === 'horizontal'\"\n    [attr.src]=\"imgSrc()\"\n    [attr.alt]=\"imgAlt() | translate\"\n  />\n}\n\n<div class=\"content-container\" [class.card-content-split]=\"imgSrc()\">\n  @if (heading() || displayContentActionBar()) {\n    <div class=\"card-header d-flex justify-content-between\">\n      <ng-content #cardHeaderIcon select=\"[headerIcon]\" />\n      @if (heading()) {\n        <div class=\"text-truncate\">{{ heading() | translate }}</div>\n      }\n\n      <div class=\"cab d-flex ms-6 my-n4 me-n5\">\n        @if (displayContentActionBar()) {\n          <si-content-action-bar\n            class=\"ms-auto\"\n            [primaryActions]=\"primaryActionsComputed()\"\n            [secondaryActions]=\"secondaryActions()\"\n            [actionParam]=\"actionParam()\"\n            [viewType]=\"actionBarViewTypeComputed()\"\n            [attr.title]=\"actionBarTitleComputed() | translate\"\n          />\n        }\n      </div>\n    </div>\n  }\n  <ng-content #cardBody select=\"[body]\" />\n  <ng-content #cardFooter select=\"[footer]\" />\n</div>\n", styles: [":host{block-size:100%}:host.card-horizontal{flex-direction:row}:host.expanded{position:absolute;inset:0}.card-header{block-size:40px}.text-truncate{flex:0 1 auto}.cab{flex:1 0 0;min-inline-size:40px}.card-img-top{block-size:50%;inline-size:auto;object-fit:var(--si-card-img-object-fit, scale-down);object-position:var(--si-card-img-object-position, center top)}.card-img-start{block-size:auto;inline-size:50%;object-fit:var(--si-card-img-object-fit, scale-down);object-position:var(--si-card-img-object-position, left center)}.card-content-split{flex:0 0 50%}.content-container{overflow:hidden;position:relative;display:flex;flex-direction:column;flex:1 1 auto;min-inline-size:0;word-wrap:break-word;border-radius:inherit}\n"], dependencies: [{ kind: "component", type: SiContentActionBarComponent, selector: "si-content-action-bar", inputs: ["primaryActions", "secondaryActions", "actionParam", "viewType", "toggleItemLabel", "preventIconsInDropdownMenus", "disabled"] }, { kind: "pipe", type: SiTranslatePipe, name: "translate" }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiDashboardCardComponent, decorators: [{
            type: Component,
            args: [{ selector: 'si-dashboard-card', imports: [SiContentActionBarComponent, SiTranslatePipe], host: {
                        '[class.elevation-2]': 'isExpanded()',
                        '[class.expanded]': 'isExpanded()',
                        '[class.d-none]': 'hide'
                    }, template: "@if (imgSrc()) {\n  <img\n    class=\"card-content-split\"\n    [class.card-img-top]=\"imgDir() !== 'horizontal'\"\n    [class.card-img-start]=\"imgDir() === 'horizontal'\"\n    [attr.src]=\"imgSrc()\"\n    [attr.alt]=\"imgAlt() | translate\"\n  />\n}\n\n<div class=\"content-container\" [class.card-content-split]=\"imgSrc()\">\n  @if (heading() || displayContentActionBar()) {\n    <div class=\"card-header d-flex justify-content-between\">\n      <ng-content #cardHeaderIcon select=\"[headerIcon]\" />\n      @if (heading()) {\n        <div class=\"text-truncate\">{{ heading() | translate }}</div>\n      }\n\n      <div class=\"cab d-flex ms-6 my-n4 me-n5\">\n        @if (displayContentActionBar()) {\n          <si-content-action-bar\n            class=\"ms-auto\"\n            [primaryActions]=\"primaryActionsComputed()\"\n            [secondaryActions]=\"secondaryActions()\"\n            [actionParam]=\"actionParam()\"\n            [viewType]=\"actionBarViewTypeComputed()\"\n            [attr.title]=\"actionBarTitleComputed() | translate\"\n          />\n        }\n      </div>\n    </div>\n  }\n  <ng-content #cardBody select=\"[body]\" />\n  <ng-content #cardFooter select=\"[footer]\" />\n</div>\n", styles: [":host{block-size:100%}:host.card-horizontal{flex-direction:row}:host.expanded{position:absolute;inset:0}.card-header{block-size:40px}.text-truncate{flex:0 1 auto}.cab{flex:1 0 0;min-inline-size:40px}.card-img-top{block-size:50%;inline-size:auto;object-fit:var(--si-card-img-object-fit, scale-down);object-position:var(--si-card-img-object-position, center top)}.card-img-start{block-size:auto;inline-size:50%;object-fit:var(--si-card-img-object-fit, scale-down);object-position:var(--si-card-img-object-position, left center)}.card-content-split{flex:0 0 50%}.content-container{overflow:hidden;position:relative;display:flex;flex-direction:column;flex:1 1 auto;min-inline-size:0;word-wrap:break-word;border-radius:inherit}\n"] }]
        }], ctorParameters: () => [] });

/**
 * Copyright (c) Siemens 2016 - 2025
 * SPDX-License-Identifier: MIT
 */
const FIX_SCROLL_PADDING_RESIZE_OBSERVER_THROTTLE = 10;
class SiDashboardComponent {
    destroyRef = inject(DestroyRef);
    /**
     * Heading for the dashboard page.
     */
    heading = input();
    /**
     * Opt-in to enable expand interaction for all cards.
     *
     * @defaultValue false
     */
    enableExpandInteractions = input(false, { transform: booleanAttribute });
    /**
     * Option to turn off the sticky behavior of the heading and menu bar.
     *
     * @defaultValue true
     */
    sticky = input(true, { transform: booleanAttribute });
    /**
     * Option to hide the menu bar.
     *
     * @defaultValue false
     */
    hideMenubar = input(false, { transform: booleanAttribute });
    /**
     * Is `true` if a card is expanded.
     * @defaultref {@link _isExpanded}
     */
    get isExpanded() {
        return this._isExpanded;
    }
    dashboardFrameEndPadding = null;
    hideMenubarComputed = computed(() => this.hideMenubar() || this.hideMenubarInternal());
    _isExpanded = false;
    scrollPosition = [0, 0];
    cards = [];
    expandedPortalOutlet = viewChild.required('expandedPortalOutlet', {
        read: CdkPortalOutlet
    });
    dashboardFrame = viewChild.required('dashboardFrame');
    dashboard = viewChild.required('dashboard');
    dashboardFrameDimensions;
    dashboardDimensions;
    scroller = inject(ViewportScroller);
    dashboardService = inject(SiDashboardService);
    resizeObserver = inject(ResizeObserverService);
    scrollbarHelper = inject(ScrollbarHelper);
    cdRef = inject(ChangeDetectorRef);
    document = inject(DOCUMENT);
    hideMenubarInternal = signal(false);
    constructor() {
        this.dashboardService.cards$
            .pipe(takeUntilDestroyed())
            .subscribe(cards => this.subscribeToCards(cards));
    }
    ngOnChanges(changes) {
        if (changes.enableExpandInteractions) {
            this.initCards();
        }
    }
    ngAfterViewInit() {
        this.resizeObserver
            .observe(this.dashboard().nativeElement, FIX_SCROLL_PADDING_RESIZE_OBSERVER_THROTTLE)
            .pipe(takeUntilDestroyed(this.destroyRef))
            .subscribe(x => this.setDashboardFrameEndPadding(this.dashboardFrameDimensions, x));
        this.resizeObserver
            .observe(this.dashboardFrame().nativeElement, FIX_SCROLL_PADDING_RESIZE_OBSERVER_THROTTLE)
            .pipe(takeUntilDestroyed(this.destroyRef))
            .subscribe(dims => this.setDashboardFrameEndPadding(dims, this.dashboardDimensions));
    }
    subscribeToCards(cards) {
        this.cards = cards;
        this.initCards();
    }
    initCards() {
        for (const card of this.cards) {
            // We only enforce expand if the dashboard value is true, otherwise we would remove the individual
            // card settings.
            const enableExpandInteractions = this.enableExpandInteractions();
            if (enableExpandInteractions) {
                card.enableExpandInteractionInternal.set(enableExpandInteractions);
            }
            card.expandChange.subscribe((expand) => {
                if (expand) {
                    this.expand(card);
                }
                else {
                    this.restoreDashboard();
                }
                this.cdRef.markForCheck();
            });
        }
    }
    /**
     * Expands the provided card to full size in the dashboard.
     * @param card - The card to be expanded.
     */
    expand(card) {
        if (this.isExpanded) {
            this.restoreDashboard();
        }
        if (this.sticky()) {
            this.scrollPosition = [
                this.dashboardFrame().nativeElement.scrollLeft,
                this.dashboardFrame().nativeElement.scrollTop
            ];
        }
        else {
            this.scrollPosition = this.scroller.getScrollPosition();
        }
        // Make sure card.expand() is called first and prevent recursions.
        if (!card.isExpanded()) {
            card.expand();
        }
        else {
            if (!card.showMenubar()) {
                this.hideMenubarInternal.set(true);
            }
            this._isExpanded = true;
            this.expandedPortalOutlet().detach();
            this.expandedPortalOutlet().attach(new DomPortal(card.element.nativeElement));
        }
    }
    /**
     * Restores the expanded card to it's previous position.
     */
    restore() {
        // Restore all cards
        for (const card of this.cards) {
            if (card.isExpanded()) {
                card.restore();
            }
        }
        // Restore the dashboard and scroll to previous position
        this.restoreDashboard();
        // Subscribe to cards events again
        this.initCards();
        this.cdRef.markForCheck();
    }
    /**
     * Restored the UI state of the dashboard. This method is only part
     * of restoring a card and needs to be invoked after the card.restore()
     * method. In general this is achieved by listening to card events.
     */
    restoreDashboard() {
        this.expandedPortalOutlet().detach();
        this.hideMenubarInternal.set(false);
        this.toggleCardsHide(false);
        const scrollBehavior = this.document.documentElement.style.scrollBehavior;
        this.document.documentElement.style.scrollBehavior = 'auto';
        setTimeout(() => {
            if (this.sticky()) {
                this.dashboardFrame().nativeElement.scrollTo({
                    left: this.scrollPosition[0],
                    top: this.scrollPosition[1],
                    behavior: 'auto'
                });
            }
            else {
                this.scroller.scrollToPosition(this.scrollPosition);
                this.document.documentElement.style.scrollBehavior = scrollBehavior;
            }
            this.cdRef.markForCheck();
        });
        this._isExpanded = false;
    }
    toggleCardsHide(expand) {
        for (const card of this.cards) {
            card.hide = !card.isExpanded() && expand;
        }
    }
    setDashboardFrameEndPadding(dashboardFrameDimensions, dashboardDimensions) {
        if (!this.sticky()) {
            return;
        }
        if (this.dashboardDimensions === dashboardDimensions &&
            this.dashboardFrameDimensions === dashboardFrameDimensions) {
            return;
        }
        this.dashboardDimensions = dashboardDimensions;
        this.dashboardFrameDimensions = dashboardFrameDimensions;
        let padding = this.document.body.offsetWidth >= BOOTSTRAP_BREAKPOINTS.mdMinimum ? 32 : 16;
        if (dashboardDimensions &&
            dashboardFrameDimensions &&
            dashboardDimensions.height > dashboardFrameDimensions.height) {
            padding = padding - this.scrollbarHelper.width;
        }
        this.dashboardFrameEndPadding = padding;
        this.cdRef.markForCheck();
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiDashboardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: SiDashboardComponent, isStandalone: true, selector: "si-dashboard", inputs: { heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: false, transformFunction: null }, enableExpandInteractions: { classPropertyName: "enableExpandInteractions", publicName: "enableExpandInteractions", isSignal: true, isRequired: false, transformFunction: null }, sticky: { classPropertyName: "sticky", publicName: "sticky", isSignal: true, isRequired: false, transformFunction: null }, hideMenubar: { classPropertyName: "hideMenubar", publicName: "hideMenubar", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "si-layout-fixed-height" }, providers: [SiDashboardService], viewQueries: [{ propertyName: "expandedPortalOutlet", first: true, predicate: ["expandedPortalOutlet"], descendants: true, read: CdkPortalOutlet, isSignal: true }, { propertyName: "dashboardFrame", first: true, predicate: ["dashboardFrame"], descendants: true, isSignal: true }, { propertyName: "dashboard", first: true, predicate: ["dashboard"], descendants: true, isSignal: true }], usesOnChanges: true, ngImport: i0, template: "<div\n  class=\"si-layout-fixed-height si-dashboard si-layout-main-padding py-6\"\n  [class.sticky]=\"sticky()\"\n>\n  <div class=\"si-dashboard-header\" [class.sticky]=\"sticky()\">\n    @if (heading()) {\n      <div class=\"si-layout-header\">\n        <h2 class=\"si-layout-title si-layout-top-element\">{{ heading() | translate }}</h2>\n      </div>\n    }\n    @if (!hideMenubarComputed()) {\n      <div class=\"mb-6\" [class.si-layout-top-element]=\"!heading()\">\n        <ng-content select=\"[menubar]\" />\n      </div>\n    }\n  </div>\n  <div\n    #dashboardFrame\n    class=\"si-layout-fixed-height si-dashboard-content ps-2 pt-2 ms-n2 mt-n2\"\n    [class.sticky]=\"sticky()\"\n    [style.padding-inline-end.px]=\"dashboardFrameEndPadding\"\n  >\n    <div class=\"si-layout-fixed-height\" [class.d-none]=\"isExpanded\">\n      <div #dashboard class=\"si-layout-fixed-height fix-si-layout-fixed-height\">\n        <ng-content select=\"[dashboard]\" />\n      </div>\n    </div>\n    <div class=\"position-relative flex-grow-1 flex-shrink-1 mb-6\" [class.d-none]=\"!isExpanded\">\n      <ng-container #expandedPortalOutlet cdkPortalOutlet />\n    </div>\n  </div>\n</div>\n", styles: [".si-dashboard.sticky{padding-inline-end:0;overflow-x:hidden}.si-dashboard .si-dashboard-header.sticky{padding-inline-end:16px}@media (min-width: 768px){.si-dashboard .si-dashboard-header.sticky{padding-inline-end:32px}}.si-dashboard .si-dashboard-content.sticky{overflow-y:auto;overflow-x:hidden}.si-dashboard .fix-si-layout-fixed-height{min-block-size:auto}\n"], dependencies: [{ kind: "ngmodule", type: PortalModule }, { kind: "directive", type: i1.CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }, { kind: "pipe", type: SiTranslatePipe, name: "translate" }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiDashboardComponent, decorators: [{
            type: Component,
            args: [{ selector: 'si-dashboard', imports: [PortalModule, SiTranslatePipe], providers: [SiDashboardService], host: { class: 'si-layout-fixed-height' }, template: "<div\n  class=\"si-layout-fixed-height si-dashboard si-layout-main-padding py-6\"\n  [class.sticky]=\"sticky()\"\n>\n  <div class=\"si-dashboard-header\" [class.sticky]=\"sticky()\">\n    @if (heading()) {\n      <div class=\"si-layout-header\">\n        <h2 class=\"si-layout-title si-layout-top-element\">{{ heading() | translate }}</h2>\n      </div>\n    }\n    @if (!hideMenubarComputed()) {\n      <div class=\"mb-6\" [class.si-layout-top-element]=\"!heading()\">\n        <ng-content select=\"[menubar]\" />\n      </div>\n    }\n  </div>\n  <div\n    #dashboardFrame\n    class=\"si-layout-fixed-height si-dashboard-content ps-2 pt-2 ms-n2 mt-n2\"\n    [class.sticky]=\"sticky()\"\n    [style.padding-inline-end.px]=\"dashboardFrameEndPadding\"\n  >\n    <div class=\"si-layout-fixed-height\" [class.d-none]=\"isExpanded\">\n      <div #dashboard class=\"si-layout-fixed-height fix-si-layout-fixed-height\">\n        <ng-content select=\"[dashboard]\" />\n      </div>\n    </div>\n    <div class=\"position-relative flex-grow-1 flex-shrink-1 mb-6\" [class.d-none]=\"!isExpanded\">\n      <ng-container #expandedPortalOutlet cdkPortalOutlet />\n    </div>\n  </div>\n</div>\n", styles: [".si-dashboard.sticky{padding-inline-end:0;overflow-x:hidden}.si-dashboard .si-dashboard-header.sticky{padding-inline-end:16px}@media (min-width: 768px){.si-dashboard .si-dashboard-header.sticky{padding-inline-end:32px}}.si-dashboard .si-dashboard-content.sticky{overflow-y:auto;overflow-x:hidden}.si-dashboard .fix-si-layout-fixed-height{min-block-size:auto}\n"] }]
        }], ctorParameters: () => [] });

/**
 * Copyright (c) Siemens 2016 - 2025
 * SPDX-License-Identifier: MIT
 */
class SiDashboardModule {
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiDashboardModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
    static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.0.6", ngImport: i0, type: SiDashboardModule, imports: [SiDashboardCardComponent, SiDashboardComponent], exports: [SiDashboardCardComponent, SiDashboardComponent] });
    static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiDashboardModule, imports: [SiDashboardCardComponent, SiDashboardComponent] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiDashboardModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [SiDashboardCardComponent, SiDashboardComponent],
                    exports: [SiDashboardCardComponent, SiDashboardComponent]
                }]
        }] });

/**
 * Copyright (c) Siemens 2016 - 2025
 * SPDX-License-Identifier: MIT
 */
/**
 * The SiWidgetBaseComponent<T> implements the timing for the skeleton loading
 * indicator of widgets. It supports a generic value input property that represents
 * the main value to be displayed by a widget. When the value is not set, the `showLoadingIndicator`
 * changes after the `initialLoadingIndicatorDebounceTime` delay to `true` and subclasses
 * should show the skeleton loading indicator.
 */
class SiWidgetBaseComponent {
    /**
     * The main value to be displayed. If no value is set,
     * the skeleton indicates the loading of the value. Disable
     * the automatic loading mechanism by setting `SiWidgetBodyBaseComponent.disableAutoLoadingIndicator`.
     */
    value = input.required();
    /**
     * Option to disable automatic start of skeleton loading indication.
     *
     * @defaultValue false
     */
    disableAutoLoadingIndicator = input(false, { transform: booleanAttribute });
    /**
     * Input to start and stop the skeleton loading indication.
     *
     * @defaultValue false
     */
    showLoadingIndicatorInput = input(false, {
        // eslint-disable-next-line @angular-eslint/no-input-rename
        alias: 'showLoadingIndicator',
        transform: booleanAttribute
    });
    showLoadingIndicatorInternal = signal(false);
    showLoadingIndicator = computed(() => {
        return this.showLoadingIndicatorInternal() ?? this.showLoadingIndicatorInput();
    });
    /**
     * Initial delay time in milliseconds before enabling loading indicator.
     * Only used once initially during construction.
     *
     * @defaultValue 300
     */
    initialLoadingIndicatorDebounceTime = input(300);
    cdRef = inject(ChangeDetectorRef);
    loadingTimer;
    ngOnChanges(changes) {
        if (!this.disableAutoLoadingIndicator() &&
            !changes.value?.firstChange &&
            changes.value?.currentValue) {
            if (this.loadingTimer) {
                clearTimeout(this.loadingTimer);
                this.loadingTimer = undefined;
            }
            this.showLoadingIndicatorInternal.set(false);
        }
    }
    ngOnInit() {
        if (!this.disableAutoLoadingIndicator() && !this.value()) {
            this.loadingTimer = setTimeout(() => {
                this.showLoadingIndicatorInternal.set(!this.value());
            }, this.initialLoadingIndicatorDebounceTime());
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiWidgetBaseComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.0.6", type: SiWidgetBaseComponent, isStandalone: true, selector: "ng-component", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, disableAutoLoadingIndicator: { classPropertyName: "disableAutoLoadingIndicator", publicName: "disableAutoLoadingIndicator", isSignal: true, isRequired: false, transformFunction: null }, showLoadingIndicatorInput: { classPropertyName: "showLoadingIndicatorInput", publicName: "showLoadingIndicator", isSignal: true, isRequired: false, transformFunction: null }, initialLoadingIndicatorDebounceTime: { classPropertyName: "initialLoadingIndicatorDebounceTime", publicName: "initialLoadingIndicatorDebounceTime", isSignal: true, isRequired: false, transformFunction: null } }, usesOnChanges: true, ngImport: i0, template: '', isInline: true });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiWidgetBaseComponent, decorators: [{
            type: Component,
            args: [{
                    template: ''
                }]
        }] });

/**
 * Copyright (c) Siemens 2016 - 2025
 * SPDX-License-Identifier: MIT
 */
/**
 * The `<si-link-widget>` supports an easy composition of links and actions
 * with support for skeleton loading indicator.
 */
class SiLinkWidgetComponent extends SiWidgetBaseComponent {
    /**
     * Option to enable trailing link arrow icons for each link.
     *
     * @defaultValue false
     */
    showLinkIcons = input(false, { transform: booleanAttribute });
    /**
     * The number of skeleton progress indication rows.
     *
     * @defaultValue 3
     */
    numberOfLinks = input(3);
    ghosts = computed(() => new Array(this.numberOfLinks() ?? 3));
    icons = addIcons({ elementRight2 });
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiLinkWidgetComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: SiLinkWidgetComponent, isStandalone: true, selector: "si-link-widget", inputs: { showLinkIcons: { classPropertyName: "showLinkIcons", publicName: "showLinkIcons", isSignal: true, isRequired: false, transformFunction: null }, numberOfLinks: { classPropertyName: "numberOfLinks", publicName: "numberOfLinks", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "si-link-widget" }, usesInheritance: true, ngImport: i0, template: "@if (!showLoadingIndicator() && value()) {\n  @for (link of value(); track link) {\n    @if (link.action) {\n      <button type=\"button\" class=\"btn btn-link\" [siLink]=\"link\">{{\n        link.title | translate\n      }}</button>\n    } @else {\n      <a [siLink]=\"link\">\n        {{ link.title | translate }}\n        @if (showLinkIcons()) {\n          <si-icon class=\"link-icon link-end flip-rtl\" [icon]=\"icons.elementRight2\" />\n        }\n      </a>\n    }\n  }\n} @else {\n  @for (some of ghosts(); track $index) {\n    <div class=\"si-link-widget-skeleton\"></div>\n  }\n}\n", dependencies: [{ kind: "component", type: SiIconComponent, selector: "si-icon", inputs: ["icon"] }, { kind: "directive", type: SiLinkDirective, selector: "[siLink]", inputs: ["siLink", "siLinkDefaultTarget", "actionParam", "activeClass", "exactMatch", "ariaCurrent"], outputs: ["activeChange"], exportAs: ["siLink"] }, { kind: "pipe", type: SiTranslatePipe, name: "translate" }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiLinkWidgetComponent, decorators: [{
            type: Component,
            args: [{ selector: 'si-link-widget', imports: [SiIconComponent, SiLinkDirective, SiTranslatePipe], host: { class: 'si-link-widget' }, template: "@if (!showLoadingIndicator() && value()) {\n  @for (link of value(); track link) {\n    @if (link.action) {\n      <button type=\"button\" class=\"btn btn-link\" [siLink]=\"link\">{{\n        link.title | translate\n      }}</button>\n    } @else {\n      <a [siLink]=\"link\">\n        {{ link.title | translate }}\n        @if (showLinkIcons()) {\n          <si-icon class=\"link-icon link-end flip-rtl\" [icon]=\"icons.elementRight2\" />\n        }\n      </a>\n    }\n  }\n} @else {\n  @for (some of ghosts(); track $index) {\n    <div class=\"si-link-widget-skeleton\"></div>\n  }\n}\n" }]
        }] });

/**
 * Copyright (c) Siemens 2016 - 2025
 * SPDX-License-Identifier: MIT
 */
/**
 * The `<si-link-widget>` supports an easy composition of links and actions
 * with support for skeleton loading indicator.
 */
class SiListWidgetItemComponent extends SiWidgetBaseComponent {
    isLink = computed(() => {
        return typeof this.value()?.label === 'object';
    });
    badgeColor = computed(() => {
        return this.value()?.badgeColor ? 'bg-' + this.value()?.badgeColor : 'bg-default';
    });
    link = computed(() => {
        return this.value()?.label;
    });
    label = computed(() => {
        return this.value()?.label;
    });
    icons = addIcons({ elementRight2 });
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiListWidgetItemComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: SiListWidgetItemComponent, isStandalone: true, selector: "si-list-widget-item", host: { attributes: { "role": "listitem" }, classAttribute: "list-group-item d-flex align-items-center" }, usesInheritance: true, ngImport: i0, template: "@let valueObject = value();\n@if (!showLoadingIndicator() && valueObject) {\n  @if (valueObject.badge) {\n    <span class=\"mx-0 badge me-4\" [ngClass]=\"badgeColor()\">{{\n      valueObject.badge | translate\n    }}</span>\n  }\n  <span class=\"me-auto\">\n    @if (!isLink()) {\n      <span class=\"si-h5\">{{ label() | translate }}</span>\n    } @else {\n      <a class=\"\" [siLink]=\"link()\"\n        >{{ link().title | translate\n        }}<si-icon class=\"link-icon link-start flip-rtl\" [icon]=\"icons.elementRight2\" />\n      </a>\n    }\n    @if (valueObject.description) {\n      <div class=\"mt-1 si-body text-secondary\">{{ valueObject.description | translate }}</div>\n    }\n  </span>\n  <span>{{ valueObject.text | translate }}</span>\n  @if (valueObject.action) {\n    @if (valueObject.action.action) {\n      <button\n        type=\"button\"\n        class=\"btn btn-circle btn-sm btn-tertiary ms-4 p-2\"\n        [attr.aria-label]=\"valueObject.action.title | translate\"\n        [siLink]=\"valueObject.action\"\n      >\n        @if (valueObject.actionIcon) {\n          <si-icon class=\"icon\" [icon]=\"valueObject.actionIcon\" />\n        }\n      </button>\n    } @else {\n      <a\n        class=\"ms-4 p-2\"\n        [siLink]=\"valueObject.action\"\n        [attr.aria-label]=\"valueObject.action.title | translate\"\n      >\n        @if (valueObject.actionIcon) {\n          <si-icon class=\"icon\" [icon]=\"valueObject.actionIcon\" />\n        }\n      </a>\n    }\n  }\n} @else {\n  <div class=\"si-link-widget-skeleton my-4\"></div>\n}\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: SiIconComponent, selector: "si-icon", inputs: ["icon"] }, { kind: "directive", type: SiLinkDirective, selector: "[siLink]", inputs: ["siLink", "siLinkDefaultTarget", "actionParam", "activeClass", "exactMatch", "ariaCurrent"], outputs: ["activeChange"], exportAs: ["siLink"] }, { kind: "pipe", type: SiTranslatePipe, name: "translate" }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiListWidgetItemComponent, decorators: [{
            type: Component,
            args: [{ selector: 'si-list-widget-item', imports: [NgClass, SiIconComponent, SiLinkDirective, SiTranslatePipe], host: {
                        class: 'list-group-item d-flex align-items-center',
                        role: 'listitem'
                    }, template: "@let valueObject = value();\n@if (!showLoadingIndicator() && valueObject) {\n  @if (valueObject.badge) {\n    <span class=\"mx-0 badge me-4\" [ngClass]=\"badgeColor()\">{{\n      valueObject.badge | translate\n    }}</span>\n  }\n  <span class=\"me-auto\">\n    @if (!isLink()) {\n      <span class=\"si-h5\">{{ label() | translate }}</span>\n    } @else {\n      <a class=\"\" [siLink]=\"link()\"\n        >{{ link().title | translate\n        }}<si-icon class=\"link-icon link-start flip-rtl\" [icon]=\"icons.elementRight2\" />\n      </a>\n    }\n    @if (valueObject.description) {\n      <div class=\"mt-1 si-body text-secondary\">{{ valueObject.description | translate }}</div>\n    }\n  </span>\n  <span>{{ valueObject.text | translate }}</span>\n  @if (valueObject.action) {\n    @if (valueObject.action.action) {\n      <button\n        type=\"button\"\n        class=\"btn btn-circle btn-sm btn-tertiary ms-4 p-2\"\n        [attr.aria-label]=\"valueObject.action.title | translate\"\n        [siLink]=\"valueObject.action\"\n      >\n        @if (valueObject.actionIcon) {\n          <si-icon class=\"icon\" [icon]=\"valueObject.actionIcon\" />\n        }\n      </button>\n    } @else {\n      <a\n        class=\"ms-4 p-2\"\n        [siLink]=\"valueObject.action\"\n        [attr.aria-label]=\"valueObject.action.title | translate\"\n      >\n        @if (valueObject.actionIcon) {\n          <si-icon class=\"icon\" [icon]=\"valueObject.actionIcon\" />\n        }\n      </a>\n    }\n  }\n} @else {\n  <div class=\"si-link-widget-skeleton my-4\"></div>\n}\n" }]
        }] });

/**
 * Copyright (c) Siemens 2016 - 2025
 * SPDX-License-Identifier: MIT
 */
/**
 * The `<si-list-widget-body>` implements the body of the <si-list-widget> that can be
 * used for composition within other components.
 */
class SiListWidgetBodyComponent extends SiWidgetBaseComponent {
    /** Optional footer link for the list widget */
    link = input();
    /**
     * label for the "search placeholder" name
     *
     * @defaultValue
     * ```
     * t(() => $localize`:@@SI_LIST_WIDGET.SEARCH_PLACEHOLDER:Search...`)
     * ```
     */
    searchPlaceholderLabel = input(t(() => $localize `:@@SI_LIST_WIDGET.SEARCH_PLACEHOLDER:Search...`));
    /**
     * Enable ascending and descending SiListWidgetItem sorting. If enabled,
     * items are initially ascending sorted.
     */
    sort = input();
    /**
     * Enables the search functionality.
     *
     * @defaultValue false
     */
    search = input(false, { transform: booleanAttribute });
    /**
     * Compare function of for two `SiListWidgetItem`s that is used to sort
     * the array of items. The default compares the item labels by using the
     * string `localeCompare()` function.
     *
     * @param a - first `SiListWidgetItem` of the comparison.
     *
     * @param b - second `SiListWidgetItem` of the comparison.
     *
     * @returns A value `< 0` if `a` is smaller, `> 0` if `b` is smaller, otherwise `0`.
     *
     * @defaultValue
     * ```
     * (
     *     a: SiListWidgetItem,
     *     b: SiListWidgetItem
     *   ) => {
     *     const aLabel = typeof a.label === 'object' ? a.label.title! : a.label;
     *     const bLabel = typeof b.label === 'object' ? b.label.title! : b.label;
     *     return aLabel.localeCompare(bLabel);
     *   }
     * ```
     */
    compareFn = input((a, b) => {
        const aLabel = typeof a.label === 'object' ? a.label.title : a.label;
        const bLabel = typeof b.label === 'object' ? b.label.title : b.label;
        return aLabel.localeCompare(bLabel);
    });
    /**
     * Filter function that is used to filter down the list items when the user enters
     * a term in the search bar. Default function.
     *
     * @param item - The item be checked if it matches the searchTerm.
     *
     * @param searchTerm - The string the user typed in the search bar.
     *
     * @returns `true` if the `searchTerm` matches the `item` and the `item` shall be kept in the list.
     *
     * @defaultValue
     * ```
     * (
     *     item: SiListWidgetItem,
     *     searchTerm: string
     *   ) => {
     *     const aLabel = typeof item.label === 'object' ? item.label.title! : item.label;
     *     return aLabel.toLowerCase().includes(searchTerm.toLowerCase());
     *   }
     * ```
     */
    filterFn = input((item, searchTerm) => {
        const aLabel = typeof item.label === 'object' ? item.label.title : item.label;
        return aLabel.toLowerCase().includes(searchTerm.toLowerCase());
    });
    /**
     * The number of skeleton progress indication rows.
     *
     * @defaultValue 6
     */
    numberOfLinks = input(6);
    /** Used to display the defined number of ghost items */
    ghosts = computed(() => new Array(this.numberOfLinks() ?? 6));
    /** Holds the list items that are displayed. May be filtered and sorted. */
    filteredListWidgetItems = computed(() => {
        const value = this.value();
        const sort = this.sort();
        const searchText = this.searchText();
        let filteredListWidgetItems = value;
        if (searchText.length > 0) {
            filteredListWidgetItems = value?.filter((item) => this.filterFn()(item, searchText));
        }
        else {
            filteredListWidgetItems = value ? [...value] : undefined;
        }
        if (sort) {
            const factor = sort === 'ASC' ? 1 : -1;
            filteredListWidgetItems = filteredListWidgetItems?.sort((a, b) => (this.compareFn()(a, b) ?? 0) * factor);
        }
        return filteredListWidgetItems;
    });
    searchText = model('');
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiListWidgetBodyComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: SiListWidgetBodyComponent, isStandalone: true, selector: "si-list-widget-body", inputs: { link: { classPropertyName: "link", publicName: "link", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholderLabel: { classPropertyName: "searchPlaceholderLabel", publicName: "searchPlaceholderLabel", isSignal: true, isRequired: false, transformFunction: null }, sort: { classPropertyName: "sort", publicName: "sort", isSignal: true, isRequired: false, transformFunction: null }, search: { classPropertyName: "search", publicName: "search", isSignal: true, isRequired: false, transformFunction: null }, compareFn: { classPropertyName: "compareFn", publicName: "compareFn", isSignal: true, isRequired: false, transformFunction: null }, filterFn: { classPropertyName: "filterFn", publicName: "filterFn", isSignal: true, isRequired: false, transformFunction: null }, numberOfLinks: { classPropertyName: "numberOfLinks", publicName: "numberOfLinks", isSignal: true, isRequired: false, transformFunction: null }, searchText: { classPropertyName: "searchText", publicName: "searchText", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { searchText: "searchTextChange" }, usesInheritance: true, ngImport: i0, template: "@if (search()) {\n  <si-search-bar\n    class=\"px-6 py-4\"\n    showIcon\n    colorVariant=\"base-0\"\n    [debounceTime]=\"400\"\n    [placeholder]=\"searchPlaceholderLabel() | translate\"\n    [(ngModel)]=\"searchText\"\n  />\n}\n@let filteredListWidgetItemsList = filteredListWidgetItems();\n@if (!showLoadingIndicator() && filteredListWidgetItemsList) {\n  @if (filteredListWidgetItemsList.length > 0) {\n    <div class=\"list-group list-group-lg\" role=\"list\">\n      @for (item of filteredListWidgetItemsList; track $index) {\n        <si-list-widget-item [value]=\"item\" />\n      }\n    </div>\n  } @else {\n    <ng-content select=\"[empty-state]\" />\n  }\n} @else {\n  <div class=\"list-group list-group-lg\" role=\"list\">\n    @for (some of ghosts(); track $index) {\n      <si-list-widget-item [value]=\"undefined\" />\n    }\n  </div>\n}\n", styles: [":host{background-color:var(--element-base-1);border-radius:var(--element-radius-3);display:flex;flex-direction:column;flex:1 1 auto;overflow:hidden}:host:has(si-search-bar){padding-block-start:8px}:host-context(si-card,si-dashboard-card){padding-block-start:unset!important}.list-group{border-radius:inherit;overflow-y:auto;overflow-x:hidden}\n"], dependencies: [{ kind: "component", type: SiListWidgetItemComponent, selector: "si-list-widget-item" }, { kind: "component", type: SiSearchBarComponent, selector: "si-search-bar", inputs: ["debounceTime", "prohibitedCharacters", "placeholder", "showIcon", "tabbable", "value", "readonly", "colorVariant", "disabled", "clearButtonAriaLabel"], outputs: ["searchChange"] }, { kind: "pipe", type: SiTranslatePipe, name: "translate" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiListWidgetBodyComponent, decorators: [{
            type: Component,
            args: [{ selector: 'si-list-widget-body', imports: [SiListWidgetItemComponent, SiSearchBarComponent, SiTranslatePipe, FormsModule], host: { class: '' }, template: "@if (search()) {\n  <si-search-bar\n    class=\"px-6 py-4\"\n    showIcon\n    colorVariant=\"base-0\"\n    [debounceTime]=\"400\"\n    [placeholder]=\"searchPlaceholderLabel() | translate\"\n    [(ngModel)]=\"searchText\"\n  />\n}\n@let filteredListWidgetItemsList = filteredListWidgetItems();\n@if (!showLoadingIndicator() && filteredListWidgetItemsList) {\n  @if (filteredListWidgetItemsList.length > 0) {\n    <div class=\"list-group list-group-lg\" role=\"list\">\n      @for (item of filteredListWidgetItemsList; track $index) {\n        <si-list-widget-item [value]=\"item\" />\n      }\n    </div>\n  } @else {\n    <ng-content select=\"[empty-state]\" />\n  }\n} @else {\n  <div class=\"list-group list-group-lg\" role=\"list\">\n    @for (some of ghosts(); track $index) {\n      <si-list-widget-item [value]=\"undefined\" />\n    }\n  </div>\n}\n", styles: [":host{background-color:var(--element-base-1);border-radius:var(--element-radius-3);display:flex;flex-direction:column;flex:1 1 auto;overflow:hidden}:host:has(si-search-bar){padding-block-start:8px}:host-context(si-card,si-dashboard-card){padding-block-start:unset!important}.list-group{border-radius:inherit;overflow-y:auto;overflow-x:hidden}\n"] }]
        }] });

/**
 * Copyright (c) Siemens 2016 - 2025
 * SPDX-License-Identifier: MIT
 */
/**
 * The `<si-list-widget>` supports an easy composition of links and actions
 * with support for skeleton loading indicator, wrapped in a card.
 */
class SiListWidgetComponent extends SiWidgetBaseComponent {
    icons = addIcons({ elementRight2, elementSortDown, elementSortUp });
    /** List widget heading. */
    heading = input();
    /** Optional footer link for the list widget */
    link = input();
    /**
     * label for the "search placeholder" name
     *
     * @defaultValue
     * ```
     * t(() => $localize`:@@SI_LIST_WIDGET.SEARCH_PLACEHOLDER:Search...`)
     * ```
     */
    searchPlaceholderLabel = input(t(() => $localize `:@@SI_LIST_WIDGET.SEARCH_PLACEHOLDER:Search...`));
    /**
     * @defaultValue
     * ```
     * t(() => $localize`:@@SI_LIST_WIDGET.SORT_ASCENDING:Sort ascending`)
     * ```
     */
    sortAscendingLabel = input(t(() => $localize `:@@SI_LIST_WIDGET.SORT_ASCENDING:Sort ascending`));
    /**
     * @defaultValue
     * ```
     * t(() => $localize`:@@SI_LIST_WIDGET.SORT_DESCENDING:Sort descending`)
     * ```
     */
    sortDescendingLabel = input(t(() => $localize `:@@SI_LIST_WIDGET.SORT_DESCENDING:Sort descending`));
    /**
     * Set `ASC` of ascending sorting, `DSC` for descending sorting and `undefined` for no sorting.
     */
    sort = model();
    /**
     * Enables the search functionality.
     *
     * @defaultValue false
     */
    search = input(false, { transform: booleanAttribute });
    /**
     * Compare function of for two `SiListWidgetItem`s that is used to sort
     * the array of items. The default compares the item labels by using the
     * string `localeCompare()` function.
     *
     * @param a - first `SiListWidgetItem` of the comparison.
     *
     * @param b - second `SiListWidgetItem` of the comparison.
     *
     * @returns A value `< 0` if `a` is smaller, `> 0` if `b` is smaller, otherwise `0`.
     *
     * @defaultValue
     * ```
     * (
     *     a: SiListWidgetItem,
     *     b: SiListWidgetItem
     *   ) => {
     *     const aLabel = typeof a.label === 'object' ? a.label.title! : a.label;
     *     const bLabel = typeof b.label === 'object' ? b.label.title! : b.label;
     *     return aLabel.localeCompare(bLabel);
     *   }
     * ```
     */
    compareFn = input((a, b) => {
        const aLabel = typeof a.label === 'object' ? a.label.title : a.label;
        const bLabel = typeof b.label === 'object' ? b.label.title : b.label;
        return aLabel.localeCompare(bLabel);
    });
    /**
     * Filter function that is used to filter down the list items when the user enters
     * a term in the search bar. Default function.
     *
     * @param item - The item be checked if it matches the searchTerm.
     *
     * @param searchTerm - The string the user typed in the search bar.
     *
     * @returns `true` if the `searchTerm` matches the `item` and the `item` shall be kept in the list.
     *
     * @defaultValue
     * ```
     * (
     *     item: SiListWidgetItem,
     *     searchTerm: string
     *   ) => {
     *     const aLabel = typeof item.label === 'object' ? item.label.title! : item.label;
     *     return aLabel.toLowerCase().includes(searchTerm.toLowerCase());
     *   }
     * ```
     */
    filterFn = input((item, searchTerm) => {
        const aLabel = typeof item.label === 'object' ? item.label.title : item.label;
        return aLabel.toLowerCase().includes(searchTerm.toLowerCase());
    });
    /**
     * The number of skeleton progress indication rows.
     *
     * @defaultValue 6
     */
    numberOfLinks = input(6);
    /**
     * Optional accent line
     */
    accentLine = input();
    accentClass = computed(() => {
        const accentLine = this.accentLine();
        return accentLine ? 'accent-' + accentLine : '';
    });
    /** The menu item array used to display the sort button. */
    sortAction = computed(() => {
        const sortAction = [
            {
                label: this.sortDescendingLabel(),
                type: 'action',
                icon: this.icons.elementSortUp,
                iconOnly: true,
                action: () => this.doSort()
            }
        ];
        if (this.sort() === 'ASC') {
            sortAction[0].label = this.sortDescendingLabel();
            sortAction[0].icon = this.icons.elementSortUp;
        }
        else {
            sortAction[0].label = this.sortAscendingLabel();
            sortAction[0].icon = this.icons.elementSortDown;
        }
        return sortAction;
    });
    doSort() {
        if (this.sort() === 'ASC') {
            this.sort.set('DSC');
        }
        else {
            this.sort.set('ASC');
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiListWidgetComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: SiListWidgetComponent, isStandalone: true, selector: "si-list-widget", inputs: { heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: false, transformFunction: null }, link: { classPropertyName: "link", publicName: "link", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholderLabel: { classPropertyName: "searchPlaceholderLabel", publicName: "searchPlaceholderLabel", isSignal: true, isRequired: false, transformFunction: null }, sortAscendingLabel: { classPropertyName: "sortAscendingLabel", publicName: "sortAscendingLabel", isSignal: true, isRequired: false, transformFunction: null }, sortDescendingLabel: { classPropertyName: "sortDescendingLabel", publicName: "sortDescendingLabel", isSignal: true, isRequired: false, transformFunction: null }, sort: { classPropertyName: "sort", publicName: "sort", isSignal: true, isRequired: false, transformFunction: null }, search: { classPropertyName: "search", publicName: "search", isSignal: true, isRequired: false, transformFunction: null }, compareFn: { classPropertyName: "compareFn", publicName: "compareFn", isSignal: true, isRequired: false, transformFunction: null }, filterFn: { classPropertyName: "filterFn", publicName: "filterFn", isSignal: true, isRequired: false, transformFunction: null }, numberOfLinks: { classPropertyName: "numberOfLinks", publicName: "numberOfLinks", isSignal: true, isRequired: false, transformFunction: null }, accentLine: { classPropertyName: "accentLine", publicName: "accentLine", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sort: "sortChange" }, host: { classAttribute: "si-list-widget" }, usesInheritance: true, ngImport: i0, template: "<si-card\n  class=\"h-100\"\n  actionBarViewType=\"expanded\"\n  [ngClass]=\"accentClass()\"\n  [heading]=\"heading()\"\n  [primaryActions]=\"sort() ? sortAction() : []\"\n>\n  <si-list-widget-body\n    body\n    [compareFn]=\"compareFn()\"\n    [filterFn]=\"filterFn()\"\n    [numberOfLinks]=\"numberOfLinks()\"\n    [searchPlaceholderLabel]=\"searchPlaceholderLabel()\"\n    [search]=\"search()\"\n    [sort]=\"sort()\"\n    [value]=\"value()\"\n    [showLoadingIndicator]=\"showLoadingIndicator()\"\n  >\n    <ng-content select=\"[empty-state]\" empty-state />\n  </si-list-widget-body>\n\n  @let linkValue = link();\n  @if (linkValue) {\n    <div class=\"card-footer\" footer>\n      @if (!linkValue.action) {\n        <a [siLink]=\"linkValue\">\n          {{ linkValue.title | translate }}\n          <si-icon class=\"link-icon link-end flip-rtl\" [icon]=\"icons.elementRight2\" />\n        </a>\n      } @else {\n        <button type=\"button\" class=\"btn btn-link\" [siLink]=\"linkValue\"\n          >{{ linkValue.title | translate }}\n        </button>\n      }\n    </div>\n  }\n</si-card>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: SiCardComponent, selector: "si-card", inputs: ["primaryActions", "secondaryActions", "actionParam", "actionBarViewType", "actionBarTitle"] }, { kind: "component", type: SiIconComponent, selector: "si-icon", inputs: ["icon"] }, { kind: "directive", type: SiLinkDirective, selector: "[siLink]", inputs: ["siLink", "siLinkDefaultTarget", "actionParam", "activeClass", "exactMatch", "ariaCurrent"], outputs: ["activeChange"], exportAs: ["siLink"] }, { kind: "component", type: SiListWidgetBodyComponent, selector: "si-list-widget-body", inputs: ["link", "searchPlaceholderLabel", "sort", "search", "compareFn", "filterFn", "numberOfLinks", "searchText"], outputs: ["searchTextChange"] }, { kind: "pipe", type: SiTranslatePipe, name: "translate" }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiListWidgetComponent, decorators: [{
            type: Component,
            args: [{ selector: 'si-list-widget', imports: [
                        NgClass,
                        SiCardComponent,
                        SiIconComponent,
                        SiLinkDirective,
                        SiListWidgetBodyComponent,
                        SiTranslatePipe
                    ], host: { class: 'si-list-widget' }, template: "<si-card\n  class=\"h-100\"\n  actionBarViewType=\"expanded\"\n  [ngClass]=\"accentClass()\"\n  [heading]=\"heading()\"\n  [primaryActions]=\"sort() ? sortAction() : []\"\n>\n  <si-list-widget-body\n    body\n    [compareFn]=\"compareFn()\"\n    [filterFn]=\"filterFn()\"\n    [numberOfLinks]=\"numberOfLinks()\"\n    [searchPlaceholderLabel]=\"searchPlaceholderLabel()\"\n    [search]=\"search()\"\n    [sort]=\"sort()\"\n    [value]=\"value()\"\n    [showLoadingIndicator]=\"showLoadingIndicator()\"\n  >\n    <ng-content select=\"[empty-state]\" empty-state />\n  </si-list-widget-body>\n\n  @let linkValue = link();\n  @if (linkValue) {\n    <div class=\"card-footer\" footer>\n      @if (!linkValue.action) {\n        <a [siLink]=\"linkValue\">\n          {{ linkValue.title | translate }}\n          <si-icon class=\"link-icon link-end flip-rtl\" [icon]=\"icons.elementRight2\" />\n        </a>\n      } @else {\n        <button type=\"button\" class=\"btn btn-link\" [siLink]=\"linkValue\"\n          >{{ linkValue.title | translate }}\n        </button>\n      }\n    </div>\n  }\n</si-card>\n" }]
        }] });

/**
 * Copyright (c) Siemens 2016 - 2025
 * SPDX-License-Identifier: MIT
 */
/**
 * The items of the `<si-timeline-widget>`.
 */
class SiTimelineWidgetItemComponent extends SiWidgetBaseComponent {
    /**
     * Whether to show or hide the description row during skeleton progress indication.
     *
     * @defaultValue `true`
     */
    showDescription = input(true);
    /**
     * Aria label text for actions button dropdown.
     */
    ariaLabelDropdown = t(() => $localize `:@@SI_DASHBOARD.EXPAND_WIDGET_ACTIONS:Expand actions`);
    activatedRoute = inject(ActivatedRoute, { optional: true });
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiTimelineWidgetItemComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: SiTimelineWidgetItemComponent, isStandalone: true, selector: "si-timeline-widget-item", inputs: { showDescription: { classPropertyName: "showDescription", publicName: "showDescription", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "listitem" } }, usesInheritance: true, ngImport: i0, template: "@let valueObject = value();\n@if (!showLoadingIndicator() && valueObject) {\n  <div class=\"d-flex flex-row gap-4\" [class.pe-4]=\"!valueObject.action\">\n    <div class=\"d-flex flex-column align-items-center gap-1 pt-4\">\n      <span class=\"icon icon-stack\">\n        <si-icon [class]=\"valueObject.iconColor\" [icon]=\"valueObject.icon\" />\n        @if (valueObject.stackedIcon) {\n          <si-icon [class]=\"valueObject.stackedIconColor\" [icon]=\"valueObject.stackedIcon\" />\n        }\n      </span>\n      @if (valueObject.iconAlt) {\n        <span class=\"visually-hidden\">{{ valueObject.iconAlt | translate }}</span>\n      }\n      <div class=\"si-timeline-widget-item-lower-line\"></div>\n    </div>\n    <div class=\"d-flex flex-column gap-1 py-4 flex-grow-1\">\n      <span class=\"si-caption text-secondary\">{{ valueObject.timeStamp | translate }}</span>\n      <span class=\"si-h5\">{{ valueObject.title | translate }}</span>\n      @if (valueObject.description) {\n        <span class=\"si-body text-secondary\">{{ valueObject.description | translate }}</span>\n      }\n    </div>\n    @if (valueObject.action) {\n      @let action = valueObject.action;\n      <div class=\"si-timeline-widget-item-action align-self-center\">\n        @if (action.type === 'action') {\n          <button\n            type=\"button\"\n            class=\"d-flex btn\"\n            [ngClass]=\"action.customClass ?? 'btn-tertiary'\"\n            [class.btn-circle]=\"action.iconOnly\"\n            [class.btn-sm]=\"action.iconOnly\"\n            (click)=\"action.action(action)\"\n          >\n            @if (action.icon) {\n              <si-icon class=\"icon\" [icon]=\"action.icon\" />\n            }\n            <span [class.visually-hidden]=\"action.iconOnly\">\n              {{ action.label | translate }}\n            </span>\n          </button>\n        } @else if (action.type === 'router-link') {\n          <a\n            class=\"d-flex btn btn-ghost\"\n            [routerLink]=\"action.routerLink\"\n            [queryParams]=\"action.extras?.queryParams\"\n            [queryParamsHandling]=\"action.extras?.queryParamsHandling\"\n            [fragment]=\"action.extras?.fragment\"\n            [state]=\"action.extras?.state\"\n            [relativeTo]=\"action.extras?.relativeTo ?? activatedRoute\"\n            [preserveFragment]=\"action.extras?.preserveFragment\"\n            [skipLocationChange]=\"action.extras?.skipLocationChange\"\n            [replaceUrl]=\"action.extras?.replaceUrl\"\n            [attr.aria-label]=\"action.label | translate\"\n            [class.btn-circle]=\"action.iconOnly\"\n            [class.btn-sm]=\"action.iconOnly\"\n          >\n            @if (action.icon) {\n              <si-icon class=\"icon\" [icon]=\"action.icon\" />\n            }\n            <span [class.visually-hidden]=\"action.iconOnly\">\n              {{ action.label | translate }}\n            </span></a\n          >\n        } @else if (action.type === 'link') {\n          <a\n            class=\"d-flex btn btn-ghost\"\n            [href]=\"action.href\"\n            [target]=\"action.target\"\n            [attr.aria-label]=\"action.label | translate\"\n            [class.btn-circle]=\"action.iconOnly\"\n            [class.btn-sm]=\"action.iconOnly\"\n          >\n            @if (action.icon) {\n              <si-icon class=\"icon\" [icon]=\"action.icon\" />\n            }\n            <span [class.visually-hidden]=\"action.iconOnly\">\n              {{ action.label | translate }}\n            </span></a\n          >\n        } @else if (action.type === 'menu') {\n          <button\n            type=\"button\"\n            class=\"btn btn-circle btn-sm btn-tertiary element-options-vertical\"\n            [attr.aria-label]=\"ariaLabelDropdown | translate\"\n            [cdkMenuTriggerFor]=\"actionMenu\"\n          ></button>\n\n          <ng-template #actionMenu>\n            <si-menu-factory [items]=\"action.menuItems\" />\n          </ng-template>\n        }\n      </div>\n    }\n  </div>\n} @else {\n  <div class=\"d-flex flex-row\">\n    <div class=\"d-flex flex-column align-items-center gap-1 pt-4 pe-4\">\n      <div class=\"p-5 si-skeleton\"></div>\n    </div>\n    <div class=\"d-flex flex-column flex-grow-1 gap-1 py-4\">\n      <span class=\"si-link-widget-skeleton\"></span>\n      <span class=\"si-link-widget-skeleton\" [class.w-50]=\"!showDescription()\"></span>\n      @if (showDescription()) {\n        <span class=\"si-link-widget-skeleton w-50\"></span>\n      }\n    </div>\n  </div>\n}\n", dependencies: [{ kind: "component", type: SiIconComponent, selector: "si-icon", inputs: ["icon"] }, { kind: "pipe", type: SiTranslatePipe, name: "translate" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: A11yModule }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: SiMenuModule }, { kind: "component", type: i1$2.SiMenuFactoryComponent, selector: "si-menu-factory", inputs: ["items", "actionParam"] }, { kind: "directive", type: CdkMenuTrigger, selector: "[cdkMenuTriggerFor]", inputs: ["cdkMenuTriggerFor", "cdkMenuPosition", "cdkMenuTriggerData"], outputs: ["cdkMenuOpened", "cdkMenuClosed"], exportAs: ["cdkMenuTriggerFor"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiTimelineWidgetItemComponent, decorators: [{
            type: Component,
            args: [{ selector: 'si-timeline-widget-item', imports: [
                        SiIconComponent,
                        SiTranslatePipe,
                        NgClass,
                        A11yModule,
                        RouterLink,
                        SiMenuModule,
                        CdkMenuTrigger
                    ], host: {
                        role: 'listitem'
                    }, template: "@let valueObject = value();\n@if (!showLoadingIndicator() && valueObject) {\n  <div class=\"d-flex flex-row gap-4\" [class.pe-4]=\"!valueObject.action\">\n    <div class=\"d-flex flex-column align-items-center gap-1 pt-4\">\n      <span class=\"icon icon-stack\">\n        <si-icon [class]=\"valueObject.iconColor\" [icon]=\"valueObject.icon\" />\n        @if (valueObject.stackedIcon) {\n          <si-icon [class]=\"valueObject.stackedIconColor\" [icon]=\"valueObject.stackedIcon\" />\n        }\n      </span>\n      @if (valueObject.iconAlt) {\n        <span class=\"visually-hidden\">{{ valueObject.iconAlt | translate }}</span>\n      }\n      <div class=\"si-timeline-widget-item-lower-line\"></div>\n    </div>\n    <div class=\"d-flex flex-column gap-1 py-4 flex-grow-1\">\n      <span class=\"si-caption text-secondary\">{{ valueObject.timeStamp | translate }}</span>\n      <span class=\"si-h5\">{{ valueObject.title | translate }}</span>\n      @if (valueObject.description) {\n        <span class=\"si-body text-secondary\">{{ valueObject.description | translate }}</span>\n      }\n    </div>\n    @if (valueObject.action) {\n      @let action = valueObject.action;\n      <div class=\"si-timeline-widget-item-action align-self-center\">\n        @if (action.type === 'action') {\n          <button\n            type=\"button\"\n            class=\"d-flex btn\"\n            [ngClass]=\"action.customClass ?? 'btn-tertiary'\"\n            [class.btn-circle]=\"action.iconOnly\"\n            [class.btn-sm]=\"action.iconOnly\"\n            (click)=\"action.action(action)\"\n          >\n            @if (action.icon) {\n              <si-icon class=\"icon\" [icon]=\"action.icon\" />\n            }\n            <span [class.visually-hidden]=\"action.iconOnly\">\n              {{ action.label | translate }}\n            </span>\n          </button>\n        } @else if (action.type === 'router-link') {\n          <a\n            class=\"d-flex btn btn-ghost\"\n            [routerLink]=\"action.routerLink\"\n            [queryParams]=\"action.extras?.queryParams\"\n            [queryParamsHandling]=\"action.extras?.queryParamsHandling\"\n            [fragment]=\"action.extras?.fragment\"\n            [state]=\"action.extras?.state\"\n            [relativeTo]=\"action.extras?.relativeTo ?? activatedRoute\"\n            [preserveFragment]=\"action.extras?.preserveFragment\"\n            [skipLocationChange]=\"action.extras?.skipLocationChange\"\n            [replaceUrl]=\"action.extras?.replaceUrl\"\n            [attr.aria-label]=\"action.label | translate\"\n            [class.btn-circle]=\"action.iconOnly\"\n            [class.btn-sm]=\"action.iconOnly\"\n          >\n            @if (action.icon) {\n              <si-icon class=\"icon\" [icon]=\"action.icon\" />\n            }\n            <span [class.visually-hidden]=\"action.iconOnly\">\n              {{ action.label | translate }}\n            </span></a\n          >\n        } @else if (action.type === 'link') {\n          <a\n            class=\"d-flex btn btn-ghost\"\n            [href]=\"action.href\"\n            [target]=\"action.target\"\n            [attr.aria-label]=\"action.label | translate\"\n            [class.btn-circle]=\"action.iconOnly\"\n            [class.btn-sm]=\"action.iconOnly\"\n          >\n            @if (action.icon) {\n              <si-icon class=\"icon\" [icon]=\"action.icon\" />\n            }\n            <span [class.visually-hidden]=\"action.iconOnly\">\n              {{ action.label | translate }}\n            </span></a\n          >\n        } @else if (action.type === 'menu') {\n          <button\n            type=\"button\"\n            class=\"btn btn-circle btn-sm btn-tertiary element-options-vertical\"\n            [attr.aria-label]=\"ariaLabelDropdown | translate\"\n            [cdkMenuTriggerFor]=\"actionMenu\"\n          ></button>\n\n          <ng-template #actionMenu>\n            <si-menu-factory [items]=\"action.menuItems\" />\n          </ng-template>\n        }\n      </div>\n    }\n  </div>\n} @else {\n  <div class=\"d-flex flex-row\">\n    <div class=\"d-flex flex-column align-items-center gap-1 pt-4 pe-4\">\n      <div class=\"p-5 si-skeleton\"></div>\n    </div>\n    <div class=\"d-flex flex-column flex-grow-1 gap-1 py-4\">\n      <span class=\"si-link-widget-skeleton\"></span>\n      <span class=\"si-link-widget-skeleton\" [class.w-50]=\"!showDescription()\"></span>\n      @if (showDescription()) {\n        <span class=\"si-link-widget-skeleton w-50\"></span>\n      }\n    </div>\n  </div>\n}\n" }]
        }] });

/**
 * Copyright (c) Siemens 2016 - 2025
 * SPDX-License-Identifier: MIT
 */
class SiTimelineWidgetBodyComponent extends SiWidgetBaseComponent {
    /**
     * Number of skeleton progress indication items.
     *
     * @defaultValue 4
     */
    numberOfItems = input(4);
    /**
     * Whether to show or hide the description row during skeleton progress indication.
     *
     * @defaultValue `true`
     */
    showDescription = input(true);
    /** Used to display the defined number of ghost items */
    ghosts = computed(() => {
        return new Array(this.numberOfItems() ?? 4);
    });
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiTimelineWidgetBodyComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: SiTimelineWidgetBodyComponent, isStandalone: true, selector: "si-timeline-widget-body", inputs: { numberOfItems: { classPropertyName: "numberOfItems", publicName: "numberOfItems", isSignal: true, isRequired: false, transformFunction: null }, showDescription: { classPropertyName: "showDescription", publicName: "showDescription", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "@let valueObject = value();\n<div\n  class=\"focus-inside\"\n  tabindex=\"0\"\n  [attr.role]=\"\n    (!showLoadingIndicator() && valueObject && valueObject.length > 0) || showLoadingIndicator()\n      ? 'list'\n      : null\n  \"\n>\n  @if (!showLoadingIndicator() && valueObject) {\n    @if (valueObject && valueObject.length > 0) {\n      @for (item of valueObject; track $index) {\n        <si-timeline-widget-item [value]=\"item\" />\n      }\n    } @else {\n      <ng-content select=\"[empty-state]\" />\n    }\n  } @else {\n    @for (some of ghosts(); track $index) {\n      <si-timeline-widget-item [value]=\"undefined\" [showDescription]=\"showDescription()\" />\n    }\n  }\n</div>\n", styles: [":host{background-color:var(--element-base-1);flex:auto;overflow:hidden}:host si-timeline-widget-item:last-child ::ng-deep .si-timeline-widget-item-lower-line{display:none}div{block-size:100%;padding-inline:16px 8px;overflow-y:auto;overflow-x:hidden}\n"], dependencies: [{ kind: "component", type: SiTimelineWidgetItemComponent, selector: "si-timeline-widget-item", inputs: ["showDescription"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiTimelineWidgetBodyComponent, decorators: [{
            type: Component,
            args: [{ selector: 'si-timeline-widget-body', imports: [SiTimelineWidgetItemComponent], template: "@let valueObject = value();\n<div\n  class=\"focus-inside\"\n  tabindex=\"0\"\n  [attr.role]=\"\n    (!showLoadingIndicator() && valueObject && valueObject.length > 0) || showLoadingIndicator()\n      ? 'list'\n      : null\n  \"\n>\n  @if (!showLoadingIndicator() && valueObject) {\n    @if (valueObject && valueObject.length > 0) {\n      @for (item of valueObject; track $index) {\n        <si-timeline-widget-item [value]=\"item\" />\n      }\n    } @else {\n      <ng-content select=\"[empty-state]\" />\n    }\n  } @else {\n    @for (some of ghosts(); track $index) {\n      <si-timeline-widget-item [value]=\"undefined\" [showDescription]=\"showDescription()\" />\n    }\n  }\n</div>\n", styles: [":host{background-color:var(--element-base-1);flex:auto;overflow:hidden}:host si-timeline-widget-item:last-child ::ng-deep .si-timeline-widget-item-lower-line{display:none}div{block-size:100%;padding-inline:16px 8px;overflow-y:auto;overflow-x:hidden}\n"] }]
        }] });

/**
 * Copyright (c) Siemens 2016 - 2025
 * SPDX-License-Identifier: MIT
 */
class SiTimelineWidgetComponent extends SiWidgetBaseComponent {
    /**
     * Timeline widget header text.
     */
    heading = input();
    /**
     * Input list of primary action items. Supports up to **4** actions and omits additional ones.
     *
     * @defaultValue []
     */
    primaryActions = input([]);
    /**
     * Input list of secondary action items.
     *
     * @defaultValue []
     */
    secondaryActions = input([]);
    /**
     * Link that leads the user to more information
     * or triggers and action. The `link.title` is displayed.
     * The title will be translated.
     */
    link = input();
    /**
     * Number of skeleton progress indication items.
     *
     * @defaultValue 4
     */
    numberOfItems = input(4);
    /**
     * Whether to show or hide the description row during skeleton progress indication.
     *
     * @defaultValue `true`
     */
    showDescription = input(true);
    /**
     * Optional accent line
     */
    accentLine = input();
    accentClass = computed(() => {
        const accentLine = this.accentLine();
        return accentLine ? 'accent-' + accentLine : '';
    });
    icons = addIcons({ elementRight2 });
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiTimelineWidgetComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: SiTimelineWidgetComponent, isStandalone: true, selector: "si-timeline-widget", inputs: { heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: false, transformFunction: null }, primaryActions: { classPropertyName: "primaryActions", publicName: "primaryActions", isSignal: true, isRequired: false, transformFunction: null }, secondaryActions: { classPropertyName: "secondaryActions", publicName: "secondaryActions", isSignal: true, isRequired: false, transformFunction: null }, link: { classPropertyName: "link", publicName: "link", isSignal: true, isRequired: false, transformFunction: null }, numberOfItems: { classPropertyName: "numberOfItems", publicName: "numberOfItems", isSignal: true, isRequired: false, transformFunction: null }, showDescription: { classPropertyName: "showDescription", publicName: "showDescription", isSignal: true, isRequired: false, transformFunction: null }, accentLine: { classPropertyName: "accentLine", publicName: "accentLine", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<si-card\n  class=\"h-100\"\n  [ngClass]=\"accentClass()\"\n  [heading]=\"heading()\"\n  [primaryActions]=\"primaryActions()\"\n  [secondaryActions]=\"secondaryActions()\"\n>\n  <si-timeline-widget-body\n    body\n    [value]=\"value()\"\n    [showDescription]=\"showDescription()\"\n    [numberOfItems]=\"numberOfItems()\"\n    [class.pb-6]=\"!link()\"\n    [showLoadingIndicator]=\"showLoadingIndicator()\"\n  >\n    <ng-content select=\"[empty-state]\" empty-state />\n  </si-timeline-widget-body>\n  @let linkValue = link();\n  @if (linkValue) {\n    <div class=\"card-footer\" footer>\n      @if (!linkValue.action) {\n        <a [siLink]=\"linkValue\">\n          {{ linkValue.title | translate }}\n          <si-icon class=\"link-icon link-end flip-rtl\" [icon]=\"icons.elementRight2\" />\n        </a>\n      } @else {\n        <button type=\"button\" class=\"btn btn-link\" [siLink]=\"linkValue\">{{\n          linkValue.title | translate\n        }}</button>\n      }\n    </div>\n  }\n</si-card>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: SiLinkDirective, selector: "[siLink]", inputs: ["siLink", "siLinkDefaultTarget", "actionParam", "activeClass", "exactMatch", "ariaCurrent"], outputs: ["activeChange"], exportAs: ["siLink"] }, { kind: "component", type: SiCardComponent, selector: "si-card", inputs: ["primaryActions", "secondaryActions", "actionParam", "actionBarViewType", "actionBarTitle"] }, { kind: "component", type: SiTimelineWidgetBodyComponent, selector: "si-timeline-widget-body", inputs: ["numberOfItems", "showDescription"] }, { kind: "pipe", type: SiTranslatePipe, name: "translate" }, { kind: "component", type: SiIconComponent, selector: "si-icon", inputs: ["icon"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiTimelineWidgetComponent, decorators: [{
            type: Component,
            args: [{ selector: 'si-timeline-widget', imports: [
                        NgClass,
                        SiLinkDirective,
                        SiCardComponent,
                        SiTimelineWidgetBodyComponent,
                        SiTranslatePipe,
                        SiIconComponent
                    ], template: "<si-card\n  class=\"h-100\"\n  [ngClass]=\"accentClass()\"\n  [heading]=\"heading()\"\n  [primaryActions]=\"primaryActions()\"\n  [secondaryActions]=\"secondaryActions()\"\n>\n  <si-timeline-widget-body\n    body\n    [value]=\"value()\"\n    [showDescription]=\"showDescription()\"\n    [numberOfItems]=\"numberOfItems()\"\n    [class.pb-6]=\"!link()\"\n    [showLoadingIndicator]=\"showLoadingIndicator()\"\n  >\n    <ng-content select=\"[empty-state]\" empty-state />\n  </si-timeline-widget-body>\n  @let linkValue = link();\n  @if (linkValue) {\n    <div class=\"card-footer\" footer>\n      @if (!linkValue.action) {\n        <a [siLink]=\"linkValue\">\n          {{ linkValue.title | translate }}\n          <si-icon class=\"link-icon link-end flip-rtl\" [icon]=\"icons.elementRight2\" />\n        </a>\n      } @else {\n        <button type=\"button\" class=\"btn btn-link\" [siLink]=\"linkValue\">{{\n          linkValue.title | translate\n        }}</button>\n      }\n    </div>\n  }\n</si-card>\n" }]
        }] });

/**
 * Copyright (c) Siemens 2016 - 2025
 * SPDX-License-Identifier: MIT
 */
/**
 * The body of the `<si-value-widget>`. Useful for compositions.
 */
class SiValueWidgetBodyComponent extends SiWidgetBaseComponent {
    /**
     * The unit of the value (e.g. kWh or users). Only visible if `value` is available.
     */
    unit = input();
    /**
     * The element icon name. Only visible if `value` is available.
     */
    icon = input();
    /**
     * Show a status icon instead of the {@link icon}.
     */
    status = input();
    /**
     * Short description of the value. A description is mandatory
     * to show an icon. Only visible if `value` is available.
     */
    description = input();
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiValueWidgetBodyComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: SiValueWidgetBodyComponent, isStandalone: true, selector: "si-value-widget-body", inputs: { unit: { classPropertyName: "unit", publicName: "unit", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "@if (!showLoadingIndicator()) {\n  @if (value()) {\n    <span class=\"si-value-widget-value\">{{ value() | translate }}</span>\n    <span class=\"si-value-widget-unit\">{{ unit() | translate }}</span>\n    @if (description()) {\n      <div class=\"si-value-widget-description\">\n        @let statusValue = status();\n        @let iconValue = icon();\n        @if (statusValue) {\n          <si-status-icon class=\"icon\" [status]=\"statusValue\" />\n        } @else if (iconValue) {\n          <si-icon class=\"icon\" [icon]=\"iconValue\" />\n        }\n        <span>{{ description() | translate }}</span>\n      </div>\n    }\n  }\n} @else {\n  <span class=\"si-value-widget-value w-100\">\n    <div class=\"si-value-widget-value-skeleton\"></div>\n  </span>\n  <div class=\"si-value-widget-description si-skeleton w-100\"></div>\n}\n", dependencies: [{ kind: "component", type: SiIconComponent, selector: "si-icon", inputs: ["icon"] }, { kind: "component", type: SiStatusIconComponent, selector: "si-status-icon", inputs: ["status"] }, { kind: "pipe", type: SiTranslatePipe, name: "translate" }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiValueWidgetBodyComponent, decorators: [{
            type: Component,
            args: [{ selector: 'si-value-widget-body', imports: [SiIconComponent, SiStatusIconComponent, SiTranslatePipe], template: "@if (!showLoadingIndicator()) {\n  @if (value()) {\n    <span class=\"si-value-widget-value\">{{ value() | translate }}</span>\n    <span class=\"si-value-widget-unit\">{{ unit() | translate }}</span>\n    @if (description()) {\n      <div class=\"si-value-widget-description\">\n        @let statusValue = status();\n        @let iconValue = icon();\n        @if (statusValue) {\n          <si-status-icon class=\"icon\" [status]=\"statusValue\" />\n        } @else if (iconValue) {\n          <si-icon class=\"icon\" [icon]=\"iconValue\" />\n        }\n        <span>{{ description() | translate }}</span>\n      </div>\n    }\n  }\n} @else {\n  <span class=\"si-value-widget-value w-100\">\n    <div class=\"si-value-widget-value-skeleton\"></div>\n  </span>\n  <div class=\"si-value-widget-description si-skeleton w-100\"></div>\n}\n" }]
        }] });

/**
 * Copyright (c) Siemens 2016 - 2025
 * SPDX-License-Identifier: MIT
 */
/**
 * Is a dynamic UI component that not only displays information, but also includes
 * embedded actions which the user can interact with to perform tasks directly
 * related to the card's content. Actions might include editing settings,
 * initiating processes, or deleting resources.
 *
 * The actionable widget turns data representation into an interactive hub,
 * streamlining the user's tasks and decisions associated with the card's content.
 *
 * This component is a wrapper using the `.si-value-widget` CSS classes and the
 * `<si-card>` component. For more configuration options, use the CSS classes directly.
 */
class SiValueWidgetComponent {
    /**
     * Value widget header text.
     */
    heading = input();
    /**
     * Input list of primary action items. Supports up to **4** actions and omits additional ones.
     *
     * @defaultValue []
     */
    primaryActions = input([]);
    /**
     * Input list of secondary action items.
     *
     * @defaultValue []
     */
    secondaryActions = input([]);
    /**
     * The main value to be displayed. If no value is set,
     * the skeleton indicates the loading of the value. Disable
     * the automatic loading mechanism by setting `SiValueWidgetComponent.disableAutoLoadingIndicator`.
     */
    value = input();
    /**
     * The unit of the value (e.g. kWh or users). Only visible if `value` is available.
     */
    unit = input();
    /**
     * The element icon name. Only visible if `value` is available.
     */
    icon = input();
    /**
     * Show a status icon instead of the {@link icon}.
     */
    status = input();
    /**
     * Short description of the value. A description is mandatory
     * to show an icon. Only visible if `value` is available.
     */
    description = input();
    /**
     * Link that leads the user to more information
     * or triggers and action. The `link.title` is displayed.
     * The title will be translated.
     */
    link = input();
    /**
     * Option to disable automatic start of skeleton loading indication.
     *
     * @defaultValue false
     */
    disableAutoLoadingIndicator = input(false, { transform: booleanAttribute });
    /**
     * Input to start and stop the skeleton loading indication.
     *
     * @defaultValue false
     */
    showLoadingIndicator = input(false, { transform: booleanAttribute });
    /**
     * Initial delay time in milliseconds before enabling loading indicator.
     * Only used once initially during construction.
     *
     * @defaultValue 300
     */
    initialLoadingIndicatorDebounceTime = input(300);
    /**
     * Image source for the card.
     */
    imgSrc = input();
    /**
     * Alt text for a provided image.
     */
    imgAlt = input();
    /**
     * Defines if an image is placed on top or start (left) of the card.
     *
     * @defaultValue 'vertical'
     */
    imgDir = input('vertical');
    /**
     * Sets the image [object-fit](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit) CSS property.
     *
     * @defaultValue 'scale-down'
     */
    imgObjectFit = input('scale-down');
    /**
     * Sets the image [object-position](https://developer.mozilla.org/en-US/docs/Web/CSS/object-position) CSS property.
     */
    imgObjectPosition = input();
    /**
     * Optional accent line
     */
    accentLine = input();
    accentClass = computed(() => {
        const accentLine = this.accentLine();
        return accentLine ? 'accent-' + accentLine : '';
    });
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiValueWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: SiValueWidgetComponent, isStandalone: true, selector: "si-value-widget", inputs: { heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: false, transformFunction: null }, primaryActions: { classPropertyName: "primaryActions", publicName: "primaryActions", isSignal: true, isRequired: false, transformFunction: null }, secondaryActions: { classPropertyName: "secondaryActions", publicName: "secondaryActions", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, unit: { classPropertyName: "unit", publicName: "unit", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, link: { classPropertyName: "link", publicName: "link", isSignal: true, isRequired: false, transformFunction: null }, disableAutoLoadingIndicator: { classPropertyName: "disableAutoLoadingIndicator", publicName: "disableAutoLoadingIndicator", isSignal: true, isRequired: false, transformFunction: null }, showLoadingIndicator: { classPropertyName: "showLoadingIndicator", publicName: "showLoadingIndicator", isSignal: true, isRequired: false, transformFunction: null }, initialLoadingIndicatorDebounceTime: { classPropertyName: "initialLoadingIndicatorDebounceTime", publicName: "initialLoadingIndicatorDebounceTime", isSignal: true, isRequired: false, transformFunction: null }, imgSrc: { classPropertyName: "imgSrc", publicName: "imgSrc", isSignal: true, isRequired: false, transformFunction: null }, imgAlt: { classPropertyName: "imgAlt", publicName: "imgAlt", isSignal: true, isRequired: false, transformFunction: null }, imgDir: { classPropertyName: "imgDir", publicName: "imgDir", isSignal: true, isRequired: false, transformFunction: null }, imgObjectFit: { classPropertyName: "imgObjectFit", publicName: "imgObjectFit", isSignal: true, isRequired: false, transformFunction: null }, imgObjectPosition: { classPropertyName: "imgObjectPosition", publicName: "imgObjectPosition", isSignal: true, isRequired: false, transformFunction: null }, accentLine: { classPropertyName: "accentLine", publicName: "accentLine", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<si-card\n  class=\"h-100\"\n  [ngClass]=\"accentClass()\"\n  [heading]=\"heading()\"\n  [primaryActions]=\"primaryActions()\"\n  [secondaryActions]=\"secondaryActions()\"\n  [imgSrc]=\"imgSrc()\"\n  [imgDir]=\"imgDir()\"\n  [imgAlt]=\"imgAlt()\"\n  [imgObjectFit]=\"imgObjectFit()\"\n  [imgObjectPosition]=\"imgObjectPosition()\"\n>\n  <div class=\"card-body\" body>\n    <si-value-widget-body\n      [value]=\"value()\"\n      [unit]=\"unit()\"\n      [icon]=\"icon()\"\n      [status]=\"status()\"\n      [description]=\"description()\"\n      [disableAutoLoadingIndicator]=\"disableAutoLoadingIndicator()\"\n      [showLoadingIndicator]=\"showLoadingIndicator()\"\n      [initialLoadingIndicatorDebounceTime]=\"initialLoadingIndicatorDebounceTime()\"\n    />\n  </div>\n  @let linkObject = link();\n  @if (linkObject) {\n    <div class=\"card-footer\" footer>\n      <a [siLink]=\"linkObject\">{{ linkObject.title | translate }}</a>\n    </div>\n  }\n</si-card>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: SiCardComponent, selector: "si-card", inputs: ["primaryActions", "secondaryActions", "actionParam", "actionBarViewType", "actionBarTitle"] }, { kind: "directive", type: SiLinkDirective, selector: "[siLink]", inputs: ["siLink", "siLinkDefaultTarget", "actionParam", "activeClass", "exactMatch", "ariaCurrent"], outputs: ["activeChange"], exportAs: ["siLink"] }, { kind: "pipe", type: SiTranslatePipe, name: "translate" }, { kind: "component", type: SiValueWidgetBodyComponent, selector: "si-value-widget-body", inputs: ["unit", "icon", "status", "description"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SiValueWidgetComponent, decorators: [{
            type: Component,
            args: [{ selector: 'si-value-widget', imports: [NgClass, SiCardComponent, SiLinkDirective, SiTranslatePipe, SiValueWidgetBodyComponent], template: "<si-card\n  class=\"h-100\"\n  [ngClass]=\"accentClass()\"\n  [heading]=\"heading()\"\n  [primaryActions]=\"primaryActions()\"\n  [secondaryActions]=\"secondaryActions()\"\n  [imgSrc]=\"imgSrc()\"\n  [imgDir]=\"imgDir()\"\n  [imgAlt]=\"imgAlt()\"\n  [imgObjectFit]=\"imgObjectFit()\"\n  [imgObjectPosition]=\"imgObjectPosition()\"\n>\n  <div class=\"card-body\" body>\n    <si-value-widget-body\n      [value]=\"value()\"\n      [unit]=\"unit()\"\n      [icon]=\"icon()\"\n      [status]=\"status()\"\n      [description]=\"description()\"\n      [disableAutoLoadingIndicator]=\"disableAutoLoadingIndicator()\"\n      [showLoadingIndicator]=\"showLoadingIndicator()\"\n      [initialLoadingIndicatorDebounceTime]=\"initialLoadingIndicatorDebounceTime()\"\n    />\n  </div>\n  @let linkObject = link();\n  @if (linkObject) {\n    <div class=\"card-footer\" footer>\n      <a [siLink]=\"linkObject\">{{ linkObject.title | translate }}</a>\n    </div>\n  }\n</si-card>\n" }]
        }] });

/**
 * Copyright (c) Siemens 2016 - 2025
 * SPDX-License-Identifier: MIT
 */

/**
 * Generated bundle index. Do not edit.
 */

export { SiDashboardCardComponent, SiDashboardComponent, SiDashboardModule, SiDashboardService, SiLinkWidgetComponent, SiListWidgetBodyComponent, SiListWidgetComponent, SiListWidgetItemComponent, SiTimelineWidgetBodyComponent, SiTimelineWidgetComponent, SiTimelineWidgetItemComponent, SiValueWidgetBodyComponent, SiValueWidgetComponent };
//# sourceMappingURL=siemens-element-ng-dashboard.mjs.map
