@c8y/ngx-components 1023.14.8 → 1023.16.3

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.
Files changed (39) hide show
  1. package/alarms/index.d.ts +110 -53
  2. package/alarms/index.d.ts.map +1 -1
  3. package/assets-navigator/index.d.ts +7 -3
  4. package/assets-navigator/index.d.ts.map +1 -1
  5. package/context-dashboard/index.d.ts.map +1 -1
  6. package/fesm2022/c8y-ngx-components-alarms.mjs +365 -205
  7. package/fesm2022/c8y-ngx-components-alarms.mjs.map +1 -1
  8. package/fesm2022/c8y-ngx-components-assets-navigator.mjs +25 -6
  9. package/fesm2022/c8y-ngx-components-assets-navigator.mjs.map +1 -1
  10. package/fesm2022/c8y-ngx-components-context-dashboard.mjs +2 -4
  11. package/fesm2022/c8y-ngx-components-context-dashboard.mjs.map +1 -1
  12. package/fesm2022/c8y-ngx-components-echart.mjs +2 -2
  13. package/fesm2022/c8y-ngx-components-echart.mjs.map +1 -1
  14. package/fesm2022/c8y-ngx-components-group-breadcrumbs.mjs +192 -0
  15. package/fesm2022/c8y-ngx-components-group-breadcrumbs.mjs.map +1 -0
  16. package/fesm2022/c8y-ngx-components-module-federation-exports-assets-navigator.mjs +13 -0
  17. package/fesm2022/c8y-ngx-components-module-federation-exports-assets-navigator.mjs.map +1 -0
  18. package/fesm2022/c8y-ngx-components-widgets-implementations-alarms.mjs +2 -2
  19. package/fesm2022/c8y-ngx-components-widgets-implementations-alarms.mjs.map +1 -1
  20. package/fesm2022/c8y-ngx-components.mjs +1201 -36
  21. package/fesm2022/c8y-ngx-components.mjs.map +1 -1
  22. package/group-breadcrumbs/index.d.ts +6 -0
  23. package/group-breadcrumbs/index.d.ts.map +1 -0
  24. package/index.d.ts +873 -6
  25. package/index.d.ts.map +1 -1
  26. package/locales/de.po +66 -58
  27. package/locales/es.po +55 -48
  28. package/locales/fr.po +47 -40
  29. package/locales/ja_JP.po +43 -37
  30. package/locales/ko.po +53 -46
  31. package/locales/locales.pot +25 -15
  32. package/locales/nl.po +50 -43
  33. package/locales/pl.po +65 -58
  34. package/locales/pt_BR.po +52 -45
  35. package/locales/zh_CN.po +49 -43
  36. package/locales/zh_TW.po +61 -53
  37. package/module-federation-exports/assets-navigator/index.d.ts +2 -0
  38. package/module-federation-exports/assets-navigator/index.d.ts.map +1 -0
  39. package/package.json +1 -1
@@ -4,10 +4,10 @@ import * as i1$4 from 'ngx-bootstrap/dropdown';
4
4
  import { BsDropdownModule, BsDropdownDirective } from 'ngx-bootstrap/dropdown';
5
5
  import { CdkTrapFocus, A11yModule } from '@angular/cdk/a11y';
6
6
  import { castArray, flatten, uniq, sortBy, groupBy, camelCase, isEqual, isUndefined, throttle as throttle$1, each, mapValues, mapKeys, keys, get, isNaN as isNaN$1, isFinite, forEach, assign, min, every, first, map as map$1, find, negate, upperFirst, memoize as memoize$1, isEmpty, property, some, entries, omitBy, isDate, pick, flatMap, cloneDeep, set as set$1, orderBy, filter as filter$2, snakeCase, matches, escape, escapeRegExp, assignWith, uniqBy, toNumber, isEqualWith, clone, omit, has, transform, identity, unset, flow, findIndex as findIndex$1, isNil, chunk, values, union, without, indexOf, kebabCase, forOwn } from 'lodash-es';
7
- import { merge, of, defer, combineLatest, race, isObservable, from, Subject, BehaviorSubject, ReplaySubject, firstValueFrom, lastValueFrom, NEVER, Observable, startWith as startWith$1, filter as filter$1, tap as tap$1, mergeMap, fromEvent, pipe, throwError, concat, map as map$2, timer, fromEventPattern, withLatestFrom, distinctUntilChanged as distinctUntilChanged$1, takeUntil as takeUntil$1, switchMap as switchMap$1, shareReplay as shareReplay$1, catchError as catchError$1, empty, forkJoin, interval } from 'rxjs';
7
+ import { merge, of, defer, combineLatest, race, isObservable, from, Subject, BehaviorSubject, ReplaySubject, firstValueFrom, lastValueFrom, NEVER, Observable, startWith as startWith$1, filter as filter$1, tap as tap$1, mergeMap, fromEvent, pipe, throwError, concat, map as map$2, timer, fromEventPattern, withLatestFrom, distinctUntilChanged as distinctUntilChanged$1, takeUntil as takeUntil$1, switchMap as switchMap$1, shareReplay as shareReplay$1, catchError as catchError$1, empty, forkJoin, interval, skip as skip$1, debounceTime as debounceTime$1 } from 'rxjs';
8
8
  import { map, distinctUntilChanged, filter, startWith, switchMap, shareReplay, take, scan, takeUntil, tap, catchError, debounceTime, share, first as first$1, retryWhen, delay, concatMap, mergeMap as mergeMap$1, debounce, sample, withLatestFrom as withLatestFrom$1, every as every$1, toArray, merge as merge$1, expand, mapTo, skip, reduce, finalize, combineLatestWith } from 'rxjs/operators';
9
9
  import * as i1 from '@c8y/client';
10
- import { OperationStatus, TenantLoginOptionType, UserManagementSource, GrantType, ApplicationType, BasicAuth, CookieAuth, Realtime, FetchClient, BearerAuthFromSessionStorage, FeatureService, ApplicationAvailability, InventoryService, QueriesUtil, Client, PasswordStrength, AlarmService, TenantService, ApplicationService, UserService, aggregationType, Service, Paging } from '@c8y/client';
10
+ import { InventoryService, OperationStatus, TenantLoginOptionType, UserManagementSource, GrantType, ApplicationType, BasicAuth, CookieAuth, Realtime, FetchClient, BearerAuthFromSessionStorage, FeatureService, ApplicationAvailability, QueriesUtil, Client, PasswordStrength, AlarmService, TenantService, ApplicationService, UserService, aggregationType, Service, Paging } from '@c8y/client';
11
11
  import { __decorate, __metadata } from 'tslib';
12
12
  import * as i1$3 from '@angular/router';
13
13
  import { NavigationEnd, RouterModule as RouterModule$1, NavigationStart, RouterLink, RouterLinkActive, RouterOutlet, ActivationEnd, Router, ActivatedRoute, PRIMARY_OUTLET, ActivationStart, ChildActivationEnd, ROUTES, NavigationCancel, NavigationError } from '@angular/router';
@@ -8690,6 +8690,243 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
8690
8690
  }]
8691
8691
  }], ctorParameters: () => [] });
8692
8692
 
