@c8y/ngx-components 1023.75.1 → 1023.76.0
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/fesm2022/c8y-ngx-components-branding-plain-branding-editor.mjs +1 -1
- package/fesm2022/c8y-ngx-components-branding-plain-branding-editor.mjs.map +1 -1
- package/fesm2022/{c8y-ngx-components-dashboard-details-advanced-tab-dashboard-details-advanced-tab.component-Cek3_qZQ.mjs → c8y-ngx-components-dashboard-details-advanced-tab-dashboard-details-advanced-tab.component-DVEnCRzW.mjs} +2 -2
- package/fesm2022/c8y-ngx-components-dashboard-details-advanced-tab-dashboard-details-advanced-tab.component-DVEnCRzW.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-dashboard-details-advanced-tab.mjs +2 -2
- package/fesm2022/c8y-ngx-components-global-context.mjs +40 -18
- package/fesm2022/c8y-ngx-components-global-context.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-alarm-list.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-alarm-list.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-all-critical-alarms.mjs +4 -5
- package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-all-critical-alarms.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-recent-alarms.mjs +4 -5
- package/fesm2022/c8y-ngx-components-widgets-definitions-alarms-recent-alarms.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-asset-notes.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-asset-notes.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-asset-table.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-asset-table.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-datapoints-graph.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-datapoints-graph.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-datapoints-table.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-datapoints-table.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-device-control-message.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-device-control-message.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-html-widget.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-html-widget.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-image.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-image.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-info-gauge.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-info-gauge.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-kpi.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-kpi.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-linear-gauge.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-linear-gauge.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-map.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-map.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-markdown.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-markdown.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-radial-gauge.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-radial-gauge.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-silo.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-silo.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-three-d-rotation.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-three-d-rotation.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-alarms.mjs +66 -59
- package/fesm2022/c8y-ngx-components-widgets-implementations-alarms.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-info-gauge.mjs +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-info-gauge.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components.mjs +132 -144
- package/fesm2022/c8y-ngx-components.mjs.map +1 -1
- package/global-context/index.d.ts +87 -1
- package/global-context/index.d.ts.map +1 -1
- package/index.d.ts +10 -4
- package/index.d.ts.map +1 -1
- package/locales/de.po +3 -0
- package/locales/es.po +3 -0
- package/locales/fr.po +3 -0
- package/locales/ja_JP.po +3 -0
- package/locales/ko.po +3 -0
- package/locales/locales.pot +3 -0
- package/locales/nl.po +3 -0
- package/locales/pl.po +3 -0
- package/locales/pt_BR.po +3 -0
- package/locales/zh_CN.po +3 -0
- package/locales/zh_TW.po +3 -0
- package/package.json +1 -1
- package/widgets/definitions/alarms/all-critical-alarms/index.d.ts +1 -2
- package/widgets/definitions/alarms/all-critical-alarms/index.d.ts.map +1 -1
- package/widgets/definitions/alarms/recent-alarms/index.d.ts +1 -2
- package/widgets/definitions/alarms/recent-alarms/index.d.ts.map +1 -1
- package/widgets/implementations/alarms/index.d.ts +6 -1
- package/widgets/implementations/alarms/index.d.ts.map +1 -1
- package/fesm2022/c8y-ngx-components-dashboard-details-advanced-tab-dashboard-details-advanced-tab.component-Cek3_qZQ.mjs.map +0 -1
|
@@ -1584,6 +1584,12 @@ const PATTERN_MESSAGES_CERTIFICATES = {
|
|
|
1584
1584
|
deviceId: '$1'
|
|
1585
1585
|
}
|
|
1586
1586
|
},
|
|
1587
|
+
'^Tenant certificate authority\\(CA\\) re-signed certificate for device: (.+?)\\.$': {
|
|
1588
|
+
gettext: gettext$1('Tenant certificate authority (CA) re-signed certificate for device: "{{ deviceId }}".'),
|
|
1589
|
+
placeholders: {
|
|
1590
|
+
deviceId: '$1'
|
|
1591
|
+
}
|
|
1592
|
+
},
|
|
1587
1593
|
'^Revoked serials: (.+?)$': {
|
|
1588
1594
|
gettext: gettext$1('Revoked serials: {{ revokedSerials }}'),
|
|
1589
1595
|
placeholders: {
|
|
@@ -33022,6 +33028,122 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
33022
33028
|
type: Output
|
|
33023
33029
|
}] } });
|
|
33024
33030
|
|
|
33031
|
+
class AssetPropertyService extends Service {
|
|
33032
|
+
constructor(client, appState) {
|
|
33033
|
+
super(client);
|
|
33034
|
+
this.appState = appState;
|
|
33035
|
+
this.baseUrl = 'service/dtm';
|
|
33036
|
+
this.listUrl = '/definitions/properties';
|
|
33037
|
+
this.propertyName = 'definitions';
|
|
33038
|
+
}
|
|
33039
|
+
async canRetrieveAssetProperties() {
|
|
33040
|
+
const isAppAvailable = await this.appState.isApplicationAvailable('dtm');
|
|
33041
|
+
if (!isAppAvailable) {
|
|
33042
|
+
return false;
|
|
33043
|
+
}
|
|
33044
|
+
try {
|
|
33045
|
+
const result = await this.list({ currentPage: 1, pageSize: 1 });
|
|
33046
|
+
return result?.data?.length > 0;
|
|
33047
|
+
}
|
|
33048
|
+
catch (error) {
|
|
33049
|
+
return false;
|
|
33050
|
+
}
|
|
33051
|
+
}
|
|
33052
|
+
async list(filterInput = {}) {
|
|
33053
|
+
const headers = { accept: 'application/json' };
|
|
33054
|
+
const filter = this.buildFilter(filterInput);
|
|
33055
|
+
const res = await this.fetch(this.listUrl, this.changeFetchOptions({ headers, params: filter }, this.listUrl));
|
|
33056
|
+
if (!res.ok) {
|
|
33057
|
+
throw new Error(`Error loading asset property definitions: ${res.status} ${res.statusText}`);
|
|
33058
|
+
}
|
|
33059
|
+
const json = (await res.json());
|
|
33060
|
+
if (!Array.isArray(json.definitions)) {
|
|
33061
|
+
throw new Error('Invalid response: "definitions" must be an array.');
|
|
33062
|
+
}
|
|
33063
|
+
const paging = this.getPaging(json, filter);
|
|
33064
|
+
const data = json.definitions;
|
|
33065
|
+
return { res, data, paging };
|
|
33066
|
+
}
|
|
33067
|
+
async getByIdentifier(identifier) {
|
|
33068
|
+
const url = `${this.listUrl}/${encodeURIComponent(identifier)}`;
|
|
33069
|
+
const headers = { accept: 'application/json' };
|
|
33070
|
+
const res = await this.fetch(url, this.changeFetchOptions({ headers }, url));
|
|
33071
|
+
if (res.status === 404) {
|
|
33072
|
+
throw new Error(`Property Definition with identifier '${identifier}' not found (404).`);
|
|
33073
|
+
}
|
|
33074
|
+
if (!res.ok) {
|
|
33075
|
+
throw new Error(`Error fetching Property Definition '${identifier}': ${res.status} ${res.statusText}`);
|
|
33076
|
+
}
|
|
33077
|
+
return (await res.json());
|
|
33078
|
+
}
|
|
33079
|
+
search(searchTerm) {
|
|
33080
|
+
return this.list({ titles: [searchTerm] });
|
|
33081
|
+
}
|
|
33082
|
+
buildFilter(filter) {
|
|
33083
|
+
const newFilter = { ...filter };
|
|
33084
|
+
['identifiers', 'titles', 'tags'].forEach(key => {
|
|
33085
|
+
if (Array.isArray(newFilter[key])) {
|
|
33086
|
+
newFilter[key] = newFilter[key].join(',');
|
|
33087
|
+
}
|
|
33088
|
+
});
|
|
33089
|
+
return newFilter;
|
|
33090
|
+
}
|
|
33091
|
+
getPaging(json, filter) {
|
|
33092
|
+
if (!json.statistics ||
|
|
33093
|
+
typeof json.statistics.totalElements !== 'number' ||
|
|
33094
|
+
typeof json.statistics.currentPage !== 'number' ||
|
|
33095
|
+
typeof json.statistics.totalPages !== 'number' ||
|
|
33096
|
+
typeof json.statistics.pageSize !== 'number') {
|
|
33097
|
+
throw new Error('Invalid response: missing or invalid paging statistics.');
|
|
33098
|
+
}
|
|
33099
|
+
const { currentPage, totalPages, totalElements } = json.statistics;
|
|
33100
|
+
const statistics = {
|
|
33101
|
+
...json.statistics,
|
|
33102
|
+
nextPage: currentPage < totalPages ? currentPage + 1 : null,
|
|
33103
|
+
prevPage: currentPage > 1 ? currentPage - 1 : null,
|
|
33104
|
+
totalPages: totalPages,
|
|
33105
|
+
totalElements: totalElements
|
|
33106
|
+
};
|
|
33107
|
+
return new Paging(this, statistics, filter);
|
|
33108
|
+
}
|
|
33109
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AssetPropertyService, deps: [{ token: i1.FetchClient }, { token: AppStateService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
33110
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AssetPropertyService, providedIn: 'root' }); }
|
|
33111
|
+
}
|
|
33112
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AssetPropertyService, decorators: [{
|
|
33113
|
+
type: Injectable,
|
|
33114
|
+
args: [{
|
|
33115
|
+
providedIn: 'root'
|
|
33116
|
+
}]
|
|
33117
|
+
}], ctorParameters: () => [{ type: i1.FetchClient }, { type: AppStateService }] });
|
|
33118
|
+
|
|
33119
|
+
class AssetDefinitionsService extends Service {
|
|
33120
|
+
constructor(client) {
|
|
33121
|
+
super(client);
|
|
33122
|
+
this.baseUrl = 'service/dtm';
|
|
33123
|
+
this.listUrl = '/definitions/assets';
|
|
33124
|
+
}
|
|
33125
|
+
async getByIdentifier(identifier) {
|
|
33126
|
+
const url = `${this.listUrl}/${encodeURIComponent(identifier)}`;
|
|
33127
|
+
const headers = { accept: 'application/json' };
|
|
33128
|
+
const res = await this.fetch(url, this.changeFetchOptions({ headers }, url));
|
|
33129
|
+
if (res.status === 404) {
|
|
33130
|
+
throw new Error(`Asset Definition with identifier '${identifier}' not found (404).`);
|
|
33131
|
+
}
|
|
33132
|
+
if (!res.ok) {
|
|
33133
|
+
throw new Error(`Error fetching Asset Definition '${identifier}': ${res.status} ${res.statusText}`);
|
|
33134
|
+
}
|
|
33135
|
+
return (await res.json());
|
|
33136
|
+
}
|
|
33137
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AssetDefinitionsService, deps: [{ token: i1.FetchClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
33138
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AssetDefinitionsService, providedIn: 'root' }); }
|
|
33139
|
+
}
|
|
33140
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AssetDefinitionsService, decorators: [{
|
|
33141
|
+
type: Injectable,
|
|
33142
|
+
args: [{
|
|
33143
|
+
providedIn: 'root'
|
|
33144
|
+
}]
|
|
33145
|
+
}], ctorParameters: () => [{ type: i1.FetchClient }] });
|
|
33146
|
+
|
|
33025
33147
|
const HOOK_ACTION_CONTROLS = new InjectionToken('ActionControlHook');
|
|
33026
33148
|
/**
|
|
33027
33149
|
* You can either provide a single `ActionControlHook` as parameter:
|
|
@@ -33366,94 +33488,6 @@ class TreeNodeColumn {
|
|
|
33366
33488
|
}
|
|
33367
33489
|
}
|
|
33368
33490
|
|
|
33369
|
-
class AssetPropertyService extends Service {
|
|
33370
|
-
constructor(client, appState) {
|
|
33371
|
-
super(client);
|
|
33372
|
-
this.appState = appState;
|
|
33373
|
-
this.baseUrl = 'service/dtm';
|
|
33374
|
-
this.listUrl = '/definitions/properties';
|
|
33375
|
-
this.propertyName = 'definitions';
|
|
33376
|
-
}
|
|
33377
|
-
async canRetrieveAssetProperties() {
|
|
33378
|
-
const isAppAvailable = await this.appState.isApplicationAvailable('dtm');
|
|
33379
|
-
if (!isAppAvailable) {
|
|
33380
|
-
return false;
|
|
33381
|
-
}
|
|
33382
|
-
try {
|
|
33383
|
-
const result = await this.list({ currentPage: 1, pageSize: 1 });
|
|
33384
|
-
return result?.data?.length > 0;
|
|
33385
|
-
}
|
|
33386
|
-
catch (error) {
|
|
33387
|
-
return false;
|
|
33388
|
-
}
|
|
33389
|
-
}
|
|
33390
|
-
async list(filterInput = {}) {
|
|
33391
|
-
const headers = { accept: 'application/json' };
|
|
33392
|
-
const filter = this.buildFilter(filterInput);
|
|
33393
|
-
const res = await this.fetch(this.listUrl, this.changeFetchOptions({ headers, params: filter }, this.listUrl));
|
|
33394
|
-
if (!res.ok) {
|
|
33395
|
-
throw new Error(`Error loading asset property definitions: ${res.status} ${res.statusText}`);
|
|
33396
|
-
}
|
|
33397
|
-
const json = (await res.json());
|
|
33398
|
-
if (!Array.isArray(json.definitions)) {
|
|
33399
|
-
throw new Error('Invalid response: "definitions" must be an array.');
|
|
33400
|
-
}
|
|
33401
|
-
const paging = this.getPaging(json, filter);
|
|
33402
|
-
const data = json.definitions;
|
|
33403
|
-
return { res, data, paging };
|
|
33404
|
-
}
|
|
33405
|
-
async getByIdentifier(identifier) {
|
|
33406
|
-
const url = `${this.listUrl}/${encodeURIComponent(identifier)}`;
|
|
33407
|
-
const headers = { accept: 'application/json' };
|
|
33408
|
-
const res = await this.fetch(url, this.changeFetchOptions({ headers }, url));
|
|
33409
|
-
if (res.status === 404) {
|
|
33410
|
-
throw new Error(`Property Definition with identifier '${identifier}' not found (404).`);
|
|
33411
|
-
}
|
|
33412
|
-
if (!res.ok) {
|
|
33413
|
-
throw new Error(`Error fetching Property Definition '${identifier}': ${res.status} ${res.statusText}`);
|
|
33414
|
-
}
|
|
33415
|
-
return (await res.json());
|
|
33416
|
-
}
|
|
33417
|
-
search(searchTerm) {
|
|
33418
|
-
return this.list({ titles: [searchTerm] });
|
|
33419
|
-
}
|
|
33420
|
-
buildFilter(filter) {
|
|
33421
|
-
const newFilter = { ...filter };
|
|
33422
|
-
['identifiers', 'titles', 'tags'].forEach(key => {
|
|
33423
|
-
if (Array.isArray(newFilter[key])) {
|
|
33424
|
-
newFilter[key] = newFilter[key].join(',');
|
|
33425
|
-
}
|
|
33426
|
-
});
|
|
33427
|
-
return newFilter;
|
|
33428
|
-
}
|
|
33429
|
-
getPaging(json, filter) {
|
|
33430
|
-
if (!json.statistics ||
|
|
33431
|
-
typeof json.statistics.totalElements !== 'number' ||
|
|
33432
|
-
typeof json.statistics.currentPage !== 'number' ||
|
|
33433
|
-
typeof json.statistics.totalPages !== 'number' ||
|
|
33434
|
-
typeof json.statistics.pageSize !== 'number') {
|
|
33435
|
-
throw new Error('Invalid response: missing or invalid paging statistics.');
|
|
33436
|
-
}
|
|
33437
|
-
const { currentPage, totalPages, totalElements } = json.statistics;
|
|
33438
|
-
const statistics = {
|
|
33439
|
-
...json.statistics,
|
|
33440
|
-
nextPage: currentPage < totalPages ? currentPage + 1 : null,
|
|
33441
|
-
prevPage: currentPage > 1 ? currentPage - 1 : null,
|
|
33442
|
-
totalPages: totalPages,
|
|
33443
|
-
totalElements: totalElements
|
|
33444
|
-
};
|
|
33445
|
-
return new Paging(this, statistics, filter);
|
|
33446
|
-
}
|
|
33447
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AssetPropertyService, deps: [{ token: i1.FetchClient }, { token: AppStateService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
33448
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AssetPropertyService, providedIn: 'root' }); }
|
|
33449
|
-
}
|
|
33450
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AssetPropertyService, decorators: [{
|
|
33451
|
-
type: Injectable,
|
|
33452
|
-
args: [{
|
|
33453
|
-
providedIn: 'root'
|
|
33454
|
-
}]
|
|
33455
|
-
}], ctorParameters: () => [{ type: i1.FetchClient }, { type: AppStateService }] });
|
|
33456
|
-
|
|
33457
33491
|
class CustomColumnService {
|
|
33458
33492
|
constructor(assetPropertiesService, bottomDrawerService, bsModalService) {
|
|
33459
33493
|
this.assetPropertiesService = assetPropertiesService;
|
|
@@ -34162,34 +34196,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
34162
34196
|
}]
|
|
34163
34197
|
}] });
|
|
34164
34198
|
|
|
34165
|
-
class AssetDefinitionsService extends Service {
|
|
34166
|
-
constructor(client) {
|
|
34167
|
-
super(client);
|
|
34168
|
-
this.baseUrl = 'service/dtm';
|
|
34169
|
-
this.listUrl = '/definitions/assets';
|
|
34170
|
-
}
|
|
34171
|
-
async getByIdentifier(identifier) {
|
|
34172
|
-
const url = `${this.listUrl}/${encodeURIComponent(identifier)}`;
|
|
34173
|
-
const headers = { accept: 'application/json' };
|
|
34174
|
-
const res = await this.fetch(url, this.changeFetchOptions({ headers }, url));
|
|
34175
|
-
if (res.status === 404) {
|
|
34176
|
-
throw new Error(`Asset Definition with identifier '${identifier}' not found (404).`);
|
|
34177
|
-
}
|
|
34178
|
-
if (!res.ok) {
|
|
34179
|
-
throw new Error(`Error fetching Asset Definition '${identifier}': ${res.status} ${res.statusText}`);
|
|
34180
|
-
}
|
|
34181
|
-
return (await res.json());
|
|
34182
|
-
}
|
|
34183
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AssetDefinitionsService, deps: [{ token: i1.FetchClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
34184
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AssetDefinitionsService, providedIn: 'root' }); }
|
|
34185
|
-
}
|
|
34186
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AssetDefinitionsService, decorators: [{
|
|
34187
|
-
type: Injectable,
|
|
34188
|
-
args: [{
|
|
34189
|
-
providedIn: 'root'
|
|
34190
|
-
}]
|
|
34191
|
-
}], ctorParameters: () => [{ type: i1.FetchClient }] });
|
|
34192
|
-
|
|
34193
34199
|
var SortingOrder;
|
|
34194
34200
|
(function (SortingOrder) {
|
|
34195
34201
|
SortingOrder["ASC"] = "asc";
|
|
@@ -34373,17 +34379,6 @@ class DataGridComponent {
|
|
|
34373
34379
|
Delete: BuiltInActionType.Delete,
|
|
34374
34380
|
Export: BuiltInActionType.Export
|
|
34375
34381
|
};
|
|
34376
|
-
this.confirmRemoveColumnButtons = [
|
|
34377
|
-
{
|
|
34378
|
-
label: gettext$1('Cancel'),
|
|
34379
|
-
action: () => Promise.resolve(false)
|
|
34380
|
-
},
|
|
34381
|
-
{
|
|
34382
|
-
label: gettext$1('Remove`column,verb`'),
|
|
34383
|
-
status: 'danger',
|
|
34384
|
-
action: () => Promise.resolve(true)
|
|
34385
|
-
}
|
|
34386
|
-
];
|
|
34387
34382
|
this.isConfigContextKnown = false;
|
|
34388
34383
|
/**
|
|
34389
34384
|
* A map of rows which have been expanded.
|
|
@@ -34569,25 +34564,19 @@ class DataGridComponent {
|
|
|
34569
34564
|
this.onAddCustomColumn.emit(config);
|
|
34570
34565
|
});
|
|
34571
34566
|
}
|
|
34572
|
-
|
|
34573
|
-
ddConfigureColumns.autoClose = false;
|
|
34574
|
-
poConfirm.message = gettext$1('Do you want to remove this column?');
|
|
34567
|
+
confirmRemoveColumn(column) {
|
|
34575
34568
|
try {
|
|
34576
|
-
|
|
34577
|
-
|
|
34578
|
-
|
|
34579
|
-
|
|
34580
|
-
|
|
34581
|
-
|
|
34582
|
-
|
|
34583
|
-
column: column.header || column.name
|
|
34584
|
-
});
|
|
34585
|
-
}
|
|
34569
|
+
this.columns = this.columns.filter(col => col?.name !== column?.name);
|
|
34570
|
+
this.updateColumns();
|
|
34571
|
+
this.onRemoveCustomColumn.emit(column);
|
|
34572
|
+
this.triggerEvent({
|
|
34573
|
+
action: PX_ACTIONS.REMOVE_CUSTOM_COLUMN,
|
|
34574
|
+
column: column.header || column.name
|
|
34575
|
+
});
|
|
34586
34576
|
}
|
|
34587
34577
|
catch (e) {
|
|
34588
34578
|
this.alertService.addServerFailure(e);
|
|
34589
34579
|
}
|
|
34590
|
-
setTimeout(() => (ddConfigureColumns.autoClose = true), 0);
|
|
34591
34580
|
}
|
|
34592
34581
|
async removeFilter(filter) {
|
|
34593
34582
|
const filteringModifier = filter.externalFilterQuery
|
|
@@ -35294,7 +35283,7 @@ class DataGridComponent {
|
|
|
35294
35283
|
provide: PRODUCT_EXPERIENCE_EVENT_SOURCE,
|
|
35295
35284
|
useExisting: forwardRef(() => DataGridComponent)
|
|
35296
35285
|
}
|
|
35297
|
-
], queries: [{ propertyName: "expandableRow", first: true, predicate: ExpandableRowDirective, descendants: true }, { propertyName: "emptyState", first: true, predicate: EmptyStateContextDirective, descendants: true }, { propertyName: "columnRenderers", predicate: ColumnDirective }], viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scroll"], descendants: true, static: true }, { propertyName: "infiniteScrollContainer", first: true, predicate: ["infiniteScrollContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "tableRef", first: true, predicate: CdkTable, descendants: true }, { propertyName: "thRefs", predicate: CdkHeaderCell, descendants: true, read: ElementRef }], usesOnChanges: true, ngImport: i0, template: "@let loadingData = ((dataSource.loading$ | async) && !loadMoreComponent?.isLoading) || loading;\n\n<div\n class=\"table-data-grid-scroll\"\n #scroll\n [ngClass]=\"{\n 'table-data-grid__overlay': loadingData\n }\"\n data-cy=\"c8y-data-grid--table-data-grid-scroll\"\n>\n @if (loadingData && displayOptions.showLoadingIndicator) {\n <div class=\"table-data-grid__loading--wrapper\">\n <div class=\"table-data-grid__loading--loader\">\n <c8y-loading\n layout=\"application\"\n [message]=\"loadingItemsLabel\"\n ></c8y-loading>\n </div>\n </div>\n }\n\n @if (displayOptions.gridHeader) {\n <div class=\"table-data-grid-header separator large-padding\">\n <div\n class=\"h4\"\n [ngClass]=\"{ 'm-r-16': !!title }\"\n >\n {{ title | translate }}\n </div>\n\n @if (displayOptions.filter) {\n @if (!filteringApplied) {\n <span>\n @if (!!filteringLabelsParams.allItemsCount) {\n <small\n class=\"m-r-4\"\n ngNonBindable\n translate\n [translateParams]=\"filteringLabelsParams\"\n >\n {{ filteredItemsCount }} of {{ allItemsCount }} items\n </small>\n }\n <span\n class=\"label label-default m-r-4\"\n translate\n >\n No filters\n </span>\n </span>\n }\n @if (filteringApplied) {\n <span class=\"d-flex a-i-center\">\n @if (!!filteringLabelsParams.allItemsCount) {\n <div class=\"a-i-center\">\n <span class=\"badge badge-info m-r-4\">\n {{ (dataSource.stats$ | async).filteredSize }}\n </span>\n <small\n ngNonBindable\n translate\n [translateParams]=\"filteringLabelsParams\"\n >\n of {{ allItemsCount }} items\n </small>\n </div>\n }\n <div\n class=\"dropdown\"\n placement=\"bottom left\"\n dropdown\n #ddFilters=\"bs-dropdown\"\n [cdkTrapFocus]=\"ddFilters.isOpen\"\n [insideClick]=\"true\"\n >\n <button\n class=\"btn btn-default btn-sm m-l-8\"\n title=\"{{ 'Active filters' | translate }}\"\n aria-haspopup=\"true\"\n dropdownToggle\n data-cy=\"c8y-data-grid--filters\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"filter\"\n ></i>\n <span>{{ 'Active filters' | translate }}</span>\n <span class=\"badge badge-system\">\n {{ columnsWithFiltersApplied.length }}\n </span>\n </button>\n\n <div\n class=\"dropdown-menu\"\n *dropdownMenu\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"data-grid__dropdown bg-level-0\">\n <ul class=\"list-unstyled m-0\">\n @for (column of columnsWithFiltersApplied; track $index; let last = $last) {\n <li [ngClass]=\"{ 'separator-bottom': !last }\">\n <ng-container>\n <div\n class=\"dropdown-header sticky-top text-truncate no-border-top p-b-0\"\n title=\"{{ (column.header | translate) || column.name }}\"\n >\n <label>\n {{ (column.header | translate) || column.name }}\n </label>\n </div>\n @for (\n groupedFilterChips of column\n | mapToFilterChips\n | async\n | groupedFilterChips;\n track $index;\n let first = $first\n ) {\n <div\n class=\"list-group-item borderless d-flex d-col\"\n [ngClass]=\"{ 'p-t-0': first }\"\n >\n @if (groupedFilterChips.label) {\n <p class=\"small p-b-4\">\n {{ groupedFilterChips.label | translate }}\n </p>\n }\n <div class=\"d-flex a-i-center gap-4 flex-wrap\">\n @for (chip of groupedFilterChips.chips; track $index) {\n <span class=\"tag tag--info chip\">\n <button\n class=\"btn btn-xs btn-clean text-10 m-r-4\"\n title=\"{{ 'Remove filter' | translate }}\"\n (click)=\"removeFilter(chip.remove())\"\n data-cy=\"c8y-data-grid--remove-chip\"\n >\n <i c8yIcon=\"times\"></i>\n </button>\n {{ chip.displayValue | translate }}\n </span>\n }\n </div>\n </div>\n }\n </ng-container>\n </li>\n }\n </ul>\n </div>\n <div class=\"list-group-item separator-top sticky-bottom\">\n <button\n class=\"btn btn-sm btn-default\"\n title=\"{{ 'Clear all filters' | translate }}\"\n type=\"button\"\n (click)=\"clearFilters()\"\n data-cy=\"c8y-data-grid--clear-filters\"\n >\n {{ 'Clear all filters' | translate }}\n </button>\n </div>\n </div>\n </div>\n </span>\n }\n\n @if (displayOptions.filter) {\n <button\n class=\"btn-help btn-help--sm hidden-xs hidden-sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"filtersHelpPopover\"\n placement=\"right\"\n triggers=\"focus\"\n type=\"button\"\n data-cy=\"data-grid--help-filters\"\n >\n <i c8yIcon=\"question-circle-o\"></i>\n </button>\n }\n <ng-template #filtersHelpPopover>\n <div [innerHtml]=\"filtersHelpPopoverHtml | translate\"></div>\n </ng-template>\n\n @if (showCounterWarning) {\n <button\n class=\"btn-clean text-primary hidden-xs hidden-sm\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{\n 'The counter for the total number of items might be inaccurate.' | translate\n }}\"\n placement=\"right\"\n triggers=\"focus\"\n type=\"button\"\n >\n <i c8yIcon=\"warning\"></i>\n </button>\n }\n }\n\n <div class=\"m-l-auto\">\n <div class=\"btnbar d-flex a-i-center\">\n @for (\n headerActionControl of headerActionControls | visibleControls | async;\n track $index\n ) {\n <ng-container>\n @if (!headerActionControl.template) {\n <button\n class=\"btnbar-btn btn-link\"\n title=\"{{ headerActionControl.text | translate }}\"\n type=\"button\"\n (click)=\"headerActionControl.callback()\"\n c8yProductExperience\n inherit\n [actionData]=\"{\n action: PX_ACTIONS.CUSTOM_ACTION,\n customActionName: headerActionControl.text,\n type: headerActionControl.type\n }\"\n >\n <i\n class=\"m-r-4\"\n [c8yIcon]=\"headerActionControl.icon\"\n ></i>\n <span>{{ headerActionControl.text | translate }}</span>\n </button>\n } @else {\n <ng-container\n *ngTemplateOutlet=\"\n headerActionControl.template;\n context: { headerActionControl: headerActionControl }\n \"\n ></ng-container>\n }\n </ng-container>\n }\n\n @if (configureColumnsEnabled) {\n <div\n class=\"dropdown\"\n placement=\"bottom left\"\n dropdown\n #ddConfigureColumns=\"bs-dropdown\"\n [cdkTrapFocus]=\"ddConfigureColumns.isOpen\"\n [insideClick]=\"true\"\n >\n <button\n class=\"btnbar-btn\"\n title=\"{{ 'Configure columns' | translate }}\"\n type=\"button\"\n data-cy=\"data-grid--custom-column-btn\"\n dropdownToggle\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"columns\"\n ></i>\n <span>{{ 'Configure columns' | translate }}</span>\n </button>\n\n <ul\n class=\"dropdown-menu data-grid__dropdown\"\n *dropdownMenu\n (click)=\"$event.stopPropagation()\"\n >\n <li>\n <div\n class=\"list-group m-0\"\n cdkDropList\n (cdkDropListDropped)=\"onColumnDrop($event)\"\n >\n @for (column of columns; track $index) {\n <div\n cdkDrag\n cdkDragLockAxis=\"y\"\n >\n @if (!column.positionFixed) {\n <div class=\"list-group-item draggable-after p-l-16 p-r-16 a-i-center\">\n <label\n class=\"c8y-checkbox min-width-0\"\n title=\"{{ column.custom ? ('Custom' | translate) + ' ' : '' }}{{\n (column.header | translate) || column.name\n }}\"\n [attr.data-cy]=\"'data-grid--custom-column-header-' + column.header\"\n >\n <input\n type=\"checkbox\"\n [(ngModel)]=\"column.visible\"\n (change)=\"\n updateGridColumnsSize();\n emitConfigChange('changeColumnVisibility')\n \"\n c8yProductExperience\n inherit\n [actionData]=\"{\n action: PX_ACTIONS.CHANGE_VISIBILITY,\n column: column.name,\n visible: !column.visible\n }\"\n />\n <span></span>\n <div class=\"d-col min-width-0 m-l-8 m-r-8\">\n @if (column?.custom) {\n <span class=\"text-muted text-10 m-b-0\">\n {{ 'Custom' | translate }}\n </span>\n }\n <span class=\"text-truncate l-h-1 m-t-2\">\n {{ (column.header | translate) || column.name }}\n </span>\n </div>\n @let canRetrieve = canRetrieveAssetProperties | async;\n @if (canRetrieve) {\n @if (canRetrieve && column?.type) {\n <span\n class=\"tag tag--default a-s-end\"\n title=\"{{ column.type | translate | humanize }}\"\n >\n {{ column.type | translate | humanize }}\n </span>\n }\n }\n </label>\n @if (column.custom) {\n <button\n class=\"btn btn-dot btn-dot--danger showOnHover max-width-fit a-i-center\"\n [attr.aria-label]=\"'Remove`column,verb`' | translate\"\n tooltip=\"{{ 'Remove`column,verb`' | translate }}\"\n placement=\"left\"\n container=\"body\"\n type=\"button\"\n (click)=\"removeCustomColumn(poConfirm, column, ddConfigureColumns)\"\n >\n <c8y-popover-confirm\n [title]=\"'Confirm removal' | translate\"\n triggers=\"focus\"\n [placement]=\"'left'\"\n #poConfirm\n ></c8y-popover-confirm>\n <i\n c8yIcon=\"minus-circle\"\n data-cy=\"data-grid--custom-column-remove-btn\"\n ></i>\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n </li>\n @if (isConfigContextKnown) {\n <li class=\"p-8 sticky-bottom separator-top\">\n <button\n class=\"btn btn-default btn-block\"\n title=\"{{ 'Add custom column' | translate }}\"\n type=\"button\"\n data-cy=\"data-grid--add-custom-column\"\n (click)=\"openCustomColumn(); ddConfigureColumns.hide()\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"plus-circle\"\n ></i>\n <span>{{ 'Add custom column' | translate }}</span>\n </button>\n </li>\n }\n </ul>\n </div>\n }\n\n @if (!hideReload) {\n <button\n class=\"btnbar-btn btn-link\"\n title=\"{{ 'Reload' | translate }}\"\n type=\"button\"\n data-cy=\"data-grid--reload-btn\"\n [disabled]=\"dataSource.loading$ | async\"\n (click)=\"clickReload()\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"refresh\"\n ></i>\n <span>{{ 'Reload' | translate }}</span>\n </button>\n }\n\n @if (!serverSideDataCallback || showSearch) {\n <div class=\"input-group input-group-search m-l-sm-16 data-grid__search-input\">\n <input\n class=\"form-control\"\n placeholder=\"{{ 'Search\u2026' | translate }}\"\n type=\"search\"\n [(ngModel)]=\"searchText\"\n (ngModelChange)=\"searchText$.emit($event)\"\n (keydown.enter)=\"$event.stopPropagation(); performSearch(searchText)\"\n />\n <div class=\"input-group-addon\">\n @if (searchText.length === 0) {\n <i c8yIcon=\"search\"></i>\n }\n @if (searchText.length > 0) {\n <i\n class=\"pointer\"\n c8yIcon=\"times\"\n (click)=\"searchText = ''; searchText$.emit('')\"\n c8yProductExperience\n inherit\n [actionData]=\"{ action: PX_ACTIONS.CLEAR_SEARCH }\"\n ></i>\n }\n </div>\n </div>\n }\n </div>\n </div>\n @if (selectedItemIds.length !== 0) {\n <div\n class=\"table-data-grid-header-bulk-actions animated slideInDown fast\"\n data-cy=\"table-data-grid-header-bulk-actions\"\n >\n <h4>\n <ng-container [ngPlural]=\"selectedItemIds.length\">\n <ng-template ngPluralCase=\"=1\">\n <span translate>1 selected item.</span>\n </ng-template>\n <ng-template ngPluralCase=\"other\">\n <span\n ngNonBindable\n translate\n [translateParams]=\"{ count: selectedItemIds.length }\"\n >\n {{ count }} selected items.\n </span>\n </ng-template>\n </ng-container>\n <br class=\"visible-xs\" />\n @if (!serverSideDataCallback && selectedItemIds.length >= pagination.pageSize) {\n <small>\n <a\n class=\"interact\"\n (click)=\"setAllItemsSelected(true)\"\n c8yProductExperience\n inherit\n [actionData]=\"{ action: PX_ACTIONS.SELECT_ALL_ITEMS }\"\n >\n <span\n ngNonBindable\n translate\n [translateParams]=\"{ count: (dataSource.stats$ | async).filteredSize }\"\n >\n Select all {{ count }} items\n </span>\n </a>\n </small>\n }\n </h4>\n <div class=\"m-l-auto\">\n <div class=\"btnbar d-flex\">\n @for (\n bulkActionControl of bulkActionControls | visibleControls: selectedItemIds | async;\n track $index\n ) {\n <ng-container>\n @switch (bulkActionControl.type) {\n @case (builtInActionType.Export) {\n <button\n class=\"btnbar-btn\"\n title=\"{{ 'Export' | translate }}\"\n type=\"button\"\n (click)=\"bulkActionControl.callback(selectedItemIds, reload.bind(this))\"\n [actionData]=\"{ action: PX_ACTIONS.BULK_EXPORT }\"\n c8yProductExperience\n inherit\n >\n <i c8yIcon=\"sign-out\"></i>\n <span>{{ 'Export' | translate }}</span>\n </button>\n }\n @case (builtInActionType.Delete) {\n <button\n class=\"btnbar-btn\"\n title=\"{{ 'Delete' | translate }}\"\n type=\"button\"\n (click)=\"bulkActionControl.callback(selectedItemIds, reload.bind(this))\"\n [actionData]=\"{ action: PX_ACTIONS.BULK_DELETE }\"\n c8yProductExperience\n inherit\n >\n <i c8yIcon=\"delete\"></i>\n <span>{{ 'Delete' | translate }}</span>\n </button>\n }\n @default {\n <button\n class=\"btnbar-btn\"\n title=\"{{ bulkActionControl.text | translate }}\"\n type=\"button\"\n (click)=\"bulkActionControl.callback(selectedItemIds, reload.bind(this))\"\n [actionData]=\"{\n action: PX_ACTIONS.BULK_CUSTOM_ACTION,\n customActionName: bulkActionControl.text\n }\"\n c8yProductExperience\n inherit\n >\n <i\n [class]=\"bulkActionControl.iconClasses\"\n c8yIcon=\"{{ bulkActionControl.icon }}\"\n ></i>\n <span>{{ bulkActionControl.text | translate }}</span>\n </button>\n }\n }\n </ng-container>\n }\n\n <button\n class=\"btnbar-btn\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"cancel()\"\n [actionData]=\"{\n action: PX_ACTIONS.BULK_CANCEL\n }\"\n c8yProductExperience\n inherit\n >\n <i c8yIcon=\"times\"></i>\n <span>{{ 'Cancel' | translate }}</span>\n </button>\n </div>\n </div>\n </div>\n }\n </div>\n }\n\n <table\n class=\"table table-filtered-sorted table-data-grid large-padding\"\n [class.table-striped]=\"displayOptions.striped && !treeGrid\"\n [class.table-bordered]=\"displayOptions.bordered\"\n [class.table-hover]=\"displayOptions.hover\"\n [class.table-data-grid-with-checkboxes]=\"selectable\"\n [class.table-data-grid-with-actions]=\"actionControls.length > 0\"\n [style.grid-template-columns]=\"styles.gridTemplateColumns\"\n cdk-table\n [dataSource]=\"dataSource\"\n [multiTemplateDataRows]=\"true\"\n (mousemove)=\"resizeHandleContainerMouseMove$.emit($event)\"\n data-cy=\"c8y-data-grid--table\"\n >\n @for (column of columns; track column.name; let i = $index) {\n <ng-container [cdkColumnDef]=\"column.name\">\n @switch (column.name) {\n @case ('checkbox') {\n <th\n cdk-header-cell\n *cdkHeaderCellDef\n data-type=\"icon\"\n >\n <div>\n <label class=\"c8y-checkbox\">\n <input\n [attr.aria-label]=\"'Selected' | translate\"\n type=\"checkbox\"\n [checked]=\"currentPageSelectionState.allSelected\"\n [indeterminate]=\"\n !(\n currentPageSelectionState.allSelected ||\n currentPageSelectionState.allDeselected\n )\n \"\n (change)=\"setAllItemsInCurrentPageSelected($event.target.checked)\"\n c8yProductExperience\n inherit\n [actionData]=\"{ action: PX_ACTIONS.SELECT_ALL_ITEMS }\"\n />\n <span></span>\n </label>\n </div>\n </th>\n\n <td\n cdk-cell\n *cdkCellDef=\"let row\"\n data-type=\"icon\"\n >\n <label class=\"c8y-checkbox\">\n <input\n [attr.aria-label]=\"'Selected' | translate\"\n type=\"checkbox\"\n [checked]=\"isItemSelected(row)\"\n (change)=\"setItemsSelected([row], $event.target.checked)\"\n c8yProductExperience\n inherit\n [actionData]=\"{\n action: PX_ACTIONS.SELECT_ITEM,\n id: row.id\n }\"\n data-cy=\"c8y-data-grid--checkbox\"\n />\n <span></span>\n </label>\n </td>\n }\n\n @case ('radio-button') {\n <th\n cdk-header-cell\n *cdkHeaderCellDef\n data-type=\"icon\"\n ></th>\n\n <td\n cdk-cell\n *cdkCellDef=\"let row\"\n data-type=\"icon\"\n >\n <label class=\"c8y-radio\">\n <input\n [attr.aria-label]=\"'Selected' | translate\"\n name=\"select-row\"\n type=\"radio\"\n [checked]=\"isItemSelected(row)\"\n (change)=\"changeSelectedItem(row)\"\n c8yProductExperience\n inherit\n [actionData]=\"{\n action: PX_ACTIONS.SELECT_ITEM,\n id: row.id\n }\"\n data-cy=\"c8y-data-grid--radio\"\n />\n <span></span>\n </label>\n </td>\n }\n\n @case ('actions') {\n <th\n cdk-header-cell\n *cdkHeaderCellDef\n data-type=\"icon\"\n >\n <p class=\"text-medium sr-only\">{{ 'Actions' | translate }}</p>\n </th>\n\n <td\n cdk-cell\n *cdkCellDef=\"let row\"\n data-type=\"icon\"\n >\n @for (\n actionControl of actionControls\n | visibleControls: row\n | async\n | slice\n : 0\n : ((actionControls | visibleControls: row | async)?.length > 2 ? 1 : 2);\n track $index\n ) {\n <ng-container>\n @switch (actionControl.type) {\n @case (builtInActionType.Edit) {\n <button\n class=\"btn btn-dot\"\n [attr.aria-label]=\"'Edit' | translate\"\n tooltip=\"{{ 'Edit' | translate }}\"\n container=\"body\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"actionControl.callback(row, reload.bind(this))\"\n c8yProductExperience\n inherit\n [actionData]=\"{\n action: PX_ACTIONS.EDIT_ITEM,\n id: row.id\n }\"\n data-cy=\"c8y-data-grid--edit-button-in-row\"\n >\n <i c8yIcon=\"pencil\"></i>\n </button>\n }\n @case (builtInActionType.Delete) {\n <button\n class=\"btn btn-dot btn-dot--danger showOnHover\"\n [attr.aria-label]=\"'Delete' | translate\"\n tooltip=\"{{ 'Delete' | translate }}\"\n container=\"body\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"actionControl.callback(row, reload.bind(this))\"\n [actionData]=\"{\n action: PX_ACTIONS.DELETE_ITEM,\n id: row.id\n }\"\n c8yProductExperience\n inherit\n data-cy=\"c8y-data-grid--remove-button-in-row\"\n >\n <i c8yIcon=\"delete\"></i>\n </button>\n }\n @default {\n <button\n class=\"btn btn-dot\"\n [attr.aria-label]=\"\n (actionControl.icon ? actionControl.text : '') | translate\n \"\n tooltip=\"{{ (actionControl.icon ? actionControl.text : '') | translate }}\"\n container=\"body\"\n type=\"button\"\n [ngClass]=\"{ showOnHover: actionControl.showOnHover }\"\n [delay]=\"500\"\n (click)=\"actionControl.callback(row, reload.bind(this))\"\n [actionData]=\"{\n action: PX_ACTIONS.CUSTOM_ACTION_ITEM,\n customActionName: actionControl.text,\n id: row.id\n }\"\n c8yProductExperience\n inherit\n [attr.data-cy]=\"'c8y-data-grid--button-in-row--' + actionControl.text\"\n >\n @if (actionControl.icon) {\n <i\n c8yIcon=\"{{ actionControl.icon }}\"\n [ngClass]=\"actionControl.iconClasses\"\n ></i>\n } @else {\n <span>{{ actionControl.text | translate }}</span>\n }\n </button>\n }\n }\n </ng-container>\n }\n\n <div\n [ngClass]=\"{\n 'm-l-auto overflow-visible':\n (actionControls | visibleControls: row | async)?.length > 2\n }\"\n >\n @if ((actionControls | visibleControls: row | async)?.length > 2) {\n <div\n class=\"dropdown\"\n placement=\"bottom right\"\n container=\"body\"\n dropdown\n >\n <button\n class=\"dropdown-toggle c8y-dropdown\"\n title=\"{{ 'Actions' | translate }}\"\n aria-haspopup=\"true\"\n type=\"button\"\n data-cy=\"c8y-data-grid--row-actions-dropdown\"\n dropdownToggle\n >\n <i c8yIcon=\"ellipsis-v\"></i>\n </button>\n <ul\n class=\"dropdown-menu dropdown-menu-right\"\n *dropdownMenu\n >\n @for (\n actionControl of actionControls\n | visibleControls: row\n | async\n | slice\n : ((actionControls | visibleControls: row | async)?.length > 2 ? 1 : 2);\n track $index\n ) {\n <li>\n @switch (actionControl.type) {\n @case (builtInActionType.Edit) {\n <button\n title=\"{{ 'Edit' | translate }}\"\n type=\"button\"\n (click)=\"actionControl.callback(row, reload.bind(this))\"\n [actionData]=\"{\n action: PX_ACTIONS.EDIT_ITEM,\n id: row.id\n }\"\n c8yProductExperience\n inherit\n >\n <i c8yIcon=\"pencil\"></i>\n {{ 'Edit' | translate }}\n </button>\n }\n @case (builtInActionType.Delete) {\n <button\n title=\"{{ 'Delete' | translate }}\"\n type=\"button\"\n (click)=\"actionControl.callback(row, reload.bind(this))\"\n [actionData]=\"{\n action: PX_ACTIONS.DELETE_ITEM,\n id: row.id\n }\"\n c8yProductExperience\n inherit\n >\n <i c8yIcon=\"delete\"></i>\n {{ 'Delete' | translate }}\n </button>\n }\n @case (builtInActionType.Export) {\n <button\n title=\"{{ 'Export' | translate }}\"\n type=\"button\"\n (click)=\"actionControl.callback(row, reload.bind(this))\"\n [actionData]=\"{\n action: PX_ACTIONS.EXPORT_ITEM,\n id: row.id\n }\"\n c8yProductExperience\n inherit\n >\n <i c8yIcon=\"data-export\"></i>\n {{ 'Export' | translate }}\n </button>\n }\n @default {\n <button\n title=\"{{ actionControl.text | translate }}\"\n type=\"button\"\n (click)=\"actionControl.callback(row, reload.bind(this))\"\n c8yProductExperience\n inherit\n [actionData]=\"{\n action: PX_ACTIONS.CUSTOM_ACTION_ITEM,\n customActionName: actionControl.text,\n id: row.id\n }\"\n >\n <i\n c8yIcon=\"{{ actionControl.icon }}\"\n [ngClass]=\"actionControl.iconClasses\"\n ></i>\n {{ actionControl.text | translate }}\n </button>\n }\n }\n </li>\n }\n </ul>\n </div>\n }\n </div>\n </td>\n }\n @default {\n <th\n [class.sorted]=\"column.sortOrder\"\n [class.filtered]=\"column | map: isColumnFilteringApplied\"\n [class.hidden]=\"!column.visible\"\n cdk-header-cell\n *cdkHeaderCellDef\n [ngClass]=\"column.headerCSSClassName\"\n [attr.data-type]=\"column.dataType\"\n >\n @if (!column.filterable) {\n <div [title]=\"(column.header | translate) || column.name\">\n @let cellRendererSpec =\n [\n {\n columnName: column.name,\n value: (column.header | translate) || column.name\n }\n ] | map: getHeaderCellRendererSpec : this;\n\n @if (cellRendererSpec) {\n <c8y-cell-renderer [spec]=\"cellRendererSpec\"></c8y-cell-renderer>\n }\n </div>\n }\n\n <!-- isDropDownPlacedRight to be removed when columns are transformed to observables. -->\n @if (column.filterable) {\n <div\n class=\"dropdown\"\n placement=\"bottom {{ isDropDownPlacedRight(column) ? 'right' : 'left' }}\"\n dropdown\n #gridHeaderDropdown=\"bs-dropdown\"\n [cdkTrapFocus]=\"gridHeaderDropdown.isOpen\"\n [insideClick]=\"true\"\n >\n <button\n class=\"btn-header\"\n [title]=\"(column.header | translate) || column.name\"\n type=\"button\"\n [attr.data-cy]=\"'data-grid--header-btn--' + column.header\"\n dropdownToggle\n >\n @let cellRendererSpec =\n [\n {\n columnName: column.name,\n value: (column.header | translate) || column.name\n }\n ] | map: getHeaderCellRendererSpec : this;\n\n @if (cellRendererSpec) {\n <c8y-cell-renderer\n data-cy=\"c8y-data-grid--c8y-cell-renderer\"\n [spec]=\"cellRendererSpec\"\n ></c8y-cell-renderer>\n }\n <i\n c8yIcon=\"filter\"\n title=\"{{ 'Filter' | translate }}\"\n ></i>\n </button>\n\n <!-- isDropDownPlacedRight to be removed when columns are transformed to observables. -->\n <ul\n class=\"dropdown-menu\"\n *dropdownMenu\n [ngClass]=\"{ 'dropdown-menu-right-grid': isDropDownPlacedRight(column) }\"\n (click)=\"$event.stopPropagation()\"\n >\n <li class=\"data-grid__dropdown\">\n @let filteringFormRendererSpec =\n [\n {\n column: column,\n dropdown: gridHeaderDropdown\n }\n ] | map: getFilteringFormRendererSpec : this;\n\n @if (filteringFormRendererSpec) {\n <c8y-filtering-form-renderer\n class=\"bg-component\"\n [spec]=\"filteringFormRendererSpec\"\n data-cy=\"c8y-data-grid--c8y-filtering-form-renderer\"\n ></c8y-filtering-form-renderer>\n }\n </li>\n </ul>\n </div>\n }\n\n @if (column.sortable) {\n <button\n class=\"btn-sort\"\n [style]=\"{\n 'margin-left': !column.filterable && column.sortable ? '-20px' : null\n }\"\n [title]=\"sortColumnTitle | translate: { name: column.header | translate }\"\n type=\"button\"\n (click)=\"changeSortOrder(column.name)\"\n data-cy=\"change-sort-order\"\n >\n @switch (column.sortOrder) {\n @case ('asc') {\n <i c8yIcon=\"long-arrow-up\"></i>\n }\n @case ('desc') {\n <i c8yIcon=\"long-arrow-down\"></i>\n }\n @default {\n <i c8yIcon=\"exchange\"></i>\n }\n }\n </button>\n }\n\n @if (column.resizable) {\n <span\n class=\"resize-handle\"\n (mousedown)=\"\n resizeHandleMouseDown$.emit({ event: $event, targetColumnName: column.name })\n \"\n ></span>\n }\n </th>\n\n <td\n [class.hidden]=\"!column.visible\"\n [attr.data-cell-title]=\"column.header | translate\"\n cdk-cell\n *cdkCellDef=\"let row\"\n [ngClass]=\"column.cellCSSClassName\"\n [attr.data-cy]=\"'data-grid--' + column.header\"\n [attr.data-type]=\"column.dataType\"\n >\n @let cellRendererSpec =\n [\n {\n value: resolveCellValue(row, column.path),\n row: row,\n columnName: column.name\n }\n ] | map: getCellRendererSpec : this;\n\n @if (cellRendererSpec) {\n <c8y-cell-renderer [spec]=\"cellRendererSpec\"></c8y-cell-renderer>\n }\n </td>\n }\n }\n </ng-container>\n }\n\n <ng-container cdkColumnDef=\"infiniteScrollFooter\">\n <td\n [style.grid-column]=\"styles.gridInfiniteScrollColumn\"\n cdk-footer-cell\n *cdkFooterCellDef\n >\n <template #infiniteScrollContainer></template>\n </td>\n </ng-container>\n\n <tr\n cdk-header-row\n *cdkHeaderRowDef=\"columnNames\"\n ></tr>\n\n <tr\n data-cy=\"c8y-data-grid--row-in-data-grid\"\n cdk-row\n *cdkRowDef=\"let row; columns: columnNames; let idx = dataIndex; when: isDataRow\"\n [ngClass]=\"[\n activeClassName && row === lastClickedRow ? activeClassName : '',\n idx % 2 === 0 ? 'even' : 'odd',\n row.level > 0 ? 'data-grid-child-node level-' + row.level : ''\n ]\"\n (mouseover)=\"rowMouseOver.emit(row)\"\n (mouseleave)=\"rowMouseLeave.emit(row)\"\n (click)=\"handleClick(row)\"\n ></tr>\n\n <tr\n class=\"expanded-row\"\n [ngClass]=\"{ hidden: !(expandedRows.get(row).visible$ | async) }\"\n data-cy=\"c8y-data-grid--expanded-row-in-data-grid\"\n cdk-row\n *cdkRowDef=\"let row; columns: ['expanded-row']; when: isRowExpanded\"\n ></tr>\n\n <ng-container cdkColumnDef=\"expanded-row\">\n <td\n [style.grid-column]=\"styles.gridInfiniteScrollColumn\"\n cdk-cell\n *cdkCellDef=\"let row\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n expandableRow?.template;\n context: {\n $implicit: row,\n asyncRenderSuccess: setExpandableRowVisible.bind(this, row, true),\n asyncRenderFail: setExpandableRowVisible.bind(this, row, false)\n }\n \"\n ></ng-container>\n </td>\n </ng-container>\n\n <tr\n [class]=\"'pagination-row level-' + (row.parentRow.level + 1)\"\n cdk-row\n *cdkRowDef=\"let row; columns: ['pagination-row']; when: isPaginationRow\"\n ></tr>\n\n <ng-container cdkColumnDef=\"pagination-row\">\n <td\n [style.grid-column]=\"styles.gridInfiniteScrollColumn\"\n cdk-cell\n *cdkCellDef=\"let row\"\n >\n <div class=\"col-sm-4 no-gutter\">\n @if ((dataSource.stats$ | async).currentPageSize > 0) {\n <div\n class=\"counter p-t-8 p-b-8\"\n data-cy=\"data-grid--child-counter\"\n >\n <span\n class=\"text-muted\"\n ngNonBindable\n translate\n [translateParams]=\"{\n pageFirstItemIdx:\n (row.childrenStats.currentPage - 1) * row.childrenStats.firstPageSize + 1,\n pageLastItemIdx:\n (row.childrenStats.currentPage - 1) * row.childrenStats.firstPageSize +\n 1 +\n (row.childrenStats.currentPageSize - 1),\n itemsTotal: row.childrenStats.filteredSize\n }\"\n >\n {{ pageFirstItemIdx }} - {{ pageLastItemIdx }} of {{ itemsTotal }}\n </span>\n <span class=\"text-muted text-12 m-r-4\">{{ 'Parent node' | translate }}</span>\n <span class=\"tag tag--default\">{{ row.parentRow?.[parentNodeLabelProperty] }}</span>\n </div>\n }\n </div>\n <div class=\"col-sm-4 col-sm-offset-4 no-gutter text-right\">\n @if (row.childrenStats.filteredSize > row.childrenStats.currentPageSize) {\n <pagination\n class=\"d-flex j-c-end\"\n [ngModel]=\"row.childrenStats.currentPage\"\n (pageChanged)=\"updateChildPagination($event, row)\"\n [totalItems]=\"row.childrenStats.filteredSize\"\n [itemsPerPage]=\"row?.parentRow?.pagination?.pageSize ?? childNodePagination.pageSize\"\n [maxSize]=\"5\"\n [boundaryLinks]=\"false\"\n [previousText]=\"'Previous' | translate\"\n [nextText]=\"'Next' | translate\"\n ></pagination>\n }\n </div>\n </td>\n </ng-container>\n\n <ng-container>\n <tr\n [ngClass]=\"{ hidden: !infiniteScroll }\"\n cdk-footer-row\n *cdkFooterRowDef=\"['infiniteScrollFooter']\"\n ></tr>\n </ng-container>\n </table>\n\n @if (\n !(dataSource.loading$ | async) &&\n !loading &&\n ((dataSource.stats$ | async).filteredSize === 0 || (dataSource.data$ | async).length === 0)\n ) {\n <div class=\"d-flex m-0 p-t-40 p-b-40\">\n <div class=\"col-lg-3 col-sm-4 m-l-auto m-r-auto\">\n <ng-content select=\"c8y-ui-empty-state, .c8y-empty-state\"></ng-content>\n <ng-container\n *ngTemplateOutlet=\"\n emptyState?.templateRef;\n context: { $implicit: emptyStateContext$ | async }\n \"\n ></ng-container>\n </div>\n </div>\n }\n\n @if (pagination && !infiniteScroll) {\n <div class=\"table-data-grid-footer separator large-padding\">\n <div class=\"col-sm-4 no-gutter\">\n @if ((dataSource.stats$ | async).currentPageSize > 0) {\n <div\n class=\"counter p-t-8 p-b-8\"\n data-cy=\"data-grid--counter\"\n >\n <span\n class=\"text-muted\"\n ngNonBindable\n translate\n [translateParams]=\"paginationLabelParams\"\n >\n {{ pageFirstItemIdx }} - {{ pageLastItemIdx }} of {{ itemsTotal }}\n </span>\n </div>\n }\n </div>\n\n <div class=\"col-sm-4 no-gutter text-center\">\n @if ((dataSource.stats$ | async).filteredSize > minPossiblePageSize) {\n <div class=\"form-group form-inline p-t-8 p-b-8\">\n <label\n class=\"m-r-4\"\n for=\"filteredSize\"\n >\n {{ 'Items per page' | translate }}\n </label>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control\"\n id=\"filteredSize\"\n data-cy=\"data-grid--pagesize-options\"\n [ngModel]=\"pagination.pageSize\"\n (ngModelChange)=\"\n updatePagination({ itemsPerPage: $event, page: pagination.currentPage })\n \"\n >\n @for (pageSize of possiblePageSizes; track $index) {\n <option [ngValue]=\"pageSize\">\n {{ pageSize }}\n </option>\n }\n </select>\n </div>\n </div>\n }\n </div>\n\n <div class=\"col-sm-4 no-gutter text-right\">\n @if ((dataSource.stats$ | async).filteredSize > 0) {\n <pagination\n [class.hidden]=\"hidePagination$ | async\"\n class=\"d-flex j-c-end\"\n [ngModel]=\"pagination.currentPage\"\n (pageChanged)=\"updatePagination($event)\"\n [totalItems]=\"(dataSource.stats$ | async).filteredSize\"\n [itemsPerPage]=\"pagination.pageSize\"\n (numPages)=\"totalPagesCount$.next($event)\"\n [maxSize]=\"5\"\n [boundaryLinks]=\"false\"\n [previousText]=\"'Previous' | translate\"\n [nextText]=\"'Next' | translate\"\n ></pagination>\n }\n </div>\n </div>\n }\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: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "ngmodule", type: BsDropdownModule }, { kind: "directive", type: i1$3.BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { kind: "directive", type: i1$3.BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { kind: "directive", type: i1$3.BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { kind: "directive", type: CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i1$9.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "directive", type: ProductExperienceDirective, selector: "[c8yProductExperience]", inputs: ["actionName", "actionData", "inherit", "suppressDataOverriding"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "directive", type: i1$8.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$8.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$8.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$8.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$8.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i1$5.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "component", type: PopoverConfirmComponent, selector: "c8y-popover-confirm", inputs: ["buttons", "message", "title", "isOpen", "containerClass", "placement", "outsideClick", "adaptivePosition", "container"] }, { kind: "directive", type: NgPlural, selector: "[ngPlural]", inputs: ["ngPlural"] }, { kind: "directive", type: NgPluralCase, selector: "[ngPluralCase]" }, { kind: "component", type: CdkTable, selector: "cdk-table, table[cdk-table]", inputs: ["trackBy", "dataSource", "multiTemplateDataRows", "fixedLayout"], outputs: ["contentChanged"], exportAs: ["cdkTable"] }, { kind: "directive", type: CdkColumnDef, selector: "[cdkColumnDef]", inputs: ["cdkColumnDef", "sticky", "stickyEnd"] }, { kind: "directive", type: CdkHeaderCellDef, selector: "[cdkHeaderCellDef]" }, { kind: "directive", type: CdkHeaderCell, selector: "cdk-header-cell, th[cdk-header-cell]" }, { kind: "directive", type: CdkCellDef, selector: "[cdkCellDef]" }, { kind: "directive", type: CdkCell, selector: "cdk-cell, td[cdk-cell]" }, { kind: "component", type: CellRendererComponent, selector: "c8y-cell-renderer", inputs: ["spec"] }, { kind: "component", type: FilteringFormRendererComponent, selector: "c8y-filtering-form-renderer", inputs: ["spec"] }, { kind: "directive", type: CdkFooterCellDef, selector: "[cdkFooterCellDef]" }, { kind: "directive", type: CdkFooterCell, selector: "cdk-footer-cell, td[cdk-footer-cell]" }, { kind: "directive", type: CdkHeaderRowDef, selector: "[cdkHeaderRowDef]", inputs: ["cdkHeaderRowDef", "cdkHeaderRowDefSticky"] }, { kind: "component", type: CdkHeaderRow, selector: "cdk-header-row, tr[cdk-header-row]" }, { kind: "directive", type: CdkRowDef, selector: "[cdkRowDef]", inputs: ["cdkRowDefColumns", "cdkRowDefWhen"] }, { kind: "component", type: CdkRow, selector: "cdk-row, tr[cdk-row]" }, { kind: "directive", type: CdkFooterRowDef, selector: "[cdkFooterRowDef]", inputs: ["cdkFooterRowDef", "cdkFooterRowDefSticky"] }, { kind: "component", type: CdkFooterRow, selector: "cdk-footer-row, tr[cdk-footer-row]" }, { kind: "ngmodule", type: PaginationModule }, { kind: "component", type: i11.PaginationComponent, selector: "pagination", inputs: ["align", "maxSize", "boundaryLinks", "directionLinks", "firstText", "previousText", "nextText", "lastText", "rotate", "pageBtnClass", "disabled", "customPageTemplate", "customNextTemplate", "customPreviousTemplate", "customFirstTemplate", "customLastTemplate", "itemsPerPage", "totalItems"], outputs: ["numPages", "pageChanged"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: SlicePipe, name: "slice" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: MapFunctionPipe, name: "map" }, { kind: "pipe", type: FilterMapperPipe, name: "mapToFilterChips" }, { kind: "pipe", type: GroupedFilterChips, name: "groupedFilterChips" }, { kind: "pipe", type: VisibleControlsPipe, name: "visibleControls" }, { kind: "pipe", type: HumanizePipe, name: "humanize" }] }); }
|
|
35286
|
+
], queries: [{ propertyName: "expandableRow", first: true, predicate: ExpandableRowDirective, descendants: true }, { propertyName: "emptyState", first: true, predicate: EmptyStateContextDirective, descendants: true }, { propertyName: "columnRenderers", predicate: ColumnDirective }], viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scroll"], descendants: true, static: true }, { propertyName: "infiniteScrollContainer", first: true, predicate: ["infiniteScrollContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "tableRef", first: true, predicate: CdkTable, descendants: true }, { propertyName: "thRefs", predicate: CdkHeaderCell, descendants: true, read: ElementRef }], usesOnChanges: true, ngImport: i0, template: "@let loadingData = ((dataSource.loading$ | async) && !loadMoreComponent?.isLoading) || loading;\n\n<div\n class=\"table-data-grid-scroll\"\n #scroll\n [ngClass]=\"{\n 'table-data-grid__overlay': loadingData\n }\"\n data-cy=\"c8y-data-grid--table-data-grid-scroll\"\n>\n @if (loadingData && displayOptions.showLoadingIndicator) {\n <div class=\"table-data-grid__loading--wrapper\">\n <div class=\"table-data-grid__loading--loader\">\n <c8y-loading\n layout=\"application\"\n [message]=\"loadingItemsLabel\"\n ></c8y-loading>\n </div>\n </div>\n }\n\n @if (displayOptions.gridHeader) {\n <div class=\"table-data-grid-header separator large-padding\">\n <div\n class=\"h4\"\n [ngClass]=\"{ 'm-r-16': !!title }\"\n >\n {{ title | translate }}\n </div>\n\n @if (displayOptions.filter) {\n @if (!filteringApplied) {\n <span>\n @if (!!filteringLabelsParams.allItemsCount) {\n <small\n class=\"m-r-4\"\n ngNonBindable\n translate\n [translateParams]=\"filteringLabelsParams\"\n >\n {{ filteredItemsCount }} of {{ allItemsCount }} items\n </small>\n }\n <span\n class=\"label label-default m-r-4\"\n translate\n >\n No filters\n </span>\n </span>\n }\n @if (filteringApplied) {\n <span class=\"d-flex a-i-center\">\n @if (!!filteringLabelsParams.allItemsCount) {\n <div class=\"a-i-center\">\n <span class=\"badge badge-info m-r-4\">\n {{ (dataSource.stats$ | async).filteredSize }}\n </span>\n <small\n ngNonBindable\n translate\n [translateParams]=\"filteringLabelsParams\"\n >\n of {{ allItemsCount }} items\n </small>\n </div>\n }\n <div\n class=\"dropdown\"\n placement=\"bottom left\"\n dropdown\n #ddFilters=\"bs-dropdown\"\n [cdkTrapFocus]=\"ddFilters.isOpen\"\n [insideClick]=\"true\"\n >\n <button\n class=\"btn btn-default btn-sm m-l-8\"\n title=\"{{ 'Active filters' | translate }}\"\n aria-haspopup=\"true\"\n dropdownToggle\n data-cy=\"c8y-data-grid--filters\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"filter\"\n ></i>\n <span>{{ 'Active filters' | translate }}</span>\n <span class=\"badge badge-system\">\n {{ columnsWithFiltersApplied.length }}\n </span>\n </button>\n\n <div\n class=\"dropdown-menu\"\n *dropdownMenu\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"data-grid__dropdown bg-level-0\">\n <ul class=\"list-unstyled m-0\">\n @for (column of columnsWithFiltersApplied; track $index; let last = $last) {\n <li [ngClass]=\"{ 'separator-bottom': !last }\">\n <ng-container>\n <div\n class=\"dropdown-header sticky-top text-truncate no-border-top p-b-0\"\n title=\"{{ (column.header | translate) || column.name }}\"\n >\n <label>\n {{ (column.header | translate) || column.name }}\n </label>\n </div>\n @for (\n groupedFilterChips of column\n | mapToFilterChips\n | async\n | groupedFilterChips;\n track $index;\n let first = $first\n ) {\n <div\n class=\"list-group-item borderless d-flex d-col\"\n [ngClass]=\"{ 'p-t-0': first }\"\n >\n @if (groupedFilterChips.label) {\n <p class=\"small p-b-4\">\n {{ groupedFilterChips.label | translate }}\n </p>\n }\n <div class=\"d-flex a-i-center gap-4 flex-wrap\">\n @for (chip of groupedFilterChips.chips; track $index) {\n <span class=\"tag tag--info chip\">\n <button\n class=\"btn btn-xs btn-clean text-10 m-r-4\"\n title=\"{{ 'Remove filter' | translate }}\"\n (click)=\"removeFilter(chip.remove())\"\n data-cy=\"c8y-data-grid--remove-chip\"\n >\n <i c8yIcon=\"times\"></i>\n </button>\n {{ chip.displayValue | translate }}\n </span>\n }\n </div>\n </div>\n }\n </ng-container>\n </li>\n }\n </ul>\n </div>\n <div class=\"list-group-item separator-top sticky-bottom\">\n <button\n class=\"btn btn-sm btn-default\"\n title=\"{{ 'Clear all filters' | translate }}\"\n type=\"button\"\n (click)=\"clearFilters()\"\n data-cy=\"c8y-data-grid--clear-filters\"\n >\n {{ 'Clear all filters' | translate }}\n </button>\n </div>\n </div>\n </div>\n </span>\n }\n\n @if (displayOptions.filter) {\n <button\n class=\"btn-help btn-help--sm hidden-xs hidden-sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"filtersHelpPopover\"\n placement=\"right\"\n triggers=\"focus\"\n type=\"button\"\n data-cy=\"data-grid--help-filters\"\n >\n <i c8yIcon=\"question-circle-o\"></i>\n </button>\n }\n <ng-template #filtersHelpPopover>\n <div [innerHtml]=\"filtersHelpPopoverHtml | translate\"></div>\n </ng-template>\n\n @if (showCounterWarning) {\n <button\n class=\"btn-clean text-primary hidden-xs hidden-sm\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{\n 'The counter for the total number of items might be inaccurate.' | translate\n }}\"\n placement=\"right\"\n triggers=\"focus\"\n type=\"button\"\n >\n <i c8yIcon=\"warning\"></i>\n </button>\n }\n }\n\n <div class=\"m-l-auto\">\n <div class=\"btnbar d-flex a-i-center\">\n @for (\n headerActionControl of headerActionControls | visibleControls | async;\n track $index\n ) {\n <ng-container>\n @if (!headerActionControl.template) {\n <button\n class=\"btnbar-btn btn-link\"\n title=\"{{ headerActionControl.text | translate }}\"\n type=\"button\"\n (click)=\"headerActionControl.callback()\"\n c8yProductExperience\n inherit\n [actionData]=\"{\n action: PX_ACTIONS.CUSTOM_ACTION,\n customActionName: headerActionControl.text,\n type: headerActionControl.type\n }\"\n >\n <i\n class=\"m-r-4\"\n [c8yIcon]=\"headerActionControl.icon\"\n ></i>\n <span>{{ headerActionControl.text | translate }}</span>\n </button>\n } @else {\n <ng-container\n *ngTemplateOutlet=\"\n headerActionControl.template;\n context: { headerActionControl: headerActionControl }\n \"\n ></ng-container>\n }\n </ng-container>\n }\n\n @if (configureColumnsEnabled) {\n <div\n class=\"dropdown\"\n placement=\"bottom left\"\n dropdown\n #ddConfigureColumns=\"bs-dropdown\"\n [cdkTrapFocus]=\"ddConfigureColumns.isOpen\"\n [insideClick]=\"true\"\n >\n <button\n class=\"btnbar-btn\"\n title=\"{{ 'Configure columns' | translate }}\"\n type=\"button\"\n data-cy=\"data-grid--custom-column-btn\"\n dropdownToggle\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"columns\"\n ></i>\n <span>{{ 'Configure columns' | translate }}</span>\n </button>\n\n <ul\n class=\"dropdown-menu data-grid__dropdown\"\n *dropdownMenu\n (click)=\"$event.stopPropagation()\"\n >\n <li>\n <div\n class=\"list-group m-0\"\n cdkDropList\n (cdkDropListDropped)=\"onColumnDrop($event)\"\n >\n @for (column of columns; track $index) {\n <div\n cdkDrag\n cdkDragLockAxis=\"y\"\n >\n @if (!column.positionFixed) {\n <div class=\"list-group-item draggable-after p-l-16 p-r-16 a-i-center\">\n <label\n class=\"c8y-checkbox min-width-0\"\n title=\"{{ column.custom ? ('Custom' | translate) + ' ' : '' }}{{\n (column.header | translate) || column.name\n }}\"\n [attr.data-cy]=\"'data-grid--custom-column-header-' + column.header\"\n >\n <input\n type=\"checkbox\"\n [(ngModel)]=\"column.visible\"\n (change)=\"\n updateGridColumnsSize();\n emitConfigChange('changeColumnVisibility')\n \"\n c8yProductExperience\n inherit\n [actionData]=\"{\n action: PX_ACTIONS.CHANGE_VISIBILITY,\n column: column.name,\n visible: !column.visible\n }\"\n />\n <span></span>\n <div class=\"d-col min-width-0 m-l-8 m-r-8\">\n @if (column?.custom) {\n <span class=\"text-muted text-10 m-b-0\">\n {{ 'Custom' | translate }}\n </span>\n }\n <span class=\"text-truncate l-h-1 m-t-2\">\n {{ (column.header | translate) || column.name }}\n </span>\n </div>\n @let canRetrieve = canRetrieveAssetProperties | async;\n @if (canRetrieve) {\n @if (canRetrieve && column?.type) {\n <span\n class=\"tag tag--default a-s-end\"\n title=\"{{ column.type | translate | humanize }}\"\n >\n {{ column.type | translate | humanize }}\n </span>\n }\n }\n </label>\n @if (column.custom) {\n <button\n class=\"btn btn-dot btn-dot--danger showOnHover max-width-fit a-i-center\"\n [attr.aria-label]=\"'Remove`column,verb`' | translate\"\n [popover]=\"confirmRemovePopover\"\n type=\"button\"\n #pop=\"bs-popover\"\n (click)=\"\n currentRemoveCustomColumnPopover !== pop &&\n currentRemoveCustomColumnPopover?.hide();\n currentRemoveCustomColumnPopover = pop\n \"\n >\n <i\n c8yIcon=\"minus-circle\"\n data-cy=\"data-grid--custom-column-remove-btn\"\n ></i>\n </button>\n\n <ng-template #confirmRemovePopover>\n <h3 class=\"popover-title popover-header\">\n {{ 'Confirm removal' | translate }}\n </h3>\n <div class=\"popover-content popover-body\">\n <p>{{ 'Do you want to remove this column?' | translate }}</p>\n <div class=\"popover-footer gap-16\">\n <button\n class=\"btn btn-default btn-sm\"\n type=\"button\"\n (click)=\"pop.hide()\"\n >\n {{ 'Cancel' | translate }}\n </button>\n <button\n class=\"btn btn-danger btn-sm\"\n type=\"button\"\n (click)=\"confirmRemoveColumn(column); pop.hide()\"\n data-cy=\"popover-confirm--Remove\"\n >\n {{ 'Remove' | translate }}\n </button>\n </div>\n </div>\n </ng-template>\n }\n </div>\n }\n </div>\n }\n </div>\n </li>\n @if (isConfigContextKnown) {\n <li class=\"p-8 sticky-bottom separator-top\">\n <button\n class=\"btn btn-default btn-block\"\n title=\"{{ 'Add custom column' | translate }}\"\n type=\"button\"\n data-cy=\"data-grid--add-custom-column\"\n (click)=\"openCustomColumn(); ddConfigureColumns.hide()\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"plus-circle\"\n ></i>\n <span>{{ 'Add custom column' | translate }}</span>\n </button>\n </li>\n }\n </ul>\n </div>\n }\n\n @if (!hideReload) {\n <button\n class=\"btnbar-btn btn-link\"\n title=\"{{ 'Reload' | translate }}\"\n type=\"button\"\n data-cy=\"data-grid--reload-btn\"\n [disabled]=\"dataSource.loading$ | async\"\n (click)=\"clickReload()\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"refresh\"\n ></i>\n <span>{{ 'Reload' | translate }}</span>\n </button>\n }\n\n @if (!serverSideDataCallback || showSearch) {\n <div class=\"input-group input-group-search m-l-sm-16 data-grid__search-input\">\n <input\n class=\"form-control\"\n placeholder=\"{{ 'Search\u2026' | translate }}\"\n type=\"search\"\n [(ngModel)]=\"searchText\"\n (ngModelChange)=\"searchText$.emit($event)\"\n (keydown.enter)=\"$event.stopPropagation(); performSearch(searchText)\"\n />\n <div class=\"input-group-addon\">\n @if (searchText.length === 0) {\n <i c8yIcon=\"search\"></i>\n }\n @if (searchText.length > 0) {\n <i\n class=\"pointer\"\n c8yIcon=\"times\"\n (click)=\"searchText = ''; searchText$.emit('')\"\n c8yProductExperience\n inherit\n [actionData]=\"{ action: PX_ACTIONS.CLEAR_SEARCH }\"\n ></i>\n }\n </div>\n </div>\n }\n </div>\n </div>\n @if (selectedItemIds.length !== 0) {\n <div\n class=\"table-data-grid-header-bulk-actions animated slideInDown fast\"\n data-cy=\"table-data-grid-header-bulk-actions\"\n >\n <h4>\n <ng-container [ngPlural]=\"selectedItemIds.length\">\n <ng-template ngPluralCase=\"=1\">\n <span translate>1 selected item.</span>\n </ng-template>\n <ng-template ngPluralCase=\"other\">\n <span\n ngNonBindable\n translate\n [translateParams]=\"{ count: selectedItemIds.length }\"\n >\n {{ count }} selected items.\n </span>\n </ng-template>\n </ng-container>\n <br class=\"visible-xs\" />\n @if (!serverSideDataCallback && selectedItemIds.length >= pagination.pageSize) {\n <small>\n <a\n class=\"interact\"\n (click)=\"setAllItemsSelected(true)\"\n c8yProductExperience\n inherit\n [actionData]=\"{ action: PX_ACTIONS.SELECT_ALL_ITEMS }\"\n >\n <span\n ngNonBindable\n translate\n [translateParams]=\"{ count: (dataSource.stats$ | async).filteredSize }\"\n >\n Select all {{ count }} items\n </span>\n </a>\n </small>\n }\n </h4>\n <div class=\"m-l-auto\">\n <div class=\"btnbar d-flex\">\n @for (\n bulkActionControl of bulkActionControls | visibleControls: selectedItemIds | async;\n track $index\n ) {\n <ng-container>\n @switch (bulkActionControl.type) {\n @case (builtInActionType.Export) {\n <button\n class=\"btnbar-btn\"\n title=\"{{ 'Export' | translate }}\"\n type=\"button\"\n (click)=\"bulkActionControl.callback(selectedItemIds, reload.bind(this))\"\n [actionData]=\"{ action: PX_ACTIONS.BULK_EXPORT }\"\n c8yProductExperience\n inherit\n >\n <i c8yIcon=\"sign-out\"></i>\n <span>{{ 'Export' | translate }}</span>\n </button>\n }\n @case (builtInActionType.Delete) {\n <button\n class=\"btnbar-btn\"\n title=\"{{ 'Delete' | translate }}\"\n type=\"button\"\n (click)=\"bulkActionControl.callback(selectedItemIds, reload.bind(this))\"\n [actionData]=\"{ action: PX_ACTIONS.BULK_DELETE }\"\n c8yProductExperience\n inherit\n >\n <i c8yIcon=\"delete\"></i>\n <span>{{ 'Delete' | translate }}</span>\n </button>\n }\n @default {\n <button\n class=\"btnbar-btn\"\n title=\"{{ bulkActionControl.text | translate }}\"\n type=\"button\"\n (click)=\"bulkActionControl.callback(selectedItemIds, reload.bind(this))\"\n [actionData]=\"{\n action: PX_ACTIONS.BULK_CUSTOM_ACTION,\n customActionName: bulkActionControl.text\n }\"\n c8yProductExperience\n inherit\n >\n <i\n [class]=\"bulkActionControl.iconClasses\"\n c8yIcon=\"{{ bulkActionControl.icon }}\"\n ></i>\n <span>{{ bulkActionControl.text | translate }}</span>\n </button>\n }\n }\n </ng-container>\n }\n\n <button\n class=\"btnbar-btn\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"cancel()\"\n [actionData]=\"{\n action: PX_ACTIONS.BULK_CANCEL\n }\"\n c8yProductExperience\n inherit\n >\n <i c8yIcon=\"times\"></i>\n <span>{{ 'Cancel' | translate }}</span>\n </button>\n </div>\n </div>\n </div>\n }\n </div>\n }\n\n <table\n class=\"table table-filtered-sorted table-data-grid large-padding\"\n [class.table-striped]=\"displayOptions.striped && !treeGrid\"\n [class.table-bordered]=\"displayOptions.bordered\"\n [class.table-hover]=\"displayOptions.hover\"\n [class.table-data-grid-with-checkboxes]=\"selectable\"\n [class.table-data-grid-with-actions]=\"actionControls.length > 0\"\n [style.grid-template-columns]=\"styles.gridTemplateColumns\"\n cdk-table\n [dataSource]=\"dataSource\"\n [multiTemplateDataRows]=\"true\"\n (mousemove)=\"resizeHandleContainerMouseMove$.emit($event)\"\n data-cy=\"c8y-data-grid--table\"\n >\n @for (column of columns; track column.name; let i = $index) {\n <ng-container [cdkColumnDef]=\"column.name\">\n @switch (column.name) {\n @case ('checkbox') {\n <th\n cdk-header-cell\n *cdkHeaderCellDef\n data-type=\"icon\"\n >\n <div>\n <label class=\"c8y-checkbox\">\n <input\n [attr.aria-label]=\"'Selected' | translate\"\n type=\"checkbox\"\n [checked]=\"currentPageSelectionState.allSelected\"\n [indeterminate]=\"\n !(\n currentPageSelectionState.allSelected ||\n currentPageSelectionState.allDeselected\n )\n \"\n (change)=\"setAllItemsInCurrentPageSelected($event.target.checked)\"\n c8yProductExperience\n inherit\n [actionData]=\"{ action: PX_ACTIONS.SELECT_ALL_ITEMS }\"\n />\n <span></span>\n </label>\n </div>\n </th>\n\n <td\n cdk-cell\n *cdkCellDef=\"let row\"\n data-type=\"icon\"\n >\n <label class=\"c8y-checkbox\">\n <input\n [attr.aria-label]=\"'Selected' | translate\"\n type=\"checkbox\"\n [checked]=\"isItemSelected(row)\"\n (change)=\"setItemsSelected([row], $event.target.checked)\"\n c8yProductExperience\n inherit\n [actionData]=\"{\n action: PX_ACTIONS.SELECT_ITEM,\n id: row.id\n }\"\n data-cy=\"c8y-data-grid--checkbox\"\n />\n <span></span>\n </label>\n </td>\n }\n\n @case ('radio-button') {\n <th\n cdk-header-cell\n *cdkHeaderCellDef\n data-type=\"icon\"\n ></th>\n\n <td\n cdk-cell\n *cdkCellDef=\"let row\"\n data-type=\"icon\"\n >\n <label class=\"c8y-radio\">\n <input\n [attr.aria-label]=\"'Selected' | translate\"\n name=\"select-row\"\n type=\"radio\"\n [checked]=\"isItemSelected(row)\"\n (change)=\"changeSelectedItem(row)\"\n c8yProductExperience\n inherit\n [actionData]=\"{\n action: PX_ACTIONS.SELECT_ITEM,\n id: row.id\n }\"\n data-cy=\"c8y-data-grid--radio\"\n />\n <span></span>\n </label>\n </td>\n }\n\n @case ('actions') {\n <th\n cdk-header-cell\n *cdkHeaderCellDef\n data-type=\"icon\"\n >\n <p class=\"text-medium sr-only\">{{ 'Actions' | translate }}</p>\n </th>\n\n <td\n cdk-cell\n *cdkCellDef=\"let row\"\n data-type=\"icon\"\n >\n @for (\n actionControl of actionControls\n | visibleControls: row\n | async\n | slice\n : 0\n : ((actionControls | visibleControls: row | async)?.length > 2 ? 1 : 2);\n track $index\n ) {\n <ng-container>\n @switch (actionControl.type) {\n @case (builtInActionType.Edit) {\n <button\n class=\"btn btn-dot\"\n [attr.aria-label]=\"'Edit' | translate\"\n tooltip=\"{{ 'Edit' | translate }}\"\n container=\"body\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"actionControl.callback(row, reload.bind(this))\"\n c8yProductExperience\n inherit\n [actionData]=\"{\n action: PX_ACTIONS.EDIT_ITEM,\n id: row.id\n }\"\n data-cy=\"c8y-data-grid--edit-button-in-row\"\n >\n <i c8yIcon=\"pencil\"></i>\n </button>\n }\n @case (builtInActionType.Delete) {\n <button\n class=\"btn btn-dot btn-dot--danger showOnHover\"\n [attr.aria-label]=\"'Delete' | translate\"\n tooltip=\"{{ 'Delete' | translate }}\"\n container=\"body\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"actionControl.callback(row, reload.bind(this))\"\n [actionData]=\"{\n action: PX_ACTIONS.DELETE_ITEM,\n id: row.id\n }\"\n c8yProductExperience\n inherit\n data-cy=\"c8y-data-grid--remove-button-in-row\"\n >\n <i c8yIcon=\"delete\"></i>\n </button>\n }\n @default {\n <button\n class=\"btn btn-dot\"\n [attr.aria-label]=\"\n (actionControl.icon ? actionControl.text : '') | translate\n \"\n tooltip=\"{{ (actionControl.icon ? actionControl.text : '') | translate }}\"\n container=\"body\"\n type=\"button\"\n [ngClass]=\"{ showOnHover: actionControl.showOnHover }\"\n [delay]=\"500\"\n (click)=\"actionControl.callback(row, reload.bind(this))\"\n [actionData]=\"{\n action: PX_ACTIONS.CUSTOM_ACTION_ITEM,\n customActionName: actionControl.text,\n id: row.id\n }\"\n c8yProductExperience\n inherit\n [attr.data-cy]=\"'c8y-data-grid--button-in-row--' + actionControl.text\"\n >\n @if (actionControl.icon) {\n <i\n c8yIcon=\"{{ actionControl.icon }}\"\n [ngClass]=\"actionControl.iconClasses\"\n ></i>\n } @else {\n <span>{{ actionControl.text | translate }}</span>\n }\n </button>\n }\n }\n </ng-container>\n }\n\n <div\n [ngClass]=\"{\n 'm-l-auto overflow-visible':\n (actionControls | visibleControls: row | async)?.length > 2\n }\"\n >\n @if ((actionControls | visibleControls: row | async)?.length > 2) {\n <div\n class=\"dropdown\"\n placement=\"bottom right\"\n container=\"body\"\n dropdown\n >\n <button\n class=\"dropdown-toggle c8y-dropdown\"\n title=\"{{ 'Actions' | translate }}\"\n aria-haspopup=\"true\"\n type=\"button\"\n data-cy=\"c8y-data-grid--row-actions-dropdown\"\n dropdownToggle\n >\n <i c8yIcon=\"ellipsis-v\"></i>\n </button>\n <ul\n class=\"dropdown-menu dropdown-menu-right\"\n *dropdownMenu\n >\n @for (\n actionControl of actionControls\n | visibleControls: row\n | async\n | slice\n : ((actionControls | visibleControls: row | async)?.length > 2 ? 1 : 2);\n track $index\n ) {\n <li>\n @switch (actionControl.type) {\n @case (builtInActionType.Edit) {\n <button\n title=\"{{ 'Edit' | translate }}\"\n type=\"button\"\n (click)=\"actionControl.callback(row, reload.bind(this))\"\n [actionData]=\"{\n action: PX_ACTIONS.EDIT_ITEM,\n id: row.id\n }\"\n c8yProductExperience\n inherit\n >\n <i c8yIcon=\"pencil\"></i>\n {{ 'Edit' | translate }}\n </button>\n }\n @case (builtInActionType.Delete) {\n <button\n title=\"{{ 'Delete' | translate }}\"\n type=\"button\"\n (click)=\"actionControl.callback(row, reload.bind(this))\"\n [actionData]=\"{\n action: PX_ACTIONS.DELETE_ITEM,\n id: row.id\n }\"\n c8yProductExperience\n inherit\n >\n <i c8yIcon=\"delete\"></i>\n {{ 'Delete' | translate }}\n </button>\n }\n @case (builtInActionType.Export) {\n <button\n title=\"{{ 'Export' | translate }}\"\n type=\"button\"\n (click)=\"actionControl.callback(row, reload.bind(this))\"\n [actionData]=\"{\n action: PX_ACTIONS.EXPORT_ITEM,\n id: row.id\n }\"\n c8yProductExperience\n inherit\n >\n <i c8yIcon=\"data-export\"></i>\n {{ 'Export' | translate }}\n </button>\n }\n @default {\n <button\n title=\"{{ actionControl.text | translate }}\"\n type=\"button\"\n (click)=\"actionControl.callback(row, reload.bind(this))\"\n c8yProductExperience\n inherit\n [actionData]=\"{\n action: PX_ACTIONS.CUSTOM_ACTION_ITEM,\n customActionName: actionControl.text,\n id: row.id\n }\"\n >\n <i\n c8yIcon=\"{{ actionControl.icon }}\"\n [ngClass]=\"actionControl.iconClasses\"\n ></i>\n {{ actionControl.text | translate }}\n </button>\n }\n }\n </li>\n }\n </ul>\n </div>\n }\n </div>\n </td>\n }\n @default {\n <th\n [class.sorted]=\"column.sortOrder\"\n [class.filtered]=\"column | map: isColumnFilteringApplied\"\n [class.hidden]=\"!column.visible\"\n cdk-header-cell\n *cdkHeaderCellDef\n [ngClass]=\"column.headerCSSClassName\"\n [attr.data-type]=\"column.dataType\"\n >\n @if (!column.filterable) {\n <div [title]=\"(column.header | translate) || column.name\">\n @let cellRendererSpec =\n [\n {\n columnName: column.name,\n value: (column.header | translate) || column.name\n }\n ] | map: getHeaderCellRendererSpec : this;\n\n @if (cellRendererSpec) {\n <c8y-cell-renderer [spec]=\"cellRendererSpec\"></c8y-cell-renderer>\n }\n </div>\n }\n\n <!-- isDropDownPlacedRight to be removed when columns are transformed to observables. -->\n @if (column.filterable) {\n <div\n class=\"dropdown\"\n placement=\"bottom {{ isDropDownPlacedRight(column) ? 'right' : 'left' }}\"\n dropdown\n #gridHeaderDropdown=\"bs-dropdown\"\n [cdkTrapFocus]=\"gridHeaderDropdown.isOpen\"\n [insideClick]=\"true\"\n >\n <button\n class=\"btn-header\"\n [title]=\"(column.header | translate) || column.name\"\n type=\"button\"\n [attr.data-cy]=\"'data-grid--header-btn--' + column.header\"\n dropdownToggle\n >\n @let cellRendererSpec =\n [\n {\n columnName: column.name,\n value: (column.header | translate) || column.name\n }\n ] | map: getHeaderCellRendererSpec : this;\n\n @if (cellRendererSpec) {\n <c8y-cell-renderer\n data-cy=\"c8y-data-grid--c8y-cell-renderer\"\n [spec]=\"cellRendererSpec\"\n ></c8y-cell-renderer>\n }\n <i\n c8yIcon=\"filter\"\n title=\"{{ 'Filter' | translate }}\"\n ></i>\n </button>\n\n <!-- isDropDownPlacedRight to be removed when columns are transformed to observables. -->\n <ul\n class=\"dropdown-menu\"\n *dropdownMenu\n [ngClass]=\"{ 'dropdown-menu-right-grid': isDropDownPlacedRight(column) }\"\n (click)=\"$event.stopPropagation()\"\n >\n <li class=\"data-grid__dropdown\">\n @let filteringFormRendererSpec =\n [\n {\n column: column,\n dropdown: gridHeaderDropdown\n }\n ] | map: getFilteringFormRendererSpec : this;\n\n @if (filteringFormRendererSpec) {\n <c8y-filtering-form-renderer\n class=\"bg-component\"\n [spec]=\"filteringFormRendererSpec\"\n data-cy=\"c8y-data-grid--c8y-filtering-form-renderer\"\n ></c8y-filtering-form-renderer>\n }\n </li>\n </ul>\n </div>\n }\n\n @if (column.sortable) {\n <button\n class=\"btn-sort\"\n [style]=\"{\n 'margin-left': !column.filterable && column.sortable ? '-20px' : null\n }\"\n [title]=\"sortColumnTitle | translate: { name: column.header | translate }\"\n type=\"button\"\n (click)=\"changeSortOrder(column.name)\"\n data-cy=\"change-sort-order\"\n >\n @switch (column.sortOrder) {\n @case ('asc') {\n <i c8yIcon=\"long-arrow-up\"></i>\n }\n @case ('desc') {\n <i c8yIcon=\"long-arrow-down\"></i>\n }\n @default {\n <i c8yIcon=\"exchange\"></i>\n }\n }\n </button>\n }\n\n @if (column.resizable) {\n <span\n class=\"resize-handle\"\n (mousedown)=\"\n resizeHandleMouseDown$.emit({ event: $event, targetColumnName: column.name })\n \"\n ></span>\n }\n </th>\n\n <td\n [class.hidden]=\"!column.visible\"\n [attr.data-cell-title]=\"column.header | translate\"\n cdk-cell\n *cdkCellDef=\"let row\"\n [ngClass]=\"column.cellCSSClassName\"\n [attr.data-cy]=\"'data-grid--' + column.header\"\n [attr.data-type]=\"column.dataType\"\n >\n @let cellRendererSpec =\n [\n {\n value: resolveCellValue(row, column.path),\n row: row,\n columnName: column.name\n }\n ] | map: getCellRendererSpec : this;\n\n @if (cellRendererSpec) {\n <c8y-cell-renderer [spec]=\"cellRendererSpec\"></c8y-cell-renderer>\n }\n </td>\n }\n }\n </ng-container>\n }\n\n <ng-container cdkColumnDef=\"infiniteScrollFooter\">\n <td\n [style.grid-column]=\"styles.gridInfiniteScrollColumn\"\n cdk-footer-cell\n *cdkFooterCellDef\n >\n <template #infiniteScrollContainer></template>\n </td>\n </ng-container>\n\n <tr\n cdk-header-row\n *cdkHeaderRowDef=\"columnNames\"\n ></tr>\n\n <tr\n data-cy=\"c8y-data-grid--row-in-data-grid\"\n cdk-row\n *cdkRowDef=\"let row; columns: columnNames; let idx = dataIndex; when: isDataRow\"\n [ngClass]=\"[\n activeClassName && row === lastClickedRow ? activeClassName : '',\n idx % 2 === 0 ? 'even' : 'odd',\n row.level > 0 ? 'data-grid-child-node level-' + row.level : ''\n ]\"\n (mouseover)=\"rowMouseOver.emit(row)\"\n (mouseleave)=\"rowMouseLeave.emit(row)\"\n (click)=\"handleClick(row)\"\n ></tr>\n\n <tr\n class=\"expanded-row\"\n [ngClass]=\"{ hidden: !(expandedRows.get(row).visible$ | async) }\"\n data-cy=\"c8y-data-grid--expanded-row-in-data-grid\"\n cdk-row\n *cdkRowDef=\"let row; columns: ['expanded-row']; when: isRowExpanded\"\n ></tr>\n\n <ng-container cdkColumnDef=\"expanded-row\">\n <td\n [style.grid-column]=\"styles.gridInfiniteScrollColumn\"\n cdk-cell\n *cdkCellDef=\"let row\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n expandableRow?.template;\n context: {\n $implicit: row,\n asyncRenderSuccess: setExpandableRowVisible.bind(this, row, true),\n asyncRenderFail: setExpandableRowVisible.bind(this, row, false)\n }\n \"\n ></ng-container>\n </td>\n </ng-container>\n\n <tr\n [class]=\"'pagination-row level-' + (row.parentRow.level + 1)\"\n cdk-row\n *cdkRowDef=\"let row; columns: ['pagination-row']; when: isPaginationRow\"\n ></tr>\n\n <ng-container cdkColumnDef=\"pagination-row\">\n <td\n [style.grid-column]=\"styles.gridInfiniteScrollColumn\"\n cdk-cell\n *cdkCellDef=\"let row\"\n >\n <div class=\"col-sm-4 no-gutter\">\n @if ((dataSource.stats$ | async).currentPageSize > 0) {\n <div\n class=\"counter p-t-8 p-b-8\"\n data-cy=\"data-grid--child-counter\"\n >\n <span\n class=\"text-muted\"\n ngNonBindable\n translate\n [translateParams]=\"{\n pageFirstItemIdx:\n (row.childrenStats.currentPage - 1) * row.childrenStats.firstPageSize + 1,\n pageLastItemIdx:\n (row.childrenStats.currentPage - 1) * row.childrenStats.firstPageSize +\n 1 +\n (row.childrenStats.currentPageSize - 1),\n itemsTotal: row.childrenStats.filteredSize\n }\"\n >\n {{ pageFirstItemIdx }} - {{ pageLastItemIdx }} of {{ itemsTotal }}\n </span>\n <span class=\"text-muted text-12 m-r-4\">{{ 'Parent node' | translate }}</span>\n <span class=\"tag tag--default\">{{ row.parentRow?.[parentNodeLabelProperty] }}</span>\n </div>\n }\n </div>\n <div class=\"col-sm-4 col-sm-offset-4 no-gutter text-right\">\n @if (row.childrenStats.filteredSize > row.childrenStats.currentPageSize) {\n <pagination\n class=\"d-flex j-c-end\"\n [ngModel]=\"row.childrenStats.currentPage\"\n (pageChanged)=\"updateChildPagination($event, row)\"\n [totalItems]=\"row.childrenStats.filteredSize\"\n [itemsPerPage]=\"row?.parentRow?.pagination?.pageSize ?? childNodePagination.pageSize\"\n [maxSize]=\"5\"\n [boundaryLinks]=\"false\"\n [previousText]=\"'Previous' | translate\"\n [nextText]=\"'Next' | translate\"\n ></pagination>\n }\n </div>\n </td>\n </ng-container>\n\n <ng-container>\n <tr\n [ngClass]=\"{ hidden: !infiniteScroll }\"\n cdk-footer-row\n *cdkFooterRowDef=\"['infiniteScrollFooter']\"\n ></tr>\n </ng-container>\n </table>\n\n @if (\n !(dataSource.loading$ | async) &&\n !loading &&\n ((dataSource.stats$ | async).filteredSize === 0 || (dataSource.data$ | async).length === 0)\n ) {\n <div class=\"d-flex m-0 p-t-40 p-b-40\">\n <div class=\"col-lg-3 col-sm-4 m-l-auto m-r-auto\">\n <ng-content select=\"c8y-ui-empty-state, .c8y-empty-state\"></ng-content>\n <ng-container\n *ngTemplateOutlet=\"\n emptyState?.templateRef;\n context: { $implicit: emptyStateContext$ | async }\n \"\n ></ng-container>\n </div>\n </div>\n }\n\n @if (pagination && !infiniteScroll) {\n <div class=\"table-data-grid-footer separator large-padding\">\n <div class=\"col-sm-4 no-gutter\">\n @if ((dataSource.stats$ | async).currentPageSize > 0) {\n <div\n class=\"counter p-t-8 p-b-8\"\n data-cy=\"data-grid--counter\"\n >\n <span\n class=\"text-muted\"\n ngNonBindable\n translate\n [translateParams]=\"paginationLabelParams\"\n >\n {{ pageFirstItemIdx }} - {{ pageLastItemIdx }} of {{ itemsTotal }}\n </span>\n </div>\n }\n </div>\n\n <div class=\"col-sm-4 no-gutter text-center\">\n @if ((dataSource.stats$ | async).filteredSize > minPossiblePageSize) {\n <div class=\"form-group form-inline p-t-8 p-b-8\">\n <label\n class=\"m-r-4\"\n for=\"filteredSize\"\n >\n {{ 'Items per page' | translate }}\n </label>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control\"\n id=\"filteredSize\"\n data-cy=\"data-grid--pagesize-options\"\n [ngModel]=\"pagination.pageSize\"\n (ngModelChange)=\"\n updatePagination({ itemsPerPage: $event, page: pagination.currentPage })\n \"\n >\n @for (pageSize of possiblePageSizes; track $index) {\n <option [ngValue]=\"pageSize\">\n {{ pageSize }}\n </option>\n }\n </select>\n </div>\n </div>\n }\n </div>\n\n <div class=\"col-sm-4 no-gutter text-right\">\n @if ((dataSource.stats$ | async).filteredSize > 0) {\n <pagination\n [class.hidden]=\"hidePagination$ | async\"\n class=\"d-flex j-c-end\"\n [ngModel]=\"pagination.currentPage\"\n (pageChanged)=\"updatePagination($event)\"\n [totalItems]=\"(dataSource.stats$ | async).filteredSize\"\n [itemsPerPage]=\"pagination.pageSize\"\n (numPages)=\"totalPagesCount$.next($event)\"\n [maxSize]=\"5\"\n [boundaryLinks]=\"false\"\n [previousText]=\"'Previous' | translate\"\n [nextText]=\"'Next' | translate\"\n ></pagination>\n }\n </div>\n </div>\n }\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: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "ngmodule", type: BsDropdownModule }, { kind: "directive", type: i1$3.BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { kind: "directive", type: i1$3.BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { kind: "directive", type: i1$3.BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { kind: "directive", type: CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i1$9.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "directive", type: ProductExperienceDirective, selector: "[c8yProductExperience]", inputs: ["actionName", "actionData", "inherit", "suppressDataOverriding"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "ngmodule", type: FormsModule$1 }, { kind: "directive", type: i1$8.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$8.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$8.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$8.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$8.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i1$5.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "directive", type: NgPlural, selector: "[ngPlural]", inputs: ["ngPlural"] }, { kind: "directive", type: NgPluralCase, selector: "[ngPluralCase]" }, { kind: "component", type: CdkTable, selector: "cdk-table, table[cdk-table]", inputs: ["trackBy", "dataSource", "multiTemplateDataRows", "fixedLayout"], outputs: ["contentChanged"], exportAs: ["cdkTable"] }, { kind: "directive", type: CdkColumnDef, selector: "[cdkColumnDef]", inputs: ["cdkColumnDef", "sticky", "stickyEnd"] }, { kind: "directive", type: CdkHeaderCellDef, selector: "[cdkHeaderCellDef]" }, { kind: "directive", type: CdkHeaderCell, selector: "cdk-header-cell, th[cdk-header-cell]" }, { kind: "directive", type: CdkCellDef, selector: "[cdkCellDef]" }, { kind: "directive", type: CdkCell, selector: "cdk-cell, td[cdk-cell]" }, { kind: "component", type: CellRendererComponent, selector: "c8y-cell-renderer", inputs: ["spec"] }, { kind: "component", type: FilteringFormRendererComponent, selector: "c8y-filtering-form-renderer", inputs: ["spec"] }, { kind: "directive", type: CdkFooterCellDef, selector: "[cdkFooterCellDef]" }, { kind: "directive", type: CdkFooterCell, selector: "cdk-footer-cell, td[cdk-footer-cell]" }, { kind: "directive", type: CdkHeaderRowDef, selector: "[cdkHeaderRowDef]", inputs: ["cdkHeaderRowDef", "cdkHeaderRowDefSticky"] }, { kind: "component", type: CdkHeaderRow, selector: "cdk-header-row, tr[cdk-header-row]" }, { kind: "directive", type: CdkRowDef, selector: "[cdkRowDef]", inputs: ["cdkRowDefColumns", "cdkRowDefWhen"] }, { kind: "component", type: CdkRow, selector: "cdk-row, tr[cdk-row]" }, { kind: "directive", type: CdkFooterRowDef, selector: "[cdkFooterRowDef]", inputs: ["cdkFooterRowDef", "cdkFooterRowDefSticky"] }, { kind: "component", type: CdkFooterRow, selector: "cdk-footer-row, tr[cdk-footer-row]" }, { kind: "ngmodule", type: PaginationModule }, { kind: "component", type: i11.PaginationComponent, selector: "pagination", inputs: ["align", "maxSize", "boundaryLinks", "directionLinks", "firstText", "previousText", "nextText", "lastText", "rotate", "pageBtnClass", "disabled", "customPageTemplate", "customNextTemplate", "customPreviousTemplate", "customFirstTemplate", "customLastTemplate", "itemsPerPage", "totalItems"], outputs: ["numPages", "pageChanged"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: SlicePipe, name: "slice" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: MapFunctionPipe, name: "map" }, { kind: "pipe", type: FilterMapperPipe, name: "mapToFilterChips" }, { kind: "pipe", type: GroupedFilterChips, name: "groupedFilterChips" }, { kind: "pipe", type: VisibleControlsPipe, name: "visibleControls" }, { kind: "pipe", type: HumanizePipe, name: "humanize" }] }); }
|
|
35298
35287
|
}
|
|
35299
35288
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: DataGridComponent, decorators: [{
|
|
35300
35289
|
type: Component,
|
|
@@ -35317,7 +35306,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
35317
35306
|
CdkDrag,
|
|
35318
35307
|
FormsModule$1,
|
|
35319
35308
|
TooltipModule,
|
|
35320
|
-
PopoverConfirmComponent,
|
|
35321
35309
|
NgPlural,
|
|
35322
35310
|
NgPluralCase,
|
|
35323
35311
|
CdkTable,
|
|
@@ -35345,7 +35333,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
35345
35333
|
GroupedFilterChips,
|
|
35346
35334
|
VisibleControlsPipe,
|
|
35347
35335
|
HumanizePipe
|
|
35348
|
-
], template: "@let loadingData = ((dataSource.loading$ | async) && !loadMoreComponent?.isLoading) || loading;\n\n<div\n class=\"table-data-grid-scroll\"\n #scroll\n [ngClass]=\"{\n 'table-data-grid__overlay': loadingData\n }\"\n data-cy=\"c8y-data-grid--table-data-grid-scroll\"\n>\n @if (loadingData && displayOptions.showLoadingIndicator) {\n <div class=\"table-data-grid__loading--wrapper\">\n <div class=\"table-data-grid__loading--loader\">\n <c8y-loading\n layout=\"application\"\n [message]=\"loadingItemsLabel\"\n ></c8y-loading>\n </div>\n </div>\n }\n\n @if (displayOptions.gridHeader) {\n <div class=\"table-data-grid-header separator large-padding\">\n <div\n class=\"h4\"\n [ngClass]=\"{ 'm-r-16': !!title }\"\n >\n {{ title | translate }}\n </div>\n\n @if (displayOptions.filter) {\n @if (!filteringApplied) {\n <span>\n @if (!!filteringLabelsParams.allItemsCount) {\n <small\n class=\"m-r-4\"\n ngNonBindable\n translate\n [translateParams]=\"filteringLabelsParams\"\n >\n {{ filteredItemsCount }} of {{ allItemsCount }} items\n </small>\n }\n <span\n class=\"label label-default m-r-4\"\n translate\n >\n No filters\n </span>\n </span>\n }\n @if (filteringApplied) {\n <span class=\"d-flex a-i-center\">\n @if (!!filteringLabelsParams.allItemsCount) {\n <div class=\"a-i-center\">\n <span class=\"badge badge-info m-r-4\">\n {{ (dataSource.stats$ | async).filteredSize }}\n </span>\n <small\n ngNonBindable\n translate\n [translateParams]=\"filteringLabelsParams\"\n >\n of {{ allItemsCount }} items\n </small>\n </div>\n }\n <div\n class=\"dropdown\"\n placement=\"bottom left\"\n dropdown\n #ddFilters=\"bs-dropdown\"\n [cdkTrapFocus]=\"ddFilters.isOpen\"\n [insideClick]=\"true\"\n >\n <button\n class=\"btn btn-default btn-sm m-l-8\"\n title=\"{{ 'Active filters' | translate }}\"\n aria-haspopup=\"true\"\n dropdownToggle\n data-cy=\"c8y-data-grid--filters\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"filter\"\n ></i>\n <span>{{ 'Active filters' | translate }}</span>\n <span class=\"badge badge-system\">\n {{ columnsWithFiltersApplied.length }}\n </span>\n </button>\n\n <div\n class=\"dropdown-menu\"\n *dropdownMenu\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"data-grid__dropdown bg-level-0\">\n <ul class=\"list-unstyled m-0\">\n @for (column of columnsWithFiltersApplied; track $index; let last = $last) {\n <li [ngClass]=\"{ 'separator-bottom': !last }\">\n <ng-container>\n <div\n class=\"dropdown-header sticky-top text-truncate no-border-top p-b-0\"\n title=\"{{ (column.header | translate) || column.name }}\"\n >\n <label>\n {{ (column.header | translate) || column.name }}\n </label>\n </div>\n @for (\n groupedFilterChips of column\n | mapToFilterChips\n | async\n | groupedFilterChips;\n track $index;\n let first = $first\n ) {\n <div\n class=\"list-group-item borderless d-flex d-col\"\n [ngClass]=\"{ 'p-t-0': first }\"\n >\n @if (groupedFilterChips.label) {\n <p class=\"small p-b-4\">\n {{ groupedFilterChips.label | translate }}\n </p>\n }\n <div class=\"d-flex a-i-center gap-4 flex-wrap\">\n @for (chip of groupedFilterChips.chips; track $index) {\n <span class=\"tag tag--info chip\">\n <button\n class=\"btn btn-xs btn-clean text-10 m-r-4\"\n title=\"{{ 'Remove filter' | translate }}\"\n (click)=\"removeFilter(chip.remove())\"\n data-cy=\"c8y-data-grid--remove-chip\"\n >\n <i c8yIcon=\"times\"></i>\n </button>\n {{ chip.displayValue | translate }}\n </span>\n }\n </div>\n </div>\n }\n </ng-container>\n </li>\n }\n </ul>\n </div>\n <div class=\"list-group-item separator-top sticky-bottom\">\n <button\n class=\"btn btn-sm btn-default\"\n title=\"{{ 'Clear all filters' | translate }}\"\n type=\"button\"\n (click)=\"clearFilters()\"\n data-cy=\"c8y-data-grid--clear-filters\"\n >\n {{ 'Clear all filters' | translate }}\n </button>\n </div>\n </div>\n </div>\n </span>\n }\n\n @if (displayOptions.filter) {\n <button\n class=\"btn-help btn-help--sm hidden-xs hidden-sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"filtersHelpPopover\"\n placement=\"right\"\n triggers=\"focus\"\n type=\"button\"\n data-cy=\"data-grid--help-filters\"\n >\n <i c8yIcon=\"question-circle-o\"></i>\n </button>\n }\n <ng-template #filtersHelpPopover>\n <div [innerHtml]=\"filtersHelpPopoverHtml | translate\"></div>\n </ng-template>\n\n @if (showCounterWarning) {\n <button\n class=\"btn-clean text-primary hidden-xs hidden-sm\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{\n 'The counter for the total number of items might be inaccurate.' | translate\n }}\"\n placement=\"right\"\n triggers=\"focus\"\n type=\"button\"\n >\n <i c8yIcon=\"warning\"></i>\n </button>\n }\n }\n\n <div class=\"m-l-auto\">\n <div class=\"btnbar d-flex a-i-center\">\n @for (\n headerActionControl of headerActionControls | visibleControls | async;\n track $index\n ) {\n <ng-container>\n @if (!headerActionControl.template) {\n <button\n class=\"btnbar-btn btn-link\"\n title=\"{{ headerActionControl.text | translate }}\"\n type=\"button\"\n (click)=\"headerActionControl.callback()\"\n c8yProductExperience\n inherit\n [actionData]=\"{\n action: PX_ACTIONS.CUSTOM_ACTION,\n customActionName: headerActionControl.text,\n type: headerActionControl.type\n }\"\n >\n <i\n class=\"m-r-4\"\n [c8yIcon]=\"headerActionControl.icon\"\n ></i>\n <span>{{ headerActionControl.text | translate }}</span>\n </button>\n } @else {\n <ng-container\n *ngTemplateOutlet=\"\n headerActionControl.template;\n context: { headerActionControl: headerActionControl }\n \"\n ></ng-container>\n }\n </ng-container>\n }\n\n @if (configureColumnsEnabled) {\n <div\n class=\"dropdown\"\n placement=\"bottom left\"\n dropdown\n #ddConfigureColumns=\"bs-dropdown\"\n [cdkTrapFocus]=\"ddConfigureColumns.isOpen\"\n [insideClick]=\"true\"\n >\n <button\n class=\"btnbar-btn\"\n title=\"{{ 'Configure columns' | translate }}\"\n type=\"button\"\n data-cy=\"data-grid--custom-column-btn\"\n dropdownToggle\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"columns\"\n ></i>\n <span>{{ 'Configure columns' | translate }}</span>\n </button>\n\n <ul\n class=\"dropdown-menu data-grid__dropdown\"\n *dropdownMenu\n (click)=\"$event.stopPropagation()\"\n >\n <li>\n <div\n class=\"list-group m-0\"\n cdkDropList\n (cdkDropListDropped)=\"onColumnDrop($event)\"\n >\n @for (column of columns; track $index) {\n <div\n cdkDrag\n cdkDragLockAxis=\"y\"\n >\n @if (!column.positionFixed) {\n <div class=\"list-group-item draggable-after p-l-16 p-r-16 a-i-center\">\n <label\n class=\"c8y-checkbox min-width-0\"\n title=\"{{ column.custom ? ('Custom' | translate) + ' ' : '' }}{{\n (column.header | translate) || column.name\n }}\"\n [attr.data-cy]=\"'data-grid--custom-column-header-' + column.header\"\n >\n <input\n type=\"checkbox\"\n [(ngModel)]=\"column.visible\"\n (change)=\"\n updateGridColumnsSize();\n emitConfigChange('changeColumnVisibility')\n \"\n c8yProductExperience\n inherit\n [actionData]=\"{\n action: PX_ACTIONS.CHANGE_VISIBILITY,\n column: column.name,\n visible: !column.visible\n }\"\n />\n <span></span>\n <div class=\"d-col min-width-0 m-l-8 m-r-8\">\n @if (column?.custom) {\n <span class=\"text-muted text-10 m-b-0\">\n {{ 'Custom' | translate }}\n </span>\n }\n <span class=\"text-truncate l-h-1 m-t-2\">\n {{ (column.header | translate) || column.name }}\n </span>\n </div>\n @let canRetrieve = canRetrieveAssetProperties | async;\n @if (canRetrieve) {\n @if (canRetrieve && column?.type) {\n <span\n class=\"tag tag--default a-s-end\"\n title=\"{{ column.type | translate | humanize }}\"\n >\n {{ column.type | translate | humanize }}\n </span>\n }\n }\n </label>\n @if (column.custom) {\n <button\n class=\"btn btn-dot btn-dot--danger showOnHover max-width-fit a-i-center\"\n [attr.aria-label]=\"'Remove`column,verb`' | translate\"\n tooltip=\"{{ 'Remove`column,verb`' | translate }}\"\n placement=\"left\"\n container=\"body\"\n type=\"button\"\n (click)=\"removeCustomColumn(poConfirm, column, ddConfigureColumns)\"\n >\n <c8y-popover-confirm\n [title]=\"'Confirm removal' | translate\"\n triggers=\"focus\"\n [placement]=\"'left'\"\n #poConfirm\n ></c8y-popover-confirm>\n <i\n c8yIcon=\"minus-circle\"\n data-cy=\"data-grid--custom-column-remove-btn\"\n ></i>\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n </li>\n @if (isConfigContextKnown) {\n <li class=\"p-8 sticky-bottom separator-top\">\n <button\n class=\"btn btn-default btn-block\"\n title=\"{{ 'Add custom column' | translate }}\"\n type=\"button\"\n data-cy=\"data-grid--add-custom-column\"\n (click)=\"openCustomColumn(); ddConfigureColumns.hide()\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"plus-circle\"\n ></i>\n <span>{{ 'Add custom column' | translate }}</span>\n </button>\n </li>\n }\n </ul>\n </div>\n }\n\n @if (!hideReload) {\n <button\n class=\"btnbar-btn btn-link\"\n title=\"{{ 'Reload' | translate }}\"\n type=\"button\"\n data-cy=\"data-grid--reload-btn\"\n [disabled]=\"dataSource.loading$ | async\"\n (click)=\"clickReload()\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"refresh\"\n ></i>\n <span>{{ 'Reload' | translate }}</span>\n </button>\n }\n\n @if (!serverSideDataCallback || showSearch) {\n <div class=\"input-group input-group-search m-l-sm-16 data-grid__search-input\">\n <input\n class=\"form-control\"\n placeholder=\"{{ 'Search\u2026' | translate }}\"\n type=\"search\"\n [(ngModel)]=\"searchText\"\n (ngModelChange)=\"searchText$.emit($event)\"\n (keydown.enter)=\"$event.stopPropagation(); performSearch(searchText)\"\n />\n <div class=\"input-group-addon\">\n @if (searchText.length === 0) {\n <i c8yIcon=\"search\"></i>\n }\n @if (searchText.length > 0) {\n <i\n class=\"pointer\"\n c8yIcon=\"times\"\n (click)=\"searchText = ''; searchText$.emit('')\"\n c8yProductExperience\n inherit\n [actionData]=\"{ action: PX_ACTIONS.CLEAR_SEARCH }\"\n ></i>\n }\n </div>\n </div>\n }\n </div>\n </div>\n @if (selectedItemIds.length !== 0) {\n <div\n class=\"table-data-grid-header-bulk-actions animated slideInDown fast\"\n data-cy=\"table-data-grid-header-bulk-actions\"\n >\n <h4>\n <ng-container [ngPlural]=\"selectedItemIds.length\">\n <ng-template ngPluralCase=\"=1\">\n <span translate>1 selected item.</span>\n </ng-template>\n <ng-template ngPluralCase=\"other\">\n <span\n ngNonBindable\n translate\n [translateParams]=\"{ count: selectedItemIds.length }\"\n >\n {{ count }} selected items.\n </span>\n </ng-template>\n </ng-container>\n <br class=\"visible-xs\" />\n @if (!serverSideDataCallback && selectedItemIds.length >= pagination.pageSize) {\n <small>\n <a\n class=\"interact\"\n (click)=\"setAllItemsSelected(true)\"\n c8yProductExperience\n inherit\n [actionData]=\"{ action: PX_ACTIONS.SELECT_ALL_ITEMS }\"\n >\n <span\n ngNonBindable\n translate\n [translateParams]=\"{ count: (dataSource.stats$ | async).filteredSize }\"\n >\n Select all {{ count }} items\n </span>\n </a>\n </small>\n }\n </h4>\n <div class=\"m-l-auto\">\n <div class=\"btnbar d-flex\">\n @for (\n bulkActionControl of bulkActionControls | visibleControls: selectedItemIds | async;\n track $index\n ) {\n <ng-container>\n @switch (bulkActionControl.type) {\n @case (builtInActionType.Export) {\n <button\n class=\"btnbar-btn\"\n title=\"{{ 'Export' | translate }}\"\n type=\"button\"\n (click)=\"bulkActionControl.callback(selectedItemIds, reload.bind(this))\"\n [actionData]=\"{ action: PX_ACTIONS.BULK_EXPORT }\"\n c8yProductExperience\n inherit\n >\n <i c8yIcon=\"sign-out\"></i>\n <span>{{ 'Export' | translate }}</span>\n </button>\n }\n @case (builtInActionType.Delete) {\n <button\n class=\"btnbar-btn\"\n title=\"{{ 'Delete' | translate }}\"\n type=\"button\"\n (click)=\"bulkActionControl.callback(selectedItemIds, reload.bind(this))\"\n [actionData]=\"{ action: PX_ACTIONS.BULK_DELETE }\"\n c8yProductExperience\n inherit\n >\n <i c8yIcon=\"delete\"></i>\n <span>{{ 'Delete' | translate }}</span>\n </button>\n }\n @default {\n <button\n class=\"btnbar-btn\"\n title=\"{{ bulkActionControl.text | translate }}\"\n type=\"button\"\n (click)=\"bulkActionControl.callback(selectedItemIds, reload.bind(this))\"\n [actionData]=\"{\n action: PX_ACTIONS.BULK_CUSTOM_ACTION,\n customActionName: bulkActionControl.text\n }\"\n c8yProductExperience\n inherit\n >\n <i\n [class]=\"bulkActionControl.iconClasses\"\n c8yIcon=\"{{ bulkActionControl.icon }}\"\n ></i>\n <span>{{ bulkActionControl.text | translate }}</span>\n </button>\n }\n }\n </ng-container>\n }\n\n <button\n class=\"btnbar-btn\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"cancel()\"\n [actionData]=\"{\n action: PX_ACTIONS.BULK_CANCEL\n }\"\n c8yProductExperience\n inherit\n >\n <i c8yIcon=\"times\"></i>\n <span>{{ 'Cancel' | translate }}</span>\n </button>\n </div>\n </div>\n </div>\n }\n </div>\n }\n\n <table\n class=\"table table-filtered-sorted table-data-grid large-padding\"\n [class.table-striped]=\"displayOptions.striped && !treeGrid\"\n [class.table-bordered]=\"displayOptions.bordered\"\n [class.table-hover]=\"displayOptions.hover\"\n [class.table-data-grid-with-checkboxes]=\"selectable\"\n [class.table-data-grid-with-actions]=\"actionControls.length > 0\"\n [style.grid-template-columns]=\"styles.gridTemplateColumns\"\n cdk-table\n [dataSource]=\"dataSource\"\n [multiTemplateDataRows]=\"true\"\n (mousemove)=\"resizeHandleContainerMouseMove$.emit($event)\"\n data-cy=\"c8y-data-grid--table\"\n >\n @for (column of columns; track column.name; let i = $index) {\n <ng-container [cdkColumnDef]=\"column.name\">\n @switch (column.name) {\n @case ('checkbox') {\n <th\n cdk-header-cell\n *cdkHeaderCellDef\n data-type=\"icon\"\n >\n <div>\n <label class=\"c8y-checkbox\">\n <input\n [attr.aria-label]=\"'Selected' | translate\"\n type=\"checkbox\"\n [checked]=\"currentPageSelectionState.allSelected\"\n [indeterminate]=\"\n !(\n currentPageSelectionState.allSelected ||\n currentPageSelectionState.allDeselected\n )\n \"\n (change)=\"setAllItemsInCurrentPageSelected($event.target.checked)\"\n c8yProductExperience\n inherit\n [actionData]=\"{ action: PX_ACTIONS.SELECT_ALL_ITEMS }\"\n />\n <span></span>\n </label>\n </div>\n </th>\n\n <td\n cdk-cell\n *cdkCellDef=\"let row\"\n data-type=\"icon\"\n >\n <label class=\"c8y-checkbox\">\n <input\n [attr.aria-label]=\"'Selected' | translate\"\n type=\"checkbox\"\n [checked]=\"isItemSelected(row)\"\n (change)=\"setItemsSelected([row], $event.target.checked)\"\n c8yProductExperience\n inherit\n [actionData]=\"{\n action: PX_ACTIONS.SELECT_ITEM,\n id: row.id\n }\"\n data-cy=\"c8y-data-grid--checkbox\"\n />\n <span></span>\n </label>\n </td>\n }\n\n @case ('radio-button') {\n <th\n cdk-header-cell\n *cdkHeaderCellDef\n data-type=\"icon\"\n ></th>\n\n <td\n cdk-cell\n *cdkCellDef=\"let row\"\n data-type=\"icon\"\n >\n <label class=\"c8y-radio\">\n <input\n [attr.aria-label]=\"'Selected' | translate\"\n name=\"select-row\"\n type=\"radio\"\n [checked]=\"isItemSelected(row)\"\n (change)=\"changeSelectedItem(row)\"\n c8yProductExperience\n inherit\n [actionData]=\"{\n action: PX_ACTIONS.SELECT_ITEM,\n id: row.id\n }\"\n data-cy=\"c8y-data-grid--radio\"\n />\n <span></span>\n </label>\n </td>\n }\n\n @case ('actions') {\n <th\n cdk-header-cell\n *cdkHeaderCellDef\n data-type=\"icon\"\n >\n <p class=\"text-medium sr-only\">{{ 'Actions' | translate }}</p>\n </th>\n\n <td\n cdk-cell\n *cdkCellDef=\"let row\"\n data-type=\"icon\"\n >\n @for (\n actionControl of actionControls\n | visibleControls: row\n | async\n | slice\n : 0\n : ((actionControls | visibleControls: row | async)?.length > 2 ? 1 : 2);\n track $index\n ) {\n <ng-container>\n @switch (actionControl.type) {\n @case (builtInActionType.Edit) {\n <button\n class=\"btn btn-dot\"\n [attr.aria-label]=\"'Edit' | translate\"\n tooltip=\"{{ 'Edit' | translate }}\"\n container=\"body\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"actionControl.callback(row, reload.bind(this))\"\n c8yProductExperience\n inherit\n [actionData]=\"{\n action: PX_ACTIONS.EDIT_ITEM,\n id: row.id\n }\"\n data-cy=\"c8y-data-grid--edit-button-in-row\"\n >\n <i c8yIcon=\"pencil\"></i>\n </button>\n }\n @case (builtInActionType.Delete) {\n <button\n class=\"btn btn-dot btn-dot--danger showOnHover\"\n [attr.aria-label]=\"'Delete' | translate\"\n tooltip=\"{{ 'Delete' | translate }}\"\n container=\"body\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"actionControl.callback(row, reload.bind(this))\"\n [actionData]=\"{\n action: PX_ACTIONS.DELETE_ITEM,\n id: row.id\n }\"\n c8yProductExperience\n inherit\n data-cy=\"c8y-data-grid--remove-button-in-row\"\n >\n <i c8yIcon=\"delete\"></i>\n </button>\n }\n @default {\n <button\n class=\"btn btn-dot\"\n [attr.aria-label]=\"\n (actionControl.icon ? actionControl.text : '') | translate\n \"\n tooltip=\"{{ (actionControl.icon ? actionControl.text : '') | translate }}\"\n container=\"body\"\n type=\"button\"\n [ngClass]=\"{ showOnHover: actionControl.showOnHover }\"\n [delay]=\"500\"\n (click)=\"actionControl.callback(row, reload.bind(this))\"\n [actionData]=\"{\n action: PX_ACTIONS.CUSTOM_ACTION_ITEM,\n customActionName: actionControl.text,\n id: row.id\n }\"\n c8yProductExperience\n inherit\n [attr.data-cy]=\"'c8y-data-grid--button-in-row--' + actionControl.text\"\n >\n @if (actionControl.icon) {\n <i\n c8yIcon=\"{{ actionControl.icon }}\"\n [ngClass]=\"actionControl.iconClasses\"\n ></i>\n } @else {\n <span>{{ actionControl.text | translate }}</span>\n }\n </button>\n }\n }\n </ng-container>\n }\n\n <div\n [ngClass]=\"{\n 'm-l-auto overflow-visible':\n (actionControls | visibleControls: row | async)?.length > 2\n }\"\n >\n @if ((actionControls | visibleControls: row | async)?.length > 2) {\n <div\n class=\"dropdown\"\n placement=\"bottom right\"\n container=\"body\"\n dropdown\n >\n <button\n class=\"dropdown-toggle c8y-dropdown\"\n title=\"{{ 'Actions' | translate }}\"\n aria-haspopup=\"true\"\n type=\"button\"\n data-cy=\"c8y-data-grid--row-actions-dropdown\"\n dropdownToggle\n >\n <i c8yIcon=\"ellipsis-v\"></i>\n </button>\n <ul\n class=\"dropdown-menu dropdown-menu-right\"\n *dropdownMenu\n >\n @for (\n actionControl of actionControls\n | visibleControls: row\n | async\n | slice\n : ((actionControls | visibleControls: row | async)?.length > 2 ? 1 : 2);\n track $index\n ) {\n <li>\n @switch (actionControl.type) {\n @case (builtInActionType.Edit) {\n <button\n title=\"{{ 'Edit' | translate }}\"\n type=\"button\"\n (click)=\"actionControl.callback(row, reload.bind(this))\"\n [actionData]=\"{\n action: PX_ACTIONS.EDIT_ITEM,\n id: row.id\n }\"\n c8yProductExperience\n inherit\n >\n <i c8yIcon=\"pencil\"></i>\n {{ 'Edit' | translate }}\n </button>\n }\n @case (builtInActionType.Delete) {\n <button\n title=\"{{ 'Delete' | translate }}\"\n type=\"button\"\n (click)=\"actionControl.callback(row, reload.bind(this))\"\n [actionData]=\"{\n action: PX_ACTIONS.DELETE_ITEM,\n id: row.id\n }\"\n c8yProductExperience\n inherit\n >\n <i c8yIcon=\"delete\"></i>\n {{ 'Delete' | translate }}\n </button>\n }\n @case (builtInActionType.Export) {\n <button\n title=\"{{ 'Export' | translate }}\"\n type=\"button\"\n (click)=\"actionControl.callback(row, reload.bind(this))\"\n [actionData]=\"{\n action: PX_ACTIONS.EXPORT_ITEM,\n id: row.id\n }\"\n c8yProductExperience\n inherit\n >\n <i c8yIcon=\"data-export\"></i>\n {{ 'Export' | translate }}\n </button>\n }\n @default {\n <button\n title=\"{{ actionControl.text | translate }}\"\n type=\"button\"\n (click)=\"actionControl.callback(row, reload.bind(this))\"\n c8yProductExperience\n inherit\n [actionData]=\"{\n action: PX_ACTIONS.CUSTOM_ACTION_ITEM,\n customActionName: actionControl.text,\n id: row.id\n }\"\n >\n <i\n c8yIcon=\"{{ actionControl.icon }}\"\n [ngClass]=\"actionControl.iconClasses\"\n ></i>\n {{ actionControl.text | translate }}\n </button>\n }\n }\n </li>\n }\n </ul>\n </div>\n }\n </div>\n </td>\n }\n @default {\n <th\n [class.sorted]=\"column.sortOrder\"\n [class.filtered]=\"column | map: isColumnFilteringApplied\"\n [class.hidden]=\"!column.visible\"\n cdk-header-cell\n *cdkHeaderCellDef\n [ngClass]=\"column.headerCSSClassName\"\n [attr.data-type]=\"column.dataType\"\n >\n @if (!column.filterable) {\n <div [title]=\"(column.header | translate) || column.name\">\n @let cellRendererSpec =\n [\n {\n columnName: column.name,\n value: (column.header | translate) || column.name\n }\n ] | map: getHeaderCellRendererSpec : this;\n\n @if (cellRendererSpec) {\n <c8y-cell-renderer [spec]=\"cellRendererSpec\"></c8y-cell-renderer>\n }\n </div>\n }\n\n <!-- isDropDownPlacedRight to be removed when columns are transformed to observables. -->\n @if (column.filterable) {\n <div\n class=\"dropdown\"\n placement=\"bottom {{ isDropDownPlacedRight(column) ? 'right' : 'left' }}\"\n dropdown\n #gridHeaderDropdown=\"bs-dropdown\"\n [cdkTrapFocus]=\"gridHeaderDropdown.isOpen\"\n [insideClick]=\"true\"\n >\n <button\n class=\"btn-header\"\n [title]=\"(column.header | translate) || column.name\"\n type=\"button\"\n [attr.data-cy]=\"'data-grid--header-btn--' + column.header\"\n dropdownToggle\n >\n @let cellRendererSpec =\n [\n {\n columnName: column.name,\n value: (column.header | translate) || column.name\n }\n ] | map: getHeaderCellRendererSpec : this;\n\n @if (cellRendererSpec) {\n <c8y-cell-renderer\n data-cy=\"c8y-data-grid--c8y-cell-renderer\"\n [spec]=\"cellRendererSpec\"\n ></c8y-cell-renderer>\n }\n <i\n c8yIcon=\"filter\"\n title=\"{{ 'Filter' | translate }}\"\n ></i>\n </button>\n\n <!-- isDropDownPlacedRight to be removed when columns are transformed to observables. -->\n <ul\n class=\"dropdown-menu\"\n *dropdownMenu\n [ngClass]=\"{ 'dropdown-menu-right-grid': isDropDownPlacedRight(column) }\"\n (click)=\"$event.stopPropagation()\"\n >\n <li class=\"data-grid__dropdown\">\n @let filteringFormRendererSpec =\n [\n {\n column: column,\n dropdown: gridHeaderDropdown\n }\n ] | map: getFilteringFormRendererSpec : this;\n\n @if (filteringFormRendererSpec) {\n <c8y-filtering-form-renderer\n class=\"bg-component\"\n [spec]=\"filteringFormRendererSpec\"\n data-cy=\"c8y-data-grid--c8y-filtering-form-renderer\"\n ></c8y-filtering-form-renderer>\n }\n </li>\n </ul>\n </div>\n }\n\n @if (column.sortable) {\n <button\n class=\"btn-sort\"\n [style]=\"{\n 'margin-left': !column.filterable && column.sortable ? '-20px' : null\n }\"\n [title]=\"sortColumnTitle | translate: { name: column.header | translate }\"\n type=\"button\"\n (click)=\"changeSortOrder(column.name)\"\n data-cy=\"change-sort-order\"\n >\n @switch (column.sortOrder) {\n @case ('asc') {\n <i c8yIcon=\"long-arrow-up\"></i>\n }\n @case ('desc') {\n <i c8yIcon=\"long-arrow-down\"></i>\n }\n @default {\n <i c8yIcon=\"exchange\"></i>\n }\n }\n </button>\n }\n\n @if (column.resizable) {\n <span\n class=\"resize-handle\"\n (mousedown)=\"\n resizeHandleMouseDown$.emit({ event: $event, targetColumnName: column.name })\n \"\n ></span>\n }\n </th>\n\n <td\n [class.hidden]=\"!column.visible\"\n [attr.data-cell-title]=\"column.header | translate\"\n cdk-cell\n *cdkCellDef=\"let row\"\n [ngClass]=\"column.cellCSSClassName\"\n [attr.data-cy]=\"'data-grid--' + column.header\"\n [attr.data-type]=\"column.dataType\"\n >\n @let cellRendererSpec =\n [\n {\n value: resolveCellValue(row, column.path),\n row: row,\n columnName: column.name\n }\n ] | map: getCellRendererSpec : this;\n\n @if (cellRendererSpec) {\n <c8y-cell-renderer [spec]=\"cellRendererSpec\"></c8y-cell-renderer>\n }\n </td>\n }\n }\n </ng-container>\n }\n\n <ng-container cdkColumnDef=\"infiniteScrollFooter\">\n <td\n [style.grid-column]=\"styles.gridInfiniteScrollColumn\"\n cdk-footer-cell\n *cdkFooterCellDef\n >\n <template #infiniteScrollContainer></template>\n </td>\n </ng-container>\n\n <tr\n cdk-header-row\n *cdkHeaderRowDef=\"columnNames\"\n ></tr>\n\n <tr\n data-cy=\"c8y-data-grid--row-in-data-grid\"\n cdk-row\n *cdkRowDef=\"let row; columns: columnNames; let idx = dataIndex; when: isDataRow\"\n [ngClass]=\"[\n activeClassName && row === lastClickedRow ? activeClassName : '',\n idx % 2 === 0 ? 'even' : 'odd',\n row.level > 0 ? 'data-grid-child-node level-' + row.level : ''\n ]\"\n (mouseover)=\"rowMouseOver.emit(row)\"\n (mouseleave)=\"rowMouseLeave.emit(row)\"\n (click)=\"handleClick(row)\"\n ></tr>\n\n <tr\n class=\"expanded-row\"\n [ngClass]=\"{ hidden: !(expandedRows.get(row).visible$ | async) }\"\n data-cy=\"c8y-data-grid--expanded-row-in-data-grid\"\n cdk-row\n *cdkRowDef=\"let row; columns: ['expanded-row']; when: isRowExpanded\"\n ></tr>\n\n <ng-container cdkColumnDef=\"expanded-row\">\n <td\n [style.grid-column]=\"styles.gridInfiniteScrollColumn\"\n cdk-cell\n *cdkCellDef=\"let row\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n expandableRow?.template;\n context: {\n $implicit: row,\n asyncRenderSuccess: setExpandableRowVisible.bind(this, row, true),\n asyncRenderFail: setExpandableRowVisible.bind(this, row, false)\n }\n \"\n ></ng-container>\n </td>\n </ng-container>\n\n <tr\n [class]=\"'pagination-row level-' + (row.parentRow.level + 1)\"\n cdk-row\n *cdkRowDef=\"let row; columns: ['pagination-row']; when: isPaginationRow\"\n ></tr>\n\n <ng-container cdkColumnDef=\"pagination-row\">\n <td\n [style.grid-column]=\"styles.gridInfiniteScrollColumn\"\n cdk-cell\n *cdkCellDef=\"let row\"\n >\n <div class=\"col-sm-4 no-gutter\">\n @if ((dataSource.stats$ | async).currentPageSize > 0) {\n <div\n class=\"counter p-t-8 p-b-8\"\n data-cy=\"data-grid--child-counter\"\n >\n <span\n class=\"text-muted\"\n ngNonBindable\n translate\n [translateParams]=\"{\n pageFirstItemIdx:\n (row.childrenStats.currentPage - 1) * row.childrenStats.firstPageSize + 1,\n pageLastItemIdx:\n (row.childrenStats.currentPage - 1) * row.childrenStats.firstPageSize +\n 1 +\n (row.childrenStats.currentPageSize - 1),\n itemsTotal: row.childrenStats.filteredSize\n }\"\n >\n {{ pageFirstItemIdx }} - {{ pageLastItemIdx }} of {{ itemsTotal }}\n </span>\n <span class=\"text-muted text-12 m-r-4\">{{ 'Parent node' | translate }}</span>\n <span class=\"tag tag--default\">{{ row.parentRow?.[parentNodeLabelProperty] }}</span>\n </div>\n }\n </div>\n <div class=\"col-sm-4 col-sm-offset-4 no-gutter text-right\">\n @if (row.childrenStats.filteredSize > row.childrenStats.currentPageSize) {\n <pagination\n class=\"d-flex j-c-end\"\n [ngModel]=\"row.childrenStats.currentPage\"\n (pageChanged)=\"updateChildPagination($event, row)\"\n [totalItems]=\"row.childrenStats.filteredSize\"\n [itemsPerPage]=\"row?.parentRow?.pagination?.pageSize ?? childNodePagination.pageSize\"\n [maxSize]=\"5\"\n [boundaryLinks]=\"false\"\n [previousText]=\"'Previous' | translate\"\n [nextText]=\"'Next' | translate\"\n ></pagination>\n }\n </div>\n </td>\n </ng-container>\n\n <ng-container>\n <tr\n [ngClass]=\"{ hidden: !infiniteScroll }\"\n cdk-footer-row\n *cdkFooterRowDef=\"['infiniteScrollFooter']\"\n ></tr>\n </ng-container>\n </table>\n\n @if (\n !(dataSource.loading$ | async) &&\n !loading &&\n ((dataSource.stats$ | async).filteredSize === 0 || (dataSource.data$ | async).length === 0)\n ) {\n <div class=\"d-flex m-0 p-t-40 p-b-40\">\n <div class=\"col-lg-3 col-sm-4 m-l-auto m-r-auto\">\n <ng-content select=\"c8y-ui-empty-state, .c8y-empty-state\"></ng-content>\n <ng-container\n *ngTemplateOutlet=\"\n emptyState?.templateRef;\n context: { $implicit: emptyStateContext$ | async }\n \"\n ></ng-container>\n </div>\n </div>\n }\n\n @if (pagination && !infiniteScroll) {\n <div class=\"table-data-grid-footer separator large-padding\">\n <div class=\"col-sm-4 no-gutter\">\n @if ((dataSource.stats$ | async).currentPageSize > 0) {\n <div\n class=\"counter p-t-8 p-b-8\"\n data-cy=\"data-grid--counter\"\n >\n <span\n class=\"text-muted\"\n ngNonBindable\n translate\n [translateParams]=\"paginationLabelParams\"\n >\n {{ pageFirstItemIdx }} - {{ pageLastItemIdx }} of {{ itemsTotal }}\n </span>\n </div>\n }\n </div>\n\n <div class=\"col-sm-4 no-gutter text-center\">\n @if ((dataSource.stats$ | async).filteredSize > minPossiblePageSize) {\n <div class=\"form-group form-inline p-t-8 p-b-8\">\n <label\n class=\"m-r-4\"\n for=\"filteredSize\"\n >\n {{ 'Items per page' | translate }}\n </label>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control\"\n id=\"filteredSize\"\n data-cy=\"data-grid--pagesize-options\"\n [ngModel]=\"pagination.pageSize\"\n (ngModelChange)=\"\n updatePagination({ itemsPerPage: $event, page: pagination.currentPage })\n \"\n >\n @for (pageSize of possiblePageSizes; track $index) {\n <option [ngValue]=\"pageSize\">\n {{ pageSize }}\n </option>\n }\n </select>\n </div>\n </div>\n }\n </div>\n\n <div class=\"col-sm-4 no-gutter text-right\">\n @if ((dataSource.stats$ | async).filteredSize > 0) {\n <pagination\n [class.hidden]=\"hidePagination$ | async\"\n class=\"d-flex j-c-end\"\n [ngModel]=\"pagination.currentPage\"\n (pageChanged)=\"updatePagination($event)\"\n [totalItems]=\"(dataSource.stats$ | async).filteredSize\"\n [itemsPerPage]=\"pagination.pageSize\"\n (numPages)=\"totalPagesCount$.next($event)\"\n [maxSize]=\"5\"\n [boundaryLinks]=\"false\"\n [previousText]=\"'Previous' | translate\"\n [nextText]=\"'Next' | translate\"\n ></pagination>\n }\n </div>\n </div>\n }\n</div>\n" }]
|
|
35336
|
+
], template: "@let loadingData = ((dataSource.loading$ | async) && !loadMoreComponent?.isLoading) || loading;\n\n<div\n class=\"table-data-grid-scroll\"\n #scroll\n [ngClass]=\"{\n 'table-data-grid__overlay': loadingData\n }\"\n data-cy=\"c8y-data-grid--table-data-grid-scroll\"\n>\n @if (loadingData && displayOptions.showLoadingIndicator) {\n <div class=\"table-data-grid__loading--wrapper\">\n <div class=\"table-data-grid__loading--loader\">\n <c8y-loading\n layout=\"application\"\n [message]=\"loadingItemsLabel\"\n ></c8y-loading>\n </div>\n </div>\n }\n\n @if (displayOptions.gridHeader) {\n <div class=\"table-data-grid-header separator large-padding\">\n <div\n class=\"h4\"\n [ngClass]=\"{ 'm-r-16': !!title }\"\n >\n {{ title | translate }}\n </div>\n\n @if (displayOptions.filter) {\n @if (!filteringApplied) {\n <span>\n @if (!!filteringLabelsParams.allItemsCount) {\n <small\n class=\"m-r-4\"\n ngNonBindable\n translate\n [translateParams]=\"filteringLabelsParams\"\n >\n {{ filteredItemsCount }} of {{ allItemsCount }} items\n </small>\n }\n <span\n class=\"label label-default m-r-4\"\n translate\n >\n No filters\n </span>\n </span>\n }\n @if (filteringApplied) {\n <span class=\"d-flex a-i-center\">\n @if (!!filteringLabelsParams.allItemsCount) {\n <div class=\"a-i-center\">\n <span class=\"badge badge-info m-r-4\">\n {{ (dataSource.stats$ | async).filteredSize }}\n </span>\n <small\n ngNonBindable\n translate\n [translateParams]=\"filteringLabelsParams\"\n >\n of {{ allItemsCount }} items\n </small>\n </div>\n }\n <div\n class=\"dropdown\"\n placement=\"bottom left\"\n dropdown\n #ddFilters=\"bs-dropdown\"\n [cdkTrapFocus]=\"ddFilters.isOpen\"\n [insideClick]=\"true\"\n >\n <button\n class=\"btn btn-default btn-sm m-l-8\"\n title=\"{{ 'Active filters' | translate }}\"\n aria-haspopup=\"true\"\n dropdownToggle\n data-cy=\"c8y-data-grid--filters\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"filter\"\n ></i>\n <span>{{ 'Active filters' | translate }}</span>\n <span class=\"badge badge-system\">\n {{ columnsWithFiltersApplied.length }}\n </span>\n </button>\n\n <div\n class=\"dropdown-menu\"\n *dropdownMenu\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"data-grid__dropdown bg-level-0\">\n <ul class=\"list-unstyled m-0\">\n @for (column of columnsWithFiltersApplied; track $index; let last = $last) {\n <li [ngClass]=\"{ 'separator-bottom': !last }\">\n <ng-container>\n <div\n class=\"dropdown-header sticky-top text-truncate no-border-top p-b-0\"\n title=\"{{ (column.header | translate) || column.name }}\"\n >\n <label>\n {{ (column.header | translate) || column.name }}\n </label>\n </div>\n @for (\n groupedFilterChips of column\n | mapToFilterChips\n | async\n | groupedFilterChips;\n track $index;\n let first = $first\n ) {\n <div\n class=\"list-group-item borderless d-flex d-col\"\n [ngClass]=\"{ 'p-t-0': first }\"\n >\n @if (groupedFilterChips.label) {\n <p class=\"small p-b-4\">\n {{ groupedFilterChips.label | translate }}\n </p>\n }\n <div class=\"d-flex a-i-center gap-4 flex-wrap\">\n @for (chip of groupedFilterChips.chips; track $index) {\n <span class=\"tag tag--info chip\">\n <button\n class=\"btn btn-xs btn-clean text-10 m-r-4\"\n title=\"{{ 'Remove filter' | translate }}\"\n (click)=\"removeFilter(chip.remove())\"\n data-cy=\"c8y-data-grid--remove-chip\"\n >\n <i c8yIcon=\"times\"></i>\n </button>\n {{ chip.displayValue | translate }}\n </span>\n }\n </div>\n </div>\n }\n </ng-container>\n </li>\n }\n </ul>\n </div>\n <div class=\"list-group-item separator-top sticky-bottom\">\n <button\n class=\"btn btn-sm btn-default\"\n title=\"{{ 'Clear all filters' | translate }}\"\n type=\"button\"\n (click)=\"clearFilters()\"\n data-cy=\"c8y-data-grid--clear-filters\"\n >\n {{ 'Clear all filters' | translate }}\n </button>\n </div>\n </div>\n </div>\n </span>\n }\n\n @if (displayOptions.filter) {\n <button\n class=\"btn-help btn-help--sm hidden-xs hidden-sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"filtersHelpPopover\"\n placement=\"right\"\n triggers=\"focus\"\n type=\"button\"\n data-cy=\"data-grid--help-filters\"\n >\n <i c8yIcon=\"question-circle-o\"></i>\n </button>\n }\n <ng-template #filtersHelpPopover>\n <div [innerHtml]=\"filtersHelpPopoverHtml | translate\"></div>\n </ng-template>\n\n @if (showCounterWarning) {\n <button\n class=\"btn-clean text-primary hidden-xs hidden-sm\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{\n 'The counter for the total number of items might be inaccurate.' | translate\n }}\"\n placement=\"right\"\n triggers=\"focus\"\n type=\"button\"\n >\n <i c8yIcon=\"warning\"></i>\n </button>\n }\n }\n\n <div class=\"m-l-auto\">\n <div class=\"btnbar d-flex a-i-center\">\n @for (\n headerActionControl of headerActionControls | visibleControls | async;\n track $index\n ) {\n <ng-container>\n @if (!headerActionControl.template) {\n <button\n class=\"btnbar-btn btn-link\"\n title=\"{{ headerActionControl.text | translate }}\"\n type=\"button\"\n (click)=\"headerActionControl.callback()\"\n c8yProductExperience\n inherit\n [actionData]=\"{\n action: PX_ACTIONS.CUSTOM_ACTION,\n customActionName: headerActionControl.text,\n type: headerActionControl.type\n }\"\n >\n <i\n class=\"m-r-4\"\n [c8yIcon]=\"headerActionControl.icon\"\n ></i>\n <span>{{ headerActionControl.text | translate }}</span>\n </button>\n } @else {\n <ng-container\n *ngTemplateOutlet=\"\n headerActionControl.template;\n context: { headerActionControl: headerActionControl }\n \"\n ></ng-container>\n }\n </ng-container>\n }\n\n @if (configureColumnsEnabled) {\n <div\n class=\"dropdown\"\n placement=\"bottom left\"\n dropdown\n #ddConfigureColumns=\"bs-dropdown\"\n [cdkTrapFocus]=\"ddConfigureColumns.isOpen\"\n [insideClick]=\"true\"\n >\n <button\n class=\"btnbar-btn\"\n title=\"{{ 'Configure columns' | translate }}\"\n type=\"button\"\n data-cy=\"data-grid--custom-column-btn\"\n dropdownToggle\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"columns\"\n ></i>\n <span>{{ 'Configure columns' | translate }}</span>\n </button>\n\n <ul\n class=\"dropdown-menu data-grid__dropdown\"\n *dropdownMenu\n (click)=\"$event.stopPropagation()\"\n >\n <li>\n <div\n class=\"list-group m-0\"\n cdkDropList\n (cdkDropListDropped)=\"onColumnDrop($event)\"\n >\n @for (column of columns; track $index) {\n <div\n cdkDrag\n cdkDragLockAxis=\"y\"\n >\n @if (!column.positionFixed) {\n <div class=\"list-group-item draggable-after p-l-16 p-r-16 a-i-center\">\n <label\n class=\"c8y-checkbox min-width-0\"\n title=\"{{ column.custom ? ('Custom' | translate) + ' ' : '' }}{{\n (column.header | translate) || column.name\n }}\"\n [attr.data-cy]=\"'data-grid--custom-column-header-' + column.header\"\n >\n <input\n type=\"checkbox\"\n [(ngModel)]=\"column.visible\"\n (change)=\"\n updateGridColumnsSize();\n emitConfigChange('changeColumnVisibility')\n \"\n c8yProductExperience\n inherit\n [actionData]=\"{\n action: PX_ACTIONS.CHANGE_VISIBILITY,\n column: column.name,\n visible: !column.visible\n }\"\n />\n <span></span>\n <div class=\"d-col min-width-0 m-l-8 m-r-8\">\n @if (column?.custom) {\n <span class=\"text-muted text-10 m-b-0\">\n {{ 'Custom' | translate }}\n </span>\n }\n <span class=\"text-truncate l-h-1 m-t-2\">\n {{ (column.header | translate) || column.name }}\n </span>\n </div>\n @let canRetrieve = canRetrieveAssetProperties | async;\n @if (canRetrieve) {\n @if (canRetrieve && column?.type) {\n <span\n class=\"tag tag--default a-s-end\"\n title=\"{{ column.type | translate | humanize }}\"\n >\n {{ column.type | translate | humanize }}\n </span>\n }\n }\n </label>\n @if (column.custom) {\n <button\n class=\"btn btn-dot btn-dot--danger showOnHover max-width-fit a-i-center\"\n [attr.aria-label]=\"'Remove`column,verb`' | translate\"\n [popover]=\"confirmRemovePopover\"\n type=\"button\"\n #pop=\"bs-popover\"\n (click)=\"\n currentRemoveCustomColumnPopover !== pop &&\n currentRemoveCustomColumnPopover?.hide();\n currentRemoveCustomColumnPopover = pop\n \"\n >\n <i\n c8yIcon=\"minus-circle\"\n data-cy=\"data-grid--custom-column-remove-btn\"\n ></i>\n </button>\n\n <ng-template #confirmRemovePopover>\n <h3 class=\"popover-title popover-header\">\n {{ 'Confirm removal' | translate }}\n </h3>\n <div class=\"popover-content popover-body\">\n <p>{{ 'Do you want to remove this column?' | translate }}</p>\n <div class=\"popover-footer gap-16\">\n <button\n class=\"btn btn-default btn-sm\"\n type=\"button\"\n (click)=\"pop.hide()\"\n >\n {{ 'Cancel' | translate }}\n </button>\n <button\n class=\"btn btn-danger btn-sm\"\n type=\"button\"\n (click)=\"confirmRemoveColumn(column); pop.hide()\"\n data-cy=\"popover-confirm--Remove\"\n >\n {{ 'Remove' | translate }}\n </button>\n </div>\n </div>\n </ng-template>\n }\n </div>\n }\n </div>\n }\n </div>\n </li>\n @if (isConfigContextKnown) {\n <li class=\"p-8 sticky-bottom separator-top\">\n <button\n class=\"btn btn-default btn-block\"\n title=\"{{ 'Add custom column' | translate }}\"\n type=\"button\"\n data-cy=\"data-grid--add-custom-column\"\n (click)=\"openCustomColumn(); ddConfigureColumns.hide()\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"plus-circle\"\n ></i>\n <span>{{ 'Add custom column' | translate }}</span>\n </button>\n </li>\n }\n </ul>\n </div>\n }\n\n @if (!hideReload) {\n <button\n class=\"btnbar-btn btn-link\"\n title=\"{{ 'Reload' | translate }}\"\n type=\"button\"\n data-cy=\"data-grid--reload-btn\"\n [disabled]=\"dataSource.loading$ | async\"\n (click)=\"clickReload()\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"refresh\"\n ></i>\n <span>{{ 'Reload' | translate }}</span>\n </button>\n }\n\n @if (!serverSideDataCallback || showSearch) {\n <div class=\"input-group input-group-search m-l-sm-16 data-grid__search-input\">\n <input\n class=\"form-control\"\n placeholder=\"{{ 'Search\u2026' | translate }}\"\n type=\"search\"\n [(ngModel)]=\"searchText\"\n (ngModelChange)=\"searchText$.emit($event)\"\n (keydown.enter)=\"$event.stopPropagation(); performSearch(searchText)\"\n />\n <div class=\"input-group-addon\">\n @if (searchText.length === 0) {\n <i c8yIcon=\"search\"></i>\n }\n @if (searchText.length > 0) {\n <i\n class=\"pointer\"\n c8yIcon=\"times\"\n (click)=\"searchText = ''; searchText$.emit('')\"\n c8yProductExperience\n inherit\n [actionData]=\"{ action: PX_ACTIONS.CLEAR_SEARCH }\"\n ></i>\n }\n </div>\n </div>\n }\n </div>\n </div>\n @if (selectedItemIds.length !== 0) {\n <div\n class=\"table-data-grid-header-bulk-actions animated slideInDown fast\"\n data-cy=\"table-data-grid-header-bulk-actions\"\n >\n <h4>\n <ng-container [ngPlural]=\"selectedItemIds.length\">\n <ng-template ngPluralCase=\"=1\">\n <span translate>1 selected item.</span>\n </ng-template>\n <ng-template ngPluralCase=\"other\">\n <span\n ngNonBindable\n translate\n [translateParams]=\"{ count: selectedItemIds.length }\"\n >\n {{ count }} selected items.\n </span>\n </ng-template>\n </ng-container>\n <br class=\"visible-xs\" />\n @if (!serverSideDataCallback && selectedItemIds.length >= pagination.pageSize) {\n <small>\n <a\n class=\"interact\"\n (click)=\"setAllItemsSelected(true)\"\n c8yProductExperience\n inherit\n [actionData]=\"{ action: PX_ACTIONS.SELECT_ALL_ITEMS }\"\n >\n <span\n ngNonBindable\n translate\n [translateParams]=\"{ count: (dataSource.stats$ | async).filteredSize }\"\n >\n Select all {{ count }} items\n </span>\n </a>\n </small>\n }\n </h4>\n <div class=\"m-l-auto\">\n <div class=\"btnbar d-flex\">\n @for (\n bulkActionControl of bulkActionControls | visibleControls: selectedItemIds | async;\n track $index\n ) {\n <ng-container>\n @switch (bulkActionControl.type) {\n @case (builtInActionType.Export) {\n <button\n class=\"btnbar-btn\"\n title=\"{{ 'Export' | translate }}\"\n type=\"button\"\n (click)=\"bulkActionControl.callback(selectedItemIds, reload.bind(this))\"\n [actionData]=\"{ action: PX_ACTIONS.BULK_EXPORT }\"\n c8yProductExperience\n inherit\n >\n <i c8yIcon=\"sign-out\"></i>\n <span>{{ 'Export' | translate }}</span>\n </button>\n }\n @case (builtInActionType.Delete) {\n <button\n class=\"btnbar-btn\"\n title=\"{{ 'Delete' | translate }}\"\n type=\"button\"\n (click)=\"bulkActionControl.callback(selectedItemIds, reload.bind(this))\"\n [actionData]=\"{ action: PX_ACTIONS.BULK_DELETE }\"\n c8yProductExperience\n inherit\n >\n <i c8yIcon=\"delete\"></i>\n <span>{{ 'Delete' | translate }}</span>\n </button>\n }\n @default {\n <button\n class=\"btnbar-btn\"\n title=\"{{ bulkActionControl.text | translate }}\"\n type=\"button\"\n (click)=\"bulkActionControl.callback(selectedItemIds, reload.bind(this))\"\n [actionData]=\"{\n action: PX_ACTIONS.BULK_CUSTOM_ACTION,\n customActionName: bulkActionControl.text\n }\"\n c8yProductExperience\n inherit\n >\n <i\n [class]=\"bulkActionControl.iconClasses\"\n c8yIcon=\"{{ bulkActionControl.icon }}\"\n ></i>\n <span>{{ bulkActionControl.text | translate }}</span>\n </button>\n }\n }\n </ng-container>\n }\n\n <button\n class=\"btnbar-btn\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"cancel()\"\n [actionData]=\"{\n action: PX_ACTIONS.BULK_CANCEL\n }\"\n c8yProductExperience\n inherit\n >\n <i c8yIcon=\"times\"></i>\n <span>{{ 'Cancel' | translate }}</span>\n </button>\n </div>\n </div>\n </div>\n }\n </div>\n }\n\n <table\n class=\"table table-filtered-sorted table-data-grid large-padding\"\n [class.table-striped]=\"displayOptions.striped && !treeGrid\"\n [class.table-bordered]=\"displayOptions.bordered\"\n [class.table-hover]=\"displayOptions.hover\"\n [class.table-data-grid-with-checkboxes]=\"selectable\"\n [class.table-data-grid-with-actions]=\"actionControls.length > 0\"\n [style.grid-template-columns]=\"styles.gridTemplateColumns\"\n cdk-table\n [dataSource]=\"dataSource\"\n [multiTemplateDataRows]=\"true\"\n (mousemove)=\"resizeHandleContainerMouseMove$.emit($event)\"\n data-cy=\"c8y-data-grid--table\"\n >\n @for (column of columns; track column.name; let i = $index) {\n <ng-container [cdkColumnDef]=\"column.name\">\n @switch (column.name) {\n @case ('checkbox') {\n <th\n cdk-header-cell\n *cdkHeaderCellDef\n data-type=\"icon\"\n >\n <div>\n <label class=\"c8y-checkbox\">\n <input\n [attr.aria-label]=\"'Selected' | translate\"\n type=\"checkbox\"\n [checked]=\"currentPageSelectionState.allSelected\"\n [indeterminate]=\"\n !(\n currentPageSelectionState.allSelected ||\n currentPageSelectionState.allDeselected\n )\n \"\n (change)=\"setAllItemsInCurrentPageSelected($event.target.checked)\"\n c8yProductExperience\n inherit\n [actionData]=\"{ action: PX_ACTIONS.SELECT_ALL_ITEMS }\"\n />\n <span></span>\n </label>\n </div>\n </th>\n\n <td\n cdk-cell\n *cdkCellDef=\"let row\"\n data-type=\"icon\"\n >\n <label class=\"c8y-checkbox\">\n <input\n [attr.aria-label]=\"'Selected' | translate\"\n type=\"checkbox\"\n [checked]=\"isItemSelected(row)\"\n (change)=\"setItemsSelected([row], $event.target.checked)\"\n c8yProductExperience\n inherit\n [actionData]=\"{\n action: PX_ACTIONS.SELECT_ITEM,\n id: row.id\n }\"\n data-cy=\"c8y-data-grid--checkbox\"\n />\n <span></span>\n </label>\n </td>\n }\n\n @case ('radio-button') {\n <th\n cdk-header-cell\n *cdkHeaderCellDef\n data-type=\"icon\"\n ></th>\n\n <td\n cdk-cell\n *cdkCellDef=\"let row\"\n data-type=\"icon\"\n >\n <label class=\"c8y-radio\">\n <input\n [attr.aria-label]=\"'Selected' | translate\"\n name=\"select-row\"\n type=\"radio\"\n [checked]=\"isItemSelected(row)\"\n (change)=\"changeSelectedItem(row)\"\n c8yProductExperience\n inherit\n [actionData]=\"{\n action: PX_ACTIONS.SELECT_ITEM,\n id: row.id\n }\"\n data-cy=\"c8y-data-grid--radio\"\n />\n <span></span>\n </label>\n </td>\n }\n\n @case ('actions') {\n <th\n cdk-header-cell\n *cdkHeaderCellDef\n data-type=\"icon\"\n >\n <p class=\"text-medium sr-only\">{{ 'Actions' | translate }}</p>\n </th>\n\n <td\n cdk-cell\n *cdkCellDef=\"let row\"\n data-type=\"icon\"\n >\n @for (\n actionControl of actionControls\n | visibleControls: row\n | async\n | slice\n : 0\n : ((actionControls | visibleControls: row | async)?.length > 2 ? 1 : 2);\n track $index\n ) {\n <ng-container>\n @switch (actionControl.type) {\n @case (builtInActionType.Edit) {\n <button\n class=\"btn btn-dot\"\n [attr.aria-label]=\"'Edit' | translate\"\n tooltip=\"{{ 'Edit' | translate }}\"\n container=\"body\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"actionControl.callback(row, reload.bind(this))\"\n c8yProductExperience\n inherit\n [actionData]=\"{\n action: PX_ACTIONS.EDIT_ITEM,\n id: row.id\n }\"\n data-cy=\"c8y-data-grid--edit-button-in-row\"\n >\n <i c8yIcon=\"pencil\"></i>\n </button>\n }\n @case (builtInActionType.Delete) {\n <button\n class=\"btn btn-dot btn-dot--danger showOnHover\"\n [attr.aria-label]=\"'Delete' | translate\"\n tooltip=\"{{ 'Delete' | translate }}\"\n container=\"body\"\n type=\"button\"\n [delay]=\"500\"\n (click)=\"actionControl.callback(row, reload.bind(this))\"\n [actionData]=\"{\n action: PX_ACTIONS.DELETE_ITEM,\n id: row.id\n }\"\n c8yProductExperience\n inherit\n data-cy=\"c8y-data-grid--remove-button-in-row\"\n >\n <i c8yIcon=\"delete\"></i>\n </button>\n }\n @default {\n <button\n class=\"btn btn-dot\"\n [attr.aria-label]=\"\n (actionControl.icon ? actionControl.text : '') | translate\n \"\n tooltip=\"{{ (actionControl.icon ? actionControl.text : '') | translate }}\"\n container=\"body\"\n type=\"button\"\n [ngClass]=\"{ showOnHover: actionControl.showOnHover }\"\n [delay]=\"500\"\n (click)=\"actionControl.callback(row, reload.bind(this))\"\n [actionData]=\"{\n action: PX_ACTIONS.CUSTOM_ACTION_ITEM,\n customActionName: actionControl.text,\n id: row.id\n }\"\n c8yProductExperience\n inherit\n [attr.data-cy]=\"'c8y-data-grid--button-in-row--' + actionControl.text\"\n >\n @if (actionControl.icon) {\n <i\n c8yIcon=\"{{ actionControl.icon }}\"\n [ngClass]=\"actionControl.iconClasses\"\n ></i>\n } @else {\n <span>{{ actionControl.text | translate }}</span>\n }\n </button>\n }\n }\n </ng-container>\n }\n\n <div\n [ngClass]=\"{\n 'm-l-auto overflow-visible':\n (actionControls | visibleControls: row | async)?.length > 2\n }\"\n >\n @if ((actionControls | visibleControls: row | async)?.length > 2) {\n <div\n class=\"dropdown\"\n placement=\"bottom right\"\n container=\"body\"\n dropdown\n >\n <button\n class=\"dropdown-toggle c8y-dropdown\"\n title=\"{{ 'Actions' | translate }}\"\n aria-haspopup=\"true\"\n type=\"button\"\n data-cy=\"c8y-data-grid--row-actions-dropdown\"\n dropdownToggle\n >\n <i c8yIcon=\"ellipsis-v\"></i>\n </button>\n <ul\n class=\"dropdown-menu dropdown-menu-right\"\n *dropdownMenu\n >\n @for (\n actionControl of actionControls\n | visibleControls: row\n | async\n | slice\n : ((actionControls | visibleControls: row | async)?.length > 2 ? 1 : 2);\n track $index\n ) {\n <li>\n @switch (actionControl.type) {\n @case (builtInActionType.Edit) {\n <button\n title=\"{{ 'Edit' | translate }}\"\n type=\"button\"\n (click)=\"actionControl.callback(row, reload.bind(this))\"\n [actionData]=\"{\n action: PX_ACTIONS.EDIT_ITEM,\n id: row.id\n }\"\n c8yProductExperience\n inherit\n >\n <i c8yIcon=\"pencil\"></i>\n {{ 'Edit' | translate }}\n </button>\n }\n @case (builtInActionType.Delete) {\n <button\n title=\"{{ 'Delete' | translate }}\"\n type=\"button\"\n (click)=\"actionControl.callback(row, reload.bind(this))\"\n [actionData]=\"{\n action: PX_ACTIONS.DELETE_ITEM,\n id: row.id\n }\"\n c8yProductExperience\n inherit\n >\n <i c8yIcon=\"delete\"></i>\n {{ 'Delete' | translate }}\n </button>\n }\n @case (builtInActionType.Export) {\n <button\n title=\"{{ 'Export' | translate }}\"\n type=\"button\"\n (click)=\"actionControl.callback(row, reload.bind(this))\"\n [actionData]=\"{\n action: PX_ACTIONS.EXPORT_ITEM,\n id: row.id\n }\"\n c8yProductExperience\n inherit\n >\n <i c8yIcon=\"data-export\"></i>\n {{ 'Export' | translate }}\n </button>\n }\n @default {\n <button\n title=\"{{ actionControl.text | translate }}\"\n type=\"button\"\n (click)=\"actionControl.callback(row, reload.bind(this))\"\n c8yProductExperience\n inherit\n [actionData]=\"{\n action: PX_ACTIONS.CUSTOM_ACTION_ITEM,\n customActionName: actionControl.text,\n id: row.id\n }\"\n >\n <i\n c8yIcon=\"{{ actionControl.icon }}\"\n [ngClass]=\"actionControl.iconClasses\"\n ></i>\n {{ actionControl.text | translate }}\n </button>\n }\n }\n </li>\n }\n </ul>\n </div>\n }\n </div>\n </td>\n }\n @default {\n <th\n [class.sorted]=\"column.sortOrder\"\n [class.filtered]=\"column | map: isColumnFilteringApplied\"\n [class.hidden]=\"!column.visible\"\n cdk-header-cell\n *cdkHeaderCellDef\n [ngClass]=\"column.headerCSSClassName\"\n [attr.data-type]=\"column.dataType\"\n >\n @if (!column.filterable) {\n <div [title]=\"(column.header | translate) || column.name\">\n @let cellRendererSpec =\n [\n {\n columnName: column.name,\n value: (column.header | translate) || column.name\n }\n ] | map: getHeaderCellRendererSpec : this;\n\n @if (cellRendererSpec) {\n <c8y-cell-renderer [spec]=\"cellRendererSpec\"></c8y-cell-renderer>\n }\n </div>\n }\n\n <!-- isDropDownPlacedRight to be removed when columns are transformed to observables. -->\n @if (column.filterable) {\n <div\n class=\"dropdown\"\n placement=\"bottom {{ isDropDownPlacedRight(column) ? 'right' : 'left' }}\"\n dropdown\n #gridHeaderDropdown=\"bs-dropdown\"\n [cdkTrapFocus]=\"gridHeaderDropdown.isOpen\"\n [insideClick]=\"true\"\n >\n <button\n class=\"btn-header\"\n [title]=\"(column.header | translate) || column.name\"\n type=\"button\"\n [attr.data-cy]=\"'data-grid--header-btn--' + column.header\"\n dropdownToggle\n >\n @let cellRendererSpec =\n [\n {\n columnName: column.name,\n value: (column.header | translate) || column.name\n }\n ] | map: getHeaderCellRendererSpec : this;\n\n @if (cellRendererSpec) {\n <c8y-cell-renderer\n data-cy=\"c8y-data-grid--c8y-cell-renderer\"\n [spec]=\"cellRendererSpec\"\n ></c8y-cell-renderer>\n }\n <i\n c8yIcon=\"filter\"\n title=\"{{ 'Filter' | translate }}\"\n ></i>\n </button>\n\n <!-- isDropDownPlacedRight to be removed when columns are transformed to observables. -->\n <ul\n class=\"dropdown-menu\"\n *dropdownMenu\n [ngClass]=\"{ 'dropdown-menu-right-grid': isDropDownPlacedRight(column) }\"\n (click)=\"$event.stopPropagation()\"\n >\n <li class=\"data-grid__dropdown\">\n @let filteringFormRendererSpec =\n [\n {\n column: column,\n dropdown: gridHeaderDropdown\n }\n ] | map: getFilteringFormRendererSpec : this;\n\n @if (filteringFormRendererSpec) {\n <c8y-filtering-form-renderer\n class=\"bg-component\"\n [spec]=\"filteringFormRendererSpec\"\n data-cy=\"c8y-data-grid--c8y-filtering-form-renderer\"\n ></c8y-filtering-form-renderer>\n }\n </li>\n </ul>\n </div>\n }\n\n @if (column.sortable) {\n <button\n class=\"btn-sort\"\n [style]=\"{\n 'margin-left': !column.filterable && column.sortable ? '-20px' : null\n }\"\n [title]=\"sortColumnTitle | translate: { name: column.header | translate }\"\n type=\"button\"\n (click)=\"changeSortOrder(column.name)\"\n data-cy=\"change-sort-order\"\n >\n @switch (column.sortOrder) {\n @case ('asc') {\n <i c8yIcon=\"long-arrow-up\"></i>\n }\n @case ('desc') {\n <i c8yIcon=\"long-arrow-down\"></i>\n }\n @default {\n <i c8yIcon=\"exchange\"></i>\n }\n }\n </button>\n }\n\n @if (column.resizable) {\n <span\n class=\"resize-handle\"\n (mousedown)=\"\n resizeHandleMouseDown$.emit({ event: $event, targetColumnName: column.name })\n \"\n ></span>\n }\n </th>\n\n <td\n [class.hidden]=\"!column.visible\"\n [attr.data-cell-title]=\"column.header | translate\"\n cdk-cell\n *cdkCellDef=\"let row\"\n [ngClass]=\"column.cellCSSClassName\"\n [attr.data-cy]=\"'data-grid--' + column.header\"\n [attr.data-type]=\"column.dataType\"\n >\n @let cellRendererSpec =\n [\n {\n value: resolveCellValue(row, column.path),\n row: row,\n columnName: column.name\n }\n ] | map: getCellRendererSpec : this;\n\n @if (cellRendererSpec) {\n <c8y-cell-renderer [spec]=\"cellRendererSpec\"></c8y-cell-renderer>\n }\n </td>\n }\n }\n </ng-container>\n }\n\n <ng-container cdkColumnDef=\"infiniteScrollFooter\">\n <td\n [style.grid-column]=\"styles.gridInfiniteScrollColumn\"\n cdk-footer-cell\n *cdkFooterCellDef\n >\n <template #infiniteScrollContainer></template>\n </td>\n </ng-container>\n\n <tr\n cdk-header-row\n *cdkHeaderRowDef=\"columnNames\"\n ></tr>\n\n <tr\n data-cy=\"c8y-data-grid--row-in-data-grid\"\n cdk-row\n *cdkRowDef=\"let row; columns: columnNames; let idx = dataIndex; when: isDataRow\"\n [ngClass]=\"[\n activeClassName && row === lastClickedRow ? activeClassName : '',\n idx % 2 === 0 ? 'even' : 'odd',\n row.level > 0 ? 'data-grid-child-node level-' + row.level : ''\n ]\"\n (mouseover)=\"rowMouseOver.emit(row)\"\n (mouseleave)=\"rowMouseLeave.emit(row)\"\n (click)=\"handleClick(row)\"\n ></tr>\n\n <tr\n class=\"expanded-row\"\n [ngClass]=\"{ hidden: !(expandedRows.get(row).visible$ | async) }\"\n data-cy=\"c8y-data-grid--expanded-row-in-data-grid\"\n cdk-row\n *cdkRowDef=\"let row; columns: ['expanded-row']; when: isRowExpanded\"\n ></tr>\n\n <ng-container cdkColumnDef=\"expanded-row\">\n <td\n [style.grid-column]=\"styles.gridInfiniteScrollColumn\"\n cdk-cell\n *cdkCellDef=\"let row\"\n >\n <ng-container\n *ngTemplateOutlet=\"\n expandableRow?.template;\n context: {\n $implicit: row,\n asyncRenderSuccess: setExpandableRowVisible.bind(this, row, true),\n asyncRenderFail: setExpandableRowVisible.bind(this, row, false)\n }\n \"\n ></ng-container>\n </td>\n </ng-container>\n\n <tr\n [class]=\"'pagination-row level-' + (row.parentRow.level + 1)\"\n cdk-row\n *cdkRowDef=\"let row; columns: ['pagination-row']; when: isPaginationRow\"\n ></tr>\n\n <ng-container cdkColumnDef=\"pagination-row\">\n <td\n [style.grid-column]=\"styles.gridInfiniteScrollColumn\"\n cdk-cell\n *cdkCellDef=\"let row\"\n >\n <div class=\"col-sm-4 no-gutter\">\n @if ((dataSource.stats$ | async).currentPageSize > 0) {\n <div\n class=\"counter p-t-8 p-b-8\"\n data-cy=\"data-grid--child-counter\"\n >\n <span\n class=\"text-muted\"\n ngNonBindable\n translate\n [translateParams]=\"{\n pageFirstItemIdx:\n (row.childrenStats.currentPage - 1) * row.childrenStats.firstPageSize + 1,\n pageLastItemIdx:\n (row.childrenStats.currentPage - 1) * row.childrenStats.firstPageSize +\n 1 +\n (row.childrenStats.currentPageSize - 1),\n itemsTotal: row.childrenStats.filteredSize\n }\"\n >\n {{ pageFirstItemIdx }} - {{ pageLastItemIdx }} of {{ itemsTotal }}\n </span>\n <span class=\"text-muted text-12 m-r-4\">{{ 'Parent node' | translate }}</span>\n <span class=\"tag tag--default\">{{ row.parentRow?.[parentNodeLabelProperty] }}</span>\n </div>\n }\n </div>\n <div class=\"col-sm-4 col-sm-offset-4 no-gutter text-right\">\n @if (row.childrenStats.filteredSize > row.childrenStats.currentPageSize) {\n <pagination\n class=\"d-flex j-c-end\"\n [ngModel]=\"row.childrenStats.currentPage\"\n (pageChanged)=\"updateChildPagination($event, row)\"\n [totalItems]=\"row.childrenStats.filteredSize\"\n [itemsPerPage]=\"row?.parentRow?.pagination?.pageSize ?? childNodePagination.pageSize\"\n [maxSize]=\"5\"\n [boundaryLinks]=\"false\"\n [previousText]=\"'Previous' | translate\"\n [nextText]=\"'Next' | translate\"\n ></pagination>\n }\n </div>\n </td>\n </ng-container>\n\n <ng-container>\n <tr\n [ngClass]=\"{ hidden: !infiniteScroll }\"\n cdk-footer-row\n *cdkFooterRowDef=\"['infiniteScrollFooter']\"\n ></tr>\n </ng-container>\n </table>\n\n @if (\n !(dataSource.loading$ | async) &&\n !loading &&\n ((dataSource.stats$ | async).filteredSize === 0 || (dataSource.data$ | async).length === 0)\n ) {\n <div class=\"d-flex m-0 p-t-40 p-b-40\">\n <div class=\"col-lg-3 col-sm-4 m-l-auto m-r-auto\">\n <ng-content select=\"c8y-ui-empty-state, .c8y-empty-state\"></ng-content>\n <ng-container\n *ngTemplateOutlet=\"\n emptyState?.templateRef;\n context: { $implicit: emptyStateContext$ | async }\n \"\n ></ng-container>\n </div>\n </div>\n }\n\n @if (pagination && !infiniteScroll) {\n <div class=\"table-data-grid-footer separator large-padding\">\n <div class=\"col-sm-4 no-gutter\">\n @if ((dataSource.stats$ | async).currentPageSize > 0) {\n <div\n class=\"counter p-t-8 p-b-8\"\n data-cy=\"data-grid--counter\"\n >\n <span\n class=\"text-muted\"\n ngNonBindable\n translate\n [translateParams]=\"paginationLabelParams\"\n >\n {{ pageFirstItemIdx }} - {{ pageLastItemIdx }} of {{ itemsTotal }}\n </span>\n </div>\n }\n </div>\n\n <div class=\"col-sm-4 no-gutter text-center\">\n @if ((dataSource.stats$ | async).filteredSize > minPossiblePageSize) {\n <div class=\"form-group form-inline p-t-8 p-b-8\">\n <label\n class=\"m-r-4\"\n for=\"filteredSize\"\n >\n {{ 'Items per page' | translate }}\n </label>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control\"\n id=\"filteredSize\"\n data-cy=\"data-grid--pagesize-options\"\n [ngModel]=\"pagination.pageSize\"\n (ngModelChange)=\"\n updatePagination({ itemsPerPage: $event, page: pagination.currentPage })\n \"\n >\n @for (pageSize of possiblePageSizes; track $index) {\n <option [ngValue]=\"pageSize\">\n {{ pageSize }}\n </option>\n }\n </select>\n </div>\n </div>\n }\n </div>\n\n <div class=\"col-sm-4 no-gutter text-right\">\n @if ((dataSource.stats$ | async).filteredSize > 0) {\n <pagination\n [class.hidden]=\"hidePagination$ | async\"\n class=\"d-flex j-c-end\"\n [ngModel]=\"pagination.currentPage\"\n (pageChanged)=\"updatePagination($event)\"\n [totalItems]=\"(dataSource.stats$ | async).filteredSize\"\n [itemsPerPage]=\"pagination.pageSize\"\n (numPages)=\"totalPagesCount$.next($event)\"\n [maxSize]=\"5\"\n [boundaryLinks]=\"false\"\n [previousText]=\"'Previous' | translate\"\n [nextText]=\"'Next' | translate\"\n ></pagination>\n }\n </div>\n </div>\n }\n</div>\n" }]
|
|
35349
35337
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
35350
35338
|
type: Optional
|
|
35351
35339
|
}, {
|