@porscheinformatik/clr-addons
Version:
Addon components for Clarity Angular
1 lines • 2.27 MB
Source Map (JSON)
{"version":3,"file":"clr-addons.mjs","sources":["../../../src/clr-addons/back-button/back-button.ts","../../../src/clr-addons/back-button/back-button.html","../../../src/clr-addons/back-button/back-button.module.ts","../../../src/clr-addons/back-button/index.ts","../../../src/clr-addons/breadcrumb/breadcrumb.service.ts","../../../src/clr-addons/breadcrumb/breadcrumb.ts","../../../src/clr-addons/breadcrumb/breadcrumb.html","../../../src/clr-addons/breadcrumb/breadcrumb.module.ts","../../../src/clr-addons/breadcrumb/breadcrumb-model.interface.ts","../../../src/clr-addons/breadcrumb/index.ts","../../../src/clr-addons/collapse-expand-section/collapse-expand-section.ts","../../../src/clr-addons/collapse-expand-section/collapse-expand-section.html","../../../src/clr-addons/collapse-expand-section/collapse-expand-section.module.ts","../../../src/clr-addons/collapse-expand-section/index.ts","../../../src/clr-addons/content-panel/content-panel.ts","../../../src/clr-addons/content-panel/content-panel.html","../../../src/clr-addons/content-panel/content-panel-container.ts","../../../src/clr-addons/content-panel/content-panel-container-content.ts","../../../src/clr-addons/content-panel/content-panel-container-footer.ts","../../../src/clr-addons/content-panel/content-panel.module.ts","../../../src/clr-addons/content-panel/index.ts","../../../src/clr-addons/data-list-validator/data-list.validator.ts","../../../src/clr-addons/data-list-validator/data-list-predefined-validator.directive.ts","../../../src/clr-addons/data-list-validator/data-list-validator.module.ts","../../../src/clr-addons/data-list-validator/index.ts","../../../src/clr-addons/date-time-container/date-time-container.ts","../../../src/clr-addons/date-time-container/time-input.ts","../../../src/clr-addons/date-time-container/date-time-module.ts","../../../src/clr-addons/date-time-container/index.ts","../../../src/clr-addons/dot-pager/dot-pager.ts","../../../src/clr-addons/dot-pager/dot-pager.html","../../../src/clr-addons/dot-pager/dot-pager.module.ts","../../../src/clr-addons/dot-pager/index.ts","../../../src/clr-addons/dropdown/clr-dropdown-overflow.directive.ts","../../../src/clr-addons/flow-bar/flow-bar.ts","../../../src/clr-addons/flow-bar/flow-bar.html","../../../src/clr-addons/dropdown/clr-dropdown-overflow.module.ts","../../../src/clr-addons/dropdown/index.ts","../../../src/clr-addons/flow-bar/flow-bar.module.ts","../../../src/clr-addons/flow-bar/index.ts","../../../src/clr-addons/generic-quick-list/generic-quick-list.ts","../../../src/clr-addons/generic-quick-list/generic-quick-list.html","../../../src/clr-addons/generic-quick-list/generic-quick-list.module.ts","../../../src/clr-addons/generic-quick-list/index.ts","../../../src/clr-addons/letter-avatar/letter-avatar.ts","../../../src/clr-addons/letter-avatar/letter-avatar.html","../../../src/clr-addons/letter-avatar/letter-avatar.module.ts","../../../src/clr-addons/letter-avatar/index.ts","../../../src/clr-addons/main-nav-group/main-nav-group-item.ts","../../../src/clr-addons/main-nav-group/main-nav-group.ts","../../../src/clr-addons/main-nav-group/main-nav-group.html","../../../src/clr-addons/main-nav-group/main-nav-group.module.ts","../../../src/clr-addons/main-nav-group/index.ts","../../../src/clr-addons/multilingual/multilingual-validators.ts","../../../src/clr-addons/abstract-form-component/control-id.service.ts","../../../src/clr-addons/abstract-form-component/abstract-form-component.ts","../../../src/clr-addons/multilingual/abstract-multilingual.ts","../../../src/clr-addons/multilingual/multilingual-selector.ts","../../../src/clr-addons/multilingual/multilingual-input/multilingual-input.ts","../../../src/clr-addons/multilingual/multilingual-input/multilingual-input.html","../../../src/clr-addons/multilingual/multilingual-textarea/multilingual-textarea.ts","../../../src/clr-addons/multilingual/multilingual-textarea/multilingual-textarea.html","../../../src/clr-addons/multilingual/multilingual.module.ts","../../../src/clr-addons/multilingual/index.ts","../../../src/clr-addons/notification/notification-ref.ts","../../../src/clr-addons/notification/scheduler-utils.ts","../../../src/clr-addons/notification/notification.ts","../../../src/clr-addons/notification/notification.html","../../../src/clr-addons/notification/notification.module.ts","../../../src/clr-addons/notification/notification.service.ts","../../../src/clr-addons/notification/index.ts","../../../src/clr-addons/util/escape.util.ts","../../../src/clr-addons/util/numeric.format.util.ts","../../../src/clr-addons/util/index.ts","../../../src/clr-addons/numericfield/numeric-field.ts","../../../src/clr-addons/numericfield/numeric-field-validators.ts","../../../src/clr-addons/numericfield/numeric-field.module.ts","../../../src/clr-addons/numericfield/index.ts","../../../src/clr-addons/pager/pager.ts","../../../src/clr-addons/pager/pager.html","../../../src/clr-addons/paged-search-result-list/paged-search-result-list.ts","../../../src/clr-addons/paged-search-result-list/paged-search-result-list.html","../../../src/clr-addons/pager/pager.module.ts","../../../src/clr-addons/paged-search-result-list/paged-search-result-list.module.ts","../../../src/clr-addons/paged-search-result-list/index.ts","../../../src/clr-addons/pager/index.ts","../../../src/clr-addons/progress-spinner/progress-spinner.ts","../../../src/clr-addons/progress-spinner/progress-spinner.module.ts","../../../src/clr-addons/progress-spinner/index.ts","../../../src/clr-addons/quick-list/add-option.service.ts","../../../src/clr-addons/quick-list/add-option.ts","../../../src/clr-addons/quick-list/add-option.html","../../../src/clr-addons/quick-list/quick-list.ts","../../../src/clr-addons/quick-list/quick-list.html","../../../src/clr-addons/quick-list/quick-list.module.ts","../../../src/clr-addons/quick-list/index.ts","../../../src/clr-addons/searchfield/search-field.ts","../../../src/clr-addons/searchfield/search-field.module.ts","../../../src/clr-addons/searchfield/index.ts","../../../src/clr-addons/treetable/enums/selection-type.ts","../../../src/clr-addons/treetable/providers/sort.ts","../../../src/clr-addons/treetable/providers/items.ts","../../../src/clr-addons/treetable/providers/selection.ts","../../../src/clr-addons/treetable/enums/sort-order.enum.ts","../../../src/clr-addons/treetable/treetable-column.ts","../../../src/clr-addons/treetable/treetable-action-overflow.ts","../../../src/clr-addons/treetable/treetable-row.ts","../../../src/clr-addons/treetable/treetable-row.html","../../../src/clr-addons/treetable/treetable-items.ts","../../../src/clr-addons/treetable/treetable.ts","../../../src/clr-addons/treetable/treetable.html","../../../src/clr-addons/treetable/treetable-cell.ts","../../../src/clr-addons/treetable/treetable-placeholder.ts","../../../src/clr-addons/treetable/renderer/header-renderer.ts","../../../src/clr-addons/treetable/renderer/cell-renderer.ts","../../../src/clr-addons/treetable/renderer/row-renderer.ts","../../../src/clr-addons/treetable/renderer/main-renderer.ts","../../../src/clr-addons/treetable/treetable.module.ts","../../../src/clr-addons/treetable/interfaces/comparator.interface.ts","../../../src/clr-addons/treetable/index.ts","../../../src/clr-addons/view-edit-section/view-edit-section.ts","../../../src/clr-addons/view-edit-section/view-edit-section.html","../../../src/clr-addons/view-edit-section/view-edit-section.module.ts","../../../src/clr-addons/view-edit-section/index.ts","../../../src/clr-addons/history/history.http.service.ts","../../../src/clr-addons/history/history.service.ts","../../../src/clr-addons/history/history.provider.ts","../../../src/clr-addons/history/history.ts","../../../src/clr-addons/history/history.html","../../../src/clr-addons/history/history-pinned.ts","../../../src/clr-addons/history/history-pinned.html","../../../src/clr-addons/history/history-model.interface.ts","../../../src/clr-addons/history/history.http.impl.service.ts","../../../src/clr-addons/history/history.module.ts","../../../src/clr-addons/history/index.ts","../../../src/clr-addons/autocomplete-off/autocomplete-off.directive.ts","../../../src/clr-addons/autocomplete-off/autocomplete-off.module.ts","../../../src/clr-addons/icons/svg-tag-generator.ts","../../../src/clr-addons/icons/shapes.ts","../../../src/clr-addons/icons/index.ts","../../../src/clr-addons/brand-avatar/brand-avatar.ts","../../../src/clr-addons/brand-avatar/brand-avatar.html","../../../src/clr-addons/brand-avatar/brand-avatar.module.ts","../../../src/clr-addons/brand-avatar/index.ts","../../../src/clr-addons/location-bar/location-bar.model.ts","../../../src/clr-addons/location-bar/location-bar.provider.ts","../../../src/clr-addons/abstract-form-component/label.ts","../../../src/clr-addons/location-bar/location-bar-search/location-bar-search.component.ts","../../../src/clr-addons/location-bar/location-bar-search/location-bar-search.component.html","../../../src/clr-addons/location-bar/location-bar-node/location-bar-node.component.ts","../../../src/clr-addons/location-bar/location-bar-node/location-bar-node.component.html","../../../src/clr-addons/location-bar/location-bar.component.ts","../../../src/clr-addons/location-bar/location-bar.component.html","../../../src/clr-addons/abstract-form-component/form.module.ts","../../../src/clr-addons/location-bar/location-bar.module.ts","../../../src/clr-addons/datagrid/datagrid-state-persistence/datagrid-field.directive.ts","../../../src/clr-addons/datagrid/column-reorder/column-reorder.directive.ts","../../../src/clr-addons/datagrid/column-reorder/dynamic-cell-content.component.ts","../../../src/clr-addons/datagrid/column-reorder/datagrid-column-reorder.module.ts","../../../src/clr-addons/datagrid/datagrid-state-persistence/state-persistence-key.directive.ts","../../../src/clr-addons/datagrid/datagrid-state-persistence/column-hidden-state-persistence.directive.ts","../../../src/clr-addons/datagrid/datagrid-state-persistence/datagrid-state-persistence.module.ts","../../../src/clr-addons/datagrid/enum-filter/enum-filter.component.ts","../../../src/clr-addons/datagrid/enum-filter/enum-filter.component.html","../../../src/clr-addons/datagrid/enum-filter/enum-filter.module.ts","../../../src/clr-addons/datagrid/date-filter/nested-property.ts","../../../src/clr-addons/datagrid/date-filter/date-filter.component.ts","../../../src/clr-addons/datagrid/date-filter/date-filter.component.html","../../../src/clr-addons/datagrid/date-filter/date-filter.module.ts","../../../src/clr-addons/daterangepicker/daterange.constants.ts","../../../src/clr-addons/daterangepicker/models/day.model.ts","../../../src/clr-addons/daterangepicker/providers/opened-datepickers-tracker.service.ts","../../../src/clr-addons/daterangepicker/directives/datepicker/datepicker.component.ts","../../../src/clr-addons/daterangepicker/directives/datepicker/datepicker.component.html","../../../src/clr-addons/daterangepicker/models/popover-positions.model.ts","../../../src/clr-addons/daterangepicker/providers/daterange-control-state.service.ts","../../../src/clr-addons/daterangepicker/providers/daterange-parsing.service.ts","../../../src/clr-addons/daterangepicker/providers/daterange.service.ts","../../../src/clr-addons/daterangepicker/directives/abstract-container.component.ts","../../../src/clr-addons/daterangepicker/models/time.model.ts","../../../src/clr-addons/daterangepicker/directives/daterangepicker/daterangepicker.directive.ts","../../../src/clr-addons/daterangepicker/directives/timepicker/timepicker.component.ts","../../../src/clr-addons/daterangepicker/directives/timepicker/timepicker.component.html","../../../src/clr-addons/daterangepicker/directives/daterangepicker-container/daterangepicker-container.component.ts","../../../src/clr-addons/daterangepicker/directives/daterangepicker-container/daterangepicker-container.component.html","../../../src/clr-addons/daterangepicker/directives/if-daterange-error.directive.ts","../../../src/clr-addons/daterangepicker/validators/daterange-max.validator.ts","../../../src/clr-addons/daterangepicker/validators/daterange-min.validator.ts","../../../src/clr-addons/daterangepicker/validators/daterange-order.validator.ts","../../../src/clr-addons/daterangepicker/validators/daterange-required.validator.ts","../../../src/clr-addons/daterangepicker/daterangepicker.module.ts","../../../src/clr-addons/clr-control-warning/if-warning.directive.ts","../../../src/clr-addons/clr-control-warning/if-warning.module.ts","../../../src/clr-addons/action-panel/action-panel.ts","../../../src/clr-addons/action-panel/action-panel.html","../../../src/clr-addons/action-panel/action-panel-container.ts","../../../src/clr-addons/action-panel/action-panel-container-content.ts","../../../src/clr-addons/action-panel/action-panel-container-footer.ts","../../../src/clr-addons/action-panel/action-panel.module.ts","../../../src/clr-addons/readonly/readonly.directive.ts","../../../src/clr-addons/readonly/readonly.module.ts","../../../src/clr-addons/export-datagrid-button/export-datagrid.service.ts","../../../src/clr-addons/export-datagrid-button/export-type.model.ts","../../../src/clr-addons/export-datagrid-button/export-datagrid-button.component.ts","../../../src/clr-addons/export-datagrid-button/export-datagrid-button.component.html","../../../src/clr-addons/export-datagrid-button/export-datagrid-button.module.ts","../../../src/clr-addons/clr-addons.module.ts","../../../src/clr-addons/readonly/index.ts","../../../src/clr-addons/index.ts","../../../src/clr-addons/clr-addons.ts"],"sourcesContent":["/*\n * Copyright (c) 2018-2025 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\n\nimport { Component } from '@angular/core';\nimport { Location } from '@angular/common';\nimport { arrowIcon, ClarityIcons } from '@cds/core/icon';\n\nClarityIcons.addIcons(arrowIcon);\n\n@Component({\n selector: 'clr-back-button',\n templateUrl: './back-button.html',\n standalone: false,\n})\nexport class ClrBackButton {\n constructor(private location: Location) {}\n\n public back(): void {\n this.location.back();\n }\n}\n","<button type=\"button\" class=\"btn btn-icon btn-link back-button\" (click)=\"back()\">\n <cds-icon shape=\"arrow\" direction=\"left\" size=\"36\"></cds-icon>\n</button>\n","/*\n * Copyright (c) 2018-2019 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\n\nimport { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { ClarityModule } from '@clr/angular';\n\nimport { ClrBackButton } from './back-button';\n\n@NgModule({\n imports: [CommonModule, ClarityModule, FormsModule],\n declarations: [ClrBackButton],\n exports: [ClrBackButton],\n})\nexport class ClrBackButtonModule {}\n","/*\n * Copyright (c) 2018-2019 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\n\nexport * from './back-button';\nexport * from './back-button.module';\n","/*\n * Copyright (c) 2018-2019 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\n\nimport { Injectable } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { ClrBreadcrumbModel } from './breadcrumb-model.interface';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class ClrBreadcrumbService {\n breadcrumbChange: Subject<ClrBreadcrumbModel[]> = new Subject();\n\n updateBreadcrumb(breadcrumbElements: ClrBreadcrumbModel[]): void {\n this.breadcrumbChange.next(breadcrumbElements);\n }\n}\n","/*\n * Copyright (c) 2018-2025 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\n\nimport { Component, OnDestroy } from '@angular/core';\nimport { ClrBreadcrumbModel } from './breadcrumb-model.interface';\nimport { ClrBreadcrumbService } from './breadcrumb.service';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\n\n@Component({\n selector: 'clr-breadcrumb',\n templateUrl: './breadcrumb.html',\n standalone: false,\n})\nexport class ClrBreadcrumb implements OnDestroy {\n /**\n * The array of breadcrumb elements to be displayed.\n */\n breadcrumbElements: ClrBreadcrumbModel[] = [];\n destroyed = new Subject<void>();\n\n constructor(private breadcrumbService: ClrBreadcrumbService) {\n this.breadcrumbService.breadcrumbChange.pipe(takeUntil(this.destroyed)).subscribe(r => {\n this.breadcrumbElements = r;\n });\n }\n\n ngOnDestroy(): void {\n this.destroyed.next();\n this.destroyed.complete();\n }\n}\n","<nav aria-label=\"breadcrumb\" *ngIf=\"breadcrumbElements.length\">\n <ol class=\"breadcrumb\">\n <ng-container *ngFor=\"let breadcrumbItem of breadcrumbElements\">\n <li *ngIf=\"breadcrumbItem.url\" class=\"breadcrumb-item\">\n <a [routerLink]=\"breadcrumbItem.url\">{{breadcrumbItem.label}}</a>\n </li>\n <li *ngIf=\"!breadcrumbItem.url\" class=\"breadcrumb-item active\">{{breadcrumbItem.label}}</li>\n </ng-container>\n </ol>\n</nav>\n","/*\n * Copyright (c) 2018-2019 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\n\nimport { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\nimport { ClarityModule } from '@clr/angular';\nimport { ClrBreadcrumb } from './breadcrumb';\nimport { RouterModule } from '@angular/router';\nimport { ClrBreadcrumbService } from './breadcrumb.service';\n\n@NgModule({\n imports: [CommonModule, ClarityModule, RouterModule],\n declarations: [ClrBreadcrumb],\n exports: [ClrBreadcrumb],\n providers: [ClrBreadcrumbService],\n})\nexport class ClrBreadcrumbModule {}\n","/*\n * Copyright (c) 2018-2019 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\n\nexport interface ClrBreadcrumbModel {\n /**\n * The label to be displayed.\n */\n label: string;\n\n /**\n * The url where the navigation goes.\n */\n url?: string;\n}\n","/*\n * Copyright (c) 2018-2019 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\n\nexport * from './breadcrumb';\nexport * from './breadcrumb.module';\nexport * from './breadcrumb-model.interface';\nexport * from './breadcrumb.service';\n","/*\n * Copyright (c) 2018-2025 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\n\nimport { AfterViewInit, Component, EventEmitter, Input, Output } from '@angular/core';\nimport { animate, state, style, transition, trigger } from '@angular/animations';\nimport { angleIcon, ClarityIcons } from '@cds/core/icon';\n\nClarityIcons.addIcons(angleIcon);\n\n@Component({\n selector: 'clr-collapse-expand-section',\n templateUrl: './collapse-expand-section.html',\n animations: [\n trigger('collapseExpandAnimation', [\n transition(':enter', [\n style({ opacity: 0, height: 0, overflow: 'hidden' }),\n animate('300ms', style({ opacity: 1, height: '*' })),\n ]),\n transition(':leave', [\n style({ opacity: 1, height: '*', overflow: 'hidden' }),\n animate('300ms', style({ opacity: 0, height: 0 })),\n ]),\n ]),\n trigger('rotateIcon', [\n state('true', style({ transform: 'rotate(0)' })),\n state('false', style({ transform: 'rotate(180deg)' })),\n transition('true => false', animate('300ms ease-out')),\n transition('false => true', animate('300ms ease-in')),\n ]),\n ],\n standalone: false,\n})\nexport class ClrCollapseExpandSection implements AfterViewInit {\n @Input('clrIsCollapsed') isCollapsed = true;\n @Input('clrDisableHeaderStyles') disableHeaderStyles = false;\n\n // there is no suitable option to detect, if the the subtitle is available or not\n // see https://github.com/angular/angular/issues/26083\n @Input('clrDisableSubtitle') disableSubtitle = false;\n\n @Output('clrCollapsed') collapsed = new EventEmitter();\n @Output('clrExpanded') expanded = new EventEmitter();\n\n public disableAnimation = true;\n\n ngAfterViewInit() {\n // do not animate before first change detection cycle\n setTimeout(() => {\n this.disableAnimation = false;\n }, 0);\n }\n\n onCollapseExpand(): void {\n if (this.isCollapsed) {\n this.expanded.emit();\n } else {\n this.collapsed.emit();\n }\n\n this.isCollapsed = !this.isCollapsed;\n }\n}\n","<div class=\"ces\">\n <div class=\"ces-title\" [class.disabled-header-styles]=\"disableHeaderStyles\">\n <h2 *ngIf=\"!disableHeaderStyles; else title\">\n <ng-container *ngTemplateOutlet=\"title\"></ng-container>\n </h2>\n <ng-template #title>\n <ng-content select=\"[clr-ces-title]\"></ng-content>\n <button type=\"button\" (click)=\"onCollapseExpand()\" class=\"btn btn-icon btn-link ces-caret-btn\">\n <cds-icon\n shape=\"angle\"\n direction=\"up\"\n size=\"28\"\n class=\"ces-caret-icon\"\n [@rotateIcon]=\"isCollapsed\"\n [@.disabled]=\"disableAnimation\"\n ></cds-icon>\n </button>\n </ng-template>\n </div>\n <div class=\"ces-subtitle\" *ngIf=\"!disableSubtitle\">\n <h4 *ngIf=\"!disableHeaderStyles; else subtitle\">\n <ng-container *ngTemplateOutlet=\"subtitle\"></ng-container>\n </h4>\n <ng-template #subtitle>\n <ng-content select=\"[clr-ces-subtitle]\"></ng-content>\n </ng-template>\n </div>\n <div [@collapseExpandAnimation]=\"isCollapsed\" [@.disabled]=\"disableAnimation\" *ngIf=\"!isCollapsed\">\n <ng-content select=\"[clr-ces-content]\"></ng-content>\n </div>\n</div>\n","/*\n * Copyright (c) 2018-2019 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\n\nimport { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { ClarityModule } from '@clr/angular';\n\nimport { ClrCollapseExpandSection } from './collapse-expand-section';\n\n@NgModule({\n imports: [CommonModule, ClarityModule, FormsModule],\n declarations: [ClrCollapseExpandSection],\n exports: [ClrCollapseExpandSection],\n})\nexport class ClrCollapseExpandSectionModule {}\n","/*\n * Copyright (c) 2018-2019 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\n\nexport * from './collapse-expand-section';\nexport * from './collapse-expand-section.module';\n","/*\n * Copyright (c) 2018-2025 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\n\nimport { animate, style, transition, trigger } from '@angular/animations';\nimport { Component, EventEmitter, Output } from '@angular/core';\nimport { ClarityIcons, timesIcon } from '@cds/core/icon';\n\nClarityIcons.addIcons(timesIcon);\n\n@Component({\n selector: 'clr-content-panel',\n templateUrl: './content-panel.html',\n animations: [\n trigger('slideIn', [\n transition(':enter', [style({ opacity: 0, width: 0 }), animate('0.2s', style({ opacity: 1, width: '*' }))]),\n transition(':leave', [style({ opacity: 1, width: '*' }), animate('0.2s', style({ opacity: 0, width: 0 }))]),\n ]),\n trigger('fade', [\n transition(':enter', [style({ opacity: 0 }), animate('0.2s ease-in-out', style({ opacity: 0.85 }))]),\n transition(':leave', [animate('0.2s ease-in-out', style({ opacity: 0 }))]),\n ]),\n ],\n host: {\n '[class.content-panel]': 'true',\n },\n standalone: false,\n})\nexport class ClrContentPanel {\n _open = false;\n\n @Output('clrOpened') opened: EventEmitter<any> = new EventEmitter();\n @Output('clrClosed') closed: EventEmitter<any> = new EventEmitter();\n\n public isOpen(): boolean {\n return this._open;\n }\n\n public open(): void {\n if (this._open) {\n return;\n }\n this._open = true;\n this.opened.emit();\n }\n\n public close(): void {\n if (!this._open) {\n return;\n }\n this._open = false;\n this.closed.emit();\n }\n\n public toggle(): void {\n if (this._open) {\n this.close();\n } else {\n this.open();\n }\n }\n\n resizeWindow(): void {\n // this event is used by the tree table to adjust the colomns width\n window.dispatchEvent(new Event('resize'));\n }\n}\n","<ng-container *ngIf=\"_open\">\n <div [@slideIn] class=\"content-panel-content-wrapper\" (@slideIn.done)=\"resizeWindow()\">\n <h3 class=\"content-panel-title\">\n <button type=\"button\" class=\"close content-panel-close-btn\" (click)=\"close()\">\n <cds-icon class=\"content-panel-close-icon\" shape=\"times\" size=\"24\"></cds-icon>\n </button>\n <ng-content select=\"[clr-content-panel-title]\"></ng-content>\n </h3>\n <ng-content select=\"[clr-content-panel-content]\"></ng-content>\n </div>\n <div [@fade] class=\"content-panel-backdrop\" (click)=\"close()\" (@fade.done)=\"resizeWindow()\"></div>\n</ng-container>\n","/*\n * Copyright (c) 2018-2025 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\n\nimport { Component } from '@angular/core';\n\n@Component({\n selector: 'clr-content-panel-container',\n template: `\n <div class=\"content-panel-outer-wrapper\">\n <ng-content select=\"clr-content-panel-container-content\"></ng-content>\n <ng-content select=\"clr-content-panel-container-footer\"></ng-content>\n </div>\n <ng-content select=\"clr-content-panel\"></ng-content>\n `,\n host: {\n '[class.content-container]': 'true',\n '[class.content-panel-container]': 'true',\n },\n standalone: false,\n})\nexport class ClrContentPanelContainer {}\n","/*\n * Copyright (c) 2018-2025 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\n\nimport { Component } from '@angular/core';\n\n@Component({\n selector: 'clr-content-panel-container-content',\n template: ` <ng-content></ng-content> `,\n host: {\n '[class.content-area]': 'true',\n },\n standalone: false,\n})\nexport class ClrContentPanelContainerContent {}\n","/*\n * Copyright (c) 2018-2025 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\n\nimport { Component } from '@angular/core';\n\n@Component({\n selector: 'clr-content-panel-container-footer',\n template: ` <ng-content></ng-content> `,\n host: {\n '[class.content-area-footer]': 'true',\n },\n standalone: false,\n})\nexport class ClrContentPanelContainerFooter {}\n","/*\n * Copyright (c) 2018-2019 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\n\nimport { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { ClarityModule } from '@clr/angular';\n\nimport { ClrContentPanel } from './content-panel';\nimport { ClrContentPanelContainer } from './content-panel-container';\nimport { ClrContentPanelContainerContent } from './content-panel-container-content';\nimport { ClrContentPanelContainerFooter } from './content-panel-container-footer';\n\n@NgModule({\n imports: [CommonModule, ClarityModule, FormsModule],\n declarations: [\n ClrContentPanel,\n ClrContentPanelContainer,\n ClrContentPanelContainerContent,\n ClrContentPanelContainerFooter,\n ],\n exports: [ClrContentPanel, ClrContentPanelContainer, ClrContentPanelContainerContent, ClrContentPanelContainerFooter],\n})\nexport class ClrContentPanelModule {}\n","/*\n * Copyright (c) 2018-2019 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\n\nexport * from './content-panel';\nexport * from './content-panel-container';\nexport * from './content-panel-container-content';\nexport * from './content-panel-container-footer';\nexport * from './content-panel.module';\n","/*\n * Copyright (c) 2018-2020 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\nimport { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';\n\n/**\n * Class to provide validators for the Clr Data List.\n */\nexport class ClrDataListValidators {\n /**\n * @description\n * Validator that requires the control's value to be found in a possible values array.\n * This prohibits the user from entering custom values.\n *\n * @usageNotes\n *\n * ### Validate against an array of possible values\n *\n * ```typescript\n * const control = new FormControl('1234', ClrDataListValidators.predefined(['ASDF', 'QWER']));\n *\n * console.log(control.errors); // {predefined: {predefined: ['ASDF', 'QWER'], actual: '1234'}}\n * ```\n *\n * @returns A validator function that returns an error map with the\n * `predefined` property if the validation check fails, otherwise `null`.\n *\n */\n static predefined(possibleValues: string[]): ValidatorFn {\n const validatorFn: ValidatorFn = (control: AbstractControl): ValidationErrors | null => {\n if (!control.value) {\n return null; // don't validate empty values to allow optional controls\n }\n const value: string = possibleValues.find(v => v === control.value);\n\n return !value ? { predefined: { predefined: possibleValues, actual: control.value } } : null;\n };\n return validatorFn;\n }\n}\n","/*\n * Copyright (c) 2018-2025 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\nimport { Directive, Input } from '@angular/core';\nimport { AbstractControl, NG_VALIDATORS, Validator } from '@angular/forms';\nimport { ClrDataListValidators } from './data-list.validator';\n\n/**\n * Directive which validates data list values, to be used in template driven forms.\n * @see {@link ClrDataListValidators#predefined}\n */\n@Directive({\n selector: '[clrDataListPredefined]',\n providers: [{ provide: NG_VALIDATORS, useExisting: ClrDataListPredefinedValidatorDirective, multi: true }],\n standalone: false,\n})\nexport class ClrDataListPredefinedValidatorDirective implements Validator {\n @Input() clrDataListPredefined: string[] = [];\n\n validate(control: AbstractControl): { [key: string]: any } | null {\n return ClrDataListValidators.predefined(this.clrDataListPredefined)(control);\n }\n}\n","/*\n * Copyright (c) 2018-2020 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\n\nimport { NgModule } from '@angular/core';\nimport { ClrDataListPredefinedValidatorDirective } from './data-list-predefined-validator.directive';\n\n@NgModule({\n declarations: [ClrDataListPredefinedValidatorDirective],\n exports: [ClrDataListPredefinedValidatorDirective],\n})\nexport class ClrDataListValidatorModule {}\n","/*\n * Copyright (c) 2018-2020 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\n\nexport * from './data-list.validator';\nexport * from './data-list-predefined-validator.directive';\nexport * from './data-list-validator.module';\n","/*\n * Copyright (c) 2018-2025 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\n\nimport { AfterViewInit, Component, ElementRef, Renderer2, TemplateRef, ViewChild } from '@angular/core';\n\n@Component({\n selector: 'clr-date-time-container',\n template: `\n <ng-content select=\"clr-date-container\"></ng-content>\n\n <ng-template #timeInput>\n <div class=\"clr-input-wrapper\">\n <ng-content select=\"[clrTime]\"></ng-content>\n </div>\n </ng-template>\n `,\n host: {\n '[class.date-time-container]': 'true',\n },\n standalone: false,\n})\nexport class ClrDateTimeContainer implements AfterViewInit {\n @ViewChild('timeInput', { static: true }) timeInput: TemplateRef<any>;\n\n constructor(private renderer: Renderer2, private inputEl: ElementRef) {}\n\n ngAfterViewInit(): void {\n // Create the time input\n const timeInputElement = this.timeInput.createEmbeddedView(null).rootNodes[0];\n // Select the clr input wrapper of the date-container\n const inputWrapper = this.inputEl.nativeElement.querySelector('.clr-input-wrapper');\n // Append it as a child\n this.renderer.appendChild(inputWrapper, timeInputElement);\n }\n}\n","/*\n * Copyright (c) 2018-2025 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\n\nimport { Directive } from '@angular/core';\n\n@Directive({\n selector: '[clrTime]',\n host: {\n '[class.clr-input]': 'true',\n },\n standalone: false,\n})\nexport class ClrTimeInput {}\n","/*\n * Copyright (c) 2018-2019 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\n\nimport { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { ClarityModule, ClrFormsModule } from '@clr/angular';\n\nimport { ClrDateTimeContainer } from './date-time-container';\nimport { ClrTimeInput } from './time-input';\n\n@NgModule({\n imports: [CommonModule, ClarityModule, ClrFormsModule, FormsModule],\n declarations: [ClrDateTimeContainer, ClrTimeInput],\n exports: [ClrDateTimeContainer, ClrTimeInput],\n})\nexport class ClrDateTimeModule {}\n","/*\n * Copyright (c) 2018-2019 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\n\nexport * from './date-time-container';\nexport * from './date-time-module';\nexport * from './time-input';\n","/*\n * Copyright (c) 2018-2025 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\n\nimport { Component, EventEmitter, Input, Output } from '@angular/core';\n\n@Component({\n selector: 'clr-dot-pager',\n templateUrl: './dot-pager.html',\n host: { '[class.dot-pager]': 'true' },\n standalone: false,\n})\nexport class ClrDotPager {\n uniqueName = Math.floor(Math.random() * 100000);\n @Output('clrCurrentPageChange') currentPageChange: EventEmitter<number> = new EventEmitter(false);\n\n /**\n * Page count, a value of 0 means no pagination\n */\n private _pages = 0;\n public get pages(): number {\n return this._pages;\n }\n\n @Input('clrPages')\n public set pages(pages: number) {\n this._pages = pages;\n }\n\n /**\n * Current page\n */\n private _currentPage = 0;\n public get currentPage(): number {\n return this._currentPage;\n }\n\n @Input('clrCurrentPage')\n public set currentPage(currentPage: number) {\n if (currentPage !== this._currentPage) {\n this._currentPage = currentPage;\n this.currentPageChange.emit(currentPage);\n }\n }\n\n pageArray(): any[] {\n return Array(this._pages);\n }\n}\n","<clr-radio-container *ngIf=\"pages > 0\" clrInline>\n <clr-radio-wrapper *ngFor=\"let a of pageArray(); let page = index\">\n <input clrRadio type=\"radio\" [value]=\"page+1\" [(ngModel)]=\"currentPage\" name=\"{{uniqueName}}\" />\n <label> </label>\n </clr-radio-wrapper>\n</clr-radio-container>\n","/*\n * Copyright (c) 2018-2019 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\n\nimport { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { ClarityModule } from '@clr/angular';\n\nimport { ClrDotPager } from './dot-pager';\n\n@NgModule({\n imports: [CommonModule, ClarityModule, FormsModule],\n declarations: [ClrDotPager],\n exports: [ClrDotPager],\n})\nexport class ClrDotPagerModule {}\n","/*\n * Copyright (c) 2018-2019 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\n\nexport * from './dot-pager';\nexport * from './dot-pager.module';\n","/*\n * Copyright (c) 2018-2025 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\n\nimport { AfterViewChecked, ContentChildren, Directive, ElementRef, Input, OnDestroy, QueryList } from '@angular/core';\nimport { ClrDropdown } from '@clr/angular';\nimport { Subscription } from 'rxjs';\n\n@Directive({\n selector: 'clr-dropdown-menu',\n standalone: false,\n})\nexport class ClrDropdownOverflowDirective implements AfterViewChecked, OnDestroy {\n @Input() clrDropdownMenuMaxHeight: string | number; // can be of px, rem, vh, or a number (which then is considered as px value)\n @Input() clrDropdownMenuItemMinHeight: string | number; // can be of px, rem, vh, or a number (which then is considered as px value)\n\n @Input()\n set clrMarginBottom(value: string | number) {\n this.marginBottomPx = this.convertToPixels(value);\n }\n\n @ContentChildren(ClrDropdown, { descendants: true }) private nestedDropdownChildren: QueryList<ClrDropdown>;\n\n public readonly defaultItemMinHeightRem = 1.5;\n\n private alreadyChecked = false;\n private marginBottomPx = 2;\n\n private nestedDropdownSubscription: Subscription;\n\n public constructor(private elRef: ElementRef) {}\n\n ngAfterViewChecked(): void {\n // first trigger manually because the subscription lower only triggers after first change\n if (!this.nestedDropdownChildren?.length) {\n this.applyDropdownOverflowStyles();\n }\n\n if (!this.nestedDropdownSubscription) {\n this.nestedDropdownSubscription = this.nestedDropdownChildren.changes.subscribe(\n (children: QueryList<ClrDropdown>) => {\n // if there are any nested dropdowns, our overflow fix prevents those from showing and needs to be removed\n if (!children?.length) {\n this.applyDropdownOverflowStyles();\n } else if (children?.length) {\n this.removeDropdownOverflowStyles();\n }\n }\n );\n }\n }\n\n ngOnDestroy(): void {\n this.nestedDropdownSubscription?.unsubscribe();\n }\n\n private applyDropdownOverflowStyles(): void {\n // the vertical position of our element in the current window\n const y = this.elRef.nativeElement.getBoundingClientRect().y;\n if (y !== 0 && !this.alreadyChecked) {\n const itemMinHeightPx = this.getItemMinHeight(this.clrDropdownMenuItemMinHeight);\n // see https://stackoverflow.com/questions/22754315/for-loop-for-htmlcollection-elements\n for (const item of this.getAllChildDropdownMenuItems()) {\n item.style.minHeight = itemMinHeightPx + 'px';\n }\n const height = window.innerHeight - y;\n const maxHeight = this.getMenuMaxHeight(this.clrDropdownMenuMaxHeight, height - this.marginBottomPx);\n this.elRef.nativeElement.style.maxHeight = maxHeight + 'px';\n\n this.elRef.nativeElement.style.overflowY = 'auto';\n this.alreadyChecked = true;\n }\n }\n\n private removeDropdownOverflowStyles(): void {\n for (const item of this.getAllChildDropdownMenuItems()) {\n item.style.minHeight = null;\n }\n\n this.elRef.nativeElement.style.maxHeight = null;\n this.elRef.nativeElement.style.overflowY = null;\n this.alreadyChecked = false;\n }\n\n private getAllChildDropdownMenuItems() {\n return this.elRef.nativeElement.getElementsByClassName('dropdown-item');\n }\n\n private getMenuMaxHeight(menuMaxHeightProvided: string | number, menuMaxHeightPx: number): number {\n if (menuMaxHeightProvided) {\n const maxHeightPx = this.convertToPixels(menuMaxHeightProvided);\n return maxHeightPx > menuMaxHeightPx ? menuMaxHeightPx : maxHeightPx;\n }\n return menuMaxHeightPx;\n }\n\n private getItemMinHeight(itemMinHeightProvided: string | number): number {\n if (itemMinHeightProvided) {\n return this.convertToPixels(itemMinHeightProvided);\n }\n return this.convertRemToPixels(this.defaultItemMinHeightRem);\n }\n\n private convertToPixels(value: string | number): number {\n if (typeof value === 'string') {\n if (value.endsWith('px')) {\n return parseFloat(value.replace('px', ''));\n } else if (value.endsWith('rem')) {\n return this.convertRemToPixels(parseFloat(value.replace('rem', '')));\n } else if (value.endsWith('vh')) {\n return this.convertVhToPixels(parseFloat(value.replace('vh', '')));\n }\n return parseFloat(value);\n }\n return value;\n }\n\n private convertRemToPixels(rem: number): number {\n return rem * parseFloat(getComputedStyle(document.documentElement).fontSize);\n }\n\n private convertVhToPixels(vh: number): number {\n const pxPerVhUnit = window.innerHeight / 100;\n return vh * pxPerVhUnit;\n }\n}\n","/*\n * Copyright (c) 2018-2025 Porsche Informatik. All Rights Reserved.\n * This software is released under MIT license.\n * The full license information can be found in LICENSE in the root directory of this project.\n */\n\nimport { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';\nimport { Observable } from 'rxjs';\nimport { angleIcon, ClarityIcons } from '@cds/core/icon';\n\nClarityIcons.addIcons(angleIcon);\n\nexport interface ClrFlowBarStep {\n title: Observable<string>;\n enabled: boolean;\n activeSubStep?: ClrFlowBarStep;\n subSteps?: ClrFlowBarStep[];\n}\n\n@Component({\n selector: 'clr-flow-bar',\n templateUrl: './flow-bar.html',\n host: {\n '[class.flow-bar]': 'true',\n },\n standalone: false,\n})\nexport class ClrFlowBar implements OnInit {\n @Input('clrSteps') _steps: ClrFlowBarStep[] = [];\n @Input('clrActiveStep') _activeStep: ClrFlowBarStep;\n @Output('clrActiveStepChange') _activeStepChange: EventEmitter<ClrFlowBarStep> = new EventEmitter(false);\n\n ngOnInit(): void {\n // If no active step is set as input or the active step is not enabled, select the first enabled step\n if (!this._activeStep || !this._activeStep.enabled) {\n this._activeStep = this._steps.find(step => {\n return step.enabled;\n });\n if (this._activeStep) {\n // If sub steps exist then set the first non disabled sub step per default\n if (this.activeTabHasSubSteps()) {\n this._activeStep.activeSubStep = this._activeStep.subSteps.find(step => {\n return step.enabled;\n });\n }\n // Do async update here to avoid ExpressionChangedAfterItHasBeenCheckedError\n setTimeout(() => {\n this._activeStepChange.emit(this._activeStep);\n });\n }\n }\n }\n\n public changeActiveStep(step: ClrFlowBarStep): void {\n const previousIndex = this._steps.indexOf(this._activeStep);\n this._activeStep = step;\n if (this.activeTabHasSubSteps()) {\n if (previousIndex < this._steps.indexOf(this._activeStep)) {\n this._activeStep.activeSubStep = this._activeStep.subSteps[0];\n } else {\n this._activeStep.activeSubStep = this._activeStep.subSteps[this._activeStep.subSteps.length - 1];\n }\n }\n this._activeStepChange.emit(this._activeStep);\n }\n\n public changeActiveSubStep(subStep: ClrFlowBarStep): void {\n this._activeStep.activeSubStep = subStep;\n }\n\n public previous(): void {\n if (this.isPreviousAvailable()) {\n // If active step has no sub steps or first sub step is selected -> go to previous main step\n if (!this.activeTabHasSubSteps() || this.isFirstSubStep()) {\n this.changeActiveStep(this.findPreviousEnabledStep());\n } else {\n const subStepIndex = this._activeStep.subSteps.indexOf(this._activeStep.activeSubStep);\n this._activeStep.activeSubStep = this._activeStep.subSteps[subStepIndex - 1];\n }\n }\n }\n\n public next(): void {\n if (this.isNextAvailable()) {\n // If active step has no sub steps or last sub step is selected -> go to next main step\n if (!this.activeTabHasSubSteps() || this.isLastSubStep()) {\n this.changeActiveStep(this.findNextEnabledStep());\n } else {\n const subStepIndex = this._activeStep.subSteps.indexOf(this._activeStep.activeSubStep);\n this._activeStep.activeSubStep = this._activeStep.subSteps[subStepIndex + 1];\n }\n }\n }\n\n public isPreviousAvailable(): boolean {\n if (this._activeStep) {\n if (!this.activeTabHasSubSteps() || this.isFirstSubStep()) {\n const index = this.getCurrentIndex();\n return index > 0 && this.isAnyPreviousStepEnabled(index);\n } else {\n return true;\n }\n }\n return false;\n }\n\n public isNextAvailable(): boolean {\n if (this._activeStep) {\n if (!this.activeTabHasSubSteps() || this.isLastSubStep()) {\n const index = this.getCurrentIndex();\n return index < this._steps.length - 1 && this.isAnyFollowingStepEnabled(index);\n } else {\n return true;\n }\n }\n return false;\n }\n\n public isLastStep(): boolean {\n if (this.getCurrentIndex() === this._steps.length - 1) {\n if (this.activeTabHasSubSteps()) {\n return this.isLastSubStep();\n } else {\n return true;\n }\n }\n return false;\n }\n\n private getCurrentIndex(): number {\n return this._steps.findIndex(value => {\n return value === this._activeStep;\n });\n }\n\n // Convenience methods for easier to read code\n private activeTabHasSubSteps(): boolean {\n return this._activeStep.subSteps && this._activeStep.subSteps.length > 0;\n }\n\n private isFirstSubStep(): boolean {\n return this._activeStep.activeSubStep === this._activeStep.subSteps[0];\n }\n\n private isLastSubStep(): boolean {\n return this._activeStep.activeSubStep === this._activeStep.subSteps[this._activeStep.subSteps.length - 1];\n }\n\n private isAnyPreviousStepEnabled(index: number): boolean {\n return this._steps.slice(0, index).find(step => step.enabled) !== undefined;\n }\n\n private isAnyFollowingStepEnabled(index: number): boolean {\n return this._steps.slice(index + 1, this._steps.length).find(step => step.enabled) !== undefined;\n }\n\n private findPreviousEnabledStep(): ClrFlowBarStep {\n const index = this.getCurrentIndex();\n return this._steps\n .slice(0, index)\n .reverse()\n .find(step => step.enabled);\n }\n\n private findNextEnabledStep(): ClrFlowBarStep {\n const index = this.getCurrentIndex();\n return this._steps.slice(index + 1, this._steps.length).find(step => step.enabled);\n }\n}\n","<div class=\"flow-bar-wrapper\">\n <ng-container *ngFor=\"let step of _steps; let index = index; let last = last\">\n <div class=\"flow-bar-step\" [class.active]=\"step === _activeStep\">\n <button\n class=\"btn btn-link flow-bar-btn\"\n [disabled]=\"!step.enabled\"\n [class.active]=\"step === _activeStep\"\n (click)=\"changeActiveStep(step)\"\n >\n {{index + 1}}. {{(step.title | async)}}\n </button>\n <cds-icon shape=\"angle\" direction=\"right\" *ngIf=\"!last\"></cds-icon>\n </div>\n </ng-container>\n</div>\n<clr-dropdown class=\"flow-bar-dropdown clr-flex-fill\">\n <button type=\"button\" class=\"btn btn-outline-primary\" clrDropdownTrigger>\n {{_steps.indexOf(_activeStep) + 1}}. {{_activeStep?.title | async}}\n <cds-icon shape=\"angle\" direction=\"down\"></cds-icon>\n </button>\n <clr-dropdow