UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

415 lines (408 loc) 111 kB
import * as i0 from '@angular/core'; import { Injectable, Optional, Inject, Input, Component, EventEmitter, Output, NgModule } from '@angular/core'; import { gettext } from '@c8y/ngx-components/gettext'; import * as i1 from '@c8y/ngx-components'; import { NavigatorNode, Permissions, ListGroupComponent, ListItemComponent, C8yTranslatePipe, ListItemIconComponent, C8yTranslateDirective, PluginLoadedPipe, EmptyStateComponent, IconDirective, ListItemRadioComponent, TitleComponent, BreadcrumbComponent, BreadcrumbItemComponent, ProductExperienceDirective, CoreModule, hookRoute, hookNavigator, hookStepper, Steppers } from '@c8y/ngx-components'; import * as i2 from '@c8y/ngx-components/ecosystem/shared'; import * as i2$1 from '@c8y/ngx-components/assets-navigator'; import { ASSET_NAVIGATOR_CONFIG, AssetSelectorComponent, AssetSelectorModule } from '@c8y/ngx-components/assets-navigator'; import { EcosystemModule } from '@c8y/ngx-components/ecosystem'; import { IconSelectorWrapperComponent, IconSelectorModule } from '@c8y/ngx-components/icon-selector'; import { PopoverDirective, PopoverModule } from 'ngx-bootstrap/popover'; import { TooltipDirective, TooltipModule } from 'ngx-bootstrap/tooltip'; import * as i3 from '@c8y/client'; import { isUndefined, uniqBy, startCase } from 'lodash-es'; import { take, map, filter } from 'rxjs/operators'; import * as i5 from '@angular/forms'; import { FormsModule } from '@angular/forms'; import { NgIf, AsyncPipe, NgFor } from '@angular/common'; import * as i2$2 from '@angular/cdk/stepper'; const DEFAULT_HOME_DASHBOARD_NAME = 'home-cockpit1'; const USER_HOME_DASHBOARD_NAME = 'home-cockpit-user'; const DEFAULT_CONFIG = { rootNodes: [], features: { alarms: true, dataExplorer: true, groups: true, reports: true, exports: true, dataPointLibrary: true, globalSmartRules: true, smartRules: true, subassets: true, search: true, dashboardManager: true }, hideNavigator: false, homeDashboardName: DEFAULT_HOME_DASHBOARD_NAME, userSpecificHomeDashboard: false, icon: { class: 'c8y-cockpit' }, htmlWidgetDisableSanitization: false, htmlWidgetDefaultToAdvancedMode: false }; var HomeDashboardType; (function (HomeDashboardType) { /** * Shared by all Cockpit apps */ HomeDashboardType[HomeDashboardType["DEFAULT"] = 0] = "DEFAULT"; /** * Only for the current Cockpit. */ HomeDashboardType[HomeDashboardType["APP"] = 1] = "APP"; /** * Only for the current user. */ HomeDashboardType[HomeDashboardType["USER"] = 2] = "USER"; })(HomeDashboardType || (HomeDashboardType = {})); const COCKPIT_CONFIG_PATH = 'cockpit-application-configuration'; class CockpitConfigGuard { constructor(permissions, appState, ecosystemService) { this.permissions = permissions; this.appState = appState; this.ecosystemService = ecosystemService; this.configNode = new NavigatorNode({ path: `/${COCKPIT_CONFIG_PATH}`, parent: gettext('Configuration'), label: gettext('Application configuration'), icon: 'imac-settings', preventDuplicates: true }); } get() { if (this.canActivate()) { return this.configNode; } return; } canActivate() { return (this.permissions.hasRole(Permissions.ROLE_APPLICATION_MANAGEMENT_ADMIN) && this.ecosystemService.isOwner(this.appState.currentApplication.value)); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CockpitConfigGuard, deps: [{ token: i1.Permissions }, { token: i1.AppStateService }, { token: i2.EcosystemService }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CockpitConfigGuard, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CockpitConfigGuard, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: i1.Permissions }, { type: i1.AppStateService }, { type: i2.EcosystemService }] }); class CockpitConfigService { get excludedFeatureKeys() { return Object.keys(this.currentConfig.features).filter(key => !this.currentConfig.features[key]); } constructor(navigatorService, tabsService, searchService, assetNodeService, inventoryService, appState, applicationService, optionsService, permissions, moduleConfig) { this.navigatorService = navigatorService; this.tabsService = tabsService; this.searchService = searchService; this.assetNodeService = assetNodeService; this.inventoryService = inventoryService; this.appState = appState; this.applicationService = applicationService; this.optionsService = optionsService; this.permissions = permissions; this.moduleConfig = moduleConfig; this.currentConfig = DEFAULT_CONFIG; this.nodes = []; this.navigationFactory = { get: () => this.nodes }; this.DEFAULT_NODE_PRIORITY = 2000; this.registerFilterForFeatures(); this.init(); } init() { if (this.optionsService.hideNavigator !== undefined) { this.currentConfig.hideNavigator = this.optionsService.hideNavigator; } this.appState.currentApplicationConfig.subscribe(config => { if (config) { this.currentConfig = { ...DEFAULT_CONFIG, ...config }; } }); this.appState.currentApplicationConfig.pipe(take(1)).subscribe(() => { this.setRootNodes(); }); } /** * Save and apply new cockpit configuration * @param config - New cockpit configuration */ async saveConfig(config) { this.currentConfig = config; await this.storeApplicationConfig(this.currentConfig); await this.updateApplication(this.currentConfig); } /** * Update current application using the provided configuration * @param config - Cockpit configuration */ async updateApplication(config) { if (!config.appTitle && !config.icon) { return; } const application = this.appState.currentApplication.value; const updatedApp = { ...application, name: config.appTitle || application.name }; const manifest = { ...updatedApp.manifest, name: updatedApp.name, icon: config.icon || { class: 'c8y-cockpit' } }; await this.applicationService.update({ id: updatedApp.id, name: updatedApp.name, manifest }); this.appState.currentApplication.next(updatedApp); } refresh() { this.optionsService.hideNavigator = this.currentConfig.hideNavigator; this.navigatorService.refresh(); this.searchService.refresh(); } async setRootNodes() { this.addNodesToFactories(); this.nodes.length = 0; for (const node of this.currentConfig.rootNodes) { try { const { data } = await this.inventoryService.detail(node.id); if (data) { this.nodes.push(this.assetNodeService.createAssetNode({ mo: data, hideDevices: node.hideDevices, priority: isUndefined(this.moduleConfig?.rootNodePriority) ? this.DEFAULT_NODE_PRIORITY : this.moduleConfig.rootNodePriority })); } } catch (error) { // do nothing } } this.nodes = uniqBy(this.nodes, 'path'); this.refresh(); } getAppDashboardName() { return `${DEFAULT_HOME_DASHBOARD_NAME.substring(0, DEFAULT_HOME_DASHBOARD_NAME.length - 1)}_${this.appState.state.app.id}`; } async storeApplicationConfig(config) { await this.appState.updateCurrentApplicationConfig(config); } addNodesToFactories() { const nodeInFactories = this.navigatorService.factories.find(fatcory => fatcory === this.navigationFactory); if (!nodeInFactories) { this.navigatorService.factories.push(this.navigationFactory); } } registerFilterForFeatures() { this.navigatorService.items$ = this.navigatorService.items$.pipe(map(nodes => this.setHiddenAttrLock(nodes)), map(nodes => this.filterNavigatorNode(nodes))); this.tabsService.items$ = this.tabsService.items$.pipe(map(tabs => this.filterTabs(tabs))); this.searchService.items$ = this.searchService.items$.pipe(map(search => (this.currentConfig.features.search ? search : []))); } setHiddenAttrLock(nodes) { nodes.forEach(node => { Object.keys(this.currentConfig.features).forEach(key => { const childNode = node.find(startCase(key).toLowerCase()); if (childNode) { if (!this.permissions.hasRole(Permissions.ROLE_APPLICATION_MANAGEMENT_ADMIN) && childNode.lockHiddenAttr === undefined && childNode.hidden === true) { childNode.lockHiddenAttr = childNode.hidden; } } }); }); return nodes; } filterTabs(tabs) { return tabs.filter(tab => !this.excludedFeatureKeys.some(key => tab.featureId === key)); } filterNavigatorNode(nodes) { if (!this.currentConfig) { return nodes; } const disabledFeatures = this.excludedFeatureKeys; const filteredNodes = nodes.filter(node => !disabledFeatures.some(key => node.featureId === key)); this.showAllChildrenNodes(nodes); this.hideChildrenNodesThatAreDisabled(nodes, disabledFeatures); return filteredNodes; } hideChildrenNodesThatAreDisabled(nodes, disabledFeatures) { nodes.forEach(node => disabledFeatures.forEach(key => { const childNode = node.find(key, 'featureId'); if (childNode) { childNode.hidden = true; } })); } showAllChildrenNodes(nodes) { nodes.forEach(node => { Object.keys(this.currentConfig.features).forEach(key => { const childNode = node.find(startCase(key).toLowerCase()); if (childNode) { if (childNode.lockHiddenAttr === true) { return; } childNode.hidden = false; } }); }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CockpitConfigService, deps: [{ token: i1.NavigatorService }, { token: i1.TabsService }, { token: i1.SearchService }, { token: i2$1.AssetNodeService }, { token: i3.InventoryService }, { token: i1.AppStateService }, { token: i3.ApplicationService }, { token: i1.OptionsService }, { token: i1.Permissions }, { token: ASSET_NAVIGATOR_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CockpitConfigService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CockpitConfigService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: i1.NavigatorService }, { type: i1.TabsService }, { type: i1.SearchService }, { type: i2$1.AssetNodeService }, { type: i3.InventoryService }, { type: i1.AppStateService }, { type: i3.ApplicationService }, { type: i1.OptionsService }, { type: i1.Permissions }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [ASSET_NAVIGATOR_CONFIG] }] }] }); class MiscConfigComponent { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MiscConfigComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: MiscConfigComponent, isStandalone: true, selector: "c8y-misc-config", inputs: { config: "config" }, ngImport: i0, template: "<c8y-list-group class=\"separator-top\">\n <c8y-li>\n <div class=\"d-flex a-i-center\">\n <p>{{ 'Always collapse navigator on start up' | translate }}</p>\n <label\n class=\"c8y-switch c8y-switch--inline m-l-auto\"\n title=\"{{ 'Collapse navigator on start up' | translate }}\"\n >\n <input data-cy=\"c8y-misc-config--collapse-button\" type=\"checkbox\" [(ngModel)]=\"config.hideNavigator\" name=\"hideNavigator\" />\n <span></span>\n </label>\n </div>\n </c8y-li>\n</c8y-list-group>\n", dependencies: [{ kind: "component", type: ListGroupComponent, selector: "c8y-list-group" }, { kind: "component", type: ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i5.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MiscConfigComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-misc-config', imports: [ListGroupComponent, ListItemComponent, FormsModule, C8yTranslatePipe], template: "<c8y-list-group class=\"separator-top\">\n <c8y-li>\n <div class=\"d-flex a-i-center\">\n <p>{{ 'Always collapse navigator on start up' | translate }}</p>\n <label\n class=\"c8y-switch c8y-switch--inline m-l-auto\"\n title=\"{{ 'Collapse navigator on start up' | translate }}\"\n >\n <input data-cy=\"c8y-misc-config--collapse-button\" type=\"checkbox\" [(ngModel)]=\"config.hideNavigator\" name=\"hideNavigator\" />\n <span></span>\n </label>\n </div>\n </c8y-li>\n</c8y-list-group>\n" }] }], propDecorators: { config: [{ type: Input }] } }); class FeatureConfigComponent { constructor() { this.onUpdate = new EventEmitter(); } updateFeatures() { this.onUpdate.emit(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FeatureConfigComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: FeatureConfigComponent, isStandalone: true, selector: "c8y-feature-config", inputs: { config: "config" }, outputs: { onUpdate: "onUpdate" }, ngImport: i0, template: "<c8y-list-group>\n <c8y-li data-cy=\"feature-config--feature-list\" *ngIf=\"'SearchModule' | c8yPluginLoaded | async\">\n <c8y-li-icon icon=\"search\"></c8y-li-icon>\n <div class=\"d-flex a-i-center\">\n <div>\n <p>{{ 'Global search' | translate }}</p>\n <p>\n <small translate>Display the global search in the main header.</small>\n </p>\n </div>\n <label\n class=\"c8y-switch c8y-switch--inline m-l-auto\"\n title=\"{{ 'Global search' | translate }}\"\n >\n <input\n name=\"search\"\n type=\"checkbox\"\n [(ngModel)]=\"config.features.search\"\n (change)=\"updateFeatures()\"\n />\n <span></span>\n </label>\n </div>\n </c8y-li>\n <c8y-li data-cy=\"feature-config--feature-list\">\n <c8y-li-icon icon=\"c8y-group\"></c8y-li-icon>\n <div class=\"d-flex a-i-center\">\n <div>\n <p>{{ 'Groups' | translate }}</p>\n <p>\n <small translate>Display top level groups under the Groups navigator menu.</small>\n </p>\n </div>\n <label\n class=\"c8y-switch c8y-switch--inline m-l-auto\"\n title=\"{{ 'Groups' | translate }}\"\n >\n <input\n name=\"groups\"\n type=\"checkbox\"\n [(ngModel)]=\"config.features.groups\"\n (change)=\"updateFeatures()\"\n />\n <span></span>\n </label>\n </div>\n </c8y-li>\n <c8y-li data-cy=\"feature-config--feature-list\" *ngIf=\"'CockpitAlarmsModule' | c8yPluginLoaded | async\">\n <c8y-li-icon icon=\"bell\"></c8y-li-icon>\n <div class=\"d-flex a-i-center\">\n <div>\n <p>{{ 'Alarms' | translate }}</p>\n <p>\n <small translate>Display a link to the global alarms list in the navigator menu.</small>\n </p>\n </div>\n <label\n class=\"c8y-switch c8y-switch--inline m-l-auto\"\n title=\"{{ 'Global Alarms view' | translate }}\"\n >\n <input\n name=\"alarms\"\n type=\"checkbox\"\n [(ngModel)]=\"config.features.alarms\"\n (change)=\"updateFeatures()\"\n />\n <span></span>\n </label>\n </div>\n </c8y-li>\n <c8y-li data-cy=\"feature-config--feature-list\">\n <c8y-li-icon icon=\"c8y-data-explorer\"></c8y-li-icon>\n <div class=\"d-flex a-i-center\">\n <div>\n <p>{{ 'Data explorer' | translate }}</p>\n <p>\n <small translate>\n Display the data explorer in the navigator menu and on the group tabs.\n </small>\n </p>\n </div>\n <label\n class=\"c8y-switch c8y-switch--inline m-l-auto\"\n title=\"{{ 'Data explorer' | translate }}\"\n >\n <input\n name=\"dataExplorer\"\n type=\"checkbox\"\n [(ngModel)]=\"config.features.dataExplorer\"\n (change)=\"updateFeatures()\"\n />\n <span></span>\n </label>\n </div>\n </c8y-li>\n <c8y-li data-cy=\"feature-config--feature-list\" *ngIf=\"'ReportDashboardModule' | c8yPluginLoaded | async\">\n <c8y-li-icon icon=\"c8y-reports\"></c8y-li-icon>\n <div class=\"d-flex a-i-center\">\n <div>\n <p>{{ 'Reports' | translate }}</p>\n <p>\n <small translate>Display a link to the Reports list in the navigator menu.</small>\n </p>\n </div>\n <label\n class=\"c8y-switch c8y-switch--inline m-l-auto\"\n title=\"{{ 'Reports' | translate }}\"\n >\n <input\n name=\"reports\"\n type=\"checkbox\"\n [(ngModel)]=\"config.features.reports\"\n (change)=\"updateFeatures()\"\n />\n <span></span>\n </label>\n </div>\n </c8y-li>\n <c8y-li data-cy=\"feature-config--feature-list\" *ngIf=\"'exportsProviders' | c8yPluginLoaded | async\">\n <c8y-li-icon icon=\"graph-report\"></c8y-li-icon>\n <div class=\"d-flex a-i-center\">\n <div>\n <p>{{ 'Exports' | translate }}</p>\n <p>\n <small translate>\n Display a link to the Exports list under the Configuration navigator menu.\n </small>\n </p>\n </div>\n <label\n class=\"c8y-switch c8y-switch--inline m-l-auto\"\n title=\"{{ 'Exports' | translate }}\"\n >\n <input\n name=\"exports\"\n type=\"checkbox\"\n [(ngModel)]=\"config.features.exports\"\n (change)=\"updateFeatures()\"\n />\n <span></span>\n </label>\n </div>\n </c8y-li>\n <c8y-li data-cy=\"feature-config--feature-list\" *ngIf=\"'DatapointLibraryModule' | c8yPluginLoaded | async\">\n <c8y-li-icon icon=\"c8y-data-points\"></c8y-li-icon>\n <div class=\"d-flex a-i-center\">\n <div>\n <p>{{ 'Data point library' | translate }}</p>\n <p>\n <small translate>\n Display a link to the Data point library under the Configuration navigator menu.\n </small>\n </p>\n </div>\n <label\n class=\"c8y-switch c8y-switch--inline m-l-auto\"\n title=\"{{ 'Data point library' | translate }}\"\n >\n <input\n name=\"dataPointLibrary\"\n type=\"checkbox\"\n [(ngModel)]=\"config.features.dataPointLibrary\"\n (change)=\"updateFeatures()\"\n />\n <span></span>\n </label>\n </div>\n </c8y-li>\n <c8y-li data-cy=\"feature-config--feature-list\">\n <c8y-li-icon icon=\"c8y-smart-rules\"></c8y-li-icon>\n <div class=\"d-flex a-i-center\">\n <div>\n <p>{{ 'Global smart rules' | translate }}</p>\n <p>\n <small translate>\n Display a link to the Global smart rules under the Configuration navigator menu.\n </small>\n </p>\n </div>\n <label\n class=\"c8y-switch c8y-switch--inline m-l-auto\"\n title=\"{{ 'Global smart rules' | translate }}\"\n >\n <input\n name=\"globalSmartRules\"\n type=\"checkbox\"\n [(ngModel)]=\"config.features.globalSmartRules\"\n (change)=\"updateFeatures()\"\n />\n <span></span>\n </label>\n </div>\n </c8y-li>\n <c8y-li data-cy=\"feature-config--feature-list\">\n <c8y-li-icon icon=\"c8y-group-open\"></c8y-li-icon>\n <div class=\"d-flex a-i-center\">\n <div>\n <p>{{ 'Subassets view' | translate }}</p>\n <p><small translate>Display the \"Subassets\" tab on groups.</small></p>\n </div>\n <label\n class=\"c8y-switch c8y-switch--inline m-l-auto\"\n title=\"{{ 'Subassets view' | translate }}\"\n >\n <input\n name=\"subassets\"\n type=\"checkbox\"\n [(ngModel)]=\"config.features.subassets\"\n (change)=\"updateFeatures()\"\n />\n <span></span>\n </label>\n </div>\n </c8y-li>\n <c8y-li data-cy=\"feature-config--feature-list\">\n <c8y-li-icon icon=\"c8y-smart-rules\"></c8y-li-icon>\n <div class=\"d-flex a-i-center\">\n <div>\n <p>{{ 'Smart rules for devices and groups' | translate }}</p>\n <p>\n <small translate>Display the smart rules tab on groups and devices.</small>\n </p>\n </div>\n <label\n class=\"c8y-switch c8y-switch--inline m-l-auto\"\n title=\"{{ 'Smart rules for devices and groups' | translate }}\"\n >\n <input\n name=\"smartRules\"\n type=\"checkbox\"\n [(ngModel)]=\"config.features.smartRules\"\n (change)=\"updateFeatures()\"\n />\n <span></span>\n </label>\n </div>\n </c8y-li>\n <c8y-li data-cy=\"feature-config--feature-list\" *ngIf=\"'DashboardManagerModule' | c8yPluginLoaded | async\">\n <c8y-li-icon icon=\"management1\"></c8y-li-icon>\n <div class=\"d-flex a-i-center\">\n <div>\n <p>{{ 'Dashboard manager' | translate }}</p>\n <p>\n <small translate>\n Display a link to the Dashboard manager under the Configuration navigator menu.\n </small>\n </p>\n </div>\n <label\n class=\"c8y-switch c8y-switch--inline m-l-auto\"\n title=\"{{ 'Dashboard manager' | translate }}\"\n >\n <input\n name=\"dashboardManager\"\n type=\"checkbox\"\n [(ngModel)]=\"config.features.dashboardManager\"\n (change)=\"updateFeatures()\"\n />\n <span></span>\n </label>\n </div>\n </c8y-li>\n</c8y-list-group>\n", dependencies: [{ kind: "component", type: ListGroupComponent, selector: "c8y-list-group" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i5.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: PluginLoadedPipe, name: "c8yPluginLoaded" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FeatureConfigComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-feature-config', imports: [ ListGroupComponent, NgIf, ListItemComponent, ListItemIconComponent, C8yTranslateDirective, FormsModule, C8yTranslatePipe, AsyncPipe, PluginLoadedPipe ], template: "<c8y-list-group>\n <c8y-li data-cy=\"feature-config--feature-list\" *ngIf=\"'SearchModule' | c8yPluginLoaded | async\">\n <c8y-li-icon icon=\"search\"></c8y-li-icon>\n <div class=\"d-flex a-i-center\">\n <div>\n <p>{{ 'Global search' | translate }}</p>\n <p>\n <small translate>Display the global search in the main header.</small>\n </p>\n </div>\n <label\n class=\"c8y-switch c8y-switch--inline m-l-auto\"\n title=\"{{ 'Global search' | translate }}\"\n >\n <input\n name=\"search\"\n type=\"checkbox\"\n [(ngModel)]=\"config.features.search\"\n (change)=\"updateFeatures()\"\n />\n <span></span>\n </label>\n </div>\n </c8y-li>\n <c8y-li data-cy=\"feature-config--feature-list\">\n <c8y-li-icon icon=\"c8y-group\"></c8y-li-icon>\n <div class=\"d-flex a-i-center\">\n <div>\n <p>{{ 'Groups' | translate }}</p>\n <p>\n <small translate>Display top level groups under the Groups navigator menu.</small>\n </p>\n </div>\n <label\n class=\"c8y-switch c8y-switch--inline m-l-auto\"\n title=\"{{ 'Groups' | translate }}\"\n >\n <input\n name=\"groups\"\n type=\"checkbox\"\n [(ngModel)]=\"config.features.groups\"\n (change)=\"updateFeatures()\"\n />\n <span></span>\n </label>\n </div>\n </c8y-li>\n <c8y-li data-cy=\"feature-config--feature-list\" *ngIf=\"'CockpitAlarmsModule' | c8yPluginLoaded | async\">\n <c8y-li-icon icon=\"bell\"></c8y-li-icon>\n <div class=\"d-flex a-i-center\">\n <div>\n <p>{{ 'Alarms' | translate }}</p>\n <p>\n <small translate>Display a link to the global alarms list in the navigator menu.</small>\n </p>\n </div>\n <label\n class=\"c8y-switch c8y-switch--inline m-l-auto\"\n title=\"{{ 'Global Alarms view' | translate }}\"\n >\n <input\n name=\"alarms\"\n type=\"checkbox\"\n [(ngModel)]=\"config.features.alarms\"\n (change)=\"updateFeatures()\"\n />\n <span></span>\n </label>\n </div>\n </c8y-li>\n <c8y-li data-cy=\"feature-config--feature-list\">\n <c8y-li-icon icon=\"c8y-data-explorer\"></c8y-li-icon>\n <div class=\"d-flex a-i-center\">\n <div>\n <p>{{ 'Data explorer' | translate }}</p>\n <p>\n <small translate>\n Display the data explorer in the navigator menu and on the group tabs.\n </small>\n </p>\n </div>\n <label\n class=\"c8y-switch c8y-switch--inline m-l-auto\"\n title=\"{{ 'Data explorer' | translate }}\"\n >\n <input\n name=\"dataExplorer\"\n type=\"checkbox\"\n [(ngModel)]=\"config.features.dataExplorer\"\n (change)=\"updateFeatures()\"\n />\n <span></span>\n </label>\n </div>\n </c8y-li>\n <c8y-li data-cy=\"feature-config--feature-list\" *ngIf=\"'ReportDashboardModule' | c8yPluginLoaded | async\">\n <c8y-li-icon icon=\"c8y-reports\"></c8y-li-icon>\n <div class=\"d-flex a-i-center\">\n <div>\n <p>{{ 'Reports' | translate }}</p>\n <p>\n <small translate>Display a link to the Reports list in the navigator menu.</small>\n </p>\n </div>\n <label\n class=\"c8y-switch c8y-switch--inline m-l-auto\"\n title=\"{{ 'Reports' | translate }}\"\n >\n <input\n name=\"reports\"\n type=\"checkbox\"\n [(ngModel)]=\"config.features.reports\"\n (change)=\"updateFeatures()\"\n />\n <span></span>\n </label>\n </div>\n </c8y-li>\n <c8y-li data-cy=\"feature-config--feature-list\" *ngIf=\"'exportsProviders' | c8yPluginLoaded | async\">\n <c8y-li-icon icon=\"graph-report\"></c8y-li-icon>\n <div class=\"d-flex a-i-center\">\n <div>\n <p>{{ 'Exports' | translate }}</p>\n <p>\n <small translate>\n Display a link to the Exports list under the Configuration navigator menu.\n </small>\n </p>\n </div>\n <label\n class=\"c8y-switch c8y-switch--inline m-l-auto\"\n title=\"{{ 'Exports' | translate }}\"\n >\n <input\n name=\"exports\"\n type=\"checkbox\"\n [(ngModel)]=\"config.features.exports\"\n (change)=\"updateFeatures()\"\n />\n <span></span>\n </label>\n </div>\n </c8y-li>\n <c8y-li data-cy=\"feature-config--feature-list\" *ngIf=\"'DatapointLibraryModule' | c8yPluginLoaded | async\">\n <c8y-li-icon icon=\"c8y-data-points\"></c8y-li-icon>\n <div class=\"d-flex a-i-center\">\n <div>\n <p>{{ 'Data point library' | translate }}</p>\n <p>\n <small translate>\n Display a link to the Data point library under the Configuration navigator menu.\n </small>\n </p>\n </div>\n <label\n class=\"c8y-switch c8y-switch--inline m-l-auto\"\n title=\"{{ 'Data point library' | translate }}\"\n >\n <input\n name=\"dataPointLibrary\"\n type=\"checkbox\"\n [(ngModel)]=\"config.features.dataPointLibrary\"\n (change)=\"updateFeatures()\"\n />\n <span></span>\n </label>\n </div>\n </c8y-li>\n <c8y-li data-cy=\"feature-config--feature-list\">\n <c8y-li-icon icon=\"c8y-smart-rules\"></c8y-li-icon>\n <div class=\"d-flex a-i-center\">\n <div>\n <p>{{ 'Global smart rules' | translate }}</p>\n <p>\n <small translate>\n Display a link to the Global smart rules under the Configuration navigator menu.\n </small>\n </p>\n </div>\n <label\n class=\"c8y-switch c8y-switch--inline m-l-auto\"\n title=\"{{ 'Global smart rules' | translate }}\"\n >\n <input\n name=\"globalSmartRules\"\n type=\"checkbox\"\n [(ngModel)]=\"config.features.globalSmartRules\"\n (change)=\"updateFeatures()\"\n />\n <span></span>\n </label>\n </div>\n </c8y-li>\n <c8y-li data-cy=\"feature-config--feature-list\">\n <c8y-li-icon icon=\"c8y-group-open\"></c8y-li-icon>\n <div class=\"d-flex a-i-center\">\n <div>\n <p>{{ 'Subassets view' | translate }}</p>\n <p><small translate>Display the \"Subassets\" tab on groups.</small></p>\n </div>\n <label\n class=\"c8y-switch c8y-switch--inline m-l-auto\"\n title=\"{{ 'Subassets view' | translate }}\"\n >\n <input\n name=\"subassets\"\n type=\"checkbox\"\n [(ngModel)]=\"config.features.subassets\"\n (change)=\"updateFeatures()\"\n />\n <span></span>\n </label>\n </div>\n </c8y-li>\n <c8y-li data-cy=\"feature-config--feature-list\">\n <c8y-li-icon icon=\"c8y-smart-rules\"></c8y-li-icon>\n <div class=\"d-flex a-i-center\">\n <div>\n <p>{{ 'Smart rules for devices and groups' | translate }}</p>\n <p>\n <small translate>Display the smart rules tab on groups and devices.</small>\n </p>\n </div>\n <label\n class=\"c8y-switch c8y-switch--inline m-l-auto\"\n title=\"{{ 'Smart rules for devices and groups' | translate }}\"\n >\n <input\n name=\"smartRules\"\n type=\"checkbox\"\n [(ngModel)]=\"config.features.smartRules\"\n (change)=\"updateFeatures()\"\n />\n <span></span>\n </label>\n </div>\n </c8y-li>\n <c8y-li data-cy=\"feature-config--feature-list\" *ngIf=\"'DashboardManagerModule' | c8yPluginLoaded | async\">\n <c8y-li-icon icon=\"management1\"></c8y-li-icon>\n <div class=\"d-flex a-i-center\">\n <div>\n <p>{{ 'Dashboard manager' | translate }}</p>\n <p>\n <small translate>\n Display a link to the Dashboard manager under the Configuration navigator menu.\n </small>\n </p>\n </div>\n <label\n class=\"c8y-switch c8y-switch--inline m-l-auto\"\n title=\"{{ 'Dashboard manager' | translate }}\"\n >\n <input\n name=\"dashboardManager\"\n type=\"checkbox\"\n [(ngModel)]=\"config.features.dashboardManager\"\n (change)=\"updateFeatures()\"\n />\n <span></span>\n </label>\n </div>\n </c8y-li>\n</c8y-list-group>\n" }] }], propDecorators: { config: [{ type: Input }], onUpdate: [{ type: Output }] } }); class RootNodeConfigComponent { constructor() { this.disabled = false; this.onUpdate = new EventEmitter(); } /** * Removes one of the root nodes. * @param node The node to remove. */ removeNavigatorNode(node) { const index = this.config.rootNodes.indexOf(node); if (index > -1) { const newNodes = this.config.rootNodes.filter((_, i) => i !== index); this.config.rootNodes = newNodes; this.onUpdate.emit(); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RootNodeConfigComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: RootNodeConfigComponent, isStandalone: true, selector: "c8y-root-node-config", inputs: { config: "config", disabled: "disabled" }, outputs: { onUpdate: "onUpdate" }, ngImport: i0, template: "<div class=\"col-sm-6\">\n <label title=\"{{ 'Current top level nodes' | translate }}\" translate>\n Current top level nodes\n </label>\n <c8y-list-group class=\"separator-top\">\n <c8y-li *ngIf=\"config.rootNodes.length === 0\">\n <c8y-ui-empty-state\n [icon]=\"'folder-open'\"\n [title]=\"'No top level nodes set.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </c8y-li>\n <c8y-li *ngFor=\"let node of config.rootNodes; let index = index\">\n <c8y-li-icon icon=\"c8y-group\"></c8y-li-icon>\n <div class=\"content-flex-30\">\n <div class=\"col-6\">\n <div class=\"text-truncate\" title=\"{{ node.name }}\">\n {{ node.name }}\n </div>\n </div>\n <div class=\"col-4\">\n <label class=\"c8y-switch c8y-switch--inline d-flex\" title=\"{{ 'Hide devices' | translate }}\">\n <input\n type=\"checkbox\"\n [(ngModel)]=\"node.hideDevices\"\n name=\"node.{{ index }}.hideDevices\"\n (change)=\"onUpdate.emit()\"\n [disabled]=\"disabled\"\n />\n <span></span>\n <small class=\"text-truncate a-s-center l-h-1\">{{ 'Hide devices' | translate }}</small>\n </label>\n </div>\n <div class=\"col-2 text-right\">\n <div class=\"d-flex fit-w\">\n <button\n class=\"btn-dot btn-dot--danger m-l-auto\"\n type=\"button\"\n [attr.aria-label]=\"'Remove' | translate\"\n tooltip=\"{{ 'Remove' | translate }}\"\n [disabled]=\"disabled\"\n [delay]=\"500\"\n (click)=\"removeNavigatorNode(node)\"\n >\n <i c8yIcon=\"minus-circle\"></i>\n </button>\n </div>\n </div>\n </div>\n </c8y-li>\n </c8y-list-group>\n</div>\n\n<div class=\"col-sm-6 col-md-5\" style=\"height: calc(100vh - 430px)\">\n <label title=\"{{ 'Select top level nodes' | translate }}\" translate>Select top level nodes</label>\n <c8y-asset-selector\n [config]=\"{ groupsOnly: true, multi: true, groupsSelectable: true }\"\n [(ngModel)]=\"config.rootNodes\"\n [disabled]=\"disabled\"\n (onSelected)=\"onUpdate.emit()\"\n name=\"rootNodes\"\n class=\"border-top d-block\"\n ></c8y-asset-selector>\n</div>\n", dependencies: [{ kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: ListGroupComponent, selector: "c8y-list-group" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i5.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "component", type: AssetSelectorComponent, selector: "c8y-asset-selector", inputs: ["config", "active", "index", "asset", "selectedDevice", "selected", "rootNode", "selectedItems", "container", "isNodeSelectable", "disabled"], outputs: ["onSelected", "onClearSelected", "onRowSelected", "onLoad"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RootNodeConfigComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-root-node-config', imports: [ C8yTranslateDirective, ListGroupComponent, NgIf, ListItemComponent, EmptyStateComponent, NgFor, ListItemIconComponent, FormsModule, TooltipDirective, IconDirective, AssetSelectorComponent, C8yTranslatePipe ], template: "<div class=\"col-sm-6\">\n <label title=\"{{ 'Current top level nodes' | translate }}\" translate>\n Current top level nodes\n </label>\n <c8y-list-group class=\"separator-top\">\n <c8y-li *ngIf=\"config.rootNodes.length === 0\">\n <c8y-ui-empty-state\n [icon]=\"'folder-open'\"\n [title]=\"'No top level nodes set.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </c8y-li>\n <c8y-li *ngFor=\"let node of config.rootNodes; let index = index\">\n <c8y-li-icon icon=\"c8y-group\"></c8y-li-icon>\n <div class=\"content-flex-30\">\n <div class=\"col-6\">\n <div class=\"text-truncate\" title=\"{{ node.name }}\">\n {{ node.name }}\n </div>\n </div>\n <div class=\"col-4\">\n <label class=\"c8y-switch c8y-switch--inline d-flex\" title=\"{{ 'Hide devices' | translate }}\">\n <input\n type=\"checkbox\"\n [(ngModel)]=\"node.hideDevices\"\n name=\"node.{{ index }}.hideDevices\"\n (change)=\"onUpdate.emit()\"\n [disabled]=\"disabled\"\n />\n <span></span>\n <small class=\"text-truncate a-s-center l-h-1\">{{ 'Hide devices' | translate }}</small>\n </label>\n </div>\n <div class=\"col-2 text-right\">\n <div class=\"d-flex fit-w\">\n <button\n class=\"btn-dot btn-dot--danger m-l-auto\"\n type=\"button\"\n [attr.aria-label]=\"'Remove' | translate\"\n tooltip=\"{{ 'Remove' | translate }}\"\n [disabled]=\"disabled\"\n [delay]=\"500\"\n (click)=\"removeNavigatorNode(node)\"\n >\n <i c8yIcon=\"minus-circle\"></i>\n </button>\n </div>\n </div>\n </div>\n </c8y-li>\n </c8y-list-group>\n</div>\n\n<div class=\"col-sm-6 col-md-5\" style=\"height: calc(100vh - 430px)\">\n <label title=\"{{ 'Select top level nodes' | translate }}\" translate>Select top level nodes</label>\n <c8y-asset-selector\n [config]=\"{ groupsOnly: true, multi: true, groupsSelectable: true }\"\n [(ngModel)]=\"config.rootNodes\"\n [disabled]=\"disabled\"\n (onSelected)=\"onUpdate.emit()\"\n name=\"rootNodes\"\n class=\"border-top d-block\"\n ></c8y-asset-selector>\n</div>\n" }] }], propDecorators: { config: [{ type: Input }], disabled: [{ type: Input }], onUpdate: [{ type: Output }] } }); class HomeDashboardConfigComponent { /** * @ignore */ constructor(cockpitConfigService) { this.cockpitConfigService = cockpitConfigService; /** * The types of dashboard that can be configured. */ this.homeDashboardTypes = HomeDashboardType; } /** * @ignore */ dashboardChange(selected, type) { if (!selected) { return; } switch (type) { case this.homeDashboardTypes.DEFAULT: { this.config.homeDashboardName = DEFAULT_HOME_DASHBOARD_NAME; this.config.userSpecificHomeDashboard = false; break; } case this.homeDashboardTypes.APP: { this.config.homeDashboardName = this.cockpitConfigService.getAppDashboardName(); this.config.userSpecificHomeDashboard = false; break; } case this.homeDashboardTypes.USER: { this.config.homeDashboardName = USER_HOME_DASHBOARD_NAME; this.config.userSpecificHomeDashboard = true; break; } } } /** * @ignore */ verifySelected(type) { if (type === this.homeDashboardTypes.USER) { return this.config.userSpecificHomeDashboard; } if (type === this.homeDashboardTypes.DEFAULT) { return this.config.homeDashboardName === DEFAULT_HOME_DASHBOARD_NAME; } return this.config.homeDashboardName === this.cockpitConfigService.getAppDashboardName(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: HomeDashboardConfigComponent, deps: [{ token: CockpitConfigService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: HomeDashboardConfigComponent, isStandalone: true, selector: "c8y-home-dashboard-config", inputs: { config: "config" }, ngImport: i0, template: "<c8y-list-group>\n <c8y-li data-cy=\"home-dashboard-config--dashboard-list\">\n <c8y-li-radio\n (onSelect)=\"dashboardChange($event, homeDashboardTypes.DEFAULT)\"\n [selected]=\"verifySelected(homeDashboardTypes.DEFAULT)\"\n ></c8y-li-radio>\n <p translate>Default home dashboard</p>\n <small translate>Changes done in the home dashboard are reflected across the platform.</small>\n </c8y-li>\n <c8y-li data-cy=\"home-dashboard-config--dashboard-list\">\n <c8y-li-radio\n (onSelect)=\"dashboardChange($event, homeDashboardTypes.APP)\"\n [selected]=\"verifySelected(homeDashboardTypes.APP)\"\n ></c8y-li-radio>\n <p translate>Custom home dashboard</p>\n <small translate>\n Changes done to the home dashboard are reflected only in the current application.\n </small>\n </c8y-li>\n <c8y-li data-cy=\"home-dashboard-config--dashboard-list\">\n <c8y-li-radio\n (onSelect)=\"dashboardChange($event, homeDashboardTypes.USER)\"\n [selected]=\"verifySelected(homeDashboardTypes.USER)\"\n ></c8y-li-radio>\n <p translate>User home dashboard</p>\n <small translate>\n Changes done to the home dashboard are reflected only for the current user. NOTE: This user\n needs to have inventory write permission.\n </small>\n </c8y-li>\n</c8y-list-group>\n", dependencies: [{ kind: "component", type: ListGroupComponent, selector: "c8y-list-group" }, { kind: "component", type: ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: ListItemRadioComponent, selector: "c8y-list-item-radio, c8y-li-radio", inputs: ["selected", "name", "disabled", "value"], outputs: ["onSelect"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: HomeDashboardConfigComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-home-dashboard-config', imports: [ListGroupComponent, ListItemComponent, ListItemRadioComponent, C8yTranslateDirective], template: "<c8y-list-group>\n <c8y-li data-cy=\"home-dashboard-config--dashboard-list\">\n <c8y-li-radio\n (onSelect)=\"dashboardChange($event, homeDashboardTypes.DEFAULT)\"\n [selected]=\"verifySelected(homeDashboardTypes.DEFAULT)\"\n ></c8y-li-radio>\n <p translate>Default home dashboard</p>\n <small translate>Changes done in the home dashboard are reflected across the platform.</small>\n </c8y-li>\n <c8y-li data-cy=\"home-dashboard-config--dashboard-list\">\n <c8y-li-radio\n (onSelect)=\"dashboardChange($event, homeDashboardTypes.APP)\"\n [selected]=\"verifySelected(homeDashboardTypes.APP)\"\n ></c8y-li-radio>\n <p translate>Custom home dashboard</p>\n <small translate>\n Changes done to the home dashboard are reflected only in the current application.\n </small>\n </c8y-li>\n <c8y-li data-cy=\"home-dashboard-config--dashboard-list\">\n <c8y-li-radio\n (onSelect)=\"dashboardChange($event, homeDashboardTypes.USER)\"\n [selected]=\"verifySelected(homeDashboardTypes.USER)\"\n ></c8y-li-radio>\n <p translate>User home dashboard</p>\n <small translate>\n Changes done to the home dashboard are reflected only for the current user. NOTE: This user\n needs to have inventory write permission.\n </small>\n </c8y-li>\n</c8y-list-group>\n" }] }], ctorParameters: () => [{ type: CockpitConfigService }], propDecor