@c8y/ngx-components 1023.17.16 → 1023.17.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -25,11 +25,11 @@ class GroupBreadcrumbEllipsisComponent {
25
25
  this.isLoading = false;
26
26
  }
27
27
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: GroupBreadcrumbEllipsisComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
28
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: GroupBreadcrumbEllipsisComponent, isStandalone: true, selector: "c8y-group-breadcrumb-ellipsis", ngImport: i0, template: "<button\n class=\"btn-clean btn btn-xs\"\n [ngStyle]=\"{ cursor: isLoading ? 'wait' : 'pointer' }\"\n title=\"{{ 'Show all paths' | translate }}\"\n type=\"button\"\n (click)=\"!isLoading && onClick()\"\n>\n ...\n</button>\n", dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
28
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: GroupBreadcrumbEllipsisComponent, isStandalone: true, selector: "c8y-group-breadcrumb-ellipsis", ngImport: i0, template: "<button\n class=\"btn-clean btn btn-xs p-t-0 p-b-0\"\n [ngStyle]=\"{ cursor: isLoading ? 'wait' : 'pointer' }\"\n title=\"{{ 'Show all paths' | translate }}\"\n type=\"button\"\n (click)=\"!isLoading && onClick()\"\n>\n ...\n</button>\n", dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
29
29
  }
30
30
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: GroupBreadcrumbEllipsisComponent, decorators: [{
31
31
  type: Component,
32
- args: [{ selector: 'c8y-group-breadcrumb-ellipsis', standalone: true, imports: [NgStyle, C8yTranslatePipe], template: "<button\n class=\"btn-clean btn btn-xs\"\n [ngStyle]=\"{ cursor: isLoading ? 'wait' : 'pointer' }\"\n title=\"{{ 'Show all paths' | translate }}\"\n type=\"button\"\n (click)=\"!isLoading && onClick()\"\n>\n ...\n</button>\n" }]
32
+ args: [{ selector: 'c8y-group-breadcrumb-ellipsis', standalone: true, imports: [NgStyle, C8yTranslatePipe], template: "<button\n class=\"btn-clean btn btn-xs p-t-0 p-b-0\"\n [ngStyle]=\"{ cursor: isLoading ? 'wait' : 'pointer' }\"\n title=\"{{ 'Show all paths' | translate }}\"\n type=\"button\"\n (click)=\"!isLoading && onClick()\"\n>\n ...\n</button>\n" }]
33
33
  }] });
34
34
 