8693
+ /**
8694
+ * Service for retrieving ancestor paths in the Cumulocity asset hierarchy.
8695
+ *
8696
+ * This service traverses upward through parent relationships (assetParents, deviceParents,
8697
+ * additionParents) to find all possible paths from root ancestors down to a target asset.
8698
+ *
8699
+ * @example
8700
+ * Given this hierarchy:
8701
+ * ```
8702
+ * Root1 -> Building1 -> Floor1 -> Device
8703
+ * Root2 -> Building2 -> Floor1 -> Device
8704
+ * ```
8705
+ *
8706
+ * Calling `getAncestorPaths('Device')` returns:
8707
+ * ```
8708
+ * [
8709
+ * [Root1, Building1, Floor1, Device],
8710
+ * [Root2, Building2, Floor1, Device]
8711
+ * ]
8712
+ * ```
8713
+ */
8714
+ class AssetHierarchyService {
8715
+ constructor() {
8716
+ this.inventory = inject(InventoryService);
8717
+ this.alertService = inject(AlertService);
8718
+ }
8719
+ /**
8720
+ * Retrieves all ancestor paths from root nodes down to the specified asset.
8721
+ *
8722
+ * This method fetches the target asset and all its ancestors, then constructs
8723
+ * all possible paths from root ancestors (objects with no parents) down to the
8724
+ * target asset. Multiple paths may exist if the asset has multiple parent chains.
8725
+ *
8726
+ * @param assetId - The ID of the target asset
8727
+ * @returns A promise that resolves to an array of paths, where each path is an
8728
+ * array of managed objects ordered from root to target asset.
8729
+ * Returns an empty array if the asset is not found or an error occurs.
8730
+ */
8731
+ async getAncestorPaths(assetId) {
8732
+ if (!assetId) {
8733
+ return [];
8734
+ }
8735
+ try {
8736
+ const { data: asset } = await this.inventory.detail(assetId, {
8737
+ withParents: true
8738
+ });
8739
+ const parentIdsOfAsset = this.getParentIds(asset).filter(id => id !== assetId); // Remove self-references to avoid fetching the asset twice in case of circular relations
8740
+ // If asset has no parents, it's a root node itself
8741
+ if (!parentIdsOfAsset || parentIdsOfAsset.length === 0) {
8742
+ return [[asset]];
8743
+ }
8744
+ const { data: parents } = await this.inventory.list({
8745
+ pageSize: 2000,
8746
+ ids: parentIdsOfAsset.join(','),
8747
+ withParents: true,
8748
+ withChildren: true
8749
+ });
8750
+ // Deduplicate managed objects by ID to handle self-referencing parents and circular relationships
8751
+ const allManagedObjects = [asset, ...parents];
8752
+ const uniqueManagedObjectsMap = new Map(allManagedObjects.map(mo => [mo.id, mo]));
8753
+ const parentsAndAsset = Array.from(uniqueManagedObjectsMap.values());
8754
+ const roots = parentsAndAsset.filter(parent => this.getParentIds(parent).length === 0);
8755
+ // Find all paths from each root to the target asset
8756
+ const breadcrumbPaths = [];
8757
+ roots.forEach(root => {
8758
+ const paths = this.findAllPathsToAsset(root, assetId, parentsAndAsset);
8759
+ breadcrumbPaths.push(...paths);
8760
+ });
8761
+ return breadcrumbPaths;
8762
+ }
8763
+ catch (e) {
8764
+ this.alertService.addServerFailure(e);
8765
+ return [];
8766
+ }
8767
+ }
8768
+ /**
8769
+ * Gets all parent IDs of a managed object.
8770
+ */
8771
+ getParentIds(managedObject) {
8772
+ const assetParents = managedObject.assetParents?.references?.map(parent => parent.managedObject.id) ?? [];
8773
+ const deviceParents = managedObject.deviceParents?.references?.map(parent => parent.managedObject.id) ?? [];
8774
+ const additionParents = managedObject.additionParents?.references?.map(parent => parent.managedObject.id) ?? [];
8775
+ return [...assetParents, ...deviceParents, ...additionParents];
8776
+ }
8777
+ /**
8778
+ * Gets all child IDs of a managed object.
8779
+ */
8780
+ getChildrenIds(managedObject) {
8781
+ const childAssets = managedObject.childAssets?.references?.map(child => child.managedObject.id) ?? [];
8782
+ const childDevices = managedObject.childDevices?.references?.map(child => child.managedObject.id) ?? [];
8783
+ const childAdditions = managedObject.childAdditions?.references?.map(child => child.managedObject.id) ?? [];
8784
+ return [...childAssets, ...childDevices, ...childAdditions];
8785
+ }
8786
+ /**
8787
+ * Recursively finds all paths from a root node to the target asset.
8788
+ * Returns an array of paths, where each path is an array of managed objects.
8789
+ */
8790
+ findAllPathsToAsset(managedObject, targetAssetId, allManagedObjects, currentPath = []) {
8791
+ // Check for cycles - if this node is already in the current path, stop traversal
8792
+ if (currentPath.some(ancestor => ancestor.id === managedObject.id)) {
8793
+ return [];
8794
+ }
8795
+ const newPath = [...currentPath, managedObject];
8796
+ // If we found the target asset, return this path
8797
+ if (managedObject.id === targetAssetId) {
8798
+ return [newPath];
8799
+ }
8800
+ // Otherwise, continue searching in children
8801
+ const childrenIds = this.getChildrenIds(managedObject);
8802
+ const filteredChildren = allManagedObjects.filter(mo => childrenIds.includes(mo.id));
8803
+ const allPaths = [];
8804
+ filteredChildren.forEach(child => {
8805
+ const paths = this.findAllPathsToAsset(child, targetAssetId, allManagedObjects, newPath);
8806
+ allPaths.push(...paths);
8807
+ });
8808
+ return allPaths;
8809
+ }
8810
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AssetHierarchyService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
8811
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AssetHierarchyService, providedIn: 'root' }); }
8812
+ }
8813
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AssetHierarchyService, decorators: [{
8814
+ type: Injectable,
8815
+ args: [{
8816
+ providedIn: 'root'
8817
+ }]
8818
+ }] });
8819
+
8820
+ /**
8821
+ * Pipe that strips HTML tags from a string.
8822
+ *
8823
+ * Useful for creating plain text versions of HTML content,
8824
+ * such as for aria-labels or other accessibility attributes.
8825
+ *
8826
+ * @example
8827
+ * ```html
8828
+ * <div [attr.aria-label]="htmlContent | stripHtml">
8829
+ * <div [innerHTML]="htmlContent"></div>
8830
+ * </div>
8831
+ * ```
8832
+ *
8833
+ * @example
8834
+ * ```typescript
8835
+ * const html = '<p>Hello <strong>world</strong></p>';
8836
+ * // Result: 'Hello world'
8837
+ * ```
8838
+ */
8839
+ class StripHtmlPipe {
8840
+ /**
8841
+ * Strips HTML tags from the input string.
8842
+ *
8843
+ * @param value - The HTML string to process
8844
+ * @returns Plain text with HTML tags removed
8845
+ */
8846
+ transform(value) {
8847
+ if (!value) {
8848
+ return '';
8849
+ }
8850
+ const tmp = document.createElement('div');
8851
+ tmp.innerHTML = value;
8852
+ return tmp.textContent || tmp.innerText || '';
8853
+ }
8854
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: StripHtmlPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
8855
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: StripHtmlPipe, isStandalone: true, name: "stripHtml" }); }
8856
+ }
8857
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: StripHtmlPipe, decorators: [{
8858
+ type: Pipe,
8859
+ args: [{
8860
+ name: 'stripHtml',
8861
+ standalone: true,
8862
+ pure: true
8863
+ }]
8864
+ }] });
8865
+
8866
+ /**
8867
+ * Icon Panel Component
8868
+ *
8869
+ * Displays information in a grid of bordered panels, each with an icon, label, and content.
8870
+ * Useful for showing structured metadata, device information, connection status, etc.
8871
+ *
8872
+ * @example
8873
+ * ```typescript
8874
+ * sections: IconPanelSection[] = [
8875
+ * {
8876
+ * id: 'device-info',
8877
+ * label: 'Device Information',
8878
+ * icon: 'c8y-device',
8879
+ * visible: true,
8880
+ * content: '<p>Device ID: THM-001</p><p>Type: Sensor</p>',
8881
+ * colClass: 'col-xs-12 col-md-6'
8882
+ * },
8883
+ * {
8884
+ * id: 'status',
8885
+ * label: 'Status',
8886
+ * icon: 'c8y-connection',
8887
+ * visible: true,
8888
+ * content: 'Connected',
8889
+ * colClass: 'col-xs-12 col-md-6'
8890
+ * }
8891
+ * ];
8892
+ * ```
8893
+ *
8894
+ * ```html
8895
+ * <c8y-icon-panel [sections]="sections"></c8y-icon-panel>
8896
+ * ```
8897
+ *
8898
+ * You can also project additional content:
8899
+ * ```html
8900
+ * <c8y-icon-panel [sections]="sections">
8901
+ * <div class="col-xs-12">
8902
+ * <p>Additional custom content here</p>
8903
+ * </div>
8904
+ * </c8y-icon-panel>
8905
+ * ```
8906
+ */
8907
+ class IconPanelComponent {
8908
+ constructor() {
8909
+ /**
8910
+ * Array of sections to display in the panel
8911
+ */
8912
+ this.sections = [];
8913
+ /**
8914
+ * Accessible label for the icon panel region.
8915
+ */
8916
+ this.ariaLabel = 'Information sections';
8917
+ }
8918
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: IconPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8919
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: IconPanelComponent, isStandalone: true, selector: "c8y-icon-panel", inputs: { sections: "sections", ariaLabel: "ariaLabel" }, ngImport: i0, template: "<div\n class=\"d-flex row tight-grid flex-wrap a-i-stretch\"\n [attr.aria-label]=\"ariaLabel | translate\"\n role=\"region\"\n data-cy=\"c8y-icon-panel\"\n>\n @for (section of sections; track section.id) {\n @if (section.visible) {\n <div\n class=\"d-flex m-b-8\"\n [attr.aria-label]=\"\n (section.label | translate) + ': ' + (section.content | translate | stripHtml)\n \"\n role=\"definition\"\n [ngClass]=\"section.colClass || 'col-xs-12 col-md-6'\"\n [attr.data-cy]=\"section.dataCy\"\n >\n <div [ngClass]=\"section.containerClass || 'border-all fit-w d-flex'\">\n <div class=\"p-8\">\n <i\n [class]=\"'icon-24 m-t-4 c8y-icon ' + (section.iconClass || '')\"\n [c8yIcon]=\"section.icon\"\n aria-hidden=\"true\"\n ></i>\n </div>\n <div class=\"p-t-8 p-b-8 p-r-8 flex-grow\">\n <p class=\"text-label-small m-b-4\">{{ section.label | translate }}</p>\n <div\n class=\"small fit-w\"\n [innerHTML]=\"section.content | translate\"\n ></div>\n </div>\n </div>\n </div>\n }\n }\n\n <ng-content></ng-content>\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: StripHtmlPipe, name: "stripHtml" }] }); }
8920
+ }
8921
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: IconPanelComponent, decorators: [{
8922
+ type: Component,
8923
+ args: [{ selector: 'c8y-icon-panel', standalone: true, imports: [NgClass, C8yTranslatePipe, IconDirective, StripHtmlPipe], template: "<div\n class=\"d-flex row tight-grid flex-wrap a-i-stretch\"\n [attr.aria-label]=\"ariaLabel | translate\"\n role=\"region\"\n data-cy=\"c8y-icon-panel\"\n>\n @for (section of sections; track section.id) {\n @if (section.visible) {\n <div\n class=\"d-flex m-b-8\"\n [attr.aria-label]=\"\n (section.label | translate) + ': ' + (section.content | translate | stripHtml)\n \"\n role=\"definition\"\n [ngClass]=\"section.colClass || 'col-xs-12 col-md-6'\"\n [attr.data-cy]=\"section.dataCy\"\n >\n <div [ngClass]=\"section.containerClass || 'border-all fit-w d-flex'\">\n <div class=\"p-8\">\n <i\n [class]=\"'icon-24 m-t-4 c8y-icon ' + (section.iconClass || '')\"\n [c8yIcon]=\"section.icon\"\n aria-hidden=\"true\"\n ></i>\n </div>\n <div class=\"p-t-8 p-b-8 p-r-8 flex-grow\">\n <p class=\"text-label-small m-b-4\">{{ section.label | translate }}</p>\n <div\n class=\"small fit-w\"\n [innerHTML]=\"section.content | translate\"\n ></div>\n </div>\n </div>\n </div>\n }\n }\n\n <ng-content></ng-content>\n</div>\n" }]
8924
+ }], propDecorators: { sections: [{
8925
+ type: Input
8926
+ }], ariaLabel: [{
8927
+ type: Input
8928
+ }] } });
8929
+
8693
8930
  class GeoService {
8694
8931
  constructor() {
8695
8932
  this.C8Y_POSITION_FRAGMENT = 'c8y_Position';
@@ -13959,7 +14196,7 @@ class BreadcrumbService extends ExtensionPointForPlugins {
13959
14196
  }
13960
14197
  sortByPreferredPath(breadcrumbs) {
13961
14198
  if (this.preferredPath) {
13962
- return breadcrumbs.sort(bc => bc.items.find((item) => !!item.path.match(this.preferredPath)) ? -1 : 1);
14199
+ return breadcrumbs.sort(bc => bc.items.find((item) => !!item.path?.match(this.preferredPath)) ? -1 : 1);
13963
14200
  }
13964
14201
  return breadcrumbs;
13965
14202
  }
@@ -14378,6 +14615,8 @@ class BreadcrumbOutletComponent {
14378
14615
  constructor() {
14379
14616
  this.showAll = false;
14380
14617
  this.breadcrumbs = [];
14618
+ this.dropdownOpen = false;
14619
+ this.GROUP_ICON = 'c8y-group';
14381
14620
  }
14382
14621
  /**
14383
14622
  * For upgrade only. Old angularjs routes start with hash, new ones not.
@@ -14385,23 +14624,27 @@ class BreadcrumbOutletComponent {
14385
14624
  normalizePath(path) {
14386
14625
  return path?.replace(/^#\/?/, '');
14387
14626
  }
14627
+ ngOnChanges() {
14628
+ this.dropdownOpen =
14629
+ this.breadcrumbs?.length > 1 && this.breadcrumbs.some(b => b.forceDropdownOpen);
14630
+ }
14388
14631
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: BreadcrumbOutletComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
14389
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: BreadcrumbOutletComponent, isStandalone: true, selector: "c8y-breadcrumb-outlet", inputs: { breadcrumbs: "breadcrumbs" }, ngImport: i0, template: "<div\n class=\"breadcrumbs-container\"\n [ngClass]=\"{\n multiple: breadcrumbs.length > 1,\n open: showAll\n }\"\n *ngIf=\"breadcrumbs && breadcrumbs.length > 0\"\n>\n <button\n class=\"btn-show-all-breadcrumbs pull-left\"\n type=\"button\"\n title=\"{{ 'Expand/collapse all breadcrumbs' | translate }}\"\n *ngIf=\"breadcrumbs.length > 1\"\n (click)=\"showAll = !showAll\"\n >\n <i\n *ngIf=\"!showAll\"\n [c8yIcon]=\"'caret-right'\"\n tooltip=\"{{ 'Show all breadcrumbs' | translate }}\"\n container=\"body\"\n placement=\"top\"\n ></i>\n <i\n *ngIf=\"showAll\"\n [c8yIcon]=\"'caret-down'\"\n tooltip=\"{{ 'Expand breadcrumbs' | translate }}\"\n container=\"body\"\n placement=\"top\"\n ></i>\n </button>\n\n <ul class=\"breadcrumbs text-muted\" [attr.role]=\"'navigation'\" *ngFor=\"let breadcrumb of breadcrumbs; let first = first\">\n <ng-container *ngIf=\"first || showAll\">\n <li class=\"text-muted\" *ngFor=\"let item of breadcrumb.items; let firstItem = first\">\n <span *ngIf=\"!firstItem\">></span>\n <ng-container\n *c8yOutlet=\"item.component || item.template; injector: breadcrumb.injector\"\n ></ng-container>\n <ng-container *ngIf=\"item.label && item.path\">\n <a\n [routerLink]=\"normalizePath(item.path)\"\n class=\"word-break\"\n title=\"{{ item.label | translate }}\"\n [attr.aria-label]=\"'breadcrumb'\"\n >\n <i [c8yIcon]=\"item.icon\" *ngIf=\"firstItem\" class=\"m-r-4\"></i>\n <span>{{ item.label | translate }}</span>\n </a>\n </ng-container>\n <ng-container *ngIf=\"item.label && !item.path\">\n <i [c8yIcon]=\"item.icon\" *ngIf=\"firstItem\" class=\"m-r-4\"></i>\n <span title=\"{{ item.label | translate }}\">{{ item.label | translate }}</span>\n </ng-container>\n </li>\n </ng-container>\n </ul>\n</div>\n", dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i1$5.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: OutletDirective, selector: "[c8yOutlet]", inputs: ["c8yOutlet", "c8yOutletProperties", "c8yOutletInjector"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
14632
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: BreadcrumbOutletComponent, isStandalone: true, selector: "c8y-breadcrumb-outlet", inputs: { breadcrumbs: "breadcrumbs", dropdownOpen: "dropdownOpen" }, usesOnChanges: true, ngImport: i0, template: "@if (breadcrumbs && breadcrumbs.length > 0) {\n <div class=\"breadcrumbs-container d-flex\">\n @if (breadcrumbs.length > 1) {\n <div\n container=\"body\"\n dropdown\n #breadcrumbDropdown=\"bs-dropdown\"\n [isOpen]=\"dropdownOpen\"\n >\n <button\n class=\"btn-clean btn-xs btn p-l-4 p-r-4\"\n title=\"{{ 'Show all paths' | translate }}\"\n type=\"button\"\n dropdownToggle\n >\n <i [c8yIcon]=\"breadcrumbDropdown.isOpen ? 'caret-down' : 'caret-right'\"></i>\n </button>\n <div\n class=\"dropdown-menu\"\n *dropdownMenu\n >\n @for (breadcrumb of breadcrumbs; track breadcrumb; let i = $index; let first = $first) {\n <!-- in dropdown menu, show all breadcrumbs except the first one -->\n @if (!first) {\n <div class=\"p-t-8 p-r-8 p-b-8 p-l-16 separator-bottom\">\n <ul class=\"breadcrumbs text-muted m-l-4\">\n @for (\n item of breadcrumb.items;\n track item;\n let isLast = $last;\n let isFirst = $first\n ) {\n <li class=\"text-muted\">\n @if (!isFirst) {\n <span><i [c8yIcon]=\"'forward'\"></i></span>\n }\n @if (!isLast) {\n <a\n class=\"word-break\"\n [routerLink]=\"item.path\"\n >\n @if (item.icon) {\n <i\n class=\"m-r-4\"\n [c8yIcon]=\"item.icon\"\n ></i>\n }\n <span>{{ item.label | translate }}</span>\n </a>\n } @else {\n @if (item.icon) {\n <i\n class=\"m-r-4\"\n [c8yIcon]=\"item.icon\"\n ></i>\n }\n <span>{{ item.label | translate }}</span>\n }\n </li>\n }\n </ul>\n </div>\n }\n }\n </div>\n </div>\n }\n <ul\n class=\"breadcrumbs text-muted\"\n [attr.role]=\"'navigation'\"\n >\n <!-- show only first breadcrumb- applicable both for single and multiple breadcrumb cases (for multiple breadcrumbs, rest are in dropdown) -->\n @for (item of breadcrumbs[0].items; track item; let firstItem = $first) {\n <li class=\"text-muted\">\n @if (!firstItem) {\n <span><i c8yIcon=\"forward\"></i></span>\n }\n <ng-container\n *c8yOutlet=\"item.component || item.template; injector: breadcrumbs[0].injector\"\n ></ng-container>\n @if (item.label && item.path) {\n <a\n class=\"word-break\"\n title=\"{{ item.label | translate }}\"\n [attr.aria-label]=\"'breadcrumb'\"\n [routerLink]=\"normalizePath(item.path)\"\n >\n <i\n class=\"m-r-4\"\n [c8yIcon]=\"item.icon\"\n ></i>\n <span>{{ item.label | translate }}</span>\n </a>\n }\n @if (item.label && !item.path) {\n <i\n class=\"m-r-4\"\n [c8yIcon]=\"item.icon\"\n ></i>\n <span title=\"{{ item.label | translate }}\">{{ item.label | translate }}</span>\n }\n </li>\n }\n </ul>\n </div>\n}\n", dependencies: [{ kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: OutletDirective, selector: "[c8yOutlet]", inputs: ["c8yOutlet", "c8yOutletProperties", "c8yOutletInjector"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: BsDropdownModule }, { kind: "directive", type: i1$4.BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { kind: "directive", type: i1$4.BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { kind: "directive", type: i1$4.BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
14390
14633
  }
14391
14634
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: BreadcrumbOutletComponent, decorators: [{
14392
14635
  type: Component,
14393
14636
  args: [{ selector: 'c8y-breadcrumb-outlet', standalone: true, imports: [
14394
- NgIf,
14395
- NgClass,
14396
14637
  IconDirective,
14397
14638
  TooltipModule,
14398
- NgFor,
14399
14639
  OutletDirective,
14400
14640
  RouterLink,
14401
- C8yTranslatePipe
14402
- ], template: "<div\n class=\"breadcrumbs-container\"\n [ngClass]=\"{\n multiple: breadcrumbs.length > 1,\n open: showAll\n }\"\n *ngIf=\"breadcrumbs && breadcrumbs.length > 0\"\n>\n <button\n class=\"btn-show-all-breadcrumbs pull-left\"\n type=\"button\"\n title=\"{{ 'Expand/collapse all breadcrumbs' | translate }}\"\n *ngIf=\"breadcrumbs.length > 1\"\n (click)=\"showAll = !showAll\"\n >\n <i\n *ngIf=\"!showAll\"\n [c8yIcon]=\"'caret-right'\"\n tooltip=\"{{ 'Show all breadcrumbs' | translate }}\"\n container=\"body\"\n placement=\"top\"\n ></i>\n <i\n *ngIf=\"showAll\"\n [c8yIcon]=\"'caret-down'\"\n tooltip=\"{{ 'Expand breadcrumbs' | translate }}\"\n container=\"body\"\n placement=\"top\"\n ></i>\n </button>\n\n <ul class=\"breadcrumbs text-muted\" [attr.role]=\"'navigation'\" *ngFor=\"let breadcrumb of breadcrumbs; let first = first\">\n <ng-container *ngIf=\"first || showAll\">\n <li class=\"text-muted\" *ngFor=\"let item of breadcrumb.items; let firstItem = first\">\n <span *ngIf=\"!firstItem\">></span>\n <ng-container\n *c8yOutlet=\"item.component || item.template; injector: breadcrumb.injector\"\n ></ng-container>\n <ng-container *ngIf=\"item.label && item.path\">\n <a\n [routerLink]=\"normalizePath(item.path)\"\n class=\"word-break\"\n title=\"{{ item.label | translate }}\"\n [attr.aria-label]=\"'breadcrumb'\"\n >\n <i [c8yIcon]=\"item.icon\" *ngIf=\"firstItem\" class=\"m-r-4\"></i>\n <span>{{ item.label | translate }}</span>\n </a>\n </ng-container>\n <ng-container *ngIf=\"item.label && !item.path\">\n <i [c8yIcon]=\"item.icon\" *ngIf=\"firstItem\" class=\"m-r-4\"></i>\n <span title=\"{{ item.label | translate }}\">{{ item.label | translate }}</span>\n </ng-container>\n </li>\n </ng-container>\n </ul>\n</div>\n" }]
14641
+ C8yTranslatePipe,
14642
+ BsDropdownModule
14643
+ ], template: "@if (breadcrumbs && breadcrumbs.length > 0) {\n <div class=\"breadcrumbs-container d-flex\">\n @if (breadcrumbs.length > 1) {\n <div\n container=\"body\"\n dropdown\n #breadcrumbDropdown=\"bs-dropdown\"\n [isOpen]=\"dropdownOpen\"\n >\n <button\n class=\"btn-clean btn-xs btn p-l-4 p-r-4\"\n title=\"{{ 'Show all paths' | translate }}\"\n type=\"button\"\n dropdownToggle\n >\n <i [c8yIcon]=\"breadcrumbDropdown.isOpen ? 'caret-down' : 'caret-right'\"></i>\n </button>\n <div\n class=\"dropdown-menu\"\n *dropdownMenu\n >\n @for (breadcrumb of breadcrumbs; track breadcrumb; let i = $index; let first = $first) {\n <!-- in dropdown menu, show all breadcrumbs except the first one -->\n @if (!first) {\n <div class=\"p-t-8 p-r-8 p-b-8 p-l-16 separator-bottom\">\n <ul class=\"breadcrumbs text-muted m-l-4\">\n @for (\n item of breadcrumb.items;\n track item;\n let isLast = $last;\n let isFirst = $first\n ) {\n <li class=\"text-muted\">\n @if (!isFirst) {\n <span><i [c8yIcon]=\"'forward'\"></i></span>\n }\n @if (!isLast) {\n <a\n class=\"word-break\"\n [routerLink]=\"item.path\"\n >\n @if (item.icon) {\n <i\n class=\"m-r-4\"\n [c8yIcon]=\"item.icon\"\n ></i>\n }\n <span>{{ item.label | translate }}</span>\n </a>\n } @else {\n @if (item.icon) {\n <i\n class=\"m-r-4\"\n [c8yIcon]=\"item.icon\"\n ></i>\n }\n <span>{{ item.label | translate }}</span>\n }\n </li>\n }\n </ul>\n </div>\n }\n }\n </div>\n </div>\n }\n <ul\n class=\"breadcrumbs text-muted\"\n [attr.role]=\"'navigation'\"\n >\n <!-- show only first breadcrumb- applicable both for single and multiple breadcrumb cases (for multiple breadcrumbs, rest are in dropdown) -->\n @for (item of breadcrumbs[0].items; track item; let firstItem = $first) {\n <li class=\"text-muted\">\n @if (!firstItem) {\n <span><i c8yIcon=\"forward\"></i></span>\n }\n <ng-container\n *c8yOutlet=\"item.component || item.template; injector: breadcrumbs[0].injector\"\n ></ng-container>\n @if (item.label && item.path) {\n <a\n class=\"word-break\"\n title=\"{{ item.label | translate }}\"\n [attr.aria-label]=\"'breadcrumb'\"\n [routerLink]=\"normalizePath(item.path)\"\n >\n <i\n class=\"m-r-4\"\n [c8yIcon]=\"item.icon\"\n ></i>\n <span>{{ item.label | translate }}</span>\n </a>\n }\n @if (item.label && !item.path) {\n <i\n class=\"m-r-4\"\n [c8yIcon]=\"item.icon\"\n ></i>\n <span title=\"{{ item.label | translate }}\">{{ item.label | translate }}</span>\n }\n </li>\n }\n </ul>\n </div>\n}\n" }]
14403
14644
  }], propDecorators: { breadcrumbs: [{
14404
14645
  type: Input
14646
+ }], dropdownOpen: [{
14647
+ type: Input
14405
14648
  }] } });
14406
14649
 
14407
14650
  class SearchOutletComponent {
@@ -14492,13 +14735,12 @@ class HeaderBarComponent {
14492
14735
  this.headerService.closeRightDrawer();
14493
14736
  }
14494
14737
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: HeaderBarComponent, deps: [{ token: HeaderService }, { token: ActionService }, { token: BreadcrumbService }, { token: SearchService }, { token: AppStateService }, { token: UserMenuService }, { token: DocsService }, { token: i4.ApiService }], target: i0.ɵɵFactoryTarget.Component }); }
14495
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: HeaderBarComponent, isStandalone: true, selector: "c8y-header-bar", inputs: { simple: "simple" }, ngImport: i0, template: "<div\n class=\"app-main-header\"\n [ngClass]=\"{\n open: (headerService.navigatorOpen$ | async) && !simple,\n drawerOpen: headerService.rightDrawerOpen$ | async\n }\"\n>\n <div\n class=\"header-bar\"\n role=\"banner\"\n >\n <button\n class=\"navigator-toggle main-header-button\"\n title=\"{{ 'Toggle navigation bar' | translate }}\"\n [attr.aria-expanded]=\"headerService.navigatorOpen$ | async\"\n [attr.aria-controls]=\"'navigator'\"\n type=\"button\"\n data-cy=\"header-bar--main-header-button\"\n (click)=\"headerService.toggleNavigator()\"\n *ngIf=\"(headerService.canToggleNavigator$ | async) && !simple\"\n >\n <i\n [c8yIcon]=\"'outdent'\"\n *ngIf=\"!(headerService.navigatorOpen$ | async)\"\n ></i>\n <i\n [c8yIcon]=\"'dedent-right'\"\n *ngIf=\"headerService.navigatorOpen$ | async\"\n ></i>\n </button>\n <div class=\"app-view\">\n <c8y-app-icon\n [name]=\"(appState$ | async).app?.name\"\n [contextPath]=\"(appState$ | async).app?.contextPath\"\n [app]=\"(app$ | async) || (appState$ | async).app\"\n ></c8y-app-icon>\n\n <span class=\"page-header\">\n <c8y-title-outlet></c8y-title-outlet>\n <c8y-breadcrumb-outlet\n class=\"app-breadcrumbs\"\n *ngIf=\"!simple\"\n [breadcrumbs]=\"breadcrumbService.items$ | async\"\n ></c8y-breadcrumb-outlet>\n </span>\n </div>\n <c8y-search-outlet\n class=\"main-header-item\"\n *ngIf=\"!simple\"\n [search]=\"searchService.items$ | async\"\n ></c8y-search-outlet>\n <c8y-action-outlet\n *ngIf=\"!simple\"\n [items]=\"actionService.items$ | async\"\n ></c8y-action-outlet>\n <c8y-app-switcher\n class=\"main-header-item\"\n title=\"{{ 'Application switcher' | translate }}\"\n *ngIf=\"appState.currentUser.value\"\n ></c8y-app-switcher>\n <ng-container *ngIf=\"showNotification$ | async; else noNotification\">\n <button\n class=\"main-header-button drawer-toggle\"\n [attr.aria-label]=\"appState.currentUser | async | shortenUserName\"\n tooltip=\"{{ appState.currentUser | async | shortenUserName }}\n{{ 'New features available' | translate }}\"\n placement=\"left\"\n [attr.aria-expanded]=\"headerService.rightDrawerOpen$ | async\"\n [attr.aria-controls]=\"'right-drawer'\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"toggleDrawer()\"\n [attr.data-cy]=\"'right-drawer-toggle-button'\"\n >\n <span\n class=\"user-dot user-dot-notification\"\n *ngIf=\"appState.currentUser | async\"\n data-cy=\"header-bar--user-dot\"\n >\n {{ appState.currentUser | async | userNameInitials }}\n </span>\n <span class=\"close-dot\">&times;</span>\n </button>\n <div\n class=\"p-relative a-s-stretch no-pointer\"\n *ngIf=\"!(headerService.rightDrawerOpen$ | async)\"\n >\n <span\n class=\"c8y-pulse c8y-pulse--md active\"\n *ngIf=\"showNotification$ | async\"\n ></span>\n </div>\n </ng-container>\n <ng-template #noNotification>\n <button\n class=\"main-header-button drawer-toggle\"\n [attr.aria-label]=\"appState.currentUser | async | shortenUserName\"\n tooltip=\"{{ appState.currentUser | async | shortenUserName }}\"\n placement=\"left\"\n [attr.aria-expanded]=\"headerService.rightDrawerOpen$ | async\"\n [attr.aria-controls]=\"'right-drawer'\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"toggleDrawer()\"\n [attr.data-cy]=\"'right-drawer-toggle-button'\"\n >\n <span\n class=\"user-dot user-dot-notification\"\n *ngIf=\"appState.currentUser | async\"\n data-cy=\"header-bar--user-dot\"\n >\n {{ appState.currentUser | async | userNameInitials }}\n </span>\n <span class=\"close-dot\">&times;</span>\n </button>\n </ng-template>\n </div>\n <div class=\"head-toggler\">\n <button\n title=\"{{ 'Toggle' | translate }}\"\n type=\"button\"\n data-cy=\"header-bar--toggle\"\n (click)=\"headerService.toggle()\"\n >\n <i [c8yIcon]=\"'angle-right'\"></i>\n </button>\n </div>\n <c8y-drawer-outlet\n id=\"right-drawer\"\n [tabindex]=\"(headerService.rightDrawerOpen$ | async) ? '0' : '-1'\"\n [attr.aria-hidden]=\"!(headerService.rightDrawerOpen$ | async)\"\n position=\"right\"\n [open]=\"headerService.rightDrawerOpen$ | async\"\n ></c8y-drawer-outlet>\n <div\n class=\"loading-bar\"\n [ngClass]=\"loadingClass$ | async\"\n ></div>\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "component", type: AppIconComponent, selector: "c8y-app-icon", inputs: ["contextPath", "name", "app"] }, { kind: "component", type: TitleOutletComponent, selector: "c8y-title-outlet" }, { kind: "component", type: BreadcrumbOutletComponent, selector: "c8y-breadcrumb-outlet", inputs: ["breadcrumbs"] }, { kind: "component", type: SearchOutletComponent, selector: "c8y-search-outlet", inputs: ["search"] }, { kind: "component", type: ActionOutletComponent, selector: "c8y-action-outlet", inputs: ["items"] }, { kind: "component", type: AppSwitcherComponent, selector: "c8y-app-switcher" }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i1$5.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: DrawerOutletComponent, selector: "c8y-drawer-outlet", inputs: ["position", "open"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: ShortenUserNamePipe, name: "shortenUserName" }, { kind: "pipe", type: UserNameInitialsPipe, name: "userNameInitials" }] }); }
14738
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: HeaderBarComponent, isStandalone: true, selector: "c8y-header-bar", inputs: { simple: "simple" }, ngImport: i0, template: "<div\n class=\"app-main-header\"\n [ngClass]=\"{\n open: (headerService.navigatorOpen$ | async) && !simple,\n drawerOpen: headerService.rightDrawerOpen$ | async\n }\"\n>\n <div\n class=\"header-bar\"\n role=\"banner\"\n >\n @if ((headerService.canToggleNavigator$ | async) && !simple) {\n <button\n class=\"navigator-toggle main-header-button\"\n title=\"{{ 'Toggle navigation bar' | translate }}\"\n [attr.aria-expanded]=\"headerService.navigatorOpen$ | async\"\n [attr.aria-controls]=\"'navigator'\"\n type=\"button\"\n data-cy=\"header-bar--main-header-button\"\n (click)=\"headerService.toggleNavigator()\"\n >\n @if (!(headerService.navigatorOpen$ | async)) {\n <i [c8yIcon]=\"'outdent'\"></i>\n }\n @if (headerService.navigatorOpen$ | async) {\n <i [c8yIcon]=\"'dedent-right'\"></i>\n }\n </button>\n }\n <div class=\"app-view\">\n <c8y-app-icon\n [name]=\"(appState$ | async).app?.name\"\n [contextPath]=\"(appState$ | async).app?.contextPath\"\n [app]=\"(app$ | async) || (appState$ | async).app\"\n ></c8y-app-icon>\n\n <span class=\"page-header\">\n <c8y-title-outlet></c8y-title-outlet>\n @if (!simple) {\n <c8y-breadcrumb-outlet\n class=\"app-breadcrumbs\"\n [breadcrumbs]=\"breadcrumbService.items$ | async\"\n ></c8y-breadcrumb-outlet>\n }\n </span>\n </div>\n @if (!simple) {\n <c8y-search-outlet\n class=\"main-header-item\"\n [search]=\"searchService.items$ | async\"\n ></c8y-search-outlet>\n }\n @if (!simple) {\n <c8y-action-outlet [items]=\"actionService.items$ | async\"></c8y-action-outlet>\n }\n @if (appState.currentUser.value) {\n <c8y-app-switcher\n class=\"main-header-item\"\n title=\"{{ 'Application switcher' | translate }}\"\n ></c8y-app-switcher>\n }\n @if (showNotification$ | async) {\n <button\n class=\"main-header-button drawer-toggle\"\n [attr.aria-label]=\"appState.currentUser | async | shortenUserName\"\n tooltip=\"{{ appState.currentUser | async | shortenUserName }}\n{{ 'New features available' | translate }}\"\n placement=\"left\"\n [attr.aria-expanded]=\"headerService.rightDrawerOpen$ | async\"\n [attr.aria-controls]=\"'right-drawer'\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"toggleDrawer()\"\n [attr.data-cy]=\"'right-drawer-toggle-button'\"\n >\n @if (appState.currentUser | async) {\n <span\n class=\"user-dot user-dot-notification\"\n data-cy=\"header-bar--user-dot\"\n >\n {{ appState.currentUser | async | userNameInitials }}\n </span>\n }\n <span class=\"close-dot\">&times;</span>\n </button>\n @if (!(headerService.rightDrawerOpen$ | async)) {\n <div class=\"p-relative a-s-stretch no-pointer\">\n @if (showNotification$ | async) {\n <span class=\"c8y-pulse c8y-pulse--md active\"></span>\n }\n </div>\n }\n } @else {\n <button\n class=\"main-header-button drawer-toggle\"\n [attr.aria-label]=\"appState.currentUser | async | shortenUserName\"\n tooltip=\"{{ appState.currentUser | async | shortenUserName }}\"\n placement=\"left\"\n [attr.aria-expanded]=\"headerService.rightDrawerOpen$ | async\"\n [attr.aria-controls]=\"'right-drawer'\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"toggleDrawer()\"\n [attr.data-cy]=\"'right-drawer-toggle-button'\"\n >\n @if (appState.currentUser | async) {\n <span\n class=\"user-dot user-dot-notification\"\n data-cy=\"header-bar--user-dot\"\n >\n {{ appState.currentUser | async | userNameInitials }}\n </span>\n }\n <span class=\"close-dot\">&times;</span>\n </button>\n }\n </div>\n <div class=\"head-toggler\">\n <button\n title=\"{{ 'Toggle' | translate }}\"\n type=\"button\"\n data-cy=\"header-bar--toggle\"\n (click)=\"headerService.toggle()\"\n >\n <i [c8yIcon]=\"'angle-right'\"></i>\n </button>\n </div>\n <c8y-drawer-outlet\n id=\"right-drawer\"\n [tabindex]=\"(headerService.rightDrawerOpen$ | async) ? '0' : '-1'\"\n [attr.aria-hidden]=\"!(headerService.rightDrawerOpen$ | async)\"\n position=\"right\"\n [open]=\"headerService.rightDrawerOpen$ | async\"\n ></c8y-drawer-outlet>\n <div\n class=\"loading-bar\"\n [ngClass]=\"loadingClass$ | async\"\n ></div>\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "component", type: AppIconComponent, selector: "c8y-app-icon", inputs: ["contextPath", "name", "app"] }, { kind: "component", type: TitleOutletComponent, selector: "c8y-title-outlet" }, { kind: "component", type: BreadcrumbOutletComponent, selector: "c8y-breadcrumb-outlet", inputs: ["breadcrumbs", "dropdownOpen"] }, { kind: "component", type: SearchOutletComponent, selector: "c8y-search-outlet", inputs: ["search"] }, { kind: "component", type: ActionOutletComponent, selector: "c8y-action-outlet", inputs: ["items"] }, { kind: "component", type: AppSwitcherComponent, selector: "c8y-app-switcher" }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i1$5.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: DrawerOutletComponent, selector: "c8y-drawer-outlet", inputs: ["position", "open"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: ShortenUserNamePipe, name: "shortenUserName" }, { kind: "pipe", type: UserNameInitialsPipe, name: "userNameInitials" }] }); }
14496
14739
  }
14497
14740
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: HeaderBarComponent, decorators: [{
14498
14741
  type: Component,
14499
14742
  args: [{ selector: 'c8y-header-bar', standalone: true, imports: [
14500
14743
  NgClass,
14501
- NgIf,
14502
14744
  IconDirective,
14503
14745
  AppIconComponent,
14504
14746
  TitleOutletComponent,
@@ -14512,7 +14754,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
14512
14754
  AsyncPipe,
14513
14755
  ShortenUserNamePipe,
14514
14756
  UserNameInitialsPipe
14515
- ], template: "<div\n class=\"app-main-header\"\n [ngClass]=\"{\n open: (headerService.navigatorOpen$ | async) && !simple,\n drawerOpen: headerService.rightDrawerOpen$ | async\n }\"\n>\n <div\n class=\"header-bar\"\n role=\"banner\"\n >\n <button\n class=\"navigator-toggle main-header-button\"\n title=\"{{ 'Toggle navigation bar' | translate }}\"\n [attr.aria-expanded]=\"headerService.navigatorOpen$ | async\"\n [attr.aria-controls]=\"'navigator'\"\n type=\"button\"\n data-cy=\"header-bar--main-header-button\"\n (click)=\"headerService.toggleNavigator()\"\n *ngIf=\"(headerService.canToggleNavigator$ | async) && !simple\"\n >\n <i\n [c8yIcon]=\"'outdent'\"\n *ngIf=\"!(headerService.navigatorOpen$ | async)\"\n ></i>\n <i\n [c8yIcon]=\"'dedent-right'\"\n *ngIf=\"headerService.navigatorOpen$ | async\"\n ></i>\n </button>\n <div class=\"app-view\">\n <c8y-app-icon\n [name]=\"(appState$ | async).app?.name\"\n [contextPath]=\"(appState$ | async).app?.contextPath\"\n [app]=\"(app$ | async) || (appState$ | async).app\"\n ></c8y-app-icon>\n\n <span class=\"page-header\">\n <c8y-title-outlet></c8y-title-outlet>\n <c8y-breadcrumb-outlet\n class=\"app-breadcrumbs\"\n *ngIf=\"!simple\"\n [breadcrumbs]=\"breadcrumbService.items$ | async\"\n ></c8y-breadcrumb-outlet>\n </span>\n </div>\n <c8y-search-outlet\n class=\"main-header-item\"\n *ngIf=\"!simple\"\n [search]=\"searchService.items$ | async\"\n ></c8y-search-outlet>\n <c8y-action-outlet\n *ngIf=\"!simple\"\n [items]=\"actionService.items$ | async\"\n ></c8y-action-outlet>\n <c8y-app-switcher\n class=\"main-header-item\"\n title=\"{{ 'Application switcher' | translate }}\"\n *ngIf=\"appState.currentUser.value\"\n ></c8y-app-switcher>\n <ng-container *ngIf=\"showNotification$ | async; else noNotification\">\n <button\n class=\"main-header-button drawer-toggle\"\n [attr.aria-label]=\"appState.currentUser | async | shortenUserName\"\n tooltip=\"{{ appState.currentUser | async | shortenUserName }}\n{{ 'New features available' | translate }}\"\n placement=\"left\"\n [attr.aria-expanded]=\"headerService.rightDrawerOpen$ | async\"\n [attr.aria-controls]=\"'right-drawer'\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"toggleDrawer()\"\n [attr.data-cy]=\"'right-drawer-toggle-button'\"\n >\n <span\n class=\"user-dot user-dot-notification\"\n *ngIf=\"appState.currentUser | async\"\n data-cy=\"header-bar--user-dot\"\n >\n {{ appState.currentUser | async | userNameInitials }}\n </span>\n <span class=\"close-dot\">&times;</span>\n </button>\n <div\n class=\"p-relative a-s-stretch no-pointer\"\n *ngIf=\"!(headerService.rightDrawerOpen$ | async)\"\n >\n <span\n class=\"c8y-pulse c8y-pulse--md active\"\n *ngIf=\"showNotification$ | async\"\n ></span>\n </div>\n </ng-container>\n <ng-template #noNotification>\n <button\n class=\"main-header-button drawer-toggle\"\n [attr.aria-label]=\"appState.currentUser | async | shortenUserName\"\n tooltip=\"{{ appState.currentUser | async | shortenUserName }}\"\n placement=\"left\"\n [attr.aria-expanded]=\"headerService.rightDrawerOpen$ | async\"\n [attr.aria-controls]=\"'right-drawer'\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"toggleDrawer()\"\n [attr.data-cy]=\"'right-drawer-toggle-button'\"\n >\n <span\n class=\"user-dot user-dot-notification\"\n *ngIf=\"appState.currentUser | async\"\n data-cy=\"header-bar--user-dot\"\n >\n {{ appState.currentUser | async | userNameInitials }}\n </span>\n <span class=\"close-dot\">&times;</span>\n </button>\n </ng-template>\n </div>\n <div class=\"head-toggler\">\n <button\n title=\"{{ 'Toggle' | translate }}\"\n type=\"button\"\n data-cy=\"header-bar--toggle\"\n (click)=\"headerService.toggle()\"\n >\n <i [c8yIcon]=\"'angle-right'\"></i>\n </button>\n </div>\n <c8y-drawer-outlet\n id=\"right-drawer\"\n [tabindex]=\"(headerService.rightDrawerOpen$ | async) ? '0' : '-1'\"\n [attr.aria-hidden]=\"!(headerService.rightDrawerOpen$ | async)\"\n position=\"right\"\n [open]=\"headerService.rightDrawerOpen$ | async\"\n ></c8y-drawer-outlet>\n <div\n class=\"loading-bar\"\n [ngClass]=\"loadingClass$ | async\"\n ></div>\n</div>\n" }]
14757
+ ], template: "<div\n class=\"app-main-header\"\n [ngClass]=\"{\n open: (headerService.navigatorOpen$ | async) && !simple,\n drawerOpen: headerService.rightDrawerOpen$ | async\n }\"\n>\n <div\n class=\"header-bar\"\n role=\"banner\"\n >\n @if ((headerService.canToggleNavigator$ | async) && !simple) {\n <button\n class=\"navigator-toggle main-header-button\"\n title=\"{{ 'Toggle navigation bar' | translate }}\"\n [attr.aria-expanded]=\"headerService.navigatorOpen$ | async\"\n [attr.aria-controls]=\"'navigator'\"\n type=\"button\"\n data-cy=\"header-bar--main-header-button\"\n (click)=\"headerService.toggleNavigator()\"\n >\n @if (!(headerService.navigatorOpen$ | async)) {\n <i [c8yIcon]=\"'outdent'\"></i>\n }\n @if (headerService.navigatorOpen$ | async) {\n <i [c8yIcon]=\"'dedent-right'\"></i>\n }\n </button>\n }\n <div class=\"app-view\">\n <c8y-app-icon\n [name]=\"(appState$ | async).app?.name\"\n [contextPath]=\"(appState$ | async).app?.contextPath\"\n [app]=\"(app$ | async) || (appState$ | async).app\"\n ></c8y-app-icon>\n\n <span class=\"page-header\">\n <c8y-title-outlet></c8y-title-outlet>\n @if (!simple) {\n <c8y-breadcrumb-outlet\n class=\"app-breadcrumbs\"\n [breadcrumbs]=\"breadcrumbService.items$ | async\"\n ></c8y-breadcrumb-outlet>\n }\n </span>\n </div>\n @if (!simple) {\n <c8y-search-outlet\n class=\"main-header-item\"\n [search]=\"searchService.items$ | async\"\n ></c8y-search-outlet>\n }\n @if (!simple) {\n <c8y-action-outlet [items]=\"actionService.items$ | async\"></c8y-action-outlet>\n }\n @if (appState.currentUser.value) {\n <c8y-app-switcher\n class=\"main-header-item\"\n title=\"{{ 'Application switcher' | translate }}\"\n ></c8y-app-switcher>\n }\n @if (showNotification$ | async) {\n <button\n class=\"main-header-button drawer-toggle\"\n [attr.aria-label]=\"appState.currentUser | async | shortenUserName\"\n tooltip=\"{{ appState.currentUser | async | shortenUserName }}\n{{ 'New features available' | translate }}\"\n placement=\"left\"\n [attr.aria-expanded]=\"headerService.rightDrawerOpen$ | async\"\n [attr.aria-controls]=\"'right-drawer'\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"toggleDrawer()\"\n [attr.data-cy]=\"'right-drawer-toggle-button'\"\n >\n @if (appState.currentUser | async) {\n <span\n class=\"user-dot user-dot-notification\"\n data-cy=\"header-bar--user-dot\"\n >\n {{ appState.currentUser | async | userNameInitials }}\n </span>\n }\n <span class=\"close-dot\">&times;</span>\n </button>\n @if (!(headerService.rightDrawerOpen$ | async)) {\n <div class=\"p-relative a-s-stretch no-pointer\">\n @if (showNotification$ | async) {\n <span class=\"c8y-pulse c8y-pulse--md active\"></span>\n }\n </div>\n }\n } @else {\n <button\n class=\"main-header-button drawer-toggle\"\n [attr.aria-label]=\"appState.currentUser | async | shortenUserName\"\n tooltip=\"{{ appState.currentUser | async | shortenUserName }}\"\n placement=\"left\"\n [attr.aria-expanded]=\"headerService.rightDrawerOpen$ | async\"\n [attr.aria-controls]=\"'right-drawer'\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"toggleDrawer()\"\n [attr.data-cy]=\"'right-drawer-toggle-button'\"\n >\n @if (appState.currentUser | async) {\n <span\n class=\"user-dot user-dot-notification\"\n data-cy=\"header-bar--user-dot\"\n >\n {{ appState.currentUser | async | userNameInitials }}\n </span>\n }\n <span class=\"close-dot\">&times;</span>\n </button>\n }\n </div>\n <div class=\"head-toggler\">\n <button\n title=\"{{ 'Toggle' | translate }}\"\n type=\"button\"\n data-cy=\"header-bar--toggle\"\n (click)=\"headerService.toggle()\"\n >\n <i [c8yIcon]=\"'angle-right'\"></i>\n </button>\n </div>\n <c8y-drawer-outlet\n id=\"right-drawer\"\n [tabindex]=\"(headerService.rightDrawerOpen$ | async) ? '0' : '-1'\"\n [attr.aria-hidden]=\"!(headerService.rightDrawerOpen$ | async)\"\n position=\"right\"\n [open]=\"headerService.rightDrawerOpen$ | async\"\n ></c8y-drawer-outlet>\n <div\n class=\"loading-bar\"\n [ngClass]=\"loadingClass$ | async\"\n ></div>\n</div>\n" }]
14516
14758
  }], ctorParameters: () => [{ type: HeaderService }, { type: ActionService }, { type: BreadcrumbService }, { type: SearchService }, { type: AppStateService }, { type: UserMenuService }, { type: DocsService }, { type: i4.ApiService }], propDecorators: { simple: [{
14517
14759
  type: Input
14518
14760
  }] } });
@@ -16091,8 +16333,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
16091
16333
  * Navigator node renderer.
16092
16334
  */
16093
16335
  class NavigatorNodeComponent {
16094
- constructor(router) {
16336
+ constructor(router, breadcrumbService) {
16095
16337
  this.router = router;
16338
+ this.breadcrumbService = breadcrumbService;
16096
16339
  /**
16097
16340
  * Event emitter responsible for broadcasting one of the following events: "icon", "expander" or "link" as string value.
16098
16341
  *
@@ -16185,6 +16428,9 @@ class NavigatorNodeComponent {
16185
16428
  break;
16186
16429
  }
16187
16430
  this.handleExpandCollapse(open, from, $event);
16431
+ if (this.node.parents?.length === 1) {
16432
+ this.breadcrumbService.selectPreferredByPath(this.node.parents[0].path);
16433
+ }
16188
16434
  this.nodeClick.emit(from);
16189
16435
  }
16190
16436
  /**
@@ -16253,7 +16499,7 @@ class NavigatorNodeComponent {
16253
16499
  injector: this.node.injector
16254
16500
  });
16255
16501
  }
16256
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: NavigatorNodeComponent, deps: [{ token: i1$3.Router }], target: i0.ɵɵFactoryTarget.Component }); }
16502
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: NavigatorNodeComponent, deps: [{ token: i1$3.Router }, { token: BreadcrumbService }], target: i0.ɵɵFactoryTarget.Component }); }
16257
16503
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: NavigatorNodeComponent, isStandalone: true, selector: "c8y-navigator-node", inputs: { node: "node", isRoot: "isRoot" }, outputs: { nodeClick: "nodeClick" }, viewQueries: [{ propertyName: "iconSlot", first: true, predicate: ["icon"], descendants: true, read: ViewContainerRef }, { propertyName: "confirm", first: true, predicate: PopoverConfirmComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "@if (node.component) {\n <ng-container\n *c8yComponentOutlet=\"node.component; environmentInjector: node.injector\"\n ></ng-container>\n}\n\n@if (!node.component) {\n <div\n class=\"slot\"\n [hidden]=\"node.hidden\"\n (dragstart)=\"node.dragStart($event)\"\n (dragend)=\"node.dragEnd($event)\"\n (drop)=\"node.drop($event)\"\n [draggable]=\"node.draggable\"\n [ngClass]=\"{ dragged: node.dragged, disabled: node.loading }\"\n >\n <ng-container>\n <div\n class=\"link\"\n tabindex=\"-1\"\n [routerLink]=\"node.canNavigate ? node.path : undefined\"\n [ngClass]=\"{\n active: isActive$ | async,\n 'dragged-hover': node.draggedHover && !node.dragged\n }\"\n (dragover)=\"node.canDrop && $event.preventDefault()\"\n (dragenter)=\"node.canDrop && node.dragEnter($event)\"\n (dragleave)=\"node.canDrop && node.dragLeave($event)\"\n >\n <ng-container *ngTemplateOutlet=\"navicon\"></ng-container>\n <button\n class=\"btn-clean\"\n title=\"{{ node.translateLabel ? (node.label | translate) : node.label }}\"\n [attr.aria-expanded]=\"node.hasChildren ? node.open : null\"\n type=\"button\"\n draggable=\"false\"\n [attr.data-cy]=\"node.label\"\n [attr.id]=\"isRoot ? node.id : undefined\"\n (click)=\"click(node.canNavigate ? 'link' : 'expander', $event)\"\n [ngClass]=\"{\n 'root-link': isRoot,\n open: node.open && node.hasChildren,\n parent: node.hasChildren\n }\"\n >\n <ng-container *ngTemplateOutlet=\"inner\"></ng-container>\n </button>\n </div>\n </ng-container>\n @if (node.children.length) {\n <div\n class=\"children panel-expand expand\"\n [collapse]=\"!node.open\"\n [isAnimated]=\"true\"\n >\n @for (childNode of node.children; track childNode) {\n <c8y-navigator-node\n [node]=\"childNode\"\n (nodeClick)=\"nodeClick.emit($event)\"\n ></c8y-navigator-node>\n }\n </div>\n }\n </div>\n}\n\n<!-- icon -->\n<ng-template #navicon>\n <!-- loader -->\n @if (node.loading && !isRoot) {\n <i\n class=\"icon-spin loadingIndicator\"\n [c8yIcon]=\"'circle-o-notch'\"\n [ngClass]=\"{ 'm-l-16': isRoot, 'm-l-8': !isRoot }\"\n ></i>\n }\n <ng-container #icon></ng-container>\n</ng-template>\n\n<ng-template #inner>\n <!--title -->\n <span>{{ node.translateLabel ? (node.label | translate) : node.label }}</span>\n\n <!--expander -->\n @if (node.hasChildren) {\n <i\n class=\"expander\"\n [c8yIcon]=\"'chevron-down'\"\n [attr.aria-label]=\"expandTitle\"\n role=\"button\"\n (click)=\"click('expander', $event)\"\n data-cy=\"c8y-navigator-node--expander\"\n ></i>\n }\n\n <!-- Popover confirm -->\n <c8y-popover-confirm\n triggers=\"focus\"\n containerClass=\"navigator-popover\"\n ></c8y-popover-confirm>\n</ng-template>\n", dependencies: [{ kind: "component", type: NavigatorNodeComponent, selector: "c8y-navigator-node", inputs: ["node", "isRoot"], outputs: ["nodeClick"] }, { kind: "directive", type: C8yComponentOutlet, selector: "[c8yComponentOutlet]", inputs: ["c8yComponentOutlet", "c8yComponentOutletInjector", "c8yComponentOutletEnvironmentInjector", "c8yComponentOutletProviders", "c8yComponentOutletInitialState"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: CollapseModule }, { kind: "directive", type: i2$1.CollapseDirective, selector: "[collapse]", inputs: ["display", "isAnimated", "collapse"], outputs: ["collapsed", "collapses", "expanded", "expands"], exportAs: ["bs-collapse"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "component", type: PopoverConfirmComponent, selector: "c8y-popover-confirm", inputs: ["buttons", "message", "title", "isOpen", "containerClass", "placement", "outsideClick", "adaptivePosition", "container"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
16258
16504
  }
16259
16505
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: NavigatorNodeComponent, decorators: [{
@@ -16269,7 +16515,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
16269
16515
  C8yTranslatePipe,
16270
16516
  AsyncPipe
16271
16517
  ], template: "@if (node.component) {\n <ng-container\n *c8yComponentOutlet=\"node.component; environmentInjector: node.injector\"\n ></ng-container>\n}\n\n@if (!node.component) {\n <div\n class=\"slot\"\n [hidden]=\"node.hidden\"\n (dragstart)=\"node.dragStart($event)\"\n (dragend)=\"node.dragEnd($event)\"\n (drop)=\"node.drop($event)\"\n [draggable]=\"node.draggable\"\n [ngClass]=\"{ dragged: node.dragged, disabled: node.loading }\"\n >\n <ng-container>\n <div\n class=\"link\"\n tabindex=\"-1\"\n [routerLink]=\"node.canNavigate ? node.path : undefined\"\n [ngClass]=\"{\n active: isActive$ | async,\n 'dragged-hover': node.draggedHover && !node.dragged\n }\"\n (dragover)=\"node.canDrop && $event.preventDefault()\"\n (dragenter)=\"node.canDrop && node.dragEnter($event)\"\n (dragleave)=\"node.canDrop && node.dragLeave($event)\"\n >\n <ng-container *ngTemplateOutlet=\"navicon\"></ng-container>\n <button\n class=\"btn-clean\"\n title=\"{{ node.translateLabel ? (node.label | translate) : node.label }}\"\n [attr.aria-expanded]=\"node.hasChildren ? node.open : null\"\n type=\"button\"\n draggable=\"false\"\n [attr.data-cy]=\"node.label\"\n [attr.id]=\"isRoot ? node.id : undefined\"\n (click)=\"click(node.canNavigate ? 'link' : 'expander', $event)\"\n [ngClass]=\"{\n 'root-link': isRoot,\n open: node.open && node.hasChildren,\n parent: node.hasChildren\n }\"\n >\n <ng-container *ngTemplateOutlet=\"inner\"></ng-container>\n </button>\n </div>\n </ng-container>\n @if (node.children.length) {\n <div\n class=\"children panel-expand expand\"\n [collapse]=\"!node.open\"\n [isAnimated]=\"true\"\n >\n @for (childNode of node.children; track childNode) {\n <c8y-navigator-node\n [node]=\"childNode\"\n (nodeClick)=\"nodeClick.emit($event)\"\n ></c8y-navigator-node>\n }\n </div>\n }\n </div>\n}\n\n<!-- icon -->\n<ng-template #navicon>\n <!-- loader -->\n @if (node.loading && !isRoot) {\n <i\n class=\"icon-spin loadingIndicator\"\n [c8yIcon]=\"'circle-o-notch'\"\n [ngClass]=\"{ 'm-l-16': isRoot, 'm-l-8': !isRoot }\"\n ></i>\n }\n <ng-container #icon></ng-container>\n</ng-template>\n\n<ng-template #inner>\n <!--title -->\n <span>{{ node.translateLabel ? (node.label | translate) : node.label }}</span>\n\n <!--expander -->\n @if (node.hasChildren) {\n <i\n class=\"expander\"\n [c8yIcon]=\"'chevron-down'\"\n [attr.aria-label]=\"expandTitle\"\n role=\"button\"\n (click)=\"click('expander', $event)\"\n data-cy=\"c8y-navigator-node--expander\"\n ></i>\n }\n\n <!-- Popover confirm -->\n <c8y-popover-confirm\n triggers=\"focus\"\n containerClass=\"navigator-popover\"\n ></c8y-popover-confirm>\n</ng-template>\n" }]
16272
- }], ctorParameters: () => [{ type: i1$3.Router }], propDecorators: { iconSlot: [{
16518
+ }], ctorParameters: () => [{ type: i1$3.Router }, { type: BreadcrumbService }], propDecorators: { iconSlot: [{
16273
16519
  type: ViewChild,
16274
16520
  args: ['icon', { read: ViewContainerRef, static: false }]
16275
16521
  }], node: [{
@@ -37470,9 +37716,22 @@ class RealtimeMessage {
37470
37716
  }
37471
37717
 
37472
37718
  /**
37473
- * A resizable grid component with two columns (A and B).
37474
- * Allows the user to resize columns by dragging the divider.
37475
- * Supports collapse/expand logic and persistent width via localStorage.
37719
+ * Resizable Grid Component
37720
+ *
37721
+ * Provides a flexible layout with two adjustable columns separated by a draggable divider.
37722
+ *
37723
+ * ## Basic Usage
37724
+ *
37725
+ * ```html
37726
+ * <c8y-resizable-grid
37727
+ * [leftColumnWidth]="'50%'"
37728
+ * [collapseThreshold]="320"
37729
+ * [collapsible]="true"
37730
+ * [trackId]="'my-layout'">
37731
+ * <div #colA>Left column content</div>
37732
+ * <div #colB>Right column content</div>
37733
+ * </c8y-resizable-grid>
37734
+ * ```
37476
37735
  */
37477
37736
  class ResizableGridComponent {
37478
37737
  /**
@@ -37503,6 +37762,10 @@ class ResizableGridComponent {
37503
37762
  * Minimum width (in pixels) before a column is considered collapsed.
37504
37763
  */
37505
37764
  this.collapseThreshold = 320;
37765
+ /**
37766
+ * If true, columns can collapse below the threshold. If false, columns stop at the threshold.
37767
+ */
37768
+ this.collapsible = true;
37506
37769
  /**
37507
37770
  * True if the user is currently resizing the grid.
37508
37771
  */
@@ -37689,10 +37952,12 @@ class ResizableGridComponent {
37689
37952
  if (!this.colA || !this.colB) {
37690
37953
  return;
37691
37954
  }
37692
- let newWidthPx = Math.max(0, targetWidthPx);
37693
37955
  const totalWidth = this.colA.nativeElement.parentElement?.offsetWidth || window.innerWidth;
37694
- const minColBWidthPx = 0; // Allow colB to go down to 0 for collapsing
37695
- newWidthPx = Math.min(newWidthPx, totalWidth - minColBWidthPx);
37956
+ // If not collapsible, enforce the threshold as the minimum
37957
+ const minWidthPx = this.collapsible ? 0 : this.collapseThreshold;
37958
+ const maxWidthPx = this.collapsible ? totalWidth : totalWidth - this.collapseThreshold;
37959
+ let newWidthPx = Math.max(minWidthPx, targetWidthPx);
37960
+ newWidthPx = Math.min(newWidthPx, maxWidthPx);
37696
37961
  const newWidthString = `${newWidthPx}px`;
37697
37962
  this._colAWidth = newWidthString;
37698
37963
  // Update lastKnownNonCollapsedWidth during drag, regardless of trackId
@@ -37720,25 +37985,38 @@ class ResizableGridComponent {
37720
37985
  const colANative = this.colA.nativeElement;
37721
37986
  const colBNative = this.colB.nativeElement;
37722
37987
  this.removeCollapseClasses();
37723
- if (colAWidth < this.collapseThreshold) {
37724
- this.renderer.addClass(colANative, 'collapsed');
37725
- this.renderer.addClass(colBNative, 'expanded');
37726
- this._colAWidth = '0px';
37727
- }
37728
- else if (colBWidth < this.collapseThreshold) {
37729
- this.renderer.addClass(colBNative, 'collapsed');
37730
- this.renderer.addClass(colANative, 'expanded');
37731
- this._colAWidth = '100%';
37988
+ // Only apply collapse logic if collapsible is true
37989
+ if (this.collapsible) {
37990
+ if (colAWidth < this.collapseThreshold) {
37991
+ this.renderer.addClass(colANative, 'collapsed');
37992
+ this.renderer.addClass(colBNative, 'expanded');
37993
+ this._colAWidth = '0px';
37994
+ }
37995
+ else if (colBWidth < this.collapseThreshold) {
37996
+ this.renderer.addClass(colBNative, 'collapsed');
37997
+ this.renderer.addClass(colANative, 'expanded');
37998
+ this._colAWidth = '100%';
37999
+ }
38000
+ else {
38001
+ // If neither is collapsed, restore the last known non-collapsed width.
38002
+ // This will be the actual width from the drag, or the localStorage value.
38003
+ this._colAWidth = this.lastKnownNonCollapsedWidth || this.leftColumnWidth;
38004
+ if (this.trackId) {
38005
+ // Ensure localStorage is up-to-date if no collapse occurred.
38006
+ const saved = localStorage.getItem(this.trackId);
38007
+ if (saved !== this._colAWidth) {
38008
+ // Only write if different
38009
+ localStorage.setItem(this.trackId, this._colAWidth);
38010
+ }
38011
+ }
38012
+ }
37732
38013
  }
37733
38014
  else {
37734
- // If neither is collapsed, restore the last known non-collapsed width.
37735
- // This will be the actual width from the drag, or the localStorage value.
38015
+ // When not collapsible, just maintain the current width without collapse
37736
38016
  this._colAWidth = this.lastKnownNonCollapsedWidth || this.leftColumnWidth;
37737
38017
  if (this.trackId) {
37738
- // Ensure localStorage is up-to-date if no collapse occurred.
37739
38018
  const saved = localStorage.getItem(this.trackId);
37740
38019
  if (saved !== this._colAWidth) {
37741
- // Only write if different
37742
38020
  localStorage.setItem(this.trackId, this._colAWidth);
37743
38021
  }
37744
38022
  }
@@ -37759,7 +38037,7 @@ class ResizableGridComponent {
37759
38037
  this.renderer.removeClass(colBNative, 'expanded');
37760
38038
  }
37761
38039
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ResizableGridComponent, deps: [{ token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component }); }
37762
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: ResizableGridComponent, isStandalone: true, selector: "c8y-resizable-grid", inputs: { leftColumnWidth: "leftColumnWidth", trackId: "trackId", collapseThreshold: "collapseThreshold" }, host: { listeners: { "window:mousemove": "onMouseMove($event)", "window:mouseup": "onMouseUp()" }, properties: { "class.is-resizing": "this.isResizing", "style.--col-a-width": "this._colAWidth" } }, viewQueries: [{ propertyName: "colA", first: true, predicate: ["colA"], descendants: true }, { propertyName: "colB", first: true, predicate: ["colB"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"resizable-grid-container\" [class.is-resizing]=\"isResizing\">\n <div #colA class=\"col-a\" [id]=\"colAId\">\n <!-- Content for the left column goes here -->\n <ng-content select=\"[left-pane]\"></ng-content>\n </div>\n <div\n class=\"resizer\"\n (mousedown)=\"onMouseDown($event)\"\n (keydown)=\"onKeyDown($event)\"\n tabindex=\"0\"\n role=\"separator\"\n aria-orientation=\"vertical\"\n [attr.aria-controls]=\"colAId + ' ' + colBId\"\n [attr.aria-label]=\"'Resize columns' | translate\"\n [attr.aria-valuenow]=\"colAWidthPercent\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n >\n <i class=\"dlt-c8y-icon-arrow-circle-divide-horizontal\"></i>\n </div>\n <div #colB class=\"col-b\" [id]=\"colBId\">\n <!-- Content for the right column goes here -->\n <ng-content select=\"[right-pane]\"></ng-content>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule$1 }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
38040
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: ResizableGridComponent, isStandalone: true, selector: "c8y-resizable-grid", inputs: { leftColumnWidth: "leftColumnWidth", trackId: "trackId", collapseThreshold: "collapseThreshold", collapsible: "collapsible" }, host: { listeners: { "window:mousemove": "onMouseMove($event)", "window:mouseup": "onMouseUp()" }, properties: { "class.is-resizing": "this.isResizing", "style.--col-a-width": "this._colAWidth" } }, viewQueries: [{ propertyName: "colA", first: true, predicate: ["colA"], descendants: true }, { propertyName: "colB", first: true, predicate: ["colB"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"resizable-grid-container\" [class.is-resizing]=\"isResizing\">\n <div #colA class=\"col-a\" [id]=\"colAId\">\n <!-- Content for the left column goes here -->\n <ng-content select=\"[left-pane]\"></ng-content>\n </div>\n <div\n class=\"resizer\"\n (mousedown)=\"onMouseDown($event)\"\n (keydown)=\"onKeyDown($event)\"\n tabindex=\"0\"\n role=\"separator\"\n aria-orientation=\"vertical\"\n [attr.aria-controls]=\"colAId + ' ' + colBId\"\n [attr.aria-label]=\"'Resize columns' | translate\"\n [attr.aria-valuenow]=\"colAWidthPercent\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n >\n <i class=\"dlt-c8y-icon-arrow-circle-divide-horizontal\"></i>\n </div>\n <div #colB class=\"col-b\" [id]=\"colBId\">\n <!-- Content for the right column goes here -->\n <ng-content select=\"[right-pane]\"></ng-content>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule$1 }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
37763
38041
  }
37764
38042
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ResizableGridComponent, decorators: [{
37765
38043
  type: Component,
@@ -37770,6 +38048,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
37770
38048
  type: Input
37771
38049
  }], collapseThreshold: [{
37772
38050
  type: Input
38051
+ }], collapsible: [{
38052
+ type: Input
37773
38053
  }], colA: [{
37774
38054
  type: ViewChild,
37775
38055
  args: ['colA']
@@ -37999,6 +38279,891 @@ function colorValidator(allowedModes) {
37999
38279
  };
38000
38280
  }
38001
38281
 
38282
+ /**
38283
+ * Displays a row of action buttons in the split view details panel.
38284
+ * Renders buttons based on the provided action configurations with support for:
38285
+ * - Icons and translatable labels
38286
+ * - Disabled and visibility states
38287
+ * - Product experience analytics tracking
38288
+ * - Custom tooltips and styling
38289
+ *
38290
+ * @example
38291
+ * ```html
38292
+ * <c8y-sv-details-actions [actions]="detailActions"></c8y-sv-details-actions>
38293
+ * ```
38294
+ *
38295
+ * @example
38296
+ * ```typescript
38297
+ * detailActions: SplitViewAction[] = [
38298
+ * {
38299
+ * id: 'edit',
38300
+ * label: 'Edit',
38301
+ * icon: 'pencil',
38302
+ * class: 'btn btn-primary',
38303
+ * action: () => this.editItem(),
38304
+ * title: 'Edit this item'
38305
+ * },
38306
+ * {
38307
+ * id: 'delete',
38308
+ * label: 'Delete',
38309
+ * icon: 'trash',
38310
+ * class: 'btn btn-danger',
38311
+ * action: () => this.deleteItem(),
38312
+ * productExperience: {
38313
+ * actionName: 'delete_item',
38314
+ * actionData: { itemType: 'device' }
38315
+ * }
38316
+ * }
38317
+ * ];
38318
+ * ```
38319
+ */
38320
+ class SplitViewDetailsActionsComponent {
38321
+ constructor() {
38322
+ /**
38323
+ * Array of action configurations to display as buttons.
38324
+ * Buttons are rendered in the order provided.
38325
+ */
38326
+ this.actions = [];
38327
+ }
38328
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SplitViewDetailsActionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
38329
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: SplitViewDetailsActionsComponent, isStandalone: true, selector: "c8y-sv-details-actions", inputs: { actions: "actions" }, ngImport: i0, template: "<div\n class=\"d-flex gap-8 a-i-center\"\n [attr.aria-label]=\"'Actions' | translate\"\n role=\"group\"\n data-cy=\"c8y-sv-details-actions\"\n>\n @for (action of actions; track action.id) {\n @if (action.visible !== false) {\n <button\n [title]=\"action.title ? (action.title | translate) : null\"\n [attr.aria-label]=\"action.title ? (action.title | translate) : (action.label | translate)\"\n [attr.aria-disabled]=\"action.disabled ? 'true' : 'false'\"\n type=\"button\"\n [ngClass]=\"action.class || ''\"\n [disabled]=\"action.disabled || false\"\n [attr.data-cy]=\"action.dataCy\"\n (click)=\"action.action()\"\n c8yProductExperience\n [actionName]=\"action.productExperience?.actionName\"\n [actionData]=\"action.productExperience?.actionData\"\n >\n <i\n [c8yIcon]=\"action.icon\"\n aria-hidden=\"true\"\n [ngClass]=\"action.iconClass || ''\"\n ></i>\n {{ action.label | translate }}\n </button>\n }\n }\n\n <ng-content></ng-content>\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: ProductExperienceDirective, selector: "[c8yProductExperience]", inputs: ["actionName", "actionData", "inherit", "suppressDataOverriding"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
38330
+ }
38331
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SplitViewDetailsActionsComponent, decorators: [{
38332
+ type: Component,
38333
+ args: [{ selector: 'c8y-sv-details-actions', standalone: true, imports: [NgClass, C8yTranslatePipe, IconDirective, ProductExperienceDirective], template: "<div\n class=\"d-flex gap-8 a-i-center\"\n [attr.aria-label]=\"'Actions' | translate\"\n role=\"group\"\n data-cy=\"c8y-sv-details-actions\"\n>\n @for (action of actions; track action.id) {\n @if (action.visible !== false) {\n <button\n [title]=\"action.title ? (action.title | translate) : null\"\n [attr.aria-label]=\"action.title ? (action.title | translate) : (action.label | translate)\"\n [attr.aria-disabled]=\"action.disabled ? 'true' : 'false'\"\n type=\"button\"\n [ngClass]=\"action.class || ''\"\n [disabled]=\"action.disabled || false\"\n [attr.data-cy]=\"action.dataCy\"\n (click)=\"action.action()\"\n c8yProductExperience\n [actionName]=\"action.productExperience?.actionName\"\n [actionData]=\"action.productExperience?.actionData\"\n >\n <i\n [c8yIcon]=\"action.icon\"\n aria-hidden=\"true\"\n [ngClass]=\"action.iconClass || ''\"\n ></i>\n {{ action.label | translate }}\n </button>\n }\n }\n\n <ng-content></ng-content>\n</div>\n" }]
38334
+ }], propDecorators: { actions: [{
38335
+ type: Input
38336
+ }] } });
38337
+
38338
+ /**
38339
+ * Extra header component for split view details.
38340
+ * Provides a flexible content projection area below the main header.
38341
+ *
38342
+ * Use this component to add custom content like metadata, status information,
38343
+ * or any other details you want to display at the top of the details panel.
38344
+ *
38345
+ * @example
38346
+ * ```html
38347
+ * <c8y-sv-details>
38348
+ * <c8y-sv-extra-header>
38349
+ * <div class="row p-16">
38350
+ * <div class="col-sm-6">
38351
+ * <label>Device ID:</label>
38352
+ * <span>{{ device.id }}</span>
38353
+ * </div>
38354
+ * <div class="col-sm-6">
38355
+ * <label>Status:</label>
38356
+ * <span>{{ device.status }}</span>
38357
+ * </div>
38358
+ * </div>
38359
+ * </c8y-sv-extra-header>
38360
+ * </c8y-sv-details>
38361
+ * ```
38362
+ */
38363
+ class SplitViewExtraHeaderComponent {
38364
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SplitViewExtraHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
38365
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: SplitViewExtraHeaderComponent, isStandalone: true, selector: "c8y-sv-extra-header", host: { classAttribute: "d-contents" }, ngImport: i0, template: '<ng-content></ng-content>', isInline: true }); }
38366
+ }
38367
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SplitViewExtraHeaderComponent, decorators: [{
38368
+ type: Component,
38369
+ args: [{
38370
+ selector: 'c8y-sv-extra-header',
38371
+ template: '<ng-content></ng-content>',
38372
+ host: { class: 'd-contents' },
38373
+ standalone: true
38374
+ }]
38375
+ }] });
38376
+
38377
+ class SplitViewFooterComponent {
38378
+ constructor() {
38379
+ this.cssClass = '';
38380
+ }
38381
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SplitViewFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
38382
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: SplitViewFooterComponent, isStandalone: true, selector: "c8y-sv-footer", inputs: { cssClass: "cssClass" }, host: { classAttribute: "d-contents" }, ngImport: i0, template: "<div\n class=\"card-footer separator-top fit-w sticky-bottom m-t-auto bg-inherit\"\n [ngClass]=\"cssClass\"\n data-cy=\"c8y-sv-footer\"\n>\n <ng-content></ng-content>\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
38383
+ }
38384
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SplitViewFooterComponent, decorators: [{
38385
+ type: Component,
38386
+ args: [{ selector: 'c8y-sv-footer', host: { class: 'd-contents' }, standalone: true, imports: [NgClass], template: "<div\n class=\"card-footer separator-top fit-w sticky-bottom m-t-auto bg-inherit\"\n [ngClass]=\"cssClass\"\n data-cy=\"c8y-sv-footer\"\n>\n <ng-content></ng-content>\n</div>\n" }]
38387
+ }], propDecorators: { cssClass: [{
38388
+ type: Input
38389
+ }] } });
38390
+
38391
+ /**
38392
+ * Service to manage selection state in split view components.
38393
+ * Provides methods to select/deselect items and track selection state.
38394
+ */
38395
+ class SplitViewSelectionService {
38396
+ constructor() {
38397
+ this._selectedItem$ = new BehaviorSubject(null);
38398
+ }
38399
+ ngOnDestroy() {
38400
+ this._selectedItem$.complete();
38401
+ }
38402
+ /**
38403
+ * Observable of the currently selected item
38404
+ */
38405
+ get selectedItem$() {
38406
+ return this._selectedItem$.asObservable();
38407
+ }
38408
+ /**
38409
+ * Get the current selected item value
38410
+ */
38411
+ get selectedItem() {
38412
+ return this._selectedItem$.value;
38413
+ }
38414
+ /**
38415
+ * Check if an item is currently selected
38416
+ */
38417
+ get hasSelection() {
38418
+ return this._selectedItem$.value !== null;
38419
+ }
38420
+ /**
38421
+ * Select an item
38422
+ */
38423
+ select(item) {
38424
+ this._selectedItem$.next(item);
38425
+ }
38426
+ /**
38427
+ * Clear the current selection
38428
+ */
38429
+ clearSelection() {
38430
+ this._selectedItem$.next(null);
38431
+ }
38432
+ /**
38433
+ * Check if a specific item is selected
38434
+ */
38435
+ isSelected(item) {
38436
+ return this._selectedItem$.value === item;
38437
+ }
38438
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SplitViewSelectionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
38439
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SplitViewSelectionService }); }
38440
+ }
38441
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SplitViewSelectionService, decorators: [{
38442
+ type: Injectable
38443
+ }] });
38444
+
38445
+ /**
38446
+ * Split View Details Component
38447
+ *
38448
+ * Displays the details panel of a split-view layout.
38449
+ *
38450
+ * ## Basic Usage
38451
+ *
38452
+ * ```html
38453
+ * <c8y-sv-details
38454
+ * emptyStateIcon="c8y-devices"
38455
+ * emptyStateTitle="No device selected"
38456
+ * emptyStateSubtitle="Select a device to view details">
38457
+ *
38458
+ * @if (selectedItem) {
38459
+ * <c8y-sv-extra-header>
38460
+ * <c8y-icon-panel [sections]="sections"></c8y-icon-panel>
38461
+ * </c8y-sv-extra-header>
38462
+ * }
38463
+ *
38464
+ * @if (selectedItem) {
38465
+ * <h3>{{ selectedItem.name }}</h3>
38466
+ * <p>{{ selectedItem.description }}</p>
38467
+ * }
38468
+ * </c8y-sv-details>
38469
+ * ```
38470
+ *
38471
+ * ## Router-Outlet Integration
38472
+ *
38473
+ * ```html
38474
+ * <c8y-sv-details (backClick)="handleBackClick()">
38475
+ * <router-outlet></router-outlet>
38476
+ * </c8y-sv-details>
38477
+ * ```
38478
+ *
38479
+ * ```typescript
38480
+ * async handleBackClick(): Promise<void> {
38481
+ * await this.alarmsViewService.closeDetailsView(this.activatedRoute);
38482
+ * }
38483
+ * ```
38484
+ */
38485
+ class SplitViewDetailsComponent {
38486
+ constructor(selectionService, location, cdr) {
38487
+ this.selectionService = selectionService;
38488
+ this.location = location;
38489
+ this.cdr = cdr;
38490
+ this.destroyRef = inject(DestroyRef);
38491
+ this._routerOutletActivated = false;
38492
+ /**
38493
+ * Aria label for the details panel region.
38494
+ */
38495
+ this.ariaLabel = gettext$1('Details panel');
38496
+ /**
38497
+ * Custom CSS classes
38498
+ */
38499
+ this.cssClass = '';
38500
+ /**
38501
+ * Empty state icon when nothing is selected
38502
+ */
38503
+ this.emptyStateIcon = 'c8y-alert-idle';
38504
+ /**
38505
+ * Empty state title when nothing is selected
38506
+ */
38507
+ this.emptyStateTitle = gettext$1('No item selected');
38508
+ /**
38509
+ * Empty state subtitle when nothing is selected
38510
+ */
38511
+ this.emptyStateSubtitle = gettext$1('Select an item from the list to view details');
38512
+ /**
38513
+ * Emits when the back button is clicked.
38514
+ * Allows parent components to handle custom navigation logic.
38515
+ * If not handled, default behavior (location.back or clearSelection) is used.
38516
+ */
38517
+ this.backClick = new EventEmitter();
38518
+ }
38519
+ ngAfterViewInit() {
38520
+ // Listen to router outlet activation/deactivation events directly
38521
+ if (this.routerOutlet) {
38522
+ // Set initial state and mark for check
38523
+ this._routerOutletActivated = !!this.routerOutlet.isActivated;
38524
+ this.cdr?.markForCheck();
38525
+ // Subscribe to activation events
38526
+ this.routerOutlet.activateEvents.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
38527
+ this._routerOutletActivated = true;
38528
+ this.cdr?.markForCheck();
38529
+ });
38530
+ // Subscribe to deactivation events
38531
+ this.routerOutlet.deactivateEvents.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
38532
+ this._routerOutletActivated = false;
38533
+ this.cdr?.markForCheck();
38534
+ });
38535
+ }
38536
+ }
38537
+ ngOnDestroy() {
38538
+ this.backClick.complete();
38539
+ }
38540
+ get hasExtraHeader() {
38541
+ return !!this.extraHeaderComponent;
38542
+ }
38543
+ get hasActions() {
38544
+ return !!this.actionsComponent;
38545
+ }
38546
+ get hasFooter() {
38547
+ return !!this.footerComponent;
38548
+ }
38549
+ /**
38550
+ * Check if an item is selected or if router-outlet is activated
38551
+ */
38552
+ get hasSelection() {
38553
+ // Check selection service first
38554
+ if (this.selectionService?.hasSelection) {
38555
+ return true;
38556
+ }
38557
+ // Check router outlet activation state (updated via outlet events)
38558
+ return this._routerOutletActivated;
38559
+ }
38560
+ /**
38561
+ * Clear the current selection (back button handler).
38562
+ * Emits backClick event for parent to handle, or uses default behavior:
38563
+ * - Router-outlet: navigates back using browser history
38564
+ * - Selection service: clears the selection
38565
+ */
38566
+ clearSelection() {
38567
+ // Emit event for parent to handle
38568
+ if (this.backClick.observed) {
38569
+ this.backClick.emit();
38570
+ }
38571
+ // Default behavior: If using router-outlet, go back in history
38572
+ else if (this.routerOutlet?.isActivated && this.location) {
38573
+ this.location.back();
38574
+ }
38575
+ // Otherwise clear selection service
38576
+ else {
38577
+ this.selectionService?.clearSelection();
38578
+ }
38579
+ }
38580
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SplitViewDetailsComponent, deps: [{ token: SplitViewSelectionService, optional: true }, { token: i1$a.Location, optional: true }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
38581
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: SplitViewDetailsComponent, isStandalone: true, selector: "c8y-sv-details", inputs: { title: "title", ariaLabel: "ariaLabel", cssClass: "cssClass", emptyStateIcon: "emptyStateIcon", emptyStateTitle: "emptyStateTitle", emptyStateSubtitle: "emptyStateSubtitle" }, outputs: { backClick: "backClick" }, host: { classAttribute: "d-contents" }, queries: [{ propertyName: "extraHeaderComponent", first: true, predicate: SplitViewExtraHeaderComponent, descendants: true }, { propertyName: "actionsComponent", first: true, predicate: SplitViewDetailsActionsComponent, descendants: true }, { propertyName: "footerComponent", first: true, predicate: SplitViewFooterComponent, descendants: true }, { propertyName: "routerOutlet", first: true, predicate: RouterOutlet, descendants: true }], ngImport: i0, template: "<div\n class=\"inner-scroll fit-h d-col fit-w split-view__detail\"\n [class.split-view__detail--selected]=\"hasSelection\"\n [attr.aria-label]=\"ariaLabel | translate\"\n role=\"region\"\n [ngClass]=\"cssClass\"\n data-cy=\"c8y-sv-details\"\n>\n <!-- Back button for mobile/tablet -->\n @if (hasSelection) {\n <div class=\"card-header separator sticky-top visible-sm visible-xs\">\n <button\n class=\"btn btn-clean text-primary\"\n [title]=\"'Back' | translate\"\n [attr.aria-label]=\"'Back' | translate\"\n type=\"button\"\n (click)=\"clearSelection()\"\n >\n <i c8yIcon=\"chevron-left\"></i>\n <span>{{ 'Back' | translate }}</span>\n </button>\n </div>\n }\n <!-- Content when item is selected -->\n @if (title || hasExtraHeader) {\n <div\n class=\"p-l-24 p-r-24 card-header flex-no-shrink sticky-top bg-component separator\"\n [ngClass]=\"{ 'flex-wrap': hasExtraHeader, 'gap-8': hasExtraHeader && title }\"\n >\n <h4 class=\"card-title\">{{ title | translate }}</h4>\n <ng-content select=\"c8y-sv-header-actions\"></ng-content>\n @if (hasExtraHeader) {\n <div class=\"details-info fit-w\">\n <ng-content select=\"c8y-sv-extra-header\"></ng-content>\n </div>\n }\n </div>\n }\n <!-- Empty state when nothing is selected -->\n @if (!hasSelection) {\n <div class=\"d-flex a-i-center j-c-center flex-grow p-24\">\n <c8y-ui-empty-state\n [icon]=\"emptyStateIcon\"\n [title]=\"emptyStateTitle\"\n [subtitle]=\"emptyStateSubtitle\"\n ></c8y-ui-empty-state>\n </div>\n }\n <!-- Content when item is selected -->\n @if (hasSelection) {\n <div\n class=\"p-24\"\n [ngClass]=\"{ 'p-t-0': !title && !hasExtraHeader }\"\n >\n <div class=\"details-content\">\n <ng-content\n select=\":not(c8y-sv-extra-header):not(c8y-sv-details-actions):not(c8y-sv-footer):not(c8y-sv-header-actions)\"\n ></ng-content>\n </div>\n\n @if (hasActions) {\n <div class=\"details-actions\">\n <ng-content select=\"c8y-sv-details-actions\"></ng-content>\n </div>\n }\n </div>\n @if (hasFooter) {\n <ng-content select=\"c8y-sv-footer\"></ng-content>\n }\n }\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
38582
+ }
38583
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SplitViewDetailsComponent, decorators: [{
38584
+ type: Component,
38585
+ args: [{ selector: 'c8y-sv-details', host: { class: 'd-contents' }, standalone: true, imports: [NgClass, C8yTranslatePipe, EmptyStateComponent, IconDirective], template: "<div\n class=\"inner-scroll fit-h d-col fit-w split-view__detail\"\n [class.split-view__detail--selected]=\"hasSelection\"\n [attr.aria-label]=\"ariaLabel | translate\"\n role=\"region\"\n [ngClass]=\"cssClass\"\n data-cy=\"c8y-sv-details\"\n>\n <!-- Back button for mobile/tablet -->\n @if (hasSelection) {\n <div class=\"card-header separator sticky-top visible-sm visible-xs\">\n <button\n class=\"btn btn-clean text-primary\"\n [title]=\"'Back' | translate\"\n [attr.aria-label]=\"'Back' | translate\"\n type=\"button\"\n (click)=\"clearSelection()\"\n >\n <i c8yIcon=\"chevron-left\"></i>\n <span>{{ 'Back' | translate }}</span>\n </button>\n </div>\n }\n <!-- Content when item is selected -->\n @if (title || hasExtraHeader) {\n <div\n class=\"p-l-24 p-r-24 card-header flex-no-shrink sticky-top bg-component separator\"\n [ngClass]=\"{ 'flex-wrap': hasExtraHeader, 'gap-8': hasExtraHeader && title }\"\n >\n <h4 class=\"card-title\">{{ title | translate }}</h4>\n <ng-content select=\"c8y-sv-header-actions\"></ng-content>\n @if (hasExtraHeader) {\n <div class=\"details-info fit-w\">\n <ng-content select=\"c8y-sv-extra-header\"></ng-content>\n </div>\n }\n </div>\n }\n <!-- Empty state when nothing is selected -->\n @if (!hasSelection) {\n <div class=\"d-flex a-i-center j-c-center flex-grow p-24\">\n <c8y-ui-empty-state\n [icon]=\"emptyStateIcon\"\n [title]=\"emptyStateTitle\"\n [subtitle]=\"emptyStateSubtitle\"\n ></c8y-ui-empty-state>\n </div>\n }\n <!-- Content when item is selected -->\n @if (hasSelection) {\n <div\n class=\"p-24\"\n [ngClass]=\"{ 'p-t-0': !title && !hasExtraHeader }\"\n >\n <div class=\"details-content\">\n <ng-content\n select=\":not(c8y-sv-extra-header):not(c8y-sv-details-actions):not(c8y-sv-footer):not(c8y-sv-header-actions)\"\n ></ng-content>\n </div>\n\n @if (hasActions) {\n <div class=\"details-actions\">\n <ng-content select=\"c8y-sv-details-actions\"></ng-content>\n </div>\n }\n </div>\n @if (hasFooter) {\n <ng-content select=\"c8y-sv-footer\"></ng-content>\n }\n }\n</div>\n" }]
38586
+ }], ctorParameters: () => [{ type: SplitViewSelectionService, decorators: [{
38587
+ type: Optional
38588
+ }] }, { type: i1$a.Location, decorators: [{
38589
+ type: Optional
38590
+ }] }, { type: i0.ChangeDetectorRef }], propDecorators: { title: [{
38591
+ type: Input
38592
+ }], ariaLabel: [{
38593
+ type: Input
38594
+ }], cssClass: [{
38595
+ type: Input
38596
+ }], emptyStateIcon: [{
38597
+ type: Input
38598
+ }], emptyStateTitle: [{
38599
+ type: Input
38600
+ }], emptyStateSubtitle: [{
38601
+ type: Input
38602
+ }], backClick: [{
38603
+ type: Output
38604
+ }], extraHeaderComponent: [{
38605
+ type: ContentChild,
38606
+ args: [SplitViewExtraHeaderComponent]
38607
+ }], actionsComponent: [{
38608
+ type: ContentChild,
38609
+ args: [SplitViewDetailsActionsComponent]
38610
+ }], footerComponent: [{
38611
+ type: ContentChild,
38612
+ args: [SplitViewFooterComponent]
38613
+ }], routerOutlet: [{
38614
+ type: ContentChild,
38615
+ args: [RouterOutlet]
38616
+ }] } });
38617
+
38618
+ const DEFAULT_RESIZABLE_CONFIG = Object.freeze({
38619
+ collapseThreshold: 320,
38620
+ leftColumnWidth: '50%',
38621
+ trackId: 'c8y-sv-resizable-default',
38622
+ collapsible: true
38623
+ });
38624
+ /**
38625
+ * A responsive split view layout component with automatic selection management and resizable panes.
38626
+ *
38627
+ * #### Basic usage
38628
+ *
38629
+ *
38630
+ * ```typescript
38631
+ * export class MyComponent {
38632
+ * items: Device[] = [];
38633
+ * selectedItem?: Device;
38634
+ *
38635
+ * onSelectionChange(item: Device | null) {
38636
+ * this.selectedItem = item || undefined;
38637
+ * }
38638
+ * }
38639
+ * ```
38640
+ *
38641
+ * ```html
38642
+ * <c8y-sv (selectionChange)="onSelectionChange($event)">
38643
+ * <c8y-sv-list [title]="'Devices'">
38644
+ * <c8y-sv-header-actions>
38645
+ * <button class="btn btn-primary">Add Device</button>
38646
+ * </c8y-sv-header-actions>
38647
+ *
38648
+ * @for (item of items; track item.id) {
38649
+ * <c8y-li [c8ySvListItem]="item">
38650
+ * {{ item.name }}
38651
+ * </c8y-li>
38652
+ * }
38653
+ *
38654
+ * <c8y-sv-footer>
38655
+ * Total: {{ items.length }}
38656
+ * </c8y-sv-footer>
38657
+ * </c8y-sv-list>
38658
+ *
38659
+ * <c8y-sv-details
38660
+ * emptyStateIcon="c8y-devices"
38661
+ * emptyStateTitle="No device selected"
38662
+ * emptyStateSubtitle="Select a device to view details">
38663
+ * @if (selectedItem) {
38664
+ * <c8y-sv-extra-header>
38665
+ * <c8y-icon-panel [sections]="sections"></c8y-icon-panel>
38666
+ * </c8y-sv-extra-header>
38667
+ * }
38668
+ *
38669
+ * @if (selectedItem) {
38670
+ * <h3>{{ selectedItem.name }}</h3>
38671
+ * <p>{{ selectedItem.description }}</p>
38672
+ * }
38673
+ * </c8y-sv-details>
38674
+ * </c8y-sv>
38675
+ * ```
38676
+ *
38677
+ * #### Router-Outlet integration
38678
+ *
38679
+ * For components using Angular router:
38680
+ *
38681
+ * ```html
38682
+ * <c8y-sv>
38683
+ * <c8y-alarms-list>...</c8y-alarms-list>
38684
+ *
38685
+ * <c8y-sv-details (backClick)="handleBackClick()">
38686
+ * <router-outlet></router-outlet>
38687
+ * </c8y-sv-details>
38688
+ * </c8y-sv>
38689
+ * ```
38690
+ *
38691
+ * ```typescript
38692
+ * async handleBackClick(): Promise<void> {
38693
+ * await this.alarmsViewService.closeDetailsView(this.activatedRoute);
38694
+ * }
38695
+ * ```
38696
+ *
38697
+ * #### Resizable configuration
38698
+ *
38699
+ * ```html
38700
+ * <c8y-sv
38701
+ * [isResizable]="true"
38702
+ * [resizableBreakpoint]="991"
38703
+ * [resizableConfig]="{
38704
+ * trackId: 'my-split-view',
38705
+ * leftColumnWidth: '40%',
38706
+ * collapseThreshold: 320,
38707
+ * collapsible: false
38708
+ * }"
38709
+ * [initialSelection]="items[0]"
38710
+ * (selectionChange)="onSelectionChange($event)">
38711
+ * <!-- content -->
38712
+ * </c8y-sv>
38713
+ * ```
38714
+ *
38715
+ * #### List-Only mode
38716
+ *
38717
+ * Omit `<c8y-sv-details>` for a simple list view:
38718
+ * ```html
38719
+ * <c8y-sv>
38720
+ * <c8y-sv-list [title]="'Items'">
38721
+ * @for (item of items; track item.id) {
38722
+ * <c8y-li>{{ item.name }}</c8y-li>
38723
+ * }
38724
+ * </c8y-sv-list>
38725
+ * </c8y-sv>
38726
+ * ```
38727
+ *
38728
+ */
38729
+ class SplitViewComponent {
38730
+ /**
38731
+ * Configuration for resizable grid behavior.
38732
+ *
38733
+ * @property trackId - Unique ID for persisting column widths in localStorage
38734
+ * @property leftColumnWidth - Initial width of left column (default: '50%')
38735
+ * @property collapseThreshold - Width threshold (in px) for collapsing columns (default: 320)
38736
+ * @property collapsible - Whether columns can collapse below threshold (default: true)
38737
+ *
38738
+ * @example
38739
+ * ```html
38740
+ * <c8y-sv [resizableConfig]="{
38741
+ * trackId: 'device-list-view',
38742
+ * leftColumnWidth: '40%',
38743
+ * collapseThreshold: 320,
38744
+ * collapsible: false
38745
+ * }">
38746
+ * ```
38747
+ */
38748
+ set resizableConfig(config) {
38749
+ this._resizableConfig = config ?? {};
38750
+ this.updateMemoizedResizableConfig();
38751
+ }
38752
+ get resizableConfig() {
38753
+ return this._resizableConfig;
38754
+ }
38755
+ constructor(selectionService) {
38756
+ this.selectionService = selectionService;
38757
+ this.destroyRef = inject(DestroyRef);
38758
+ /**
38759
+ * Whether to show a default router outlet in right-view if no right-view slot content provided.
38760
+ * @default true
38761
+ */
38762
+ this.showDefaultRouterOutlet = true;
38763
+ /**
38764
+ * Enable resizable grid functionality with draggable divider.
38765
+ * When `true`, users can resize the split panes by dragging the divider.
38766
+ * Above `resizableBreakpoint`, the resizable grid is active.
38767
+ * Below `resizableBreakpoint`, falls back to CSS-based responsive layout.
38768
+ * @default true
38769
+ */
38770
+ this.isResizable = true;
38771
+ /**
38772
+ * Minimum window width (in pixels) required for resizable grid to be active.
38773
+ * Below this width, the component switches to a stacked mobile layout.
38774
+ * @default 991
38775
+ */
38776
+ this.resizableBreakpoint = 991;
38777
+ /**
38778
+ * Emits when the selected item changes.
38779
+ * The event emits the selected item or `null` when selection is cleared.
38780
+ *
38781
+ * @example
38782
+ * ```html
38783
+ * <c8y-sv (selectionChange)="onSelectionChange($event)">
38784
+ * ```
38785
+ *
38786
+ * ```typescript
38787
+ * onSelectionChange(item: Device | null) {
38788
+ * this.selectedItem = item || undefined;
38789
+ * }
38790
+ * ```
38791
+ */
38792
+ this.selectionChange = new EventEmitter();
38793
+ /**
38794
+ * Internal flag to track if current viewport width allows resizable grid
38795
+ */
38796
+ this._isResizableAtCurrentWidth = true;
38797
+ this._resizableConfig = {};
38798
+ this._memoizedResizableConfig = {
38799
+ collapseThreshold: DEFAULT_RESIZABLE_CONFIG.collapseThreshold,
38800
+ leftColumnWidth: DEFAULT_RESIZABLE_CONFIG.leftColumnWidth,
38801
+ trackId: DEFAULT_RESIZABLE_CONFIG.trackId,
38802
+ collapsible: DEFAULT_RESIZABLE_CONFIG.collapsible
38803
+ };
38804
+ this._checkViewportWidth();
38805
+ }
38806
+ ngOnInit() {
38807
+ // Subscribe to selection changes and emit them
38808
+ // Ignore the initial BehaviorSubject emission (null) so consumers only see
38809
+ // real selection changes triggered by user interaction or inputs.
38810
+ this.selectionService.selectedItem$
38811
+ .pipe(skip$1(1), takeUntilDestroyed(this.destroyRef))
38812
+ .subscribe(item => {
38813
+ this.selectionChange.emit(item);
38814
+ });
38815
+ // Set initial selection if provided
38816
+ if (this.initialSelection) {
38817
+ this.selectionService.select(this.initialSelection);
38818
+ }
38819
+ // Debounced resize listener to prevent excessive change detection
38820
+ fromEvent(window, 'resize')
38821
+ .pipe(debounceTime$1(200), takeUntilDestroyed(this.destroyRef))
38822
+ .subscribe(() => {
38823
+ this._checkViewportWidth();
38824
+ });
38825
+ }
38826
+ ngOnDestroy() {
38827
+ this.selectionChange.complete();
38828
+ }
38829
+ /**
38830
+ * Checks if a details component is projected.
38831
+ *
38832
+ * Returns `true` when `<c8y-sv-details>` is present in the template.
38833
+ * Returns `false` when `<c8y-sv-details>` is not present.
38834
+ *
38835
+ * @internal Used by the template to determine layout mode
38836
+ */
38837
+ get hasProjectedDetails() {
38838
+ return !!this._detailsComp;
38839
+ }
38840
+ /**
38841
+ * Determines if the resizable grid should be active.
38842
+ *
38843
+ * Returns `true` when all conditions are met:
38844
+ * - `isResizable` is `true`
38845
+ * - Current viewport width is above `resizableBreakpoint`
38846
+ * - Details component is projected
38847
+ *
38848
+ * When `false`, falls back to CSS-based responsive layout.
38849
+ *
38850
+ * @internal Used by the template to conditionally render resizable grid
38851
+ */
38852
+ get shouldUseResizableGrid() {
38853
+ return this.isResizable && this._isResizableAtCurrentWidth && this.hasProjectedDetails;
38854
+ }
38855
+ /**
38856
+ * Returns the effective resizable configuration with all defaults applied.
38857
+ * The configuration is memoized and updated only when inputs change.
38858
+ *
38859
+ * @internal Used by the template to pass config to resizable-grid component
38860
+ */
38861
+ get effectiveResizableConfig() {
38862
+ return this._memoizedResizableConfig;
38863
+ }
38864
+ /**
38865
+ * Returns CSS classes for the split view container element.
38866
+ *
38867
+ * Always includes: `['card', 'content-fullpage', 'grid__row--1']`
38868
+ *
38869
+ * Conditionally adds `'split-view--5-7'` when:
38870
+ * - Details component is projected
38871
+ * - Resizable grid is not active (below breakpoint or disabled)
38872
+ *
38873
+ * @returns Array of CSS class names
38874
+ */
38875
+ getContainerClasses() {
38876
+ const classes = ['card', 'content-fullpage', 'grid__row--1'];
38877
+ if (this.hasProjectedDetails && (!this.isResizable || !this._isResizableAtCurrentWidth)) {
38878
+ classes.push('split-view--5-7');
38879
+ }
38880
+ return classes;
38881
+ }
38882
+ _checkViewportWidth() {
38883
+ this._isResizableAtCurrentWidth = window.innerWidth > this.resizableBreakpoint;
38884
+ }
38885
+ updateMemoizedResizableConfig() {
38886
+ const collapseThreshold = this._resizableConfig.collapseThreshold ?? DEFAULT_RESIZABLE_CONFIG.collapseThreshold;
38887
+ const leftColumnWidth = this._resizableConfig.leftColumnWidth ?? DEFAULT_RESIZABLE_CONFIG.leftColumnWidth;
38888
+ const trackId = this._resizableConfig.trackId ?? DEFAULT_RESIZABLE_CONFIG.trackId;
38889
+ const collapsible = this._resizableConfig.collapsible ?? DEFAULT_RESIZABLE_CONFIG.collapsible;
38890
+ const current = this._memoizedResizableConfig;
38891
+ if (current.collapseThreshold !== collapseThreshold ||
38892
+ current.leftColumnWidth !== leftColumnWidth ||
38893
+ current.trackId !== trackId ||
38894
+ current.collapsible !== collapsible) {
38895
+ this._memoizedResizableConfig = { collapseThreshold, leftColumnWidth, trackId, collapsible };
38896
+ }
38897
+ }
38898
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SplitViewComponent, deps: [{ token: SplitViewSelectionService }], target: i0.ɵɵFactoryTarget.Component }); }
38899
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: SplitViewComponent, isStandalone: true, selector: "c8y-sv", inputs: { showDefaultRouterOutlet: "showDefaultRouterOutlet", isResizable: "isResizable", initialSelection: "initialSelection", resizableBreakpoint: "resizableBreakpoint", resizableConfig: "resizableConfig" }, outputs: { selectionChange: "selectionChange" }, providers: [SplitViewSelectionService], queries: [{ propertyName: "_detailsComp", first: true, predicate: SplitViewDetailsComponent, descendants: true }], ngImport: i0, template: "<div\n [attr.aria-label]=\"'Split view interface' | translate\"\n tabindex=\"-1\"\n role=\"main\"\n [ngClass]=\"getContainerClasses()\"\n data-cy=\"c8y-sv\"\n>\n @if (shouldUseResizableGrid) {\n <c8y-resizable-grid\n [collapseThreshold]=\"effectiveResizableConfig.collapseThreshold\"\n [collapsible]=\"effectiveResizableConfig.collapsible\"\n [leftColumnWidth]=\"effectiveResizableConfig.leftColumnWidth\"\n [trackId]=\"effectiveResizableConfig.trackId\"\n >\n <div left-pane>\n <ng-container *ngTemplateOutlet=\"listContent\"></ng-container>\n </div>\n <div right-pane>\n <ng-container *ngTemplateOutlet=\"detailsContent\"></ng-container>\n </div>\n </c8y-resizable-grid>\n } @else {\n <ng-container *ngTemplateOutlet=\"listContent\"></ng-container>\n <ng-container *ngTemplateOutlet=\"detailsContent\"></ng-container>\n @if (showDefaultRouterOutlet && !hasProjectedDetails) {\n <router-outlet class=\"d-contents\"></router-outlet>\n }\n }\n\n <ng-template #listContent>\n <ng-content select=\":not(c8y-sv-details)\"></ng-content>\n </ng-template>\n\n <ng-template #detailsContent>\n @if (hasProjectedDetails) {\n <ng-content select=\"c8y-sv-details\"></ng-content>\n }\n </ng-template>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule$1 }, { kind: "directive", type: i1$a.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$a.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: ResizableGridComponent, selector: "c8y-resizable-grid", inputs: ["leftColumnWidth", "trackId", "collapseThreshold", "collapsible"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
38900
+ }
38901
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SplitViewComponent, decorators: [{
38902
+ type: Component,
38903
+ args: [{ selector: 'c8y-sv', standalone: true, imports: [CommonModule$1, RouterOutlet, C8yTranslatePipe, ResizableGridComponent], providers: [SplitViewSelectionService], template: "<div\n [attr.aria-label]=\"'Split view interface' | translate\"\n tabindex=\"-1\"\n role=\"main\"\n [ngClass]=\"getContainerClasses()\"\n data-cy=\"c8y-sv\"\n>\n @if (shouldUseResizableGrid) {\n <c8y-resizable-grid\n [collapseThreshold]=\"effectiveResizableConfig.collapseThreshold\"\n [collapsible]=\"effectiveResizableConfig.collapsible\"\n [leftColumnWidth]=\"effectiveResizableConfig.leftColumnWidth\"\n [trackId]=\"effectiveResizableConfig.trackId\"\n >\n <div left-pane>\n <ng-container *ngTemplateOutlet=\"listContent\"></ng-container>\n </div>\n <div right-pane>\n <ng-container *ngTemplateOutlet=\"detailsContent\"></ng-container>\n </div>\n </c8y-resizable-grid>\n } @else {\n <ng-container *ngTemplateOutlet=\"listContent\"></ng-container>\n <ng-container *ngTemplateOutlet=\"detailsContent\"></ng-container>\n @if (showDefaultRouterOutlet && !hasProjectedDetails) {\n <router-outlet class=\"d-contents\"></router-outlet>\n }\n }\n\n <ng-template #listContent>\n <ng-content select=\":not(c8y-sv-details)\"></ng-content>\n </ng-template>\n\n <ng-template #detailsContent>\n @if (hasProjectedDetails) {\n <ng-content select=\"c8y-sv-details\"></ng-content>\n }\n </ng-template>\n</div>\n" }]
38904
+ }], ctorParameters: () => [{ type: SplitViewSelectionService }], propDecorators: { showDefaultRouterOutlet: [{
38905
+ type: Input
38906
+ }], isResizable: [{
38907
+ type: Input
38908
+ }], initialSelection: [{
38909
+ type: Input
38910
+ }], resizableBreakpoint: [{
38911
+ type: Input
38912
+ }], selectionChange: [{
38913
+ type: Output
38914
+ }], resizableConfig: [{
38915
+ type: Input
38916
+ }], _detailsComp: [{
38917
+ type: ContentChild,
38918
+ args: [SplitViewDetailsComponent]
38919
+ }] } });
38920
+
38921
+ /**
38922
+ * Marker component for alert content in split-view lists.
38923
+ * Provides a named slot for displaying alerts above the list items.
38924
+ *
38925
+ * The parent split-view-list component detects this component via @ContentChild
38926
+ * and conditionally renders the alert section when present.
38927
+ *
38928
+ * This is a purely structural component with no logic or styling - all content
38929
+ * is projected and styled by the consumer.
38930
+ *
38931
+ * @example
38932
+ * ```html
38933
+ * <c8y-sv-list [title]="'Alarms'">
38934
+ * <c8y-sv-alerts>
38935
+ * @if (hasWarning) {
38936
+ * <div class="alert alert-warning" role="alert">
38937
+ * The selected item is not currently in the list.
38938
+ * </div>
38939
+ * }
38940
+ * </c8y-sv-alerts>
38941
+ * <!-- list items -->
38942
+ * @for (item of items; track item.id) {
38943
+ * <c8y-li>{{ item.name }}</c8y-li>
38944
+ * }
38945
+ * </c8y-sv-list>
38946
+ * ```
38947
+ *
38948
+ * @example Multiple alerts
38949
+ * ```html
38950
+ * <c8y-sv-list [title]="'Items'">
38951
+ * <c8y-sv-alerts>
38952
+ * @if (hasInfo) {
38953
+ * <div class="alert alert-info" role="alert">
38954
+ * Information message
38955
+ * </div>
38956
+ * }
38957
+ * @if (hasWarning) {
38958
+ * <div class="alert alert-warning" role="alert">
38959
+ * Warning message
38960
+ * </div>
38961
+ * }
38962
+ * </c8y-sv-alerts>
38963
+ * <!-- list content -->
38964
+ * </c8y-sv-list>
38965
+ * ```
38966
+ */
38967
+ class SplitViewAlertsComponent {
38968
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SplitViewAlertsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
38969
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: SplitViewAlertsComponent, isStandalone: true, selector: "c8y-sv-alerts", ngImport: i0, template: `<ng-content></ng-content>`, isInline: true }); }
38970
+ }
38971
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SplitViewAlertsComponent, decorators: [{
38972
+ type: Component,
38973
+ args: [{
38974
+ selector: 'c8y-sv-alerts',
38975
+ template: `<ng-content></ng-content>`,
38976
+ standalone: true
38977
+ }]
38978
+ }] });
38979
+
38980
+ class SplitViewListComponent {
38981
+ constructor() {
38982
+ /**
38983
+ * Optional parent split view component.
38984
+ * Used to determine if a details panel is present for automatic background styling.
38985
+ */
38986
+ this.parentSplitView = inject(SplitViewComponent, { optional: true });
38987
+ /**
38988
+ * Title for the list section.
38989
+ * Also used as aria-label if provided.
38990
+ */
38991
+ this.title = gettext$1('Split view list');
38992
+ /**
38993
+ * Whether the list is currently loading
38994
+ */
38995
+ this.loading = false;
38996
+ /**
38997
+ * Whether to show empty state
38998
+ */
38999
+ this.showEmptyState = true;
39000
+ /**
39001
+ * Custom empty state icon
39002
+ */
39003
+ this.emptyStateIcon = 'c8y-alert-idle';
39004
+ /**
39005
+ * Custom empty state title
39006
+ */
39007
+ this.emptyStateTitle = gettext$1('No items to display.');
39008
+ /**
39009
+ * Opacity for the list content (CSS opacity: 0-1 scale).
39010
+ *
39011
+ * Use this to dim the list during loading states while showing a loading indicator.
39012
+ * Defaults to 1 (fully opaque).
39013
+ *
39014
+ * @example
39015
+ * ```html
39016
+ * <!-- Dim list to 20% opacity during initial load -->
39017
+ * <c8y-sv-list [listOpacity]="isLoading ? 0.2 : 1">
39018
+ * ```
39019
+ */
39020
+ this.listOpacity = 1;
39021
+ }
39022
+ get hasAlerts() {
39023
+ return !!this.alertsComp;
39024
+ }
39025
+ /**
39026
+ * Computed property that determines if the title should be shown.
39027
+ * Uses the explicit `showTitle` input if provided, otherwise falls back to automatic detection.
39028
+ *
39029
+ * Automatic detection logic:
39030
+ * - Inside `<c8y-sv>`: shows the title (full page context)
39031
+ * - Outside `<c8y-sv>`: hides the title (widget context where widget provides its own title bar)
39032
+ */
39033
+ get shouldShowTitle() {
39034
+ return this.showTitle !== undefined ? this.showTitle : !!this.parentSplitView;
39035
+ }
39036
+ /**
39037
+ * Determines if split view layout styles should be applied based on the presence of a details panel.
39038
+ *
39039
+ * When a details panel (`<c8y-sv-details>`) is present alongside the list:
39040
+ * - Returns `true` → applies `split-view__list bg-level-1` classes (lighter background for contrast)
39041
+ *
39042
+ * When no details panel is present (single column or widget usage):
39043
+ * - Returns `false` → applies `bg-component` class (standard component background)
39044
+ *
39045
+ * This detection is automatic and based on the actual layout structure.
39046
+ */
39047
+ get isSplitView() {
39048
+ return !!this.parentSplitView?.hasProjectedDetails;
39049
+ }
39050
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SplitViewListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
39051
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: SplitViewListComponent, isStandalone: true, selector: "c8y-sv-list", inputs: { title: "title", loading: "loading", showEmptyState: "showEmptyState", emptyStateIcon: "emptyStateIcon", emptyStateTitle: "emptyStateTitle", emptyStateSubtitle: "emptyStateSubtitle", docsUrl: "docsUrl", showTitle: "showTitle", listOpacity: "listOpacity" }, host: { classAttribute: "d-contents" }, queries: [{ propertyName: "alertsComp", first: true, predicate: SplitViewAlertsComponent, descendants: true }], viewQueries: [{ propertyName: "innerScrollDiv", first: true, predicate: ["innerScrollDiv"], descendants: true }], ngImport: i0, template: "<div\n class=\"inner-scroll fit-h\"\n [attr.aria-label]=\"title | translate\"\n role=\"region\"\n [ngClass]=\"{ 'split-view__list bg-level-1': isSplitView, 'bg-component': !isSplitView }\"\n data-cy=\"c8y-sv-list\"\n #innerScrollDiv\n>\n @if (title || hasAlerts) {\n <div\n class=\"flex-wrap flex-no-shrink sticky-top gap-8\"\n [ngClass]=\"{\n 'card-header separator': title && shouldShowTitle\n }\"\n >\n @if (title && shouldShowTitle) {\n <h4 class=\"card-title\">\n {{ title | translate }}\n </h4>\n }\n <ng-content select=\"c8y-sv-header-actions\"></ng-content>\n @if (hasAlerts) {\n <ng-content select=\"c8y-sv-alerts\"></ng-content>\n }\n </div>\n }\n <div data-cy=\"c8y-sv-list--group\">\n @if (loading && !showEmptyState) {\n <div class=\"p-absolute fit-w overflow-hidden p-b-4\">\n <c8y-loading\n [layout]=\"'page'\"\n data-cy=\"c8y-sv-list--loading\"\n ></c8y-loading>\n </div>\n }\n <ng-content></ng-content>\n\n @if (showEmptyState) {\n <div class=\"p-relative p-l-24\">\n <c8y-ui-empty-state\n [icon]=\"emptyStateIcon\"\n [title]=\"emptyStateTitle\"\n [subtitle]=\"emptyStateSubtitle\"\n data-cy=\"c8y-sv-list--empty-state\"\n >\n @if (docsUrl) {\n <p>\n <small\n c8y-guide-docs\n translate\n [translateParams]=\"{ docsUrl }\"\n ngNonBindable\n >\n Find out more in the\n <a c8y-guide-href=\"{{ docsUrl }}\">user documentation</a>\n .\n </small>\n </p>\n }\n </c8y-ui-empty-state>\n </div>\n }\n </div>\n\n <ng-content select=\"c8y-sv-footer\"></ng-content>\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: GuideDocsComponent, selector: "[c8y-guide-docs]" }, { kind: "directive", type: GuideHrefDirective, selector: "[c8y-guide-href]", inputs: ["c8y-guide-href"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
39052
+ }
39053
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SplitViewListComponent, decorators: [{
39054
+ type: Component,
39055
+ args: [{ selector: 'c8y-sv-list', host: { class: 'd-contents' }, standalone: true, imports: [
39056
+ NgClass,
39057
+ LoadingComponent,
39058
+ EmptyStateComponent,
39059
+ C8yTranslatePipe,
39060
+ C8yTranslateDirective,
39061
+ GuideDocsComponent,
39062
+ GuideHrefDirective
39063
+ ], template: "<div\n class=\"inner-scroll fit-h\"\n [attr.aria-label]=\"title | translate\"\n role=\"region\"\n [ngClass]=\"{ 'split-view__list bg-level-1': isSplitView, 'bg-component': !isSplitView }\"\n data-cy=\"c8y-sv-list\"\n #innerScrollDiv\n>\n @if (title || hasAlerts) {\n <div\n class=\"flex-wrap flex-no-shrink sticky-top gap-8\"\n [ngClass]=\"{\n 'card-header separator': title && shouldShowTitle\n }\"\n >\n @if (title && shouldShowTitle) {\n <h4 class=\"card-title\">\n {{ title | translate }}\n </h4>\n }\n <ng-content select=\"c8y-sv-header-actions\"></ng-content>\n @if (hasAlerts) {\n <ng-content select=\"c8y-sv-alerts\"></ng-content>\n }\n </div>\n }\n <div data-cy=\"c8y-sv-list--group\">\n @if (loading && !showEmptyState) {\n <div class=\"p-absolute fit-w overflow-hidden p-b-4\">\n <c8y-loading\n [layout]=\"'page'\"\n data-cy=\"c8y-sv-list--loading\"\n ></c8y-loading>\n </div>\n }\n <ng-content></ng-content>\n\n @if (showEmptyState) {\n <div class=\"p-relative p-l-24\">\n <c8y-ui-empty-state\n [icon]=\"emptyStateIcon\"\n [title]=\"emptyStateTitle\"\n [subtitle]=\"emptyStateSubtitle\"\n data-cy=\"c8y-sv-list--empty-state\"\n >\n @if (docsUrl) {\n <p>\n <small\n c8y-guide-docs\n translate\n [translateParams]=\"{ docsUrl }\"\n ngNonBindable\n >\n Find out more in the\n <a c8y-guide-href=\"{{ docsUrl }}\">user documentation</a>\n .\n </small>\n </p>\n }\n </c8y-ui-empty-state>\n </div>\n }\n </div>\n\n <ng-content select=\"c8y-sv-footer\"></ng-content>\n</div>\n" }]
39064
+ }], propDecorators: { title: [{
39065
+ type: Input
39066
+ }], loading: [{
39067
+ type: Input
39068
+ }], showEmptyState: [{
39069
+ type: Input
39070
+ }], emptyStateIcon: [{
39071
+ type: Input
39072
+ }], emptyStateTitle: [{
39073
+ type: Input
39074
+ }], emptyStateSubtitle: [{
39075
+ type: Input
39076
+ }], docsUrl: [{
39077
+ type: Input
39078
+ }], showTitle: [{
39079
+ type: Input
39080
+ }], listOpacity: [{
39081
+ type: Input
39082
+ }], innerScrollDiv: [{
39083
+ type: ViewChild,
39084
+ args: ['innerScrollDiv']
39085
+ }], alertsComp: [{
39086
+ type: ContentChild,
39087
+ args: [SplitViewAlertsComponent]
39088
+ }] } });
39089
+
39090
+ class SplitViewHeaderActionsComponent {
39091
+ constructor() {
39092
+ /**
39093
+ * Parent list component reference to automatically detect if title is shown.
39094
+ * This allows automatic adjustment of spacing based on parent's showTitle setting.
39095
+ */
39096
+ this.parentList = inject(SplitViewListComponent);
39097
+ }
39098
+ /**
39099
+ * Whether the parent list shows a title.
39100
+ * Automatically inherited from parent, used to adjust spacing.
39101
+ */
39102
+ get showTitle() {
39103
+ return this.parentList.shouldShowTitle;
39104
+ }
39105
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SplitViewHeaderActionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
39106
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: SplitViewHeaderActionsComponent, isStandalone: true, selector: "c8y-sv-header-actions", host: { classAttribute: "d-contents" }, ngImport: i0, template: "<div\n [ngClass]=\"{ 'd-flex a-i-center fit-w': !showTitle, 'm-l-auto': showTitle }\"\n data-cy=\"c8y-sv-header-actions\"\n>\n <ng-content></ng-content>\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
39107
+ }
39108
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SplitViewHeaderActionsComponent, decorators: [{
39109
+ type: Component,
39110
+ args: [{ selector: 'c8y-sv-header-actions', host: { class: 'd-contents' }, standalone: true, imports: [NgClass], template: "<div\n [ngClass]=\"{ 'd-flex a-i-center fit-w': !showTitle, 'm-l-auto': showTitle }\"\n data-cy=\"c8y-sv-header-actions\"\n>\n <ng-content></ng-content>\n</div>\n" }]
39111
+ }] });
39112
+
39113
+ /**
39114
+ * Directive to handle item selection in split-view list.
39115
+ * Automatically selects the item on click and applies the 'active' class.
39116
+ *
39117
+ * Usage:
39118
+ * ```html
39119
+ * @for (device of devices; track device.id) {
39120
+ * <c8y-li [c8ySvListItem]="device">
39121
+ * {{ device.name }}
39122
+ * </c8y-li>
39123
+ * }
39124
+ * ```
39125
+ */
39126
+ class SplitViewListItemDirective {
39127
+ constructor(selectionService) {
39128
+ this.selectionService = selectionService;
39129
+ }
39130
+ get isActive() {
39131
+ return !!(this.item && this.selectionService?.isSelected(this.item));
39132
+ }
39133
+ get role() {
39134
+ return 'button';
39135
+ }
39136
+ onClick() {
39137
+ if (this.item && this.selectionService) {
39138
+ this.selectionService.select(this.item);
39139
+ }
39140
+ }
39141
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SplitViewListItemDirective, deps: [{ token: SplitViewSelectionService, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }
39142
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.15", type: SplitViewListItemDirective, isStandalone: true, selector: "[c8ySvListItem]", inputs: { item: ["c8ySvListItem", "item"] }, host: { listeners: { "click": "onClick()" }, properties: { "class.active": "this.isActive", "attr.role": "this.role" }, classAttribute: "pointer" }, ngImport: i0 }); }
39143
+ }
39144
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SplitViewListItemDirective, decorators: [{
39145
+ type: Directive,
39146
+ args: [{
39147
+ selector: '[c8ySvListItem]',
39148
+ standalone: true,
39149
+ host: { class: 'pointer' }
39150
+ }]
39151
+ }], ctorParameters: () => [{ type: SplitViewSelectionService, decorators: [{
39152
+ type: Optional
39153
+ }] }], propDecorators: { item: [{
39154
+ type: Input,
39155
+ args: [{ alias: 'c8ySvListItem' }]
39156
+ }], isActive: [{
39157
+ type: HostBinding,
39158
+ args: ['class.active']
39159
+ }], role: [{
39160
+ type: HostBinding,
39161
+ args: ['attr.role']
39162
+ }], onClick: [{
39163
+ type: HostListener,
39164
+ args: ['click']
39165
+ }] } });
39166
+
38002
39167
  /**
38003
39168
  * Barrel to export /core
38004
39169
  */
