@c8y/ngx-components 1023.15.0 → 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/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-context-dashboard.mjs +2 -4
- package/fesm2022/c8y-ngx-components-context-dashboard.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-echart.mjs +10 -5
- package/fesm2022/c8y-ngx-components-echart.mjs.map +1 -1
- 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 +1113 -72
- package/fesm2022/c8y-ngx-components.mjs.map +1 -1
- package/index.d.ts +839 -22
- package/index.d.ts.map +1 -1
- package/locales/de.po +33 -19
- package/locales/es.po +32 -19
- package/locales/fr.po +32 -19
- package/locales/ja_JP.po +31 -19
- package/locales/ko.po +32 -19
- package/locales/locales.pot +30 -8
- package/locales/nl.po +32 -19
- package/locales/pl.po +35 -22
- package/locales/pt_BR.po +32 -19
- package/locales/zh_CN.po +31 -19
- package/locales/zh_TW.po +33 -19
- package/package.json +1 -1
|
@@ -4,7 +4,7 @@ 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
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';
|
|
@@ -2971,6 +2971,18 @@ const MESSAGES_CORE_I18N = {
|
|
|
2971
2971
|
placeholders: {
|
|
2972
2972
|
revokedSerials: '$1'
|
|
2973
2973
|
}
|
|
2974
|
+
},
|
|
2975
|
+
"^Certificate serial number hex: '(.+?)'.*$": {
|
|
2976
|
+
gettext: gettext$1('Certificate serial number: "{{ serialNumber }}"'),
|
|
2977
|
+
placeholders: {
|
|
2978
|
+
serialNumber: '$1'
|
|
2979
|
+
}
|
|
2980
|
+
},
|
|
2981
|
+
'^Tenant certificate authority\\(CA\\) signed certificate for device: (.+?)\\.$': {
|
|
2982
|
+
gettext: gettext$1('Tenant certificate authority (CA) signed certificate for device: "{{ deviceId }}".'),
|
|
2983
|
+
placeholders: {
|
|
2984
|
+
deviceId: '$1'
|
|
2985
|
+
}
|
|
2974
2986
|
}
|
|
2975
2987
|
};
|
|
2976
2988
|
|
|
@@ -8805,6 +8817,116 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
8805
8817
|
}]
|
|
8806
8818
|
}] });
|
|
8807
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
|
+
|
|
8808
8930
|
class GeoService {
|
|
8809
8931
|
constructor() {
|
|
8810
8932
|
this.C8Y_POSITION_FRAGMENT = 'c8y_Position';
|
|
@@ -11731,6 +11853,55 @@ class DynamicBulkIIdentifiedResolver extends DynamicBulkDetailsResolver {
|
|
|
11731
11853
|
}
|
|
11732
11854
|
}
|
|
11733
11855
|
|
|
11856
|
+
class MOChunkLoaderService {
|
|
11857
|
+
constructor(inventory) {
|
|
11858
|
+
this.inventory = inventory;
|
|
11859
|
+
}
|
|
11860
|
+
async processInChunks(ids, chunkSize, loadChunkFn) {
|
|
11861
|
+
if (!ids.length) {
|
|
11862
|
+
return { results: [], errors: [] };
|
|
11863
|
+
}
|
|
11864
|
+
const promiseArray = [];
|
|
11865
|
+
const idsCopy = [...ids];
|
|
11866
|
+
while (idsCopy.length) {
|
|
11867
|
+
const batch = idsCopy.splice(0, chunkSize);
|
|
11868
|
+
promiseArray.push(loadChunkFn(batch));
|
|
11869
|
+
}
|
|
11870
|
+
const chunkResults = await Promise.all(promiseArray);
|
|
11871
|
+
const results = chunkResults.flatMap(r => r.managedObjects);
|
|
11872
|
+
const errors = chunkResults.flatMap(r => r.errors);
|
|
11873
|
+
return { results, errors };
|
|
11874
|
+
}
|
|
11875
|
+
async loadAChunkOfManagedObjectsBase(uniqIds, inventory, pageSize, getStatusDetails, queryFilter) {
|
|
11876
|
+
const { data: managedObjects } = await inventory.list(Object.assign({}, queryFilter || {}, {
|
|
11877
|
+
ids: uniqIds.join(),
|
|
11878
|
+
pageSize
|
|
11879
|
+
}));
|
|
11880
|
+
const notFoundMOs = uniqIds.filter(id => !managedObjects.find(tmp => tmp.id === id));
|
|
11881
|
+
if (notFoundMOs.length) {
|
|
11882
|
+
const promArray = notFoundMOs.map(id => getStatusDetails(id));
|
|
11883
|
+
const res = await Promise.all(promArray);
|
|
11884
|
+
return { managedObjects, errors: res };
|
|
11885
|
+
}
|
|
11886
|
+
return { managedObjects, errors: [] };
|
|
11887
|
+
}
|
|
11888
|
+
async getStatusDetails(moId) {
|
|
11889
|
+
try {
|
|
11890
|
+
const res = await this.inventory.detail(moId);
|
|
11891
|
+
return { id: moId, ...pick(res.res, ['status', 'statusText']) };
|
|
11892
|
+
}
|
|
11893
|
+
catch (e) {
|
|
11894
|
+
return { id: moId, ...pick(e.res, ['status', 'statusText']) };
|
|
11895
|
+
}
|
|
11896
|
+
}
|
|
11897
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MOChunkLoaderService, deps: [{ token: i1.InventoryService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
11898
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MOChunkLoaderService, providedIn: 'root' }); }
|
|
11899
|
+
}
|
|
11900
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MOChunkLoaderService, decorators: [{
|
|
11901
|
+
type: Injectable,
|
|
11902
|
+
args: [{ providedIn: 'root' }]
|
|
11903
|
+
}], ctorParameters: () => [{ type: i1.InventoryService }] });
|
|
11904
|
+
|
|
11734
11905
|
/**
|
|
11735
11906
|
* A DynamicDetailsResolver responsible to resolve managedObjects for dynamic components.
|
|
11736
11907
|
* This service implements bulk resolving. This reduces the number of requests made to
|
|
@@ -11875,55 +12046,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
11875
12046
|
args: [{ providedIn: 'root' }]
|
|
11876
12047
|
}] });
|
|
11877
12048
|
|
|
11878
|
-
class MOChunkLoaderService {
|
|
11879
|
-
constructor(inventory) {
|
|
11880
|
-
this.inventory = inventory;
|
|
11881
|
-
}
|
|
11882
|
-
async processInChunks(ids, chunkSize, loadChunkFn) {
|
|
11883
|
-
if (!ids.length) {
|
|
11884
|
-
return { results: [], errors: [] };
|
|
11885
|
-
}
|
|
11886
|
-
const promiseArray = [];
|
|
11887
|
-
const idsCopy = [...ids];
|
|
11888
|
-
while (idsCopy.length) {
|
|
11889
|
-
const batch = idsCopy.splice(0, chunkSize);
|
|
11890
|
-
promiseArray.push(loadChunkFn(batch));
|
|
11891
|
-
}
|
|
11892
|
-
const chunkResults = await Promise.all(promiseArray);
|
|
11893
|
-
const results = chunkResults.flatMap(r => r.managedObjects);
|
|
11894
|
-
const errors = chunkResults.flatMap(r => r.errors);
|
|
11895
|
-
return { results, errors };
|
|
11896
|
-
}
|
|
11897
|
-
async loadAChunkOfManagedObjectsBase(uniqIds, inventory, pageSize, getStatusDetails, queryFilter) {
|
|
11898
|
-
const { data: managedObjects } = await inventory.list(Object.assign({}, queryFilter || {}, {
|
|
11899
|
-
ids: uniqIds.join(),
|
|
11900
|
-
pageSize
|
|
11901
|
-
}));
|
|
11902
|
-
const notFoundMOs = uniqIds.filter(id => !managedObjects.find(tmp => tmp.id === id));
|
|
11903
|
-
if (notFoundMOs.length) {
|
|
11904
|
-
const promArray = notFoundMOs.map(id => getStatusDetails(id));
|
|
11905
|
-
const res = await Promise.all(promArray);
|
|
11906
|
-
return { managedObjects, errors: res };
|
|
11907
|
-
}
|
|
11908
|
-
return { managedObjects, errors: [] };
|
|
11909
|
-
}
|
|
11910
|
-
async getStatusDetails(moId) {
|
|
11911
|
-
try {
|
|
11912
|
-
const res = await this.inventory.detail(moId);
|
|
11913
|
-
return { id: moId, ...pick(res.res, ['status', 'statusText']) };
|
|
11914
|
-
}
|
|
11915
|
-
catch (e) {
|
|
11916
|
-
return { id: moId, ...pick(e.res, ['status', 'statusText']) };
|
|
11917
|
-
}
|
|
11918
|
-
}
|
|
11919
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MOChunkLoaderService, deps: [{ token: i1.InventoryService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
11920
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MOChunkLoaderService, providedIn: 'root' }); }
|
|
11921
|
-
}
|
|
11922
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MOChunkLoaderService, decorators: [{
|
|
11923
|
-
type: Injectable,
|
|
11924
|
-
args: [{ providedIn: 'root' }]
|
|
11925
|
-
}], ctorParameters: () => [{ type: i1.InventoryService }] });
|
|
11926
|
-
|
|
11927
12049
|
class AppSwitcherService {
|
|
11928
12050
|
constructor(ui) {
|
|
11929
12051
|
this.ui = ui;
|
|
@@ -29186,7 +29308,7 @@ class DashboardChildChange {
|
|
|
29186
29308
|
this.child = childToChange;
|
|
29187
29309
|
}
|
|
29188
29310
|
get resize$() {
|
|
29189
|
-
return this.child.dragSource.moved.pipe(map(move => this.getPixelSize(move)), tap(resizeDimension => this.setPixelSize(resizeDimension)), map(resizeDimension => this.getDimensionSize(resizeDimension)), distinctUntilChanged((prev, next) => prev.width === next.width && prev.height === next.height), map(dimension => this.setDimension(dimension)),
|
|
29311
|
+
return this.child.dragSource.moved.pipe(map(move => this.getPixelSize(move)), tap(resizeDimension => this.setPixelSize(resizeDimension)), map(resizeDimension => this.getDimensionSize(resizeDimension)), distinctUntilChanged((prev, next) => prev.width === next.width && prev.height === next.height), map(dimension => this.setDimension(dimension)), this.arrangePipe());
|
|
29190
29312
|
}
|
|
29191
29313
|
get drag$() {
|
|
29192
29314
|
return this.child.dragSource.moved.pipe(map(move => this.getDimensionPosition(move)), filter(dimension => dimension.x >= 0 &&
|
|
@@ -37594,9 +37716,22 @@ class RealtimeMessage {
|
|
|
37594
37716
|
}
|
|
37595
37717
|
|
|
37596
37718
|
/**
|
|
37597
|
-
*
|
|
37598
|
-
*
|
|
37599
|
-
*
|
|
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
|
+
* ```
|
|
37600
37735
|
*/
|
|
37601
37736
|
class ResizableGridComponent {
|
|
37602
37737
|
/**
|
|
@@ -37627,6 +37762,10 @@ class ResizableGridComponent {
|
|
|
37627
37762
|
* Minimum width (in pixels) before a column is considered collapsed.
|
|
37628
37763
|
*/
|
|
37629
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;
|
|
37630
37769
|
/**
|
|
37631
37770
|
* True if the user is currently resizing the grid.
|
|
37632
37771
|
*/
|
|
@@ -37813,10 +37952,12 @@ class ResizableGridComponent {
|
|
|
37813
37952
|
if (!this.colA || !this.colB) {
|
|
37814
37953
|
return;
|
|
37815
37954
|
}
|
|
37816
|
-
let newWidthPx = Math.max(0, targetWidthPx);
|
|
37817
37955
|
const totalWidth = this.colA.nativeElement.parentElement?.offsetWidth || window.innerWidth;
|
|
37818
|
-
|
|
37819
|
-
|
|
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);
|
|
37820
37961
|
const newWidthString = `${newWidthPx}px`;
|
|
37821
37962
|
this._colAWidth = newWidthString;
|
|
37822
37963
|
// Update lastKnownNonCollapsedWidth during drag, regardless of trackId
|
|
@@ -37844,25 +37985,38 @@ class ResizableGridComponent {
|
|
|
37844
37985
|
const colANative = this.colA.nativeElement;
|
|
37845
37986
|
const colBNative = this.colB.nativeElement;
|
|
37846
37987
|
this.removeCollapseClasses();
|
|
37847
|
-
if
|
|
37848
|
-
|
|
37849
|
-
this.
|
|
37850
|
-
|
|
37851
|
-
|
|
37852
|
-
|
|
37853
|
-
|
|
37854
|
-
this.
|
|
37855
|
-
|
|
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
|
+
}
|
|
37856
38013
|
}
|
|
37857
38014
|
else {
|
|
37858
|
-
//
|
|
37859
|
-
// This will be the actual width from the drag, or the localStorage value.
|
|
38015
|
+
// When not collapsible, just maintain the current width without collapse
|
|
37860
38016
|
this._colAWidth = this.lastKnownNonCollapsedWidth || this.leftColumnWidth;
|
|
37861
38017
|
if (this.trackId) {
|
|
37862
|
-
// Ensure localStorage is up-to-date if no collapse occurred.
|
|
37863
38018
|
const saved = localStorage.getItem(this.trackId);
|
|
37864
38019
|
if (saved !== this._colAWidth) {
|
|
37865
|
-
// Only write if different
|
|
37866
38020
|
localStorage.setItem(this.trackId, this._colAWidth);
|
|
37867
38021
|
}
|
|
37868
38022
|
}
|
|
@@ -37883,7 +38037,7 @@ class ResizableGridComponent {
|
|
|
37883
38037
|
this.renderer.removeClass(colBNative, 'expanded');
|
|
37884
38038
|
}
|
|
37885
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 }); }
|
|
37886
|
-
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" }] }); }
|
|
37887
38041
|
}
|
|
37888
38042
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ResizableGridComponent, decorators: [{
|
|
37889
38043
|
type: Component,
|
|
@@ -37894,6 +38048,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
37894
38048
|
type: Input
|
|
37895
38049
|
}], collapseThreshold: [{
|
|
37896
38050
|
type: Input
|
|
38051
|
+
}], collapsible: [{
|
|
38052
|
+
type: Input
|
|
37897
38053
|
}], colA: [{
|
|
37898
38054
|
type: ViewChild,
|
|
37899
38055
|
args: ['colA']
|
|
@@ -38123,6 +38279,891 @@ function colorValidator(allowedModes) {
|
|
|
38123
38279
|
};
|
|
38124
38280
|
}
|
|
38125
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
|
+
|
|
38126
39167
|
/**
|
|
38127
39168
|
* Barrel to export /core
|
|
38128
39169
|
*/
|
|
@@ -38131,5 +39172,5 @@ function colorValidator(allowedModes) {
|
|
|
38131
39172
|
* Generated bundle index. Do not edit.
|
|
38132
39173
|
*/
|
|
38133
39174
|
|
|
38134
|
-
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, 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 };
|
|
38135
39176
|
//# sourceMappingURL=c8y-ngx-components.mjs.map
|