35
35
  class GroupBreadcrumbFactory {
@@ -1 +1 @@
1
- {"version":3,"file":"c8y-ngx-components-group-breadcrumbs.mjs","sources":["../../group-breadcrumbs/group-breadcrumb.tokens.ts","../../group-breadcrumbs/group-breadcrumb-ellipsis.component.ts","../../group-breadcrumbs/group-breadcrumb-ellipsis.component.html","../../group-breadcrumbs/group-breadcrumb.factory.ts","../../group-breadcrumbs/index.ts","../../group-breadcrumbs/c8y-ngx-components-group-breadcrumbs.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport { IManagedObject } from '@c8y/client';\nimport { GroupBreadcrumbFactory } from './group-breadcrumb.factory';\n\nexport const GROUP_BREADCRUMB_CONTEXT_DATA = new InjectionToken<IManagedObject>(\n 'GROUP_BREADCRUMB_CONTEXT_DATA'\n);\n\nexport const GROUP_BREADCRUMB_FACTORY = new InjectionToken<GroupBreadcrumbFactory>(\n 'GROUP_BREADCRUMB_FACTORY'\n);\n","import { Component, inject } from '@angular/core';\nimport { NgStyle } from '@angular/common';\nimport { GROUP_BREADCRUMB_CONTEXT_DATA, GROUP_BREADCRUMB_FACTORY } from './group-breadcrumb.tokens';\nimport { AssetHierarchyService, C8yTranslatePipe } from '@c8y/ngx-components';\n\n@Component({\n selector: 'c8y-group-breadcrumb-ellipsis',\n templateUrl: './group-breadcrumb-ellipsis.component.html',\n standalone: true,\n imports: [NgStyle, C8yTranslatePipe]\n})\nexport class GroupBreadcrumbEllipsisComponent {\n isLoading = false;\n\n private assetHierarchyService = inject(AssetHierarchyService);\n private contextData = inject(GROUP_BREADCRUMB_CONTEXT_DATA);\n private factory = inject(GROUP_BREADCRUMB_FACTORY);\n\n async onClick() {\n this.isLoading = true;\n const ancestorPaths = await this.assetHierarchyService.getAncestorPaths(this.contextData.id);\n this.factory.setAncestorPaths(ancestorPaths);\n this.isLoading = false;\n }\n}\n","<button\n class=\"btn-clean btn btn-xs\"\n [ngStyle]=\"{ cursor: isLoading ? 'wait' : 'pointer' }\"\n title=\"{{ 'Show all paths' | translate }}\"\n type=\"button\"\n (click)=\"!isLoading && onClick()\"\n>\n ...\n</button>\n","import { Injectable, Injector, inject } from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\nimport { IManagedObject } from '@c8y/client';\nimport { firstValueFrom } from 'rxjs';\nimport { GroupBreadcrumbEllipsisComponent } from './group-breadcrumb-ellipsis.component';\nimport { GROUP_BREADCRUMB_CONTEXT_DATA, GROUP_BREADCRUMB_FACTORY } from './group-breadcrumb.tokens';\nimport { TranslateService } from '@ngx-translate/core';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { cloneDeep } from 'lodash-es';\nimport {\n Breadcrumb,\n BreadcrumbItemWithLabel,\n BreadcrumbService,\n ContextRouteService,\n ExtensionFactory,\n GroupService,\n RouterService,\n ViewContext\n} from '@c8y/ngx-components';\nimport { AssetNodeService } from '@c8y/ngx-components/module-federation-exports/assets-navigator';\n\n@Injectable()\nexport class GroupBreadcrumbFactory implements ExtensionFactory<Breadcrumb> {\n private readonly SUPPORTED_CONTEXTS = [ViewContext.Device, ViewContext.Group];\n private readonly GROUP_ICON = 'c8y-group';\n private readonly DEVICE_ICON = 'data-transfer';\n private deviceDefaultLabel = gettext('Device {{id}}');\n\n private currentBreadcrumbData: {\n contextData: IManagedObject;\n breadcrumbs: Breadcrumb[];\n ancestorPaths?: IManagedObject[][];\n } | null = null;\n\n private breadcrumbService = inject(BreadcrumbService);\n private routerService = inject(RouterService);\n private groupService = inject(GroupService);\n private translateService = inject(TranslateService);\n private injector = inject(Injector);\n private contextRouteService = inject(ContextRouteService);\n private assetNodeService = inject(AssetNodeService);\n\n async get(activatedRoute?: ActivatedRoute): Promise<Breadcrumb[] | null> {\n const routeData = this.contextRouteService.getContextData(activatedRoute);\n const context = routeData?.context;\n const contextData = routeData?.contextData as IManagedObject;\n\n // Only show breadcrumbs for Device/Group contexts with contextData\n if (!this.SUPPORTED_CONTEXTS.includes(context) || !contextData) {\n return null;\n }\n\n // Check if same context as before\n const isSameContext = this.currentBreadcrumbData?.contextData?.id === contextData.id;\n\n // If same context and has ancestor paths loaded, return full breadcrumb\n if (isSameContext && this.currentBreadcrumbData?.ancestorPaths) {\n return this.buildFullBreadcrumb(this.currentBreadcrumbData.ancestorPaths);\n }\n\n // If same context but no ancestor paths, return existing ellipsis breadcrumb\n if (isSameContext && this.currentBreadcrumbData?.breadcrumbs) {\n return this.currentBreadcrumbData.breadcrumbs;\n }\n\n // New context - determine if root or nested\n const rootNodesResult = await firstValueFrom(this.assetNodeService.rootGroups$);\n const rootNodes = rootNodesResult.data || [];\n\n const isRootNode = rootNodes.some(node => node.id === contextData.id);\n const icon = await this.getIcon(contextData);\n\n // Root node: simple breadcrumb\n if (isRootNode) {\n const breadcrumbs: Breadcrumb[] = [\n {\n items: [\n {\n label: gettext('Groups'),\n path: 'group',\n icon: this.GROUP_ICON\n },\n {\n label: contextData.name,\n icon,\n path: ''\n }\n ]\n }\n ];\n\n this.currentBreadcrumbData = {\n contextData: cloneDeep(contextData),\n breadcrumbs\n };\n\n return breadcrumbs;\n }\n\n // Nested node: breadcrumb with ellipsis component\n const ellipsisInjector = Injector.create({\n parent: this.injector,\n providers: [\n { provide: GROUP_BREADCRUMB_CONTEXT_DATA, useValue: contextData },\n { provide: GROUP_BREADCRUMB_FACTORY, useValue: this }\n ]\n });\n\n const breadcrumbs: Breadcrumb[] = [\n {\n injector: ellipsisInjector,\n items: [\n {\n label: gettext('Groups'),\n path: 'group',\n icon: this.GROUP_ICON\n },\n {\n component: GroupBreadcrumbEllipsisComponent\n },\n {\n label:\n contextData.name ||\n this.translateService.instant(this.deviceDefaultLabel, { id: contextData.id }),\n icon,\n path: ''\n }\n ]\n }\n ];\n\n this.currentBreadcrumbData = {\n contextData: cloneDeep(contextData),\n breadcrumbs\n };\n\n return breadcrumbs;\n }\n\n setAncestorPaths(ancestorPaths: IManagedObject[][]) {\n if (!this.currentBreadcrumbData) {\n return;\n }\n\n this.currentBreadcrumbData.ancestorPaths = ancestorPaths;\n this.breadcrumbService.refresh(); // will trigger factory `get` once again\n }\n\n private async buildFullBreadcrumb(ancestorPaths: IManagedObject[][]): Promise<Breadcrumb[]> {\n const converted = await this.convertToBreadcrumbItems(ancestorPaths);\n const sorted = this.sortBreadcrumbItems(converted);\n\n const breadcrumbs: Breadcrumb[] = sorted.map(\n bc =>\n ({\n items: [\n {\n label: gettext('Groups'),\n path: 'group',\n icon: this.GROUP_ICON\n },\n ...bc.map((item, index) => ({\n ...item,\n path: index === bc.length - 1 ? undefined : item.path\n }))\n ],\n forceDropdownOpen: sorted.length > 1\n }) as Breadcrumb\n );\n\n this.currentBreadcrumbData.breadcrumbs = breadcrumbs;\n\n return breadcrumbs;\n }\n\n private async convertToBreadcrumbItems(\n ancestorPaths: IManagedObject[][]\n ): Promise<BreadcrumbItemWithLabel[][]> {\n return Promise.all(\n ancestorPaths.map(async path =>\n Promise.all(\n path.map(async managedObject => ({\n label:\n managedObject.name ||\n this.translateService.instant(this.deviceDefaultLabel, { id: managedObject.id }),\n path: '/' + this.routerService.getHref(managedObject, ''),\n icon: await this.getIcon(managedObject)\n }))\n )\n )\n );\n }\n\n private sortBreadcrumbItems(\n breadcrumbItems: BreadcrumbItemWithLabel[][]\n ): BreadcrumbItemWithLabel[][] {\n const breadcrumbs: Breadcrumb[] = breadcrumbItems.map(items => ({ items }));\n const sorted = this.breadcrumbService.sortByPreferredPath(breadcrumbs);\n return sorted.map(breadcrumb => breadcrumb.items as BreadcrumbItemWithLabel[]);\n }\n\n private async getIcon(managedObject: IManagedObject): Promise<string> {\n if (this.groupService.isDevice(managedObject)) {\n return this.DEVICE_ICON;\n }\n return this.groupService.getIcon(managedObject);\n }\n}\n","import { hookBreadcrumb } from '@c8y/ngx-components';\nimport { GroupBreadcrumbFactory } from './group-breadcrumb.factory';\n\nexport const groupBreadcrumbsProviders = [hookBreadcrumb(GroupBreadcrumbFactory)];\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"c8y-ngx-components-group-breadcrumbs.mjs","sources":["../../group-breadcrumbs/group-breadcrumb.tokens.ts","../../group-breadcrumbs/group-breadcrumb-ellipsis.component.ts","../../group-breadcrumbs/group-breadcrumb-ellipsis.component.html","../../group-breadcrumbs/group-breadcrumb.factory.ts","../../group-breadcrumbs/index.ts","../../group-breadcrumbs/c8y-ngx-components-group-breadcrumbs.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport { IManagedObject } from '@c8y/client';\nimport { GroupBreadcrumbFactory } from './group-breadcrumb.factory';\n\nexport const GROUP_BREADCRUMB_CONTEXT_DATA = new InjectionToken<IManagedObject>(\n 'GROUP_BREADCRUMB_CONTEXT_DATA'\n);\n\nexport const GROUP_BREADCRUMB_FACTORY = new InjectionToken<GroupBreadcrumbFactory>(\n 'GROUP_BREADCRUMB_FACTORY'\n);\n","import { Component, inject } from '@angular/core';\nimport { NgStyle } from '@angular/common';\nimport { GROUP_BREADCRUMB_CONTEXT_DATA, GROUP_BREADCRUMB_FACTORY } from './group-breadcrumb.tokens';\nimport { AssetHierarchyService, C8yTranslatePipe } from '@c8y/ngx-components';\n\n@Component({\n selector: 'c8y-group-breadcrumb-ellipsis',\n templateUrl: './group-breadcrumb-ellipsis.component.html',\n standalone: true,\n imports: [NgStyle, C8yTranslatePipe]\n})\nexport class GroupBreadcrumbEllipsisComponent {\n isLoading = false;\n\n private assetHierarchyService = inject(AssetHierarchyService);\n private contextData = inject(GROUP_BREADCRUMB_CONTEXT_DATA);\n private factory = inject(GROUP_BREADCRUMB_FACTORY);\n\n async onClick() {\n this.isLoading = true;\n const ancestorPaths = await this.assetHierarchyService.getAncestorPaths(this.contextData.id);\n this.factory.setAncestorPaths(ancestorPaths);\n this.isLoading = false;\n }\n}\n","<button\n class=\"btn-clean btn btn-xs p-t-0 p-b-0\"\n [ngStyle]=\"{ cursor: isLoading ? 'wait' : 'pointer' }\"\n title=\"{{ 'Show all paths' | translate }}\"\n type=\"button\"\n (click)=\"!isLoading && onClick()\"\n>\n ...\n</button>\n","import { Injectable, Injector, inject } from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\nimport { IManagedObject } from '@c8y/client';\nimport { firstValueFrom } from 'rxjs';\nimport { GroupBreadcrumbEllipsisComponent } from './group-breadcrumb-ellipsis.component';\nimport { GROUP_BREADCRUMB_CONTEXT_DATA, GROUP_BREADCRUMB_FACTORY } from './group-breadcrumb.tokens';\nimport { TranslateService } from '@ngx-translate/core';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { cloneDeep } from 'lodash-es';\nimport {\n Breadcrumb,\n BreadcrumbItemWithLabel,\n BreadcrumbService,\n ContextRouteService,\n ExtensionFactory,\n GroupService,\n RouterService,\n ViewContext\n} from '@c8y/ngx-components';\nimport { AssetNodeService } from '@c8y/ngx-components/module-federation-exports/assets-navigator';\n\n@Injectable()\nexport class GroupBreadcrumbFactory implements ExtensionFactory<Breadcrumb> {\n private readonly SUPPORTED_CONTEXTS = [ViewContext.Device, ViewContext.Group];\n private readonly GROUP_ICON = 'c8y-group';\n private readonly DEVICE_ICON = 'data-transfer';\n private deviceDefaultLabel = gettext('Device {{id}}');\n\n private currentBreadcrumbData: {\n contextData: IManagedObject;\n breadcrumbs: Breadcrumb[];\n ancestorPaths?: IManagedObject[][];\n } | null = null;\n\n private breadcrumbService = inject(BreadcrumbService);\n private routerService = inject(RouterService);\n private groupService = inject(GroupService);\n private translateService = inject(TranslateService);\n private injector = inject(Injector);\n private contextRouteService = inject(ContextRouteService);\n private assetNodeService = inject(AssetNodeService);\n\n async get(activatedRoute?: ActivatedRoute): Promise<Breadcrumb[] | null> {\n const routeData = this.contextRouteService.getContextData(activatedRoute);\n const context = routeData?.context;\n const contextData = routeData?.contextData as IManagedObject;\n\n // Only show breadcrumbs for Device/Group contexts with contextData\n if (!this.SUPPORTED_CONTEXTS.includes(context) || !contextData) {\n return null;\n }\n\n // Check if same context as before\n const isSameContext = this.currentBreadcrumbData?.contextData?.id === contextData.id;\n\n // If same context and has ancestor paths loaded, return full breadcrumb\n if (isSameContext && this.currentBreadcrumbData?.ancestorPaths) {\n return this.buildFullBreadcrumb(this.currentBreadcrumbData.ancestorPaths);\n }\n\n // If same context but no ancestor paths, return existing ellipsis breadcrumb\n if (isSameContext && this.currentBreadcrumbData?.breadcrumbs) {\n return this.currentBreadcrumbData.breadcrumbs;\n }\n\n // New context - determine if root or nested\n const rootNodesResult = await firstValueFrom(this.assetNodeService.rootGroups$);\n const rootNodes = rootNodesResult.data || [];\n\n const isRootNode = rootNodes.some(node => node.id === contextData.id);\n const icon = await this.getIcon(contextData);\n\n // Root node: simple breadcrumb\n if (isRootNode) {\n const breadcrumbs: Breadcrumb[] = [\n {\n items: [\n {\n label: gettext('Groups'),\n path: 'group',\n icon: this.GROUP_ICON\n },\n {\n label: contextData.name,\n icon,\n path: ''\n }\n ]\n }\n ];\n\n this.currentBreadcrumbData = {\n contextData: cloneDeep(contextData),\n breadcrumbs\n };\n\n return breadcrumbs;\n }\n\n // Nested node: breadcrumb with ellipsis component\n const ellipsisInjector = Injector.create({\n parent: this.injector,\n providers: [\n { provide: GROUP_BREADCRUMB_CONTEXT_DATA, useValue: contextData },\n { provide: GROUP_BREADCRUMB_FACTORY, useValue: this }\n ]\n });\n\n const breadcrumbs: Breadcrumb[] = [\n {\n injector: ellipsisInjector,\n items: [\n {\n label: gettext('Groups'),\n path: 'group',\n icon: this.GROUP_ICON\n },\n {\n component: GroupBreadcrumbEllipsisComponent\n },\n {\n label:\n contextData.name ||\n this.translateService.instant(this.deviceDefaultLabel, { id: contextData.id }),\n icon,\n path: ''\n }\n ]\n }\n ];\n\n this.currentBreadcrumbData = {\n contextData: cloneDeep(contextData),\n breadcrumbs\n };\n\n return breadcrumbs;\n }\n\n setAncestorPaths(ancestorPaths: IManagedObject[][]) {\n if (!this.currentBreadcrumbData) {\n return;\n }\n\n this.currentBreadcrumbData.ancestorPaths = ancestorPaths;\n this.breadcrumbService.refresh(); // will trigger factory `get` once again\n }\n\n private async buildFullBreadcrumb(ancestorPaths: IManagedObject[][]): Promise<Breadcrumb[]> {\n const converted = await this.convertToBreadcrumbItems(ancestorPaths);\n const sorted = this.sortBreadcrumbItems(converted);\n\n const breadcrumbs: Breadcrumb[] = sorted.map(\n bc =>\n ({\n items: [\n {\n label: gettext('Groups'),\n path: 'group',\n icon: this.GROUP_ICON\n },\n ...bc.map((item, index) => ({\n ...item,\n path: index === bc.length - 1 ? undefined : item.path\n }))\n ],\n forceDropdownOpen: sorted.length > 1\n }) as Breadcrumb\n );\n\n this.currentBreadcrumbData.breadcrumbs = breadcrumbs;\n\n return breadcrumbs;\n }\n\n private async convertToBreadcrumbItems(\n ancestorPaths: IManagedObject[][]\n ): Promise<BreadcrumbItemWithLabel[][]> {\n return Promise.all(\n ancestorPaths.map(async path =>\n Promise.all(\n path.map(async managedObject => ({\n label:\n managedObject.name ||\n this.translateService.instant(this.deviceDefaultLabel, { id: managedObject.id }),\n path: '/' + this.routerService.getHref(managedObject, ''),\n icon: await this.getIcon(managedObject)\n }))\n )\n )\n );\n }\n\n private sortBreadcrumbItems(\n breadcrumbItems: BreadcrumbItemWithLabel[][]\n ): BreadcrumbItemWithLabel[][] {\n const breadcrumbs: Breadcrumb[] = breadcrumbItems.map(items => ({ items }));\n const sorted = this.breadcrumbService.sortByPreferredPath(breadcrumbs);\n return sorted.map(breadcrumb => breadcrumb.items as BreadcrumbItemWithLabel[]);\n }\n\n private async getIcon(managedObject: IManagedObject): Promise<string> {\n if (this.groupService.isDevice(managedObject)) {\n return this.DEVICE_ICON;\n }\n return this.groupService.getIcon(managedObject);\n }\n}\n","import { hookBreadcrumb } from '@c8y/ngx-components';\nimport { GroupBreadcrumbFactory } from './group-breadcrumb.factory';\n\nexport const groupBreadcrumbsProviders = [hookBreadcrumb(GroupBreadcrumbFactory)];\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -3,14 +3,14 @@ import { Pipe, EventEmitter, Input, Output, Component, Injectable, forwardRef, N
3
3
  import * as i1 from '@angular/forms';
4
4
  import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
5
5
  import * as i2 from '@c8y/ngx-components';
6
- import { IconDirective, C8yTranslateDirective, C8yTranslatePipe, CommonModule, DropAreaModule } from '@c8y/ngx-components';
6
+ import { IconDirective, C8yTranslateDirective, EmptyStateComponent, C8yTranslatePipe, CommonModule, DropAreaModule } from '@c8y/ngx-components';
7
7
  import { TooltipDirective, TooltipModule } from 'ngx-bootstrap/tooltip';
8
8
  import { gettext } from '@c8y/ngx-components/gettext';
9
9
  import * as i1$1 from 'ngx-bootstrap/modal';
10
10
  import { BehaviorSubject, defer, from, combineLatest } from 'rxjs';
11
11
  import { map, shareReplay, debounceTime, startWith } from 'rxjs/operators';
12
12
  import { clone } from 'lodash-es';
13
- import { NgIf, NgFor, NgClass, AsyncPipe } from '@angular/common';
13
+ import { NgClass, AsyncPipe, NgIf } from '@angular/common';
14
14
  import { PRODUCT_EXPERIENCE_ICON_SELECTOR } from '@c8y/ngx-components/icon-selector/model';
15
15
 
16
16
  class IconNamePipe {
@@ -76,21 +76,20 @@ class IconSelectorComponent {
76
76
  this.onSelect.emit(icon[0]);
77
77
  }
78
78
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: IconSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
79
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: IconSelectorComponent, isStandalone: true, selector: "c8y-icon-selector", inputs: { iconCategoriesToExclude: "iconCategoriesToExclude", showIconClass: "showIconClass", selectedIcon: "selectedIcon" }, outputs: { onSelect: "onSelect" }, ngImport: i0, template: "<div class=\"p-l-24 p-r-24 p-t-8 p-b-8 separator-bottom\">\n <div class=\"row d-flex-sm\">\n <div class=\"col-sm-6 m-b-8\">\n <div class=\"input-group-search input-group\" style=\"width: auto\">\n <input\n type=\"search\"\n class=\"form-control\"\n id=\"filter-icons\"\n [ngModel]=\"searchTerm$ | async\"\n (ngModelChange)=\"onSearchChange($event)\"\n placeholder=\"{{ 'Type to filter icons\u2026' | translate }}\"\n />\n <ng-template #searchIcon>\n <span class=\"input-group-addon\">\n <i c8yIcon=\"search\"></i>\n </span>\n </ng-template>\n <span\n class=\"input-group-addon pointer\"\n *ngIf=\"searchTerm$ | async; else searchIcon\"\n (click)=\"onSearchChange('')\"\n >\n <i c8yIcon=\"times\"></i>\n </span>\n </div>\n </div>\n <div class=\"col-sm-6 m-b-8 text-right\">\n <div class=\"d-inline-flex a-i-center text-left\">\n <label class=\"m-b-0 m-r-8 flex-no-shrink\" translate>Filter by type</label>\n <div class=\"c8y-select-wrapper\">\n <select\n id=\"exampleSelect\"\n class=\"form-control\"\n [ngModel]=\"selectedIconCategory$ | async\"\n (ngModelChange)=\"onCategoryFilterChanged($event)\"\n >\n <option *ngFor=\"let category of availableIconCategories$ | async\" [ngValue]=\"category\">\n {{ category | translate }}\n </option>\n </select>\n <span></span>\n </div>\n </div>\n </div>\n </div>\n</div>\n<div class=\"modal-inner-scroll\">\n <div class=\"modal-body\" style=\"height: calc(100vh - 293px)\">\n <div class=\"dtm-icon-grid\">\n <div *ngFor=\"let iconDefinition of filteredIcons$ | async\" class=\"d-contents\">\n <div class=\"legend form-block center grid__col--fullspan\">\n {{ iconDefinition.label | translate }}\n </div>\n\n <div class=\"d-contents\" *ngFor=\"let icon of iconDefinition.icons\">\n <div\n class=\"dtm-icon-grid__item\"\n [ngClass]=\"{\n 'dtm-icon-grid__item--selected': selectedIcon && icon[0] === selectedIcon\n }\"\n >\n <button (click)=\"onIconClicked(icon)\" class=\"dtm-icon-grid__btn\" [title]=\"icon[0] | iconName\">\n <i [c8yIcon]=\"icon[0]\" class=\"d-block icon-40\"></i>\n <small *ngIf=\"showIconClass\" class=\"text-break-word\">{{ icon[0] | iconName }}</small>\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: IconNamePipe, name: "iconName" }] }); }
79
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: IconSelectorComponent, isStandalone: true, selector: "c8y-icon-selector", inputs: { iconCategoriesToExclude: "iconCategoriesToExclude", showIconClass: "showIconClass", selectedIcon: "selectedIcon" }, outputs: { onSelect: "onSelect" }, ngImport: i0, template: "<div class=\"p-l-24 p-r-24 p-t-8 p-b-8 separator-bottom\">\n <div class=\"row d-flex-sm\">\n <div class=\"col-sm-6 m-b-8\">\n <div\n class=\"input-group-search input-group\"\n style=\"width: auto\"\n >\n <input\n class=\"form-control\"\n id=\"filter-icons\"\n placeholder=\"{{ 'Type to filter icons\u2026' | translate }}\"\n type=\"search\"\n [ngModel]=\"searchTerm$ | async\"\n (ngModelChange)=\"onSearchChange($event)\"\n />\n @if (searchTerm$ | async) {\n <span\n class=\"input-group-addon pointer\"\n (click)=\"onSearchChange('')\"\n >\n <i c8yIcon=\"times\"></i>\n </span>\n } @else {\n <span class=\"input-group-addon\">\n <i c8yIcon=\"search\"></i>\n </span>\n }\n </div>\n </div>\n <div class=\"col-sm-6 m-b-8 text-right\">\n <div class=\"d-inline-flex a-i-center text-left\">\n <label\n class=\"m-b-0 m-r-8 flex-no-shrink\"\n translate\n >\n Filter by type\n </label>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control\"\n id=\"exampleSelect\"\n [ngModel]=\"selectedIconCategory$ | async\"\n (ngModelChange)=\"onCategoryFilterChanged($event)\"\n >\n @for (category of availableIconCategories$ | async; track category) {\n <option [ngValue]=\"category\">\n {{ category | translate }}\n </option>\n }\n </select>\n <span></span>\n </div>\n </div>\n </div>\n </div>\n</div>\n<div class=\"modal-inner-scroll\">\n <div\n class=\"modal-body\"\n style=\"height: calc(100vh - 293px)\"\n >\n <div class=\"dtm-icon-grid\">\n @for (iconDefinition of filteredIcons$ | async; track iconDefinition) {\n <div class=\"d-contents\">\n <div class=\"legend form-block center grid__col--fullspan\">\n {{ iconDefinition.label | translate }}\n </div>\n\n @for (icon of iconDefinition.icons; track icon) {\n <div class=\"d-contents\">\n <div\n class=\"dtm-icon-grid__item\"\n [ngClass]=\"{\n 'dtm-icon-grid__item--selected': selectedIcon && icon[0] === selectedIcon\n }\"\n >\n <button\n class=\"dtm-icon-grid__btn\"\n [title]=\"icon[0] | iconName\"\n (click)=\"onIconClicked(icon)\"\n >\n <i\n class=\"d-block icon-40 c8y-icon-duocolor\"\n [c8yIcon]=\"icon[0]\"\n ></i>\n @if (showIconClass) {\n <small class=\"text-break-word\">\n {{ icon[0] | iconName }}\n </small>\n }\n </button>\n </div>\n </div>\n }\n </div>\n } @empty {\n <c8y-ui-empty-state\n icon=\"search\"\n style=\"grid-column: 1 / 3\"\n [title]=\"'No icons found' | translate\"\n [subtitle]=\"\n 'Try adjusting your search or filter to find what you\\'re looking for.' | translate\n \"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n }\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: IconNamePipe, name: "iconName" }] }); }
80
80
  }
81
81
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: IconSelectorComponent, decorators: [{
82
82
  type: Component,
83
83
  args: [{ selector: 'c8y-icon-selector', imports: [
84
84
  FormsModule,
85
85
  IconDirective,
86
- NgIf,
87
86
  C8yTranslateDirective,
88
- NgFor,
89
- NgClass,
90
87
  C8yTranslatePipe,
91
88
  AsyncPipe,
92
- IconNamePipe
93
- ], template: "<div class=\"p-l-24 p-r-24 p-t-8 p-b-8 separator-bottom\">\n <div class=\"row d-flex-sm\">\n <div class=\"col-sm-6 m-b-8\">\n <div class=\"input-group-search input-group\" style=\"width: auto\">\n <input\n type=\"search\"\n class=\"form-control\"\n id=\"filter-icons\"\n [ngModel]=\"searchTerm$ | async\"\n (ngModelChange)=\"onSearchChange($event)\"\n placeholder=\"{{ 'Type to filter icons\u2026' | translate }}\"\n />\n <ng-template #searchIcon>\n <span class=\"input-group-addon\">\n <i c8yIcon=\"search\"></i>\n </span>\n </ng-template>\n <span\n class=\"input-group-addon pointer\"\n *ngIf=\"searchTerm$ | async; else searchIcon\"\n (click)=\"onSearchChange('')\"\n >\n <i c8yIcon=\"times\"></i>\n </span>\n </div>\n </div>\n <div class=\"col-sm-6 m-b-8 text-right\">\n <div class=\"d-inline-flex a-i-center text-left\">\n <label class=\"m-b-0 m-r-8 flex-no-shrink\" translate>Filter by type</label>\n <div class=\"c8y-select-wrapper\">\n <select\n id=\"exampleSelect\"\n class=\"form-control\"\n [ngModel]=\"selectedIconCategory$ | async\"\n (ngModelChange)=\"onCategoryFilterChanged($event)\"\n >\n <option *ngFor=\"let category of availableIconCategories$ | async\" [ngValue]=\"category\">\n {{ category | translate }}\n </option>\n </select>\n <span></span>\n </div>\n </div>\n </div>\n </div>\n</div>\n<div class=\"modal-inner-scroll\">\n <div class=\"modal-body\" style=\"height: calc(100vh - 293px)\">\n <div class=\"dtm-icon-grid\">\n <div *ngFor=\"let iconDefinition of filteredIcons$ | async\" class=\"d-contents\">\n <div class=\"legend form-block center grid__col--fullspan\">\n {{ iconDefinition.label | translate }}\n </div>\n\n <div class=\"d-contents\" *ngFor=\"let icon of iconDefinition.icons\">\n <div\n class=\"dtm-icon-grid__item\"\n [ngClass]=\"{\n 'dtm-icon-grid__item--selected': selectedIcon && icon[0] === selectedIcon\n }\"\n >\n <button (click)=\"onIconClicked(icon)\" class=\"dtm-icon-grid__btn\" [title]=\"icon[0] | iconName\">\n <i [c8yIcon]=\"icon[0]\" class=\"d-block icon-40\"></i>\n <small *ngIf=\"showIconClass\" class=\"text-break-word\">{{ icon[0] | iconName }}</small>\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n" }]
89
+ NgClass,
90
+ IconNamePipe,
91
+ EmptyStateComponent
92
+ ], template: "<div class=\"p-l-24 p-r-24 p-t-8 p-b-8 separator-bottom\">\n <div class=\"row d-flex-sm\">\n <div class=\"col-sm-6 m-b-8\">\n <div\n class=\"input-group-search input-group\"\n style=\"width: auto\"\n >\n <input\n class=\"form-control\"\n id=\"filter-icons\"\n placeholder=\"{{ 'Type to filter icons\u2026' | translate }}\"\n type=\"search\"\n [ngModel]=\"searchTerm$ | async\"\n (ngModelChange)=\"onSearchChange($event)\"\n />\n @if (searchTerm$ | async) {\n <span\n class=\"input-group-addon pointer\"\n (click)=\"onSearchChange('')\"\n >\n <i c8yIcon=\"times\"></i>\n </span>\n } @else {\n <span class=\"input-group-addon\">\n <i c8yIcon=\"search\"></i>\n </span>\n }\n </div>\n </div>\n <div class=\"col-sm-6 m-b-8 text-right\">\n <div class=\"d-inline-flex a-i-center text-left\">\n <label\n class=\"m-b-0 m-r-8 flex-no-shrink\"\n translate\n >\n Filter by type\n </label>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control\"\n id=\"exampleSelect\"\n [ngModel]=\"selectedIconCategory$ | async\"\n (ngModelChange)=\"onCategoryFilterChanged($event)\"\n >\n @for (category of availableIconCategories$ | async; track category) {\n <option [ngValue]=\"category\">\n {{ category | translate }}\n </option>\n }\n </select>\n <span></span>\n </div>\n </div>\n </div>\n </div>\n</div>\n<div class=\"modal-inner-scroll\">\n <div\n class=\"modal-body\"\n style=\"height: calc(100vh - 293px)\"\n >\n <div class=\"dtm-icon-grid\">\n @for (iconDefinition of filteredIcons$ | async; track iconDefinition) {\n <div class=\"d-contents\">\n <div class=\"legend form-block center grid__col--fullspan\">\n {{ iconDefinition.label | translate }}\n </div>\n\n @for (icon of iconDefinition.icons; track icon) {\n <div class=\"d-contents\">\n <div\n class=\"dtm-icon-grid__item\"\n [ngClass]=\"{\n 'dtm-icon-grid__item--selected': selectedIcon && icon[0] === selectedIcon\n }\"\n >\n <button\n class=\"dtm-icon-grid__btn\"\n [title]=\"icon[0] | iconName\"\n (click)=\"onIconClicked(icon)\"\n >\n <i\n class=\"d-block icon-40 c8y-icon-duocolor\"\n [c8yIcon]=\"icon[0]\"\n ></i>\n @if (showIconClass) {\n <small class=\"text-break-word\">\n {{ icon[0] | iconName }}\n </small>\n }\n </button>\n </div>\n </div>\n }\n </div>\n } @empty {\n <c8y-ui-empty-state\n icon=\"search\"\n style=\"grid-column: 1 / 3\"\n [title]=\"'No icons found' | translate\"\n [subtitle]=\"\n 'Try adjusting your search or filter to find what you\\'re looking for.' | translate\n \"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n }\n </div>\n </div>\n</div>\n" }]
94
93
  }], ctorParameters: () => [], propDecorators: { iconCategoriesToExclude: [{
95
94
  type: Input
96
95
  }], showIconClass: [{
@@ -1 +1 @@
1
- {"version":3,"file":"c8y-ngx-components-icon-selector.mjs","sources":["../../icon-selector/icon-name.pipe.ts","../../icon-selector/icon-selector.component.ts","../../icon-selector/icon-selector.component.html","../../icon-selector/icon-selector-modal/icon-selector-modal.component.ts","../../icon-selector/icon-selector-modal/icon-selector-modal.component.html","../../icon-selector/icon-selector.service.ts","../../icon-selector/icon-selector-wrapper/icon-selector-wrapper.component.ts","../../icon-selector/icon-selector-wrapper/icon-selector-wrapper.component.html","../../icon-selector/icon-selector.module.ts","../../icon-selector/c8y-ngx-components-icon-selector.ts"],"sourcesContent":["import { Pipe, PipeTransform } from '@angular/core';\n\n@Pipe({ name: 'iconName' })\nexport class IconNamePipe implements PipeTransform {\n transform(icon: string): string {\n if (icon.startsWith('c8y-')) {\n return icon.replace(/^c8y-/, '');\n }\n return icon;\n }\n}\n","import { Component, EventEmitter, Input, Output } from '@angular/core';\nimport { BehaviorSubject, Observable, combineLatest, defer, from } from 'rxjs';\nimport { debounceTime, map, shareReplay, startWith } from 'rxjs/operators';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { IconDirective, C8yTranslateDirective, C8yTranslatePipe } from '@c8y/ngx-components';\nimport { clone } from 'lodash-es';\nimport { DefaultIconDefinition } from '@c8y/ngx-components/icon-selector/model';\nimport { SupportedIconsSuggestions } from '@c8y/ngx-components/icon-selector/icons';\nimport { FormsModule } from '@angular/forms';\nimport { NgIf, NgFor, NgClass, AsyncPipe } from '@angular/common';\nimport { IconNamePipe } from './icon-name.pipe';\n\nconst allIconCategory = gettext('All`icons-category`');\n\n@Component({\n selector: 'c8y-icon-selector',\n templateUrl: './icon-selector.component.html',\n styleUrls: [],\n imports: [\n FormsModule,\n IconDirective,\n NgIf,\n C8yTranslateDirective,\n NgFor,\n NgClass,\n C8yTranslatePipe,\n AsyncPipe,\n IconNamePipe\n ]\n})\nexport class IconSelectorComponent {\n @Input() iconCategoriesToExclude: string[] = [];\n @Input() showIconClass = true;\n @Output() onSelect = new EventEmitter<string>();\n @Input() selectedIcon: SupportedIconsSuggestions;\n\n icons$: Observable<DefaultIconDefinition[]>;\n filteredIcons$: Observable<DefaultIconDefinition[]>;\n searchTerm$ = new BehaviorSubject('');\n selectedIconCategory$ = new BehaviorSubject<string>(allIconCategory);\n availableIconCategories$: Observable<string[]>;\n\n constructor() {\n this.icons$ = defer(() => from(this.loadIconDefinitions())).pipe(\n map(icons => icons.filter(tmp => !this.iconCategoriesToExclude.includes(tmp.label))),\n shareReplay({ refCount: true, bufferSize: 1 })\n );\n this.filteredIcons$ = combineLatest([\n this.icons$,\n this.searchTerm$.pipe(debounceTime(500), startWith(this.searchTerm$.value)),\n this.selectedIconCategory$\n ]).pipe(\n map(([icons, searchTerm, category]) =>\n this.filterIconsByCategoryAndSearchTerm(icons, category, searchTerm)\n )\n );\n this.availableIconCategories$ = this.icons$.pipe(\n map(icons => [allIconCategory, ...icons.map(tmp => tmp.label)])\n );\n }\n\n async loadIconDefinitions(): Promise<DefaultIconDefinition[]> {\n const { allIcons } = await import('@c8y/ngx-components/icon-selector/icons');\n return allIcons;\n }\n\n filterIconsByCategoryAndSearchTerm(\n iconCategories: DefaultIconDefinition[],\n selectedCategory: string,\n searchTerm: string\n ): DefaultIconDefinition[] {\n if (selectedCategory !== allIconCategory) {\n iconCategories = iconCategories.filter(category => category.label === selectedCategory);\n }\n\n if (searchTerm) {\n const lowerCaseSearchTerm = searchTerm.toLowerCase();\n const matchingCategories = new Array<DefaultIconDefinition>();\n for (const category of iconCategories) {\n const matchingIcons = category.icons.filter(iconClasses =>\n iconClasses.some(iconClass => iconClass.includes(lowerCaseSearchTerm))\n );\n if (matchingIcons.length) {\n matchingCategories.push({ ...clone(category), icons: matchingIcons });\n }\n }\n return matchingCategories;\n }\n\n return iconCategories;\n }\n\n onSearchChange(searchTerm: string) {\n this.searchTerm$.next(searchTerm);\n }\n\n onCategoryFilterChanged(categoryChange: string): void {\n this.selectedIconCategory$.next(categoryChange);\n }\n\n onIconClicked(icon: ReadonlyArray<string>): void {\n this.selectedIcon = icon[0];\n this.onSelect.emit(icon[0]);\n }\n}\n","<div class=\"p-l-24 p-r-24 p-t-8 p-b-8 separator-bottom\">\n <div class=\"row d-flex-sm\">\n <div class=\"col-sm-6 m-b-8\">\n <div class=\"input-group-search input-group\" style=\"width: auto\">\n <input\n type=\"search\"\n class=\"form-control\"\n id=\"filter-icons\"\n [ngModel]=\"searchTerm$ | async\"\n (ngModelChange)=\"onSearchChange($event)\"\n placeholder=\"{{ 'Type to filter icons…' | translate }}\"\n />\n <ng-template #searchIcon>\n <span class=\"input-group-addon\">\n <i c8yIcon=\"search\"></i>\n </span>\n </ng-template>\n <span\n class=\"input-group-addon pointer\"\n *ngIf=\"searchTerm$ | async; else searchIcon\"\n (click)=\"onSearchChange('')\"\n >\n <i c8yIcon=\"times\"></i>\n </span>\n </div>\n </div>\n <div class=\"col-sm-6 m-b-8 text-right\">\n <div class=\"d-inline-flex a-i-center text-left\">\n <label class=\"m-b-0 m-r-8 flex-no-shrink\" translate>Filter by type</label>\n <div class=\"c8y-select-wrapper\">\n <select\n id=\"exampleSelect\"\n class=\"form-control\"\n [ngModel]=\"selectedIconCategory$ | async\"\n (ngModelChange)=\"onCategoryFilterChanged($event)\"\n >\n <option *ngFor=\"let category of availableIconCategories$ | async\" [ngValue]=\"category\">\n {{ category | translate }}\n </option>\n </select>\n <span></span>\n </div>\n </div>\n </div>\n </div>\n</div>\n<div class=\"modal-inner-scroll\">\n <div class=\"modal-body\" style=\"height: calc(100vh - 293px)\">\n <div class=\"dtm-icon-grid\">\n <div *ngFor=\"let iconDefinition of filteredIcons$ | async\" class=\"d-contents\">\n <div class=\"legend form-block center grid__col--fullspan\">\n {{ iconDefinition.label | translate }}\n </div>\n\n <div class=\"d-contents\" *ngFor=\"let icon of iconDefinition.icons\">\n <div\n class=\"dtm-icon-grid__item\"\n [ngClass]=\"{\n 'dtm-icon-grid__item--selected': selectedIcon && icon[0] === selectedIcon\n }\"\n >\n <button (click)=\"onIconClicked(icon)\" class=\"dtm-icon-grid__btn\" [title]=\"icon[0] | iconName\">\n <i [c8yIcon]=\"icon[0]\" class=\"d-block icon-40\"></i>\n <small *ngIf=\"showIconClass\" class=\"text-break-word\">{{ icon[0] | iconName }}</small>\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n","import { Component } from '@angular/core';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { C8yTranslatePipe } from '@c8y/ngx-components';\nimport { BsModalRef } from 'ngx-bootstrap/modal';\nimport { IconSelectorComponent } from '../icon-selector.component';\n\n@Component({\n selector: 'c8y-icon-selector-modal',\n templateUrl: './icon-selector-modal.component.html',\n imports: [IconSelectorComponent, C8yTranslatePipe]\n})\nexport class IconSelectorModalComponent {\n title: string = gettext('Select icon');\n currentSelection: string;\n saveButtonLabel: string = gettext('Select');\n iconCategoriesToExclude: string[] = [];\n showIconClass = true;\n\n readonly result: Promise<string> = new Promise((resolve, reject) => {\n this.save = resolve;\n this.cancel = reject;\n });\n\n private save: (value: string) => void;\n private cancel: (reason?: any) => void;\n\n constructor(private bsModal: BsModalRef) {}\n\n close() {\n this.bsModal.hide();\n this.cancel();\n }\n\n saveChanges(): void {\n this.bsModal.hide();\n this.save(this.currentSelection);\n }\n\n selectionChange(newSelection: string) {\n this.currentSelection = newSelection;\n }\n}\n","<div class=\"modal-header\">\n <div id=\"modal-title\" class=\"modal-title h4\">{{ title | translate }}</div>\n</div>\n<div id=\"modal-body\">\n <c8y-icon-selector\n (onSelect)=\"selectionChange($event)\"\n [selectedIcon]=\"currentSelection\"\n [iconCategoriesToExclude]=\"iconCategoriesToExclude\"\n [showIconClass]=\"showIconClass\"\n ></c8y-icon-selector>\n</div>\n<div class=\"modal-footer separator text-center\">\n <button class=\"btn btn-default\" (click)=\"close()\">\n {{ 'Cancel' | translate }}\n </button>\n <button class=\"btn btn-primary\" [disabled]=\"!currentSelection\" (click)=\"saveChanges()\">\n {{ saveButtonLabel | translate }}\n </button>\n</div>\n","import { Injectable } from '@angular/core';\nimport { BsModalService } from 'ngx-bootstrap/modal';\nimport { IconSelectorModalComponent } from './icon-selector-modal/icon-selector-modal.component';\n\n@Injectable({ providedIn: 'root' })\nexport class IconSelectorService {\n constructor(protected modal: BsModalService) {}\n\n selectIcon(\n initialState: Partial<\n Pick<\n IconSelectorModalComponent,\n | 'currentSelection'\n | 'title'\n | 'saveButtonLabel'\n | 'iconCategoriesToExclude'\n | 'showIconClass'\n >\n > = {}\n ): Promise<string> {\n const modal = this.modal.show(IconSelectorModalComponent, {\n ignoreBackdropClick: true,\n keyboard: false,\n initialState,\n class: 'modal-lg'\n });\n const content = modal.content as IconSelectorModalComponent;\n return content.result;\n }\n}\n","import { Component, forwardRef, Input, Output, EventEmitter } from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { IconSelectorService } from '../icon-selector.service';\nimport { GainsightService, IconDirective, C8yTranslatePipe } from '@c8y/ngx-components';\nimport { PRODUCT_EXPERIENCE_ICON_SELECTOR } from '@c8y/ngx-components/icon-selector/model';\nimport { NgIf } from '@angular/common';\nimport { TooltipDirective } from 'ngx-bootstrap/tooltip';\n\n/**\n * A component which acts as a wrapper for the icon selector.\n *\n * Example 1:\n * ```\n <c8y-icon-selector-wrapper\n [selectedIcon]=\"'water'\"\n (onSelect)=\"selectIcon($event)\"\n ></c8y-icon-selector-wrapper>\n * ```\n * OR as a part of a formGroup\n * Example 2:\n * ```\n <c8y-icon-selector-wrapper name=\"icon\" formControlName=\"icon\">\n </c8y-icon-selector-wrapper>\n * ```\n */\n@Component({\n selector: 'c8y-icon-selector-wrapper',\n templateUrl: './icon-selector-wrapper.component.html',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => IconSelectorWrapperComponent),\n multi: true\n }\n ],\n imports: [NgIf, IconDirective, TooltipDirective, C8yTranslatePipe]\n})\nexport class IconSelectorWrapperComponent implements ControlValueAccessor {\n @Input() canRemoveIcon = false;\n @Input() selectedIcon: string;\n /**\n * The displayed icon size, the value has to be multiple of 8.\n */\n @Input() iconSize = 32;\n @Output() onSelect: EventEmitter<string> = new EventEmitter();\n\n /**\n * @ignore\n */\n onTouched: () => void;\n\n constructor(\n private iconSelector: IconSelectorService,\n private gainsightService: GainsightService\n ) {}\n\n /**\n * @ignore\n */\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n onChange: (value: string) => void = () => {};\n\n /**\n * @ignore\n * @param icon The value to update\n */\n writeValue(icon: string): void {\n this.selectedIcon = icon;\n }\n\n /**\n * @ignore\n * @param fn The function to register for changes\n */\n registerOnChange(fn: () => void): void {\n this.onChange = fn;\n }\n\n /**\n * @ignore\n * @param fn The function to register for changes\n */\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n removeIcon() {\n this.onSelect.emit(undefined);\n }\n\n async openIconSelector() {\n try {\n this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_ICON_SELECTOR.EVENTS.ICON_SELECTOR, {\n component: PRODUCT_EXPERIENCE_ICON_SELECTOR.COMPONENTS.ICON_SELECTOR_WRAPPER_COMPONENT,\n action: PRODUCT_EXPERIENCE_ICON_SELECTOR.ACTIONS.OPEN_ICON_SELECTOR\n });\n const icon = await this.iconSelector.selectIcon({\n currentSelection: this.selectedIcon\n });\n this.onChange(icon);\n this.selectedIcon = icon;\n this.onSelect.emit(icon);\n this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_ICON_SELECTOR.EVENTS.ICON_SELECTOR, {\n component: PRODUCT_EXPERIENCE_ICON_SELECTOR.COMPONENTS.ICON_SELECTOR_WRAPPER_COMPONENT,\n action: PRODUCT_EXPERIENCE_ICON_SELECTOR.ACTIONS.ICON_SELECTED\n });\n } catch {\n // nothing to do\n }\n }\n}\n","<div class=\"d-flex a-i-center j-c-center p-relative\">\n @if (selectedIcon) {\n <div class=\"icon-{{ iconSize }} text-center l-h-1 fit-w fit-h\">\n <i\n class=\"c8y-icon-duocolor\"\n [c8yIcon]=\"selectedIcon\"\n ></i>\n </div>\n }\n\n @if (!selectedIcon) {\n <div\n class=\"icon-{{ iconSize }} text-muted text-center a-s-stretch fit-w\"\n style=\"border: 2px dashed var(--c8y-root-component-border-color)\"\n >\n <span class=\"d-flex a-i-center j-c-center text-12 fit-h\">\n <em>{{ 'Auto' | translate }}</em>\n </span>\n </div>\n }\n <div class=\"showOnHover d-flex j-c-center p-absolute fit-h fit-w\">\n @if (!selectedIcon) {\n <button\n class=\"btn btn-clean btn-icon btn-sm m-0\"\n title=\"{{ 'Select icon' | translate }}\"\n [attr.aria-label]=\"'Select icon' | translate\"\n type=\"button\"\n (click)=\"openIconSelector()\"\n >\n {{ 'Select' | translate }}\n </button>\n }\n @if (selectedIcon) {\n <button\n class=\"btn btn-dot btn-sm btn-icon m-0\"\n [attr.aria-label]=\"'Change icon' | translate\"\n tooltip=\"{{ 'Change icon' | translate }}\"\n placement=\"top\"\n container=\"body\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"openIconSelector()\"\n >\n <i [c8yIcon]=\"'replace'\"></i>\n </button>\n }\n @if (selectedIcon && canRemoveIcon) {\n <button\n class=\"btn btn-dot btn-dot--danger btn-icon btn-sm m-0\"\n [attr.aria-label]=\"'Remove icon and use default icon' | translate\"\n tooltip=\"{{ 'Remove icon and use default icon' | translate }}\"\n placement=\"top\"\n container=\"body\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"removeIcon()\"\n >\n <i [c8yIcon]=\"'trash'\"></i>\n </button>\n }\n </div>\n</div>\n","import { NgModule } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { CommonModule, DropAreaModule } from '@c8y/ngx-components';\nimport { TooltipModule } from 'ngx-bootstrap/tooltip';\nimport { IconNamePipe } from './icon-name.pipe';\nimport { IconSelectorModalComponent } from './icon-selector-modal/icon-selector-modal.component';\nimport { IconSelectorComponent } from './icon-selector.component';\nimport { IconSelectorWrapperComponent } from './icon-selector-wrapper/icon-selector-wrapper.component';\n\n@NgModule({\n imports: [\n CommonModule,\n FormsModule,\n DropAreaModule,\n TooltipModule,\n IconSelectorComponent,\n IconSelectorModalComponent,\n IconNamePipe,\n IconSelectorWrapperComponent\n ],\n exports: [\n IconSelectorComponent,\n IconSelectorModalComponent,\n IconNamePipe,\n IconSelectorWrapperComponent\n ]\n})\nexport class IconSelectorModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1","i1.IconSelectorService"],"mappings":"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"}
1
+ {"version":3,"file":"c8y-ngx-components-icon-selector.mjs","sources":["../../icon-selector/icon-name.pipe.ts","../../icon-selector/icon-selector.component.ts","../../icon-selector/icon-selector.component.html","../../icon-selector/icon-selector-modal/icon-selector-modal.component.ts","../../icon-selector/icon-selector-modal/icon-selector-modal.component.html","../../icon-selector/icon-selector.service.ts","../../icon-selector/icon-selector-wrapper/icon-selector-wrapper.component.ts","../../icon-selector/icon-selector-wrapper/icon-selector-wrapper.component.html","../../icon-selector/icon-selector.module.ts","../../icon-selector/c8y-ngx-components-icon-selector.ts"],"sourcesContent":["import { Pipe, PipeTransform } from '@angular/core';\n\n@Pipe({ name: 'iconName' })\nexport class IconNamePipe implements PipeTransform {\n transform(icon: string): string {\n if (icon.startsWith('c8y-')) {\n return icon.replace(/^c8y-/, '');\n }\n return icon;\n }\n}\n","import { Component, EventEmitter, Input, Output } from '@angular/core';\nimport { BehaviorSubject, Observable, combineLatest, defer, from } from 'rxjs';\nimport { debounceTime, map, shareReplay, startWith } from 'rxjs/operators';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport {\n IconDirective,\n C8yTranslateDirective,\n C8yTranslatePipe,\n EmptyStateComponent\n} from '@c8y/ngx-components';\nimport { clone } from 'lodash-es';\nimport { DefaultIconDefinition } from '@c8y/ngx-components/icon-selector/model';\nimport { SupportedIconsSuggestions } from '@c8y/ngx-components/icon-selector/icons';\nimport { FormsModule } from '@angular/forms';\nimport { AsyncPipe, NgClass } from '@angular/common';\nimport { IconNamePipe } from './icon-name.pipe';\n\nconst allIconCategory = gettext('All`icons-category`');\n\n@Component({\n selector: 'c8y-icon-selector',\n templateUrl: './icon-selector.component.html',\n styleUrls: [],\n imports: [\n FormsModule,\n IconDirective,\n C8yTranslateDirective,\n C8yTranslatePipe,\n AsyncPipe,\n NgClass,\n IconNamePipe,\n EmptyStateComponent\n ]\n})\nexport class IconSelectorComponent {\n @Input() iconCategoriesToExclude: string[] = [];\n @Input() showIconClass = true;\n @Output() onSelect = new EventEmitter<string>();\n @Input() selectedIcon: SupportedIconsSuggestions;\n\n icons$: Observable<DefaultIconDefinition[]>;\n filteredIcons$: Observable<DefaultIconDefinition[]>;\n searchTerm$ = new BehaviorSubject('');\n selectedIconCategory$ = new BehaviorSubject<string>(allIconCategory);\n availableIconCategories$: Observable<string[]>;\n\n constructor() {\n this.icons$ = defer(() => from(this.loadIconDefinitions())).pipe(\n map(icons => icons.filter(tmp => !this.iconCategoriesToExclude.includes(tmp.label))),\n shareReplay({ refCount: true, bufferSize: 1 })\n );\n this.filteredIcons$ = combineLatest([\n this.icons$,\n this.searchTerm$.pipe(debounceTime(500), startWith(this.searchTerm$.value)),\n this.selectedIconCategory$\n ]).pipe(\n map(([icons, searchTerm, category]) =>\n this.filterIconsByCategoryAndSearchTerm(icons, category, searchTerm)\n )\n );\n this.availableIconCategories$ = this.icons$.pipe(\n map(icons => [allIconCategory, ...icons.map(tmp => tmp.label)])\n );\n }\n\n async loadIconDefinitions(): Promise<DefaultIconDefinition[]> {\n const { allIcons } = await import('@c8y/ngx-components/icon-selector/icons');\n return allIcons;\n }\n\n filterIconsByCategoryAndSearchTerm(\n iconCategories: DefaultIconDefinition[],\n selectedCategory: string,\n searchTerm: string\n ): DefaultIconDefinition[] {\n if (selectedCategory !== allIconCategory) {\n iconCategories = iconCategories.filter(category => category.label === selectedCategory);\n }\n\n if (searchTerm) {\n const lowerCaseSearchTerm = searchTerm.toLowerCase();\n const matchingCategories = new Array<DefaultIconDefinition>();\n for (const category of iconCategories) {\n const matchingIcons = category.icons.filter(iconClasses =>\n iconClasses.some(iconClass => iconClass.includes(lowerCaseSearchTerm))\n );\n if (matchingIcons.length) {\n matchingCategories.push({ ...clone(category), icons: matchingIcons });\n }\n }\n return matchingCategories;\n }\n\n return iconCategories;\n }\n\n onSearchChange(searchTerm: string) {\n this.searchTerm$.next(searchTerm);\n }\n\n onCategoryFilterChanged(categoryChange: string): void {\n this.selectedIconCategory$.next(categoryChange);\n }\n\n onIconClicked(icon: ReadonlyArray<string>): void {\n this.selectedIcon = icon[0];\n this.onSelect.emit(icon[0]);\n }\n}\n","<div class=\"p-l-24 p-r-24 p-t-8 p-b-8 separator-bottom\">\n <div class=\"row d-flex-sm\">\n <div class=\"col-sm-6 m-b-8\">\n <div\n class=\"input-group-search input-group\"\n style=\"width: auto\"\n >\n <input\n class=\"form-control\"\n id=\"filter-icons\"\n placeholder=\"{{ 'Type to filter icons…' | translate }}\"\n type=\"search\"\n [ngModel]=\"searchTerm$ | async\"\n (ngModelChange)=\"onSearchChange($event)\"\n />\n @if (searchTerm$ | async) {\n <span\n class=\"input-group-addon pointer\"\n (click)=\"onSearchChange('')\"\n >\n <i c8yIcon=\"times\"></i>\n </span>\n } @else {\n <span class=\"input-group-addon\">\n <i c8yIcon=\"search\"></i>\n </span>\n }\n </div>\n </div>\n <div class=\"col-sm-6 m-b-8 text-right\">\n <div class=\"d-inline-flex a-i-center text-left\">\n <label\n class=\"m-b-0 m-r-8 flex-no-shrink\"\n translate\n >\n Filter by type\n </label>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control\"\n id=\"exampleSelect\"\n [ngModel]=\"selectedIconCategory$ | async\"\n (ngModelChange)=\"onCategoryFilterChanged($event)\"\n >\n @for (category of availableIconCategories$ | async; track category) {\n <option [ngValue]=\"category\">\n {{ category | translate }}\n </option>\n }\n </select>\n <span></span>\n </div>\n </div>\n </div>\n </div>\n</div>\n<div class=\"modal-inner-scroll\">\n <div\n class=\"modal-body\"\n style=\"height: calc(100vh - 293px)\"\n >\n <div class=\"dtm-icon-grid\">\n @for (iconDefinition of filteredIcons$ | async; track iconDefinition) {\n <div class=\"d-contents\">\n <div class=\"legend form-block center grid__col--fullspan\">\n {{ iconDefinition.label | translate }}\n </div>\n\n @for (icon of iconDefinition.icons; track icon) {\n <div class=\"d-contents\">\n <div\n class=\"dtm-icon-grid__item\"\n [ngClass]=\"{\n 'dtm-icon-grid__item--selected': selectedIcon && icon[0] === selectedIcon\n }\"\n >\n <button\n class=\"dtm-icon-grid__btn\"\n [title]=\"icon[0] | iconName\"\n (click)=\"onIconClicked(icon)\"\n >\n <i\n class=\"d-block icon-40 c8y-icon-duocolor\"\n [c8yIcon]=\"icon[0]\"\n ></i>\n @if (showIconClass) {\n <small class=\"text-break-word\">\n {{ icon[0] | iconName }}\n </small>\n }\n </button>\n </div>\n </div>\n }\n </div>\n } @empty {\n <c8y-ui-empty-state\n icon=\"search\"\n style=\"grid-column: 1 / 3\"\n [title]=\"'No icons found' | translate\"\n [subtitle]=\"\n 'Try adjusting your search or filter to find what you\\'re looking for.' | translate\n \"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n }\n </div>\n </div>\n</div>\n","import { Component } from '@angular/core';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { C8yTranslatePipe } from '@c8y/ngx-components';\nimport { BsModalRef } from 'ngx-bootstrap/modal';\nimport { IconSelectorComponent } from '../icon-selector.component';\n\n@Component({\n selector: 'c8y-icon-selector-modal',\n templateUrl: './icon-selector-modal.component.html',\n imports: [IconSelectorComponent, C8yTranslatePipe]\n})\nexport class IconSelectorModalComponent {\n title: string = gettext('Select icon');\n currentSelection: string;\n saveButtonLabel: string = gettext('Select');\n iconCategoriesToExclude: string[] = [];\n showIconClass = true;\n\n readonly result: Promise<string> = new Promise((resolve, reject) => {\n this.save = resolve;\n this.cancel = reject;\n });\n\n private save: (value: string) => void;\n private cancel: (reason?: any) => void;\n\n constructor(private bsModal: BsModalRef) {}\n\n close() {\n this.bsModal.hide();\n this.cancel();\n }\n\n saveChanges(): void {\n this.bsModal.hide();\n this.save(this.currentSelection);\n }\n\n selectionChange(newSelection: string) {\n this.currentSelection = newSelection;\n }\n}\n","<div class=\"modal-header\">\n <div id=\"modal-title\" class=\"modal-title h4\">{{ title | translate }}</div>\n</div>\n<div id=\"modal-body\">\n <c8y-icon-selector\n (onSelect)=\"selectionChange($event)\"\n [selectedIcon]=\"currentSelection\"\n [iconCategoriesToExclude]=\"iconCategoriesToExclude\"\n [showIconClass]=\"showIconClass\"\n ></c8y-icon-selector>\n</div>\n<div class=\"modal-footer separator text-center\">\n <button class=\"btn btn-default\" (click)=\"close()\">\n {{ 'Cancel' | translate }}\n </button>\n <button class=\"btn btn-primary\" [disabled]=\"!currentSelection\" (click)=\"saveChanges()\">\n {{ saveButtonLabel | translate }}\n </button>\n</div>\n","import { Injectable } from '@angular/core';\nimport { BsModalService } from 'ngx-bootstrap/modal';\nimport { IconSelectorModalComponent } from './icon-selector-modal/icon-selector-modal.component';\n\n@Injectable({ providedIn: 'root' })\nexport class IconSelectorService {\n constructor(protected modal: BsModalService) {}\n\n selectIcon(\n initialState: Partial<\n Pick<\n IconSelectorModalComponent,\n | 'currentSelection'\n | 'title'\n | 'saveButtonLabel'\n | 'iconCategoriesToExclude'\n | 'showIconClass'\n >\n > = {}\n ): Promise<string> {\n const modal = this.modal.show(IconSelectorModalComponent, {\n ignoreBackdropClick: true,\n keyboard: false,\n initialState,\n class: 'modal-lg'\n });\n const content = modal.content as IconSelectorModalComponent;\n return content.result;\n }\n}\n","import { Component, forwardRef, Input, Output, EventEmitter } from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { IconSelectorService } from '../icon-selector.service';\nimport { GainsightService, IconDirective, C8yTranslatePipe } from '@c8y/ngx-components';\nimport { PRODUCT_EXPERIENCE_ICON_SELECTOR } from '@c8y/ngx-components/icon-selector/model';\nimport { NgIf } from '@angular/common';\nimport { TooltipDirective } from 'ngx-bootstrap/tooltip';\n\n/**\n * A component which acts as a wrapper for the icon selector.\n *\n * Example 1:\n * ```\n <c8y-icon-selector-wrapper\n [selectedIcon]=\"'water'\"\n (onSelect)=\"selectIcon($event)\"\n ></c8y-icon-selector-wrapper>\n * ```\n * OR as a part of a formGroup\n * Example 2:\n * ```\n <c8y-icon-selector-wrapper name=\"icon\" formControlName=\"icon\">\n </c8y-icon-selector-wrapper>\n * ```\n */\n@Component({\n selector: 'c8y-icon-selector-wrapper',\n templateUrl: './icon-selector-wrapper.component.html',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => IconSelectorWrapperComponent),\n multi: true\n }\n ],\n imports: [NgIf, IconDirective, TooltipDirective, C8yTranslatePipe]\n})\nexport class IconSelectorWrapperComponent implements ControlValueAccessor {\n @Input() canRemoveIcon = false;\n @Input() selectedIcon: string;\n /**\n * The displayed icon size, the value has to be multiple of 8.\n */\n @Input() iconSize = 32;\n @Output() onSelect: EventEmitter<string> = new EventEmitter();\n\n /**\n * @ignore\n */\n onTouched: () => void;\n\n constructor(\n private iconSelector: IconSelectorService,\n private gainsightService: GainsightService\n ) {}\n\n /**\n * @ignore\n */\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n onChange: (value: string) => void = () => {};\n\n /**\n * @ignore\n * @param icon The value to update\n */\n writeValue(icon: string): void {\n this.selectedIcon = icon;\n }\n\n /**\n * @ignore\n * @param fn The function to register for changes\n */\n registerOnChange(fn: () => void): void {\n this.onChange = fn;\n }\n\n /**\n * @ignore\n * @param fn The function to register for changes\n */\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n removeIcon() {\n this.onSelect.emit(undefined);\n }\n\n async openIconSelector() {\n try {\n this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_ICON_SELECTOR.EVENTS.ICON_SELECTOR, {\n component: PRODUCT_EXPERIENCE_ICON_SELECTOR.COMPONENTS.ICON_SELECTOR_WRAPPER_COMPONENT,\n action: PRODUCT_EXPERIENCE_ICON_SELECTOR.ACTIONS.OPEN_ICON_SELECTOR\n });\n const icon = await this.iconSelector.selectIcon({\n currentSelection: this.selectedIcon\n });\n this.onChange(icon);\n this.selectedIcon = icon;\n this.onSelect.emit(icon);\n this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_ICON_SELECTOR.EVENTS.ICON_SELECTOR, {\n component: PRODUCT_EXPERIENCE_ICON_SELECTOR.COMPONENTS.ICON_SELECTOR_WRAPPER_COMPONENT,\n action: PRODUCT_EXPERIENCE_ICON_SELECTOR.ACTIONS.ICON_SELECTED\n });\n } catch {\n // nothing to do\n }\n }\n}\n","<div class=\"d-flex a-i-center j-c-center p-relative\">\n @if (selectedIcon) {\n <div class=\"icon-{{ iconSize }} text-center l-h-1 fit-w fit-h\">\n <i\n class=\"c8y-icon-duocolor\"\n [c8yIcon]=\"selectedIcon\"\n ></i>\n </div>\n }\n\n @if (!selectedIcon) {\n <div\n class=\"icon-{{ iconSize }} text-muted text-center a-s-stretch fit-w\"\n style=\"border: 2px dashed var(--c8y-root-component-border-color)\"\n >\n <span class=\"d-flex a-i-center j-c-center text-12 fit-h\">\n <em>{{ 'Auto' | translate }}</em>\n </span>\n </div>\n }\n <div class=\"showOnHover d-flex j-c-center p-absolute fit-h fit-w\">\n @if (!selectedIcon) {\n <button\n class=\"btn btn-clean btn-icon btn-sm m-0\"\n title=\"{{ 'Select icon' | translate }}\"\n [attr.aria-label]=\"'Select icon' | translate\"\n type=\"button\"\n (click)=\"openIconSelector()\"\n >\n {{ 'Select' | translate }}\n </button>\n }\n @if (selectedIcon) {\n <button\n class=\"btn btn-dot btn-sm btn-icon m-0\"\n [attr.aria-label]=\"'Change icon' | translate\"\n tooltip=\"{{ 'Change icon' | translate }}\"\n placement=\"top\"\n container=\"body\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"openIconSelector()\"\n >\n <i [c8yIcon]=\"'replace'\"></i>\n </button>\n }\n @if (selectedIcon && canRemoveIcon) {\n <button\n class=\"btn btn-dot btn-dot--danger btn-icon btn-sm m-0\"\n [attr.aria-label]=\"'Remove icon and use default icon' | translate\"\n tooltip=\"{{ 'Remove icon and use default icon' | translate }}\"\n placement=\"top\"\n container=\"body\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"removeIcon()\"\n >\n <i [c8yIcon]=\"'trash'\"></i>\n </button>\n }\n </div>\n</div>\n","import { NgModule } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { CommonModule, DropAreaModule } from '@c8y/ngx-components';\nimport { TooltipModule } from 'ngx-bootstrap/tooltip';\nimport { IconNamePipe } from './icon-name.pipe';\nimport { IconSelectorModalComponent } from './icon-selector-modal/icon-selector-modal.component';\nimport { IconSelectorComponent } from './icon-selector.component';\nimport { IconSelectorWrapperComponent } from './icon-selector-wrapper/icon-selector-wrapper.component';\n\n@NgModule({\n imports: [\n CommonModule,\n FormsModule,\n DropAreaModule,\n TooltipModule,\n IconSelectorComponent,\n IconSelectorModalComponent,\n IconNamePipe,\n IconSelectorWrapperComponent\n ],\n exports: [\n IconSelectorComponent,\n IconSelectorModalComponent,\n IconNamePipe,\n IconSelectorWrapperComponent\n ]\n})\nexport class IconSelectorModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1","i1.IconSelectorService"],"mappings":"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"}
@@ -101,6 +101,11 @@ class TimeContextComponent {
101
101
  constructor(widgetTimeContextDateRangeService) {
102
102
  this.widgetTimeContextDateRangeService = widgetTimeContextDateRangeService;
103
103
  this.timeContext = {};
104
+ this.timePickerConfig = {
105
+ showMinutes: true,
106
+ showSeconds: false,
107
+ showSpinners: false
108
+ };
104
109
  this.datapointExplorerService = inject(DatapointExplorerService);
105
110
  this.formBuilder = inject(FormBuilder);
106
111
  this.#destroyRef = inject(DestroyRef);
@@ -303,7 +308,7 @@ class TimeContextComponent {
303
308
  });
304
309
  }
305
310
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TimeContextComponent, deps: [{ token: i1.WidgetTimeContextDateRangeService }], target: i0.ɵɵFactoryTarget.Component }); }
306
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.16", type: TimeContextComponent, isStandalone: true, selector: "c8y-time-context", inputs: { changedDateContext: { classPropertyName: "changedDateContext", publicName: "changedDateContext", isSignal: false, isRequired: false, transformFunction: null }, controlsAvailable: { classPropertyName: "controlsAvailable", publicName: "controlsAvailable", isSignal: false, isRequired: false, transformFunction: null }, timeContext: { classPropertyName: "timeContext", publicName: "timeContext", isSignal: false, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { context: "contextChange" }, viewQueries: [{ propertyName: "dropdown", first: true, predicate: BsDropdownDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"controlsAvailable; else actionBarTemplate\">\n <ng-container\n [ngTemplateOutlet]=\"dateTimePicker\"\n [ngTemplateOutletContext]=\"{\n date: [form.value.currentDateContextFromDate, form.value.currentDateContextToDate]\n }\"\n ></ng-container>\n</ng-container>\n\n<ng-template #actionBarTemplate>\n <c8y-action-bar-item\n [groupId]=\"'timeContext'\"\n [inGroupPriority]=\"1\"\n [placement]=\"'left'\"\n >\n <ng-container\n [ngTemplateOutlet]=\"dateTimePicker\"\n [ngTemplateOutletContext]=\"{\n date: [form.value.currentDateContextFromDate, form.value.currentDateContextToDate]\n }\"\n ></ng-container>\n </c8y-action-bar-item>\n</ng-template>\n\n<ng-template\n #dateTimePicker\n let-date=\"date\"\n>\n <form\n class=\"d-flex gap-8 p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8\"\n [formGroup]=\"form\"\n >\n <ng-container>\n <div\n class=\"dropdown flex-grow\"\n #dropdown=\"bs-dropdown\"\n dropdown\n [insideClick]=\"true\"\n *ngIf=\"date\"\n >\n <button\n class=\"dropdown-toggle form-control l-h-tight d-flex a-i-center\"\n attr.aria-label=\"{{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{\n date[1] | c8yDate: DATE_FORMAT\n }}\"\n tooltip=\"{{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{ date[1] | c8yDate: DATE_FORMAT }}\"\n placement=\"top\"\n container=\"body\"\n data-cy=\"widget-time-context--date-picker-dropdown-button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n dropdownToggle\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"schedule1\"\n ></i>\n <div class=\"d-col text-left fit-w\">\n <span\n class=\"text-12\"\n data-cy=\"widget-time-context--selected-interval\"\n >\n {{ INTERVAL_TITLES[form.controls.currentDateContextInterval.value] | translate }}\n </span>\n <span\n class=\"text-10 text-muted text-truncate\"\n data-cy=\"widget-time-context--selected-time-range\"\n >\n {{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{ date[1] | c8yDate: DATE_FORMAT }}\n </span>\n </div>\n <span class=\"caret m-r-16 m-l-4\"></span>\n </button>\n\n <ul\n class=\"dropdown-menu dropdown-menu--date-range\"\n *dropdownMenu\n >\n <c8y-interval-picker\n class=\"d-contents\"\n formControlName=\"currentDateContextInterval\"\n ></c8y-interval-picker>\n\n <ng-container *ngIf=\"form.controls.currentDateContextInterval.value === 'custom'\">\n <div class=\"p-l-16 p-r-16\">\n <c8y-form-group\n [ngClass]=\"form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\"\n >\n <label\n [title]=\"'From`date`' | translate\"\n for=\"temporaryUserSelectedFromDate\"\n translate\n >\n From`date`\n </label>\n <c8y-date-time-picker\n id=\"temporaryUserSelectedFromDate\"\n [maxDate]=\"form.value.temporaryUserSelectedToDate\"\n [placeholder]=\"'From`date`' | translate\"\n [formControl]=\"form.controls.temporaryUserSelectedFromDate\"\n [ngClass]=\"form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"form.controls.temporaryUserSelectedFromDate.errors\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"'This date is after the latest allowed date.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"'This date is invalid.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group\n [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n >\n <label\n [title]=\"'To`date`' | translate\"\n for=\"temporaryUserSelectedToDate\"\n translate\n >\n To`date`\n </label>\n <c8y-date-time-picker\n id=\"temporaryUserSelectedToDate\"\n [minDate]=\"form.value.temporaryUserSelectedFromDate\"\n [placeholder]=\"'To`date`' | translate\"\n [formControl]=\"form.controls.temporaryUserSelectedToDate\"\n [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"form.controls.temporaryUserSelectedToDate.errors\">\n <c8y-message\n name=\"dateBeforeRangeMin\"\n [text]=\"'This date is before the earliest allowed date.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"'This date is invalid.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n\n <div class=\"p-16 d-flex gap-8 separator-top\">\n <button\n class=\"btn btn-default btn-sm flex-grow\"\n title=\"{{ 'Reset' | translate }}\"\n type=\"button\"\n (click)=\"dropdown.isOpen = false\"\n [disabled]=\"form.value.realtime\"\n translate\n >\n Reset\n </button>\n\n <button\n class=\"btn btn-primary btn-sm flex-grow\"\n title=\"{{ 'Apply' | translate }}\"\n type=\"button\"\n (click)=\"applyDatetimeContext(); dropdown.isOpen = false\"\n [disabled]=\"\n (form.pristine && form.untouched) || form.invalid || form.value.realtime\n \"\n translate\n >\n Apply\n </button>\n </div>\n </ng-container>\n </ul>\n </div>\n </ng-container>\n\n <div class=\"input-group w-auto\">\n <c8y-realtime-control\n class=\"form-control p-0 flex-no-grow w-auto\"\n formControlName=\"realtime\"\n ></c8y-realtime-control>\n\n <c8y-aggregation-picker\n *ngIf=\"controlsAvailable ? controlsAvailable.aggregation : true\"\n formControlName=\"aggregation\"\n [disabledAggregations]=\"disabledAggregations\"\n ></c8y-aggregation-picker>\n </div>\n </form>\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: CoreModule }, { kind: "component", type: i1.ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "directive", type: i1.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i1.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "component", type: i1.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i1.MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "component", type: i1.MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "component", type: i1.AggregationPickerComponent, selector: "c8y-aggregation-picker", inputs: ["disabledAggregations"] }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i1.DateTimePickerComponent, selector: "c8y-date-time-picker", inputs: ["minDate", "maxDate", "placeholder", "dateInputFormat", "adaptivePosition", "size", "dateType", "config"], outputs: ["onDateSelected"] }, { kind: "ngmodule", type: BsDatepickerModule }, { kind: "ngmodule", type: DateTimePickerModule }, { kind: "ngmodule", type: BsDropdownModule }, { kind: "directive", type: i4.BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { kind: "directive", type: i4.BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { kind: "directive", type: i4.BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.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: "component", type: IntervalPickerComponent, selector: "c8y-interval-picker", inputs: ["INTERVALS"] }, { kind: "component", type: RealtimeControlComponent, selector: "c8y-realtime-control" }, { kind: "pipe", type: i1.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i1.DatePipe, name: "c8yDate" }] }); }
311
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: TimeContextComponent, isStandalone: true, selector: "c8y-time-context", inputs: { changedDateContext: { classPropertyName: "changedDateContext", publicName: "changedDateContext", isSignal: false, isRequired: false, transformFunction: null }, controlsAvailable: { classPropertyName: "controlsAvailable", publicName: "controlsAvailable", isSignal: false, isRequired: false, transformFunction: null }, timeContext: { classPropertyName: "timeContext", publicName: "timeContext", isSignal: false, isRequired: false, transformFunction: null }, timePickerConfig: { classPropertyName: "timePickerConfig", publicName: "timePickerConfig", isSignal: false, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { context: "contextChange" }, viewQueries: [{ propertyName: "dropdown", first: true, predicate: BsDropdownDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: "@if (controlsAvailable) {\n <ng-container\n [ngTemplateOutlet]=\"dateTimePicker\"\n [ngTemplateOutletContext]=\"{\n date: [form.value.currentDateContextFromDate, form.value.currentDateContextToDate]\n }\"\n ></ng-container>\n} @else {\n <c8y-action-bar-item\n [groupId]=\"'timeContext'\"\n [inGroupPriority]=\"1\"\n [placement]=\"'left'\"\n >\n <ng-container\n [ngTemplateOutlet]=\"dateTimePicker\"\n [ngTemplateOutletContext]=\"{\n date: [form.value.currentDateContextFromDate, form.value.currentDateContextToDate]\n }\"\n ></ng-container>\n </c8y-action-bar-item>\n}\n\n<ng-template\n #dateTimePicker\n let-date=\"date\"\n>\n <form\n class=\"d-flex gap-8 p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8\"\n [formGroup]=\"form\"\n >\n <ng-container>\n @if (date) {\n <div\n class=\"dropdown flex-grow\"\n #dropdown=\"bs-dropdown\"\n dropdown\n [insideClick]=\"true\"\n >\n <button\n class=\"dropdown-toggle form-control l-h-tight d-flex a-i-center\"\n attr.aria-label=\"{{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{\n date[1] | c8yDate: DATE_FORMAT\n }}\"\n tooltip=\"{{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{ date[1] | c8yDate: DATE_FORMAT }}\"\n placement=\"top\"\n container=\"body\"\n data-cy=\"widget-time-context--date-picker-dropdown-button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n dropdownToggle\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"schedule1\"\n ></i>\n <div class=\"d-col text-left fit-w\">\n <span\n class=\"text-12\"\n data-cy=\"widget-time-context--selected-interval\"\n >\n {{ INTERVAL_TITLES[form.controls.currentDateContextInterval.value] | translate }}\n </span>\n <span\n class=\"text-10 text-muted text-truncate\"\n data-cy=\"widget-time-context--selected-time-range\"\n >\n {{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{ date[1] | c8yDate: DATE_FORMAT }}\n </span>\n </div>\n <span class=\"caret m-r-16 m-l-4\"></span>\n </button>\n\n <ul\n class=\"dropdown-menu dropdown-menu-wide dropdown-menu--date-range\"\n *dropdownMenu\n >\n <c8y-interval-picker\n class=\"d-contents\"\n formControlName=\"currentDateContextInterval\"\n ></c8y-interval-picker>\n\n @if (form.controls.currentDateContextInterval.value === 'custom') {\n <div class=\"p-l-16 p-r-16\">\n <c8y-form-group\n [ngClass]=\"form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\"\n >\n <label\n [title]=\"'From`date`' | translate\"\n for=\"temporaryUserSelectedFromDate\"\n translate\n >\n From`date`\n </label>\n <c8y-date-time-picker\n id=\"temporaryUserSelectedFromDate\"\n [maxDate]=\"form.value.temporaryUserSelectedToDate\"\n [config]=\"timePickerConfig\"\n [placeholder]=\"'From`date`' | translate\"\n [formControl]=\"form.controls.temporaryUserSelectedFromDate\"\n [ngClass]=\"\n form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\n \"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"form.controls.temporaryUserSelectedFromDate.errors\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"'This date is after the latest allowed date.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"'This date is invalid.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group\n [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n >\n <label\n [title]=\"'To`date`' | translate\"\n for=\"temporaryUserSelectedToDate\"\n translate\n >\n To`date`\n </label>\n <c8y-date-time-picker\n id=\"temporaryUserSelectedToDate\"\n [minDate]=\"form.value.temporaryUserSelectedFromDate\"\n [config]=\"timePickerConfig\"\n [placeholder]=\"'To`date`' | translate\"\n [formControl]=\"form.controls.temporaryUserSelectedToDate\"\n [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"form.controls.temporaryUserSelectedToDate.errors\">\n <c8y-message\n name=\"dateBeforeRangeMin\"\n [text]=\"'This date is before the earliest allowed date.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"'This date is invalid.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n\n <div class=\"p-16 d-flex gap-8 separator-top\">\n <button\n class=\"btn btn-default btn-sm flex-grow\"\n title=\"{{ 'Reset' | translate }}\"\n type=\"button\"\n (click)=\"dropdown.isOpen = false\"\n [disabled]=\"form.value.realtime\"\n translate\n >\n Reset\n </button>\n\n <button\n class=\"btn btn-primary btn-sm flex-grow\"\n title=\"{{ 'Apply' | translate }}\"\n type=\"button\"\n (click)=\"applyDatetimeContext(); dropdown.isOpen = false\"\n [disabled]=\"\n (form.pristine && form.untouched) || form.invalid || form.value.realtime\n \"\n translate\n >\n Apply\n </button>\n </div>\n }\n </ul>\n </div>\n }\n </ng-container>\n\n <div class=\"input-group w-auto\">\n <c8y-realtime-control\n class=\"form-control p-0 flex-no-grow w-auto\"\n formControlName=\"realtime\"\n ></c8y-realtime-control>\n\n @if (controlsAvailable ? controlsAvailable.aggregation : true) {\n <c8y-aggregation-picker\n formControlName=\"aggregation\"\n [disabledAggregations]=\"disabledAggregations\"\n ></c8y-aggregation-picker>\n }\n </div>\n </form>\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: CoreModule }, { kind: "component", type: i1.ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "directive", type: i1.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i1.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "component", type: i1.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i1.MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "component", type: i1.MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "component", type: i1.AggregationPickerComponent, selector: "c8y-aggregation-picker", inputs: ["disabledAggregations"] }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i1.DateTimePickerComponent, selector: "c8y-date-time-picker", inputs: ["minDate", "maxDate", "placeholder", "dateInputFormat", "adaptivePosition", "size", "dateType", "config"], outputs: ["onDateSelected"] }, { kind: "ngmodule", type: BsDatepickerModule }, { kind: "ngmodule", type: DateTimePickerModule }, { kind: "ngmodule", type: BsDropdownModule }, { kind: "directive", type: i4.BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { kind: "directive", type: i4.BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { kind: "directive", type: i4.BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.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: "component", type: IntervalPickerComponent, selector: "c8y-interval-picker", inputs: ["INTERVALS"] }, { kind: "component", type: RealtimeControlComponent, selector: "c8y-realtime-control" }, { kind: "pipe", type: i1.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i1.DatePipe, name: "c8yDate" }] }); }
307
312
  }
308
313
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TimeContextComponent, decorators: [{
309
314
  type: Component,
@@ -316,13 +321,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
316
321
  TooltipModule,
317
322
  IntervalPickerComponent,
318
323
  RealtimeControlComponent
319
- ], template: "<ng-container *ngIf=\"controlsAvailable; else actionBarTemplate\">\n <ng-container\n [ngTemplateOutlet]=\"dateTimePicker\"\n [ngTemplateOutletContext]=\"{\n date: [form.value.currentDateContextFromDate, form.value.currentDateContextToDate]\n }\"\n ></ng-container>\n</ng-container>\n\n<ng-template #actionBarTemplate>\n <c8y-action-bar-item\n [groupId]=\"'timeContext'\"\n [inGroupPriority]=\"1\"\n [placement]=\"'left'\"\n >\n <ng-container\n [ngTemplateOutlet]=\"dateTimePicker\"\n [ngTemplateOutletContext]=\"{\n date: [form.value.currentDateContextFromDate, form.value.currentDateContextToDate]\n }\"\n ></ng-container>\n </c8y-action-bar-item>\n</ng-template>\n\n<ng-template\n #dateTimePicker\n let-date=\"date\"\n>\n <form\n class=\"d-flex gap-8 p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8\"\n [formGroup]=\"form\"\n >\n <ng-container>\n <div\n class=\"dropdown flex-grow\"\n #dropdown=\"bs-dropdown\"\n dropdown\n [insideClick]=\"true\"\n *ngIf=\"date\"\n >\n <button\n class=\"dropdown-toggle form-control l-h-tight d-flex a-i-center\"\n attr.aria-label=\"{{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{\n date[1] | c8yDate: DATE_FORMAT\n }}\"\n tooltip=\"{{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{ date[1] | c8yDate: DATE_FORMAT }}\"\n placement=\"top\"\n container=\"body\"\n data-cy=\"widget-time-context--date-picker-dropdown-button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n dropdownToggle\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"schedule1\"\n ></i>\n <div class=\"d-col text-left fit-w\">\n <span\n class=\"text-12\"\n data-cy=\"widget-time-context--selected-interval\"\n >\n {{ INTERVAL_TITLES[form.controls.currentDateContextInterval.value] | translate }}\n </span>\n <span\n class=\"text-10 text-muted text-truncate\"\n data-cy=\"widget-time-context--selected-time-range\"\n >\n {{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{ date[1] | c8yDate: DATE_FORMAT }}\n </span>\n </div>\n <span class=\"caret m-r-16 m-l-4\"></span>\n </button>\n\n <ul\n class=\"dropdown-menu dropdown-menu--date-range\"\n *dropdownMenu\n >\n <c8y-interval-picker\n class=\"d-contents\"\n formControlName=\"currentDateContextInterval\"\n ></c8y-interval-picker>\n\n <ng-container *ngIf=\"form.controls.currentDateContextInterval.value === 'custom'\">\n <div class=\"p-l-16 p-r-16\">\n <c8y-form-group\n [ngClass]=\"form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\"\n >\n <label\n [title]=\"'From`date`' | translate\"\n for=\"temporaryUserSelectedFromDate\"\n translate\n >\n From`date`\n </label>\n <c8y-date-time-picker\n id=\"temporaryUserSelectedFromDate\"\n [maxDate]=\"form.value.temporaryUserSelectedToDate\"\n [placeholder]=\"'From`date`' | translate\"\n [formControl]=\"form.controls.temporaryUserSelectedFromDate\"\n [ngClass]=\"form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"form.controls.temporaryUserSelectedFromDate.errors\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"'This date is after the latest allowed date.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"'This date is invalid.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group\n [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n >\n <label\n [title]=\"'To`date`' | translate\"\n for=\"temporaryUserSelectedToDate\"\n translate\n >\n To`date`\n </label>\n <c8y-date-time-picker\n id=\"temporaryUserSelectedToDate\"\n [minDate]=\"form.value.temporaryUserSelectedFromDate\"\n [placeholder]=\"'To`date`' | translate\"\n [formControl]=\"form.controls.temporaryUserSelectedToDate\"\n [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"form.controls.temporaryUserSelectedToDate.errors\">\n <c8y-message\n name=\"dateBeforeRangeMin\"\n [text]=\"'This date is before the earliest allowed date.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"'This date is invalid.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n\n <div class=\"p-16 d-flex gap-8 separator-top\">\n <button\n class=\"btn btn-default btn-sm flex-grow\"\n title=\"{{ 'Reset' | translate }}\"\n type=\"button\"\n (click)=\"dropdown.isOpen = false\"\n [disabled]=\"form.value.realtime\"\n translate\n >\n Reset\n </button>\n\n <button\n class=\"btn btn-primary btn-sm flex-grow\"\n title=\"{{ 'Apply' | translate }}\"\n type=\"button\"\n (click)=\"applyDatetimeContext(); dropdown.isOpen = false\"\n [disabled]=\"\n (form.pristine && form.untouched) || form.invalid || form.value.realtime\n \"\n translate\n >\n Apply\n </button>\n </div>\n </ng-container>\n </ul>\n </div>\n </ng-container>\n\n <div class=\"input-group w-auto\">\n <c8y-realtime-control\n class=\"form-control p-0 flex-no-grow w-auto\"\n formControlName=\"realtime\"\n ></c8y-realtime-control>\n\n <c8y-aggregation-picker\n *ngIf=\"controlsAvailable ? controlsAvailable.aggregation : true\"\n formControlName=\"aggregation\"\n [disabledAggregations]=\"disabledAggregations\"\n ></c8y-aggregation-picker>\n </div>\n </form>\n</ng-template>\n" }]
324
+ ], template: "@if (controlsAvailable) {\n <ng-container\n [ngTemplateOutlet]=\"dateTimePicker\"\n [ngTemplateOutletContext]=\"{\n date: [form.value.currentDateContextFromDate, form.value.currentDateContextToDate]\n }\"\n ></ng-container>\n} @else {\n <c8y-action-bar-item\n [groupId]=\"'timeContext'\"\n [inGroupPriority]=\"1\"\n [placement]=\"'left'\"\n >\n <ng-container\n [ngTemplateOutlet]=\"dateTimePicker\"\n [ngTemplateOutletContext]=\"{\n date: [form.value.currentDateContextFromDate, form.value.currentDateContextToDate]\n }\"\n ></ng-container>\n </c8y-action-bar-item>\n}\n\n<ng-template\n #dateTimePicker\n let-date=\"date\"\n>\n <form\n class=\"d-flex gap-8 p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8\"\n [formGroup]=\"form\"\n >\n <ng-container>\n @if (date) {\n <div\n class=\"dropdown flex-grow\"\n #dropdown=\"bs-dropdown\"\n dropdown\n [insideClick]=\"true\"\n >\n <button\n class=\"dropdown-toggle form-control l-h-tight d-flex a-i-center\"\n attr.aria-label=\"{{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{\n date[1] | c8yDate: DATE_FORMAT\n }}\"\n tooltip=\"{{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{ date[1] | c8yDate: DATE_FORMAT }}\"\n placement=\"top\"\n container=\"body\"\n data-cy=\"widget-time-context--date-picker-dropdown-button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n dropdownToggle\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"schedule1\"\n ></i>\n <div class=\"d-col text-left fit-w\">\n <span\n class=\"text-12\"\n data-cy=\"widget-time-context--selected-interval\"\n >\n {{ INTERVAL_TITLES[form.controls.currentDateContextInterval.value] | translate }}\n </span>\n <span\n class=\"text-10 text-muted text-truncate\"\n data-cy=\"widget-time-context--selected-time-range\"\n >\n {{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{ date[1] | c8yDate: DATE_FORMAT }}\n </span>\n </div>\n <span class=\"caret m-r-16 m-l-4\"></span>\n </button>\n\n <ul\n class=\"dropdown-menu dropdown-menu-wide dropdown-menu--date-range\"\n *dropdownMenu\n >\n <c8y-interval-picker\n class=\"d-contents\"\n formControlName=\"currentDateContextInterval\"\n ></c8y-interval-picker>\n\n @if (form.controls.currentDateContextInterval.value === 'custom') {\n <div class=\"p-l-16 p-r-16\">\n <c8y-form-group\n [ngClass]=\"form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\"\n >\n <label\n [title]=\"'From`date`' | translate\"\n for=\"temporaryUserSelectedFromDate\"\n translate\n >\n From`date`\n </label>\n <c8y-date-time-picker\n id=\"temporaryUserSelectedFromDate\"\n [maxDate]=\"form.value.temporaryUserSelectedToDate\"\n [config]=\"timePickerConfig\"\n [placeholder]=\"'From`date`' | translate\"\n [formControl]=\"form.controls.temporaryUserSelectedFromDate\"\n [ngClass]=\"\n form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\n \"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"form.controls.temporaryUserSelectedFromDate.errors\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"'This date is after the latest allowed date.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"'This date is invalid.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group\n [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n >\n <label\n [title]=\"'To`date`' | translate\"\n for=\"temporaryUserSelectedToDate\"\n translate\n >\n To`date`\n </label>\n <c8y-date-time-picker\n id=\"temporaryUserSelectedToDate\"\n [minDate]=\"form.value.temporaryUserSelectedFromDate\"\n [config]=\"timePickerConfig\"\n [placeholder]=\"'To`date`' | translate\"\n [formControl]=\"form.controls.temporaryUserSelectedToDate\"\n [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"form.controls.temporaryUserSelectedToDate.errors\">\n <c8y-message\n name=\"dateBeforeRangeMin\"\n [text]=\"'This date is before the earliest allowed date.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"'This date is invalid.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n\n <div class=\"p-16 d-flex gap-8 separator-top\">\n <button\n class=\"btn btn-default btn-sm flex-grow\"\n title=\"{{ 'Reset' | translate }}\"\n type=\"button\"\n (click)=\"dropdown.isOpen = false\"\n [disabled]=\"form.value.realtime\"\n translate\n >\n Reset\n </button>\n\n <button\n class=\"btn btn-primary btn-sm flex-grow\"\n title=\"{{ 'Apply' | translate }}\"\n type=\"button\"\n (click)=\"applyDatetimeContext(); dropdown.isOpen = false\"\n [disabled]=\"\n (form.pristine && form.untouched) || form.invalid || form.value.realtime\n \"\n translate\n >\n Apply\n </button>\n </div>\n }\n </ul>\n </div>\n }\n </ng-container>\n\n <div class=\"input-group w-auto\">\n <c8y-realtime-control\n class=\"form-control p-0 flex-no-grow w-auto\"\n formControlName=\"realtime\"\n ></c8y-realtime-control>\n\n @if (controlsAvailable ? controlsAvailable.aggregation : true) {\n <c8y-aggregation-picker\n formControlName=\"aggregation\"\n [disabledAggregations]=\"disabledAggregations\"\n ></c8y-aggregation-picker>\n }\n </div>\n </form>\n</ng-template>\n" }]
320
325
  }], ctorParameters: () => [{ type: i1.WidgetTimeContextDateRangeService }], propDecorators: { changedDateContext: [{
321
326
  type: Input
322
327
  }], controlsAvailable: [{
323
328
  type: Input
324
329
  }], timeContext: [{
325
330
  type: Input
331
+ }], timePickerConfig: [{
332
+ type: Input
326
333
  }], dropdown: [{
327
334
  type: ViewChild,
328
335
  args: [BsDropdownDirective]