@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.
- package/alarms/index.d.ts +110 -53
- package/alarms/index.d.ts.map +1 -1
- package/assets-navigator/index.d.ts +7 -3
- package/assets-navigator/index.d.ts.map +1 -1
- package/context-dashboard/index.d.ts.map +1 -1
- package/fesm2022/c8y-ngx-components-alarms.mjs +365 -205
- package/fesm2022/c8y-ngx-components-alarms.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-assets-navigator.mjs +25 -6
- package/fesm2022/c8y-ngx-components-assets-navigator.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-context-dashboard.mjs +2 -4
- package/fesm2022/c8y-ngx-components-context-dashboard.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-echart.mjs +2 -2
- package/fesm2022/c8y-ngx-components-echart.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-group-breadcrumbs.mjs +192 -0
- package/fesm2022/c8y-ngx-components-group-breadcrumbs.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-module-federation-exports-assets-navigator.mjs +13 -0
- package/fesm2022/c8y-ngx-components-module-federation-exports-assets-navigator.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-widgets-implementations-alarms.mjs +2 -2
- package/fesm2022/c8y-ngx-components-widgets-implementations-alarms.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components.mjs +1201 -36
- package/fesm2022/c8y-ngx-components.mjs.map +1 -1
- package/group-breadcrumbs/index.d.ts +6 -0
- package/group-breadcrumbs/index.d.ts.map +1 -0
- package/index.d.ts +873 -6
- package/index.d.ts.map +1 -1
- package/locales/de.po +66 -58
- package/locales/es.po +55 -48
- package/locales/fr.po +47 -40
- package/locales/ja_JP.po +43 -37
- package/locales/ko.po +53 -46
- package/locales/locales.pot +25 -15
- package/locales/nl.po +50 -43
- package/locales/pl.po +65 -58
- package/locales/pt_BR.po +52 -45
- package/locales/zh_CN.po +49 -43
- package/locales/zh_TW.po +61 -53
- package/module-federation-exports/assets-navigator/index.d.ts +2 -0
- package/module-federation-exports/assets-navigator/index.d.ts.map +1 -0
- 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,
|
|
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
|
|
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: "
|
|
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
|
-
|
|
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: "
|
|
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\">×</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\">×</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
|
|
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\">×</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\">×</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
|
-
*
|
|
37474
|
-
*
|
|
37475
|
-
*
|
|
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
|
-
|
|
37695
|
-
|
|
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
|
|
37724
|
-
|
|
37725
|
-
this.
|
|
37726
|
-
|
|
37727
|
-
|
|
37728
|
-
|
|
37729
|
-
|
|
37730
|
-
this.
|
|
37731
|
-
|
|
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
|
-
//
|
|
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
|