@@ -38007,5 +39172,5 @@ function colorValidator(allowedModes) {
38007
39172
  * Generated bundle index. Do not edit.
38008
39173
  */
38009
39174
 
38010
- export { ACTIONS_STEPPER, AGGREGATIONS, AGGREGATION_ICONS, AGGREGATION_LABELS, AGGREGATION_LIMITS, AGGREGATION_TEXTS, AGGREGATION_VALUES, AGGREGATION_VALUES_ARR, ARRAY_VALIDATION_PREFIX, ASSET_PATH, AbstractConfigurationStrategy, ActionBarComponent, ActionBarItemComponent, ActionBarModule, ActionBarService, ActionComponent, ActionControlsExtensionService, ActionModule, ActionOutletComponent, ActionService, AggregationPickerComponent, AggregationService, AlarmRealtimeService, AlarmWithChildrenRealtimeService, AlertComponent, AlertDetailsComponent, AlertModule, AlertOutletBase, AlertOutletComponent, AlertService, AlertTextComponent, AppHrefPipe, AppIconComponent, AppStateService, AppSwitcherComponent, AppSwitcherInlineComponent, AppSwitcherService, ApplicationModule, ApplicationPluginStatus, AssetLinkPipe, AssetPropertyService, AssetTypesRealtimeService, AssetTypesService, AuditLogComponent, AuditLogModule, AuthenticationModule, BackendVersionFactory, BaseColumn, BaseFilteringFormRendererComponent, BooleanFilterMapper, BootstrapComponent, BootstrapModule, BottomDrawerComponent, BottomDrawerRef, BottomDrawerService, BreadcrumbComponent, BreadcrumbItemComponent, BreadcrumbModule, BreadcrumbOutletComponent, BreadcrumbService, BuiltInActionType, BytesPipe, C8Y_PLUGIN_CONTEXT_PATH, C8Y_PLUGIN_NAME, C8yComponentOutlet, C8yJSONSchema, C8yStepper, C8yStepperButtons, C8yStepperIcon, C8yStepperProgress, C8yTranslateDirective, C8yTranslateModule, C8yTranslatePipe, C8yTranslationCache, C8yTranslationLoader, C8yValidators, CUSTOM, CachedLocaleDictionaryService, CellRendererComponent, CellRendererContext, CellRendererDefDirective, ChangeCurrentUserPasswordService, ChangeIconComponent, ClipboardModule, ClipboardService, ColorInputComponent, ColorService, ColumnDirective, CommonModule, ConditionalTabsOutletComponent, ConfigureCustomColumnComponent, ConfirmModalComponent, ContextRouteComponent, ContextRouteGuard, ContextRouteService, CookieBannerComponent, CopyDashboardDisabledReason, CoreModule, CoreSearchModule, CountdownIntervalComponent, CountdownIntervalModule, CurrentPasswordModalComponent, CustomColumn, CustomTranslateService, CustomTranslateStore, DATA_GRID_CONFIGURATION_CONTEXT, DATA_GRID_CONFIGURATION_CONTEXT_PROVIDER, DATA_GRID_CONFIGURATION_STRATEGY, DEFAULT_INTERVAL_STATE, DEFAULT_INTERVAL_VALUE, DEFAULT_INTERVAL_VALUES, DRAWER_ANIMATION_TIME, DashboardChildActionComponent, DashboardChildChange, DashboardChildComponent, DashboardChildTitleComponent, DashboardComponent, DashboardModule, DataGridComponent, DataGridModule, DataGridService, DatapointLibraryValidationErrors, DatapointSyncService, DateContextQueryParamNames, DateFilterMapper, DateFormatService, DatePickerComponent, DatePickerModule, DatePipe, DateTimePickerComponent, DateTimePickerModule, DefaultValidationDirective, DeviceBootstrapRealtimeService, DeviceService, DeviceStatusComponent, DeviceStatusModule, DismissAlertStrategy, DocsModule, DocsService, DrawerModule, DrawerOutletComponent, DrawerService, DropAreaComponent, DropAreaModule, DropdownDirectionDirective, DynamicBulkDetailsResolver, DynamicBulkIIdentifiedResolver, DynamicComponentAlert, DynamicComponentAlertAggregator, DynamicComponentAlertsComponent, DynamicComponentComponent, DynamicComponentErrorStrategy, DynamicComponentModule, DynamicComponentService, DynamicDatapointsResolver, DynamicFormsModule, DynamicManagedObjectResolver, DynamicResolverService, ES_MAX_TIME_MILLISECONDS, EmailsValidatorDirective, EmptyComponent, EmptyStateComponent, EmptyStateContextDirective, EventRealtimeService, ExpandableRowDirective, ExtensionPointForPlugins, ExtensionPointWithoutStateForPlugins, ExtractArrayValidationErrorsPipe, FeatureCacheService, FeedbackFormComponent, FilePickerComponent, FilePickerFormControlComponent, FilePickerFormControlModule, FilePickerModule, FilesService, FilterByPipe, FilterInputComponent, FilterMapperFactory, FilterMapperModule, FilterMapperPipe, FilterMapperService, FilterNonArrayValidationErrorsPipe, FilteringActionType, FilteringFormRendererComponent, FilteringFormRendererContext, FilteringFormRendererDefDirective, ForOfDirective, FormGroupComponent, FormsModule, GENERIC_FILE_TYPE, GLOBAL_CONTEXT_AUTO_REFRESH, GainsightService, GenericFileIconPipe, GeoService, GetGroupIconPipe, GlobalConfigService, GridDataSource, GroupFragment, GroupService, GroupedFilterChips, GuideDocsComponent, GuideHrefDirective, HOOK_ACTION, HOOK_ACTION_BAR, HOOK_BREADCRUMB, HOOK_COMPONENTS, HOOK_CURRENT_APPLICATION, HOOK_CURRENT_TENANT, HOOK_CURRENT_USER, HOOK_DOCS, HOOK_DYNAMIC_PROVIDER_CONFIG, HOOK_NAVIGATOR_NODES, HOOK_OPTIONS, HOOK_PATTERN_MESSAGES, HOOK_PLUGIN, HOOK_PREVIEW, HOOK_QUERY_PARAM, HOOK_QUERY_PARAM_BOTTOM_DRAWER, HOOK_QUERY_PARAM_MODAL, HOOK_ROUTE, HOOK_SEARCH, HOOK_STEPPER, HOOK_TABS, HOOK_VERSION, HOOK_WIZARD, HeaderBarComponent, HeaderCellRendererDefDirective, HeaderModule, HeaderService, HelpComponent, HelpModule, HighlightComponent, HookProviderTypes, HumanizeAppNamePipe, HumanizePipe, HumanizeValidationMessagePipe, I18nModule, INTERVAL_OPTIONS, IconDirective, IfAllowedDirective, InjectionType, InputGroupListComponent, InputGroupListContainerDirective, InterAppService, IntervalBasedReload, InventorySearchService, IpRangeInputListComponent, JsonValidationPrettifierDirective, LANGUAGES, LAST_DAY, LAST_HOUR, LAST_MINUTE, LAST_MONTH, LAST_WEEK, LOCALE_PATH, LegacyGridConfigMapperService, LegendFieldWrapper, ListDisplaySwitchComponent, ListDisplaySwitchModule, ListGroupComponent, ListGroupModule, ListItemActionComponent, ListItemBodyComponent, ListItemCheckboxComponent, ListItemCollapseComponent, ListItemComponent, ListItemDragHandleComponent, ListItemFooterComponent, ListItemIconComponent, ListItemRadioComponent, ListItemTimelineComponent, LoadMoreComponent, LoadingComponent, MAX_PAGE_SIZE, MESSAGES_CORE_I18N, MOChunkLoaderService, ManagedObjectRealtimeService, ManagedObjectType, MapFunctionPipe, MarkdownToHtmlPipe, MaxValidationDirective, MeasurementRealtimeService, MessageBannerService, MessageDirective, MessagesComponent, MinValidationDirective, MissingTranslationCustomHandler, MoNamePipe, ModalComponent, ModalModule, ModalSelectionMode, ModalService, NEEDED_ROLE_FOR_SETUP, NEW_DASHBOARD_ROUTER_STATE_PROP, NULL_VALUE_PLACEHOLDER, NUMBER_FORMAT_REGEXP, NameTransformPipe, NavigatorBottomModule, NavigatorIconComponent, NavigatorModule, NavigatorNode, NavigatorNodeComponent, NavigatorNodeRoot, NavigatorOutletComponent, NavigatorService, NavigatorTopModule, NewPasswordComponent, NumberPipe, OperationBulkRealtimeService, OperationRealtimeService, OperationResultComponent, OptionsService, OutletDirective, PREVIEW_FEATURE_PROVIDERS, PRODUCT_EXPERIENCE_EVENT_SOURCE, PX_ACTIONS, PX_EVENT_NAME, PackageType, PasswordCheckListComponent, PasswordConfirm, PasswordConfirmModalComponent, PasswordInputComponent, PasswordService, PasswordStrengthCheckerService, PasswordStrengthComponent, PasswordStrengthService, PatternMessagesService, Permissions, PhoneValidationDirective, PlatformDetailsService, PluginLoadedPipe, PluginsExportScopes, PluginsLoaderService, PluginsModule, PluginsResolveService, PluginsService, PopoverConfirmComponent, PreviewFeatureButtonComponent, PreviewFeatureShowNotification, PreviewService, ProductExperienceDirective, ProductExperienceModule, ProgressBarComponent, PropertiesListComponent, PropertiesListModule, PropertyValueTransformService, ProviderConfigurationComponent, ProviderConfigurationModule, ProviderConfigurationNodeFactory, ProviderConfigurationRouteFactory, ProviderConfigurationService, ProviderDefinitionsService, PushStatus, PushStatusLabels, QUERY_PARAM_HANDLER_PROVIDERS, QueryParamBottomDrawerFactory, QueryParamBottomDrawerStateService, QueryParamHandlerService, QueryParamModalFactory, QueryParamModalStateService, QuickLinkComponent, QuickLinkModule, RESOLVING_COMPONENT_WAIT_TIME, RadioFilterMapper, RangeComponent, RangeDirective, RangeDisplayComponent, RangeDisplayModule, RealtimeButtonComponent, RealtimeControlComponent, RealtimeMessage, RealtimeModule, RealtimeService, RealtimeSubjectService, RelativeTimePipe, RequiredInputPlaceholderDirective, ResizableGridComponent, ResolverServerError, RouterModule, RouterService, RouterTabsResolver, SETUP_FINISHED_STEP_ID, SHOW_PREVIEW_FEATURES, SearchComponent, SearchFilters, SearchInputComponent, SearchOutletComponent, SearchResultEmptyComponent, SearchService, SelectComponent, SelectFilterMapper, SelectItemDirective, SelectKeyboardService, SelectLegacyComponent, SelectModalComponent, SelectModalFilterPipe, SelectModalModule, SelectModule, SelectedItemsComponent, SelectedItemsDirective, SendStatus, SendStatusLabels, ServiceRegistry, SetupCompletedComponent, SetupComponent, SetupModule, SetupService, SetupState, SetupStepperFactory, ShortenUserNamePipe, ShouldShowMoPipe, ShowIfFilterPipe, SimpleJsonPathValidatorDirective, SimplifiedAuthService, SkipLinkDirective, StateService, Status, StepperModule, StepperOutletComponent, StepperService, Steppers, StringFilterMapper, StringifyObjectPipe, SupportedApps, TabComponent, TabsModule, TabsOutletComponent, TabsService, TabsetAriaDirective, TenantUiService, TextAreaRowHeightDirective, TextareaAutoresizeDirective, ThemeSwitcherService, TimeIntervalComponent, TimePickerComponent, TimePickerModule, TitleComponent, TitleOutletComponent, TotpChallengeComponent, TotpSetupComponent, TranslateService, TreeNodeCellRendererComponent, TreeNodeColumn, TreeNodeHeaderCellRendererComponent, TypeaheadComponent, TypeaheadFilterMapper, UiSettingsComponent, UiSettingsModule, UniqueInCollectionByPathValidationDirective, UserEditComponent, UserEditModalComponent, UserEngagementsService, UserMenuItemComponent, UserMenuOutletComponent, UserMenuService, UserModule, UserNameInitialsPipe, UserPreferencesConfigurationStrategy, UserPreferencesService, UserPreferencesStorageInventory, UserPreferencesStorageLocal, UserTotpRevokeComponent, UserTotpSetupComponent, VERSION_MODULE_CONFIG, ValidationPattern, VersionListComponent, VersionModule, VersionService, ViewContext, ViewContextServices, VirtualScrollWindowDirective, VirtualScrollWindowStrategy, VirtualScrollerWrapperComponent, VisibleControlsPipe, WIDGET_CONFIGURATION_GRID_SIZE, WIDGET_TYPE_VALUES, WILDCARD_SEARCH_FEATURE_KEY, WebSDKVersionFactory, WidgetGlobalAutoRefreshService, WidgetTimeContextActionBarPriority, WidgetTimeContextComponent, WidgetTimeContextDateRangeService, WidgetTimeContextMediatorService, WidgetsDashboardComponent, WidgetsDashboardEventService, WizardBodyComponent, WizardComponent, WizardFooterComponent, WizardHeaderComponent, WizardModalService, WizardModule, WizardOutletComponent, WizardService, ZipService, _virtualScrollWindowStrategyFactory, alertOnError, allEntriesAreEqual, asyncValidateArrayElements, colorValidator, deviceAvailabilityIconMap, extraRoutes, fromFactories, fromTrigger, fromTriggerOnce, getActivatedRoute, getAngularLocalesLanguageString, getBasicInputArrayFormFieldConfig, getDictionaryWithTrimmedKeys, getInjectedHooks, gettext, globalAutoRefreshLoading, hookAction, hookActionBar, hookBreadcrumb, hookComponent, hookCurrentApplication, hookCurrentTenant, hookCurrentUser, hookDataGridActionControls, hookDocs, hookDrawer, hookDynamicProviderConfig, hookFilterMapper, hookGeneric, hookNavigator, hookOptions, hookPatternMessages, hookPlugin, hookPreview, hookQueryParam, hookQueryParamBottomDrawer, hookQueryParamModal, hookRoute, hookSearch, hookService, hookStepper, hookTab, hookUserMenu, hookVersion, hookWidget, hookWizard, internalApps, isEagerDynamicComponents, isExtensionFactory, isLazyDynamicComponents, isPromise, languagesFactory, loadLocale, localeId, localePathFactory, memoize, minColumnGridTrackSize, operationStatusClasses, operationStatusIcons, provideBootstrapMetadata, provideCommonPipes, provideCommonServices, provideDefaultOptionsAppInitializer, provideI18n, provideLanguageSelectorAppInitializer, providePluginsLoaderServiceAppInitializer, provideTranslationServiceInstance, ratiosByColumnTypes, removeContextIndicators, removeDuplicatesIds, resolveInjectedFactories, retryWithDelay, simpleJsonPathValidator, sortByPriority, stateToFactory, statusAlert, statusClasses, statusIcons, throttle, toObservable, toObservableOfArrays, tooltips, trimTranslationKey, uniqueInCollectionByPathValidator, validateArrayElements, validateInternationalPhoneNumber, viewContextRoutes, wrapperLegendFieldConfig };
39175
+ export { ACTIONS_STEPPER, AGGREGATIONS, AGGREGATION_ICONS, AGGREGATION_LABELS, AGGREGATION_LIMITS, AGGREGATION_TEXTS, AGGREGATION_VALUES, AGGREGATION_VALUES_ARR, ARRAY_VALIDATION_PREFIX, ASSET_PATH, AbstractConfigurationStrategy, ActionBarComponent, ActionBarItemComponent, ActionBarModule, ActionBarService, ActionComponent, ActionControlsExtensionService, ActionModule, ActionOutletComponent, ActionService, AggregationPickerComponent, AggregationService, AlarmRealtimeService, AlarmWithChildrenRealtimeService, AlertComponent, AlertDetailsComponent, AlertModule, AlertOutletBase, AlertOutletComponent, AlertService, AlertTextComponent, AppHrefPipe, AppIconComponent, AppStateService, AppSwitcherComponent, AppSwitcherInlineComponent, AppSwitcherService, ApplicationModule, ApplicationPluginStatus, AssetHierarchyService, AssetLinkPipe, AssetPropertyService, AssetTypesRealtimeService, AssetTypesService, AuditLogComponent, AuditLogModule, AuthenticationModule, BackendVersionFactory, BaseColumn, BaseFilteringFormRendererComponent, BooleanFilterMapper, BootstrapComponent, BootstrapModule, BottomDrawerComponent, BottomDrawerRef, BottomDrawerService, BreadcrumbComponent, BreadcrumbItemComponent, BreadcrumbModule, BreadcrumbOutletComponent, BreadcrumbService, BuiltInActionType, BytesPipe, C8Y_PLUGIN_CONTEXT_PATH, C8Y_PLUGIN_NAME, C8yComponentOutlet, C8yJSONSchema, C8yStepper, C8yStepperButtons, C8yStepperIcon, C8yStepperProgress, C8yTranslateDirective, C8yTranslateModule, C8yTranslatePipe, C8yTranslationCache, C8yTranslationLoader, C8yValidators, CUSTOM, CachedLocaleDictionaryService, CellRendererComponent, CellRendererContext, CellRendererDefDirective, ChangeCurrentUserPasswordService, ChangeIconComponent, ClipboardModule, ClipboardService, ColorInputComponent, ColorService, ColumnDirective, CommonModule, ConditionalTabsOutletComponent, ConfigureCustomColumnComponent, ConfirmModalComponent, ContextRouteComponent, ContextRouteGuard, ContextRouteService, CookieBannerComponent, CopyDashboardDisabledReason, CoreModule, CoreSearchModule, CountdownIntervalComponent, CountdownIntervalModule, CurrentPasswordModalComponent, CustomColumn, CustomTranslateService, CustomTranslateStore, DATA_GRID_CONFIGURATION_CONTEXT, DATA_GRID_CONFIGURATION_CONTEXT_PROVIDER, DATA_GRID_CONFIGURATION_STRATEGY, DEFAULT_INTERVAL_STATE, DEFAULT_INTERVAL_VALUE, DEFAULT_INTERVAL_VALUES, DRAWER_ANIMATION_TIME, DashboardChildActionComponent, DashboardChildChange, DashboardChildComponent, DashboardChildTitleComponent, DashboardComponent, DashboardModule, DataGridComponent, DataGridModule, DataGridService, DatapointLibraryValidationErrors, DatapointSyncService, DateContextQueryParamNames, DateFilterMapper, DateFormatService, DatePickerComponent, DatePickerModule, DatePipe, DateTimePickerComponent, DateTimePickerModule, DefaultValidationDirective, DeviceBootstrapRealtimeService, DeviceService, DeviceStatusComponent, DeviceStatusModule, DismissAlertStrategy, DocsModule, DocsService, DrawerModule, DrawerOutletComponent, DrawerService, DropAreaComponent, DropAreaModule, DropdownDirectionDirective, DynamicBulkDetailsResolver, DynamicBulkIIdentifiedResolver, DynamicComponentAlert, DynamicComponentAlertAggregator, DynamicComponentAlertsComponent, DynamicComponentComponent, DynamicComponentErrorStrategy, DynamicComponentModule, DynamicComponentService, DynamicDatapointsResolver, DynamicFormsModule, DynamicManagedObjectResolver, DynamicResolverService, ES_MAX_TIME_MILLISECONDS, EmailsValidatorDirective, EmptyComponent, EmptyStateComponent, EmptyStateContextDirective, EventRealtimeService, ExpandableRowDirective, ExtensionPointForPlugins, ExtensionPointWithoutStateForPlugins, ExtractArrayValidationErrorsPipe, FeatureCacheService, FeedbackFormComponent, FilePickerComponent, FilePickerFormControlComponent, FilePickerFormControlModule, FilePickerModule, FilesService, FilterByPipe, FilterInputComponent, FilterMapperFactory, FilterMapperModule, FilterMapperPipe, FilterMapperService, FilterNonArrayValidationErrorsPipe, FilteringActionType, FilteringFormRendererComponent, FilteringFormRendererContext, FilteringFormRendererDefDirective, ForOfDirective, FormGroupComponent, FormsModule, GENERIC_FILE_TYPE, GLOBAL_CONTEXT_AUTO_REFRESH, GainsightService, GenericFileIconPipe, GeoService, GetGroupIconPipe, GlobalConfigService, GridDataSource, GroupFragment, GroupService, GroupedFilterChips, GuideDocsComponent, GuideHrefDirective, HOOK_ACTION, HOOK_ACTION_BAR, HOOK_BREADCRUMB, HOOK_COMPONENTS, HOOK_CURRENT_APPLICATION, HOOK_CURRENT_TENANT, HOOK_CURRENT_USER, HOOK_DOCS, HOOK_DYNAMIC_PROVIDER_CONFIG, HOOK_NAVIGATOR_NODES, HOOK_OPTIONS, HOOK_PATTERN_MESSAGES, HOOK_PLUGIN, HOOK_PREVIEW, HOOK_QUERY_PARAM, HOOK_QUERY_PARAM_BOTTOM_DRAWER, HOOK_QUERY_PARAM_MODAL, HOOK_ROUTE, HOOK_SEARCH, HOOK_STEPPER, HOOK_TABS, HOOK_VERSION, HOOK_WIZARD, HeaderBarComponent, HeaderCellRendererDefDirective, HeaderModule, HeaderService, HelpComponent, HelpModule, HighlightComponent, HookProviderTypes, HumanizeAppNamePipe, HumanizePipe, HumanizeValidationMessagePipe, I18nModule, INTERVAL_OPTIONS, IconDirective, IconPanelComponent, IfAllowedDirective, InjectionType, InputGroupListComponent, InputGroupListContainerDirective, InterAppService, IntervalBasedReload, InventorySearchService, IpRangeInputListComponent, JsonValidationPrettifierDirective, LANGUAGES, LAST_DAY, LAST_HOUR, LAST_MINUTE, LAST_MONTH, LAST_WEEK, LOCALE_PATH, LegacyGridConfigMapperService, LegendFieldWrapper, ListDisplaySwitchComponent, ListDisplaySwitchModule, ListGroupComponent, ListGroupModule, ListItemActionComponent, ListItemBodyComponent, ListItemCheckboxComponent, ListItemCollapseComponent, ListItemComponent, ListItemDragHandleComponent, ListItemFooterComponent, ListItemIconComponent, ListItemRadioComponent, ListItemTimelineComponent, LoadMoreComponent, LoadingComponent, MAX_PAGE_SIZE, MESSAGES_CORE_I18N, MOChunkLoaderService, ManagedObjectRealtimeService, ManagedObjectType, MapFunctionPipe, MarkdownToHtmlPipe, MaxValidationDirective, MeasurementRealtimeService, MessageBannerService, MessageDirective, MessagesComponent, MinValidationDirective, MissingTranslationCustomHandler, MoNamePipe, ModalComponent, ModalModule, ModalSelectionMode, ModalService, NEEDED_ROLE_FOR_SETUP, NEW_DASHBOARD_ROUTER_STATE_PROP, NULL_VALUE_PLACEHOLDER, NUMBER_FORMAT_REGEXP, NameTransformPipe, NavigatorBottomModule, NavigatorIconComponent, NavigatorModule, NavigatorNode, NavigatorNodeComponent, NavigatorNodeRoot, NavigatorOutletComponent, NavigatorService, NavigatorTopModule, NewPasswordComponent, NumberPipe, OperationBulkRealtimeService, OperationRealtimeService, OperationResultComponent, OptionsService, OutletDirective, PREVIEW_FEATURE_PROVIDERS, PRODUCT_EXPERIENCE_EVENT_SOURCE, PX_ACTIONS, PX_EVENT_NAME, PackageType, PasswordCheckListComponent, PasswordConfirm, PasswordConfirmModalComponent, PasswordInputComponent, PasswordService, PasswordStrengthCheckerService, PasswordStrengthComponent, PasswordStrengthService, PatternMessagesService, Permissions, PhoneValidationDirective, PlatformDetailsService, PluginLoadedPipe, PluginsExportScopes, PluginsLoaderService, PluginsModule, PluginsResolveService, PluginsService, PopoverConfirmComponent, PreviewFeatureButtonComponent, PreviewFeatureShowNotification, PreviewService, ProductExperienceDirective, ProductExperienceModule, ProgressBarComponent, PropertiesListComponent, PropertiesListModule, PropertyValueTransformService, ProviderConfigurationComponent, ProviderConfigurationModule, ProviderConfigurationNodeFactory, ProviderConfigurationRouteFactory, ProviderConfigurationService, ProviderDefinitionsService, PushStatus, PushStatusLabels, QUERY_PARAM_HANDLER_PROVIDERS, QueryParamBottomDrawerFactory, QueryParamBottomDrawerStateService, QueryParamHandlerService, QueryParamModalFactory, QueryParamModalStateService, QuickLinkComponent, QuickLinkModule, RESOLVING_COMPONENT_WAIT_TIME, RadioFilterMapper, RangeComponent, RangeDirective, RangeDisplayComponent, RangeDisplayModule, RealtimeButtonComponent, RealtimeControlComponent, RealtimeMessage, RealtimeModule, RealtimeService, RealtimeSubjectService, RelativeTimePipe, RequiredInputPlaceholderDirective, ResizableGridComponent, ResolverServerError, RouterModule, RouterService, RouterTabsResolver, SETUP_FINISHED_STEP_ID, SHOW_PREVIEW_FEATURES, SearchComponent, SearchFilters, SearchInputComponent, SearchOutletComponent, SearchResultEmptyComponent, SearchService, SelectComponent, SelectFilterMapper, SelectItemDirective, SelectKeyboardService, SelectLegacyComponent, SelectModalComponent, SelectModalFilterPipe, SelectModalModule, SelectModule, SelectedItemsComponent, SelectedItemsDirective, SendStatus, SendStatusLabels, ServiceRegistry, SetupCompletedComponent, SetupComponent, SetupModule, SetupService, SetupState, SetupStepperFactory, ShortenUserNamePipe, ShouldShowMoPipe, ShowIfFilterPipe, SimpleJsonPathValidatorDirective, SimplifiedAuthService, SkipLinkDirective, SplitViewAlertsComponent, SplitViewComponent, SplitViewDetailsActionsComponent, SplitViewDetailsComponent, SplitViewExtraHeaderComponent, SplitViewFooterComponent, SplitViewHeaderActionsComponent, SplitViewListComponent, SplitViewListItemDirective, SplitViewSelectionService, StateService, Status, StepperModule, StepperOutletComponent, StepperService, Steppers, StringFilterMapper, StringifyObjectPipe, StripHtmlPipe, SupportedApps, TabComponent, TabsModule, TabsOutletComponent, TabsService, TabsetAriaDirective, TenantUiService, TextAreaRowHeightDirective, TextareaAutoresizeDirective, ThemeSwitcherService, TimeIntervalComponent, TimePickerComponent, TimePickerModule, TitleComponent, TitleOutletComponent, TotpChallengeComponent, TotpSetupComponent, TranslateService, TreeNodeCellRendererComponent, TreeNodeColumn, TreeNodeHeaderCellRendererComponent, TypeaheadComponent, TypeaheadFilterMapper, UiSettingsComponent, UiSettingsModule, UniqueInCollectionByPathValidationDirective, UserEditComponent, UserEditModalComponent, UserEngagementsService, UserMenuItemComponent, UserMenuOutletComponent, UserMenuService, UserModule, UserNameInitialsPipe, UserPreferencesConfigurationStrategy, UserPreferencesService, UserPreferencesStorageInventory, UserPreferencesStorageLocal, UserTotpRevokeComponent, UserTotpSetupComponent, VERSION_MODULE_CONFIG, ValidationPattern, VersionListComponent, VersionModule, VersionService, ViewContext, ViewContextServices, VirtualScrollWindowDirective, VirtualScrollWindowStrategy, VirtualScrollerWrapperComponent, VisibleControlsPipe, WIDGET_CONFIGURATION_GRID_SIZE, WIDGET_TYPE_VALUES, WILDCARD_SEARCH_FEATURE_KEY, WebSDKVersionFactory, WidgetGlobalAutoRefreshService, WidgetTimeContextActionBarPriority, WidgetTimeContextComponent, WidgetTimeContextDateRangeService, WidgetTimeContextMediatorService, WidgetsDashboardComponent, WidgetsDashboardEventService, WizardBodyComponent, WizardComponent, WizardFooterComponent, WizardHeaderComponent, WizardModalService, WizardModule, WizardOutletComponent, WizardService, ZipService, _virtualScrollWindowStrategyFactory, alertOnError, allEntriesAreEqual, asyncValidateArrayElements, colorValidator, deviceAvailabilityIconMap, extraRoutes, fromFactories, fromTrigger, fromTriggerOnce, getActivatedRoute, getAngularLocalesLanguageString, getBasicInputArrayFormFieldConfig, getDictionaryWithTrimmedKeys, getInjectedHooks, gettext, globalAutoRefreshLoading, hookAction, hookActionBar, hookBreadcrumb, hookComponent, hookCurrentApplication, hookCurrentTenant, hookCurrentUser, hookDataGridActionControls, hookDocs, hookDrawer, hookDynamicProviderConfig, hookFilterMapper, hookGeneric, hookNavigator, hookOptions, hookPatternMessages, hookPlugin, hookPreview, hookQueryParam, hookQueryParamBottomDrawer, hookQueryParamModal, hookRoute, hookSearch, hookService, hookStepper, hookTab, hookUserMenu, hookVersion, hookWidget, hookWizard, internalApps, isEagerDynamicComponents, isExtensionFactory, isLazyDynamicComponents, isPromise, languagesFactory, loadLocale, localeId, localePathFactory, memoize, minColumnGridTrackSize, operationStatusClasses, operationStatusIcons, provideBootstrapMetadata, provideCommonPipes, provideCommonServices, provideDefaultOptionsAppInitializer, provideI18n, provideLanguageSelectorAppInitializer, providePluginsLoaderServiceAppInitializer, provideTranslationServiceInstance, ratiosByColumnTypes, removeContextIndicators, removeDuplicatesIds, resolveInjectedFactories, retryWithDelay, simpleJsonPathValidator, sortByPriority, stateToFactory, statusAlert, statusClasses, statusIcons, throttle, toObservable, toObservableOfArrays, tooltips, trimTranslationKey, uniqueInCollectionByPathValidator, validateArrayElements, validateInternationalPhoneNumber, viewContextRoutes, wrapperLegendFieldConfig };
38011
39176
  //# sourceMappingURL=c8y-ngx-components.mjs.map