@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
828 lines (820 loc) • 202 kB
JavaScript
import * as i0 from '@angular/core';
import { Injectable, ViewChild, Input, Component, Inject, Optional, EventEmitter, Output, HostListener, TemplateRef, NgModule, InjectionToken, signal } from '@angular/core';
import * as i3 from '@c8y/ngx-components';
import { DataGridService, gettext, Permissions, GroupFragment, Status, ConfirmModalComponent, FormGroupComponent, ProductExperienceDirective, C8yTranslatePipe, AbstractConfigurationStrategy, DATA_GRID_CONFIGURATION_CONTEXT, DATA_GRID_CONFIGURATION_CONTEXT_PROVIDER, BuiltInActionType, DataGridComponent, EmptyStateContextDirective, EmptyStateComponent, ColumnDirective, UserPreferencesConfigurationStrategy, DATA_GRID_CONFIGURATION_STRATEGY, C8yStepper, C8yTranslateDirective, RequiredInputPlaceholderDirective, C8yStepperButtons, CoreModule, DatePipe, IconDirective, LoadingComponent, CustomColumn, TextareaAutoresizeDirective, FilterMapperPipe, GroupedFilterChips, TitleComponent, BreadcrumbComponent, BreadcrumbItemComponent, ActionBarItemComponent, HelpComponent, FilterMapperModule, hookRoute, ViewContext } from '@c8y/ngx-components';
import { NameDeviceGridColumn, ModelDeviceGridColumn, SerialNumberDeviceGridColumn, RegistrationDateDeviceGridColumn, SystemIdDeviceGridColumn, ImeiDeviceGridColumn, AlarmsDeviceGridColumn, DeviceGridComponent, DeviceGridModule } from '@c8y/ngx-components/device-grid';
import * as i1$1 from '@angular/forms';
import { FormsModule, Validators, ReactiveFormsModule, FormGroup } from '@angular/forms';
import * as i2 from '@c8y/client';
import * as i4 from '@c8y/ngx-components/assets-navigator';
import * as i1 from '@ngx-translate/core';
import { AssetTypeGridColumn, AssetTypeCellRendererComponent } from '@c8y/ngx-components/data-grid-columns/asset-type';
import { firstValueFrom, Subject, of, delay, takeUntil as takeUntil$1, tap } from 'rxjs';
import { NgIf, NgFor, NgClass, NgTemplateOutlet, NgStyle, NgSwitch, NgSwitchCase, NgSwitchDefault, AsyncPipe } from '@angular/common';
import { CdkStep } from '@angular/cdk/stepper';
import * as i4$1 from '@c8y/ngx-components/device-list';
import * as i2$1 from 'ngx-bootstrap/modal';
import { takeUntil } from 'rxjs/operators';
import { cloneDeep, clone, sortBy, isNumber, toPairs, fromPairs, find, pick } from 'lodash-es';
import { PopoverDirective, PopoverModule } from 'ngx-bootstrap/popover';
import { BsDropdownModule, BsDropdownDirective, BsDropdownToggleDirective, BsDropdownMenuDirective } from 'ngx-bootstrap/dropdown';
import { TooltipModule, TooltipDirective } from 'ngx-bootstrap/tooltip';
import * as i2$2 from '@ngx-formly/core';
import { FormlyModule } from '@ngx-formly/core';
import * as i2$3 from '@c8y/ngx-components/map';
import { defaultMapConfig, getC8yMarker, MapComponent, MapModule } from '@c8y/ngx-components/map';
import * as i1$2 from '@angular/router';
const PRODUCT_EXPERIENCE_SUB_ASSETS_SHARED = {
EVENT: 'subAssets',
DELETE_ASSET: {
COMPONENTS: { DELETE_ASSETS_MODAL: 'delete-assets-modal' },
ACTIONS: { CASCADE_DELETE: 'cascadeDelete', DELETE_DEVICE_OWNER: 'deleteDeviceOwner' },
RESULTS: { CANCELED: 'canceled', DELETED: 'deleted' }
},
ASSIGN_DEVICES: {
COMPONENTS: { ASSIGN_DEVICES: 'assign-devices' },
ACTIONS: { ASSIGN: 'assign', CANCEL: 'cancel', DISPLAY_CHILD_DEVICES: 'displayChildDevices' }
},
UNASSIGN_MODAL: {
COMPONENTS: { UNASSIGN_MODAL: 'unassign-modal' },
RESULTS: { ASSET_UNASSIGNED: 'asset-unassigned' },
ACTIONS: { CANCEL: 'cancel' }
},
GROUP_INFO: {
COMPONENTS: { GROUP_INFO: 'group-info' },
ACTIONS: { EDIT: 'edit' },
RESULTS: { EDIT_SAVED: 'edit-saved' },
PROPERTIES: { NAME: 'name', DESCRIPTION: 'description' }
},
ADD_GROUP: {
COMPONENTS: { ADD_GROUP: 'add-group' },
ACTIONS: { ADD: 'add' },
RESULTS: { ADD_SUCCESS: 'group-added' }
}
};
class SubAssetsService extends DataGridService {
constructor(translateService, inventoryService, appState, user, assetNodeService, smartGroupsService, smartRulesService, alertService, permissionsService, assetTypes, userPreferencesService) {
super(userPreferencesService);
this.translateService = translateService;
this.inventoryService = inventoryService;
this.appState = appState;
this.user = user;
this.assetNodeService = assetNodeService;
this.smartGroupsService = smartGroupsService;
this.smartRulesService = smartRulesService;
this.alertService = alertService;
this.permissionsService = permissionsService;
this.assetTypes = assetTypes;
this.userPreferencesService = userPreferencesService;
this.GRID_CONFIG_DEFAULT_STORAGE_KEY = 'sub-assets-grid-config';
this.IS_DEVICE_GROUP_FRAGMENT = 'c8y_IsDeviceGroup';
this.IS_DYNAMIC_GROUP_FRAGMENT = 'c8y_IsDynamicGroup';
}
async getCustomProperties(group) {
const assetType$ = this.assetTypes.getAssetTypeByName$(group.type);
const assetType = await firstValueFrom(assetType$);
if (assetType) {
const { data } = await this.inventoryService.childAdditionsList(assetType, {
pageSize: 2000,
query: "$filter=(has('c8y_IsAssetProperty'))"
});
return data;
}
return [];
}
getDefaultColumns(_filterable = true, _sortable = true) {
const defaultColumns = [
new AssetTypeGridColumn({ sortOrder: 'desc' }),
new NameDeviceGridColumn({ sortOrder: 'asc' }),
new ModelDeviceGridColumn(),
new SerialNumberDeviceGridColumn({ visible: false }),
new RegistrationDateDeviceGridColumn({ visible: false }),
new SystemIdDeviceGridColumn({ visible: false }),
new ImeiDeviceGridColumn({ visible: false }),
new AlarmsDeviceGridColumn()
];
return defaultColumns;
}
getDefaultPagination() {
return {
pageSize: 25,
currentPage: 1
};
}
getDefaultActionControls() {
return [];
}
async unassignAsset(asset, parentRef) {
const { id: assetId } = asset;
const { id: parentId } = parentRef;
if (this.isDevice(asset)) {
try {
await this.inventoryService.childAssetsRemove(assetId, parentId);
const alertMessage = this.translateService.instant(gettext('Device unassigned.'));
this.alertService.success(alertMessage);
}
catch (error) {
const alertMessage = this.translateService.instant(gettext('Could not unassign device.'));
this.alertService.danger(alertMessage, error);
}
await this.deactivateSmartrulesForAsset(asset, parentRef);
}
}
isDevice(asset) {
return (!asset.hasOwnProperty(this.IS_DEVICE_GROUP_FRAGMENT) &&
!asset.hasOwnProperty(this.IS_DYNAMIC_GROUP_FRAGMENT));
}
async deleteAsset(asset, parentRef, params = {}) {
const isGroup = asset.hasOwnProperty(this.IS_DEVICE_GROUP_FRAGMENT) ||
this.smartGroupsService.isSmartGroup(asset);
if (isGroup) {
await this.deleteGroup(asset, params);
}
else {
await this.deleteDevice(asset, params);
}
if (parentRef && !this.smartGroupsService.isSmartGroup(asset)) {
await this.deactivateSmartrulesForAsset(asset, parentRef);
}
}
shouldShowWithDeviceUserCheckbox(asset) {
const { owner, c8y_IsDevice: isRootDevice } = asset;
const hasDeviceUserAsOwner = asset.owner && this.isDeviceUser(owner);
return Boolean(isRootDevice && hasDeviceUserAsOwner);
}
getDefaultBulkActionControls() {
return [];
}
async getData(columns, pagination, parentReference, baseQuery = {}, text = null) {
const isRoot = !parentReference;
if (isRoot) {
const query = this.buildCombinedRootQueryFilter(columns, pagination, baseQuery);
return this.assetNodeService.getRootNodes({ ...pagination, ...(text && { text }), query });
}
const filters = {
...this.getAssetsFilters(columns, pagination, baseQuery, text),
withParents: false
};
if (this.assetNodeService.isGroup(parentReference)) {
return this.assetNodeService.getGroupItems(parentReference.id, filters);
}
if (this.assetNodeService.isDynamicGroup(parentReference)) {
return this.assetNodeService.getDynamicGroupItems(parentReference.c8y_DeviceQueryString, filters);
}
if (this.assetNodeService.isDevice(parentReference)) {
return this.assetNodeService.getDeviceChildren(parentReference.id, filters);
}
}
async getCount(columns, pagination, parentReference, baseQuery = {}, text = null) {
const defaultFilters = {
pageSize: 1,
withChildren: false
};
const filters = !parentReference
? {
query: this.buildCombinedRootQueryFilter(columns, pagination, baseQuery),
...defaultFilters
}
: {
...this.getAssetsFilters(columns, pagination, baseQuery, text),
...defaultFilters
};
return this.getAssetsStatistics(parentReference, filters);
}
getTotal(parentReference, baseQuery = {}) {
const queryFilter = this.assetNodeService.rootQueryFilter();
const query = !parentReference
? this.queriesUtil.addAndFilter(queryFilter, baseQuery)
: baseQuery;
const filters = {
query: this.queriesUtil.buildQuery(query),
withChildren: false,
withTotalPages: true,
pageSize: 1
};
return this.getAssetsStatistics(parentReference, filters);
}
async canEditGroup(group) {
return await this.permissionsService.canEdit([Permissions.ROLE_INVENTORY_ADMIN, Permissions.ROLE_MANAGED_OBJECT_ADMIN], group);
}
canCreateGroup() {
const currentUser = this.appState.currentUser.value;
const hasAdminRole = this.user.hasAnyRole(currentUser, [
Permissions.ROLE_INVENTORY_ADMIN,
Permissions.ROLE_INVENTORY_CREATE,
Permissions.ROLE_MANAGED_OBJECT_ADMIN,
Permissions.ROLE_MANAGED_OBJECT_CREATE
]);
return hasAdminRole;
}
async canAssignDevice(group) {
return await this.permissionsService.canEdit([Permissions.ROLE_INVENTORY_ADMIN, Permissions.ROLE_MANAGED_OBJECT_ADMIN], group);
}
canEditSmartGroup() {
const SMART_GROUPS_ROLES_EDIT = [
Permissions.ROLE_SMARTGROUP_UPDATE,
Permissions.ROLE_SMARTGROUP_ADMIN
];
return this.permissionsService.hasAnyRole(SMART_GROUPS_ROLES_EDIT);
}
canDeleteSmartGroup() {
const SMART_GROUPS_ROLES_DELETE = [
Permissions.ROLE_SMARTGROUP_ADMIN,
Permissions.ROLE_INVENTORY_ADMIN,
Permissions.ROLE_MANAGED_OBJECT_ADMIN
];
return this.permissionsService.hasAnyRole(SMART_GROUPS_ROLES_DELETE);
}
isSmartGroup(group) {
return this.smartGroupsService.isSmartGroup(group);
}
isUsingInventoryRoles() {
const currentUser = this.appState.currentUser.value;
const hasAnyInventoryRole = this.user.hasAnyRole(currentUser, [
Permissions.ROLE_INVENTORY_ADMIN,
Permissions.ROLE_INVENTORY_READ,
Permissions.ROLE_INVENTORY_CREATE,
Permissions.ROLE_MANAGED_OBJECT_ADMIN,
Permissions.ROLE_MANAGED_OBJECT_CREATE,
Permissions.ROLE_MANAGED_OBJECT_READ
]);
return !hasAnyInventoryRole;
}
async getAssetsStatistics(parentReference, filters) {
const isRoot = !parentReference;
if (isRoot) {
return (await this.assetNodeService.getRootNodes(filters)).paging.totalPages;
}
if (this.assetNodeService.isGroup(parentReference)) {
return (await this.assetNodeService.getGroupItems(parentReference.id, filters)).paging
.totalPages;
}
if (this.assetNodeService.isDynamicGroup(parentReference)) {
return (await this.assetNodeService.getDynamicGroupItems(parentReference.c8y_DeviceQueryString, filters)).paging.totalPages;
}
if (this.assetNodeService.isDevice(parentReference)) {
return (await this.assetNodeService.getDeviceChildren(parentReference.id, filters)).paging
.totalPages;
}
}
buildCombinedRootQueryFilter(columns, pagination, baseQuery = {}) {
const userQuery = this.getQueryObj(columns, pagination);
const rootQuery = this.assetNodeService.rootQueryFilter();
const orderedRootQuery = this.queriesUtil.addOrderbys(rootQuery, userQuery.__orderby, 'append');
const rootAndUserQuery = this.queriesUtil.addAndFilter(orderedRootQuery, userQuery.__filter);
const fullQuery = this.queriesUtil.addAndFilter(rootAndUserQuery, baseQuery);
return this.queriesUtil.buildQuery(fullQuery);
}
async deleteGroup(group, params = {}) {
const { cascade } = params;
try {
this.smartGroupsService.isSmartGroup(group)
? await this.smartGroupsService.delete(group, { cascade })
: await this.inventoryService.delete(group, { cascade });
const alertMessage = this.translateService.instant(gettext('"{{ name }}" deleted.'), {
name: group.name
});
this.alertService.success(alertMessage);
}
catch (error) {
const alertMessage = this.translateService.instant(gettext('Could not delete "{{ name }}".'), {
name: group.name
});
this.alertService.danger(alertMessage, error);
}
}
async deleteDevice(device, params = {}) {
const { cascade, withDeviceUser } = params;
try {
const { owner } = device;
const shouldRemoveOwner = withDeviceUser && owner && this.isDeviceUser(owner);
shouldRemoveOwner
? await this.deleteDeviceWithUser(device, cascade)
: await this.inventoryService.delete(device, { cascade });
const alertMessage = this.translateService.instant(gettext('Device deleted.'));
this.alertService.success(alertMessage);
}
catch (error) {
const alertMessage = this.translateService.instant(gettext('Could not delete device.'));
this.alertService.danger(alertMessage, error);
}
}
async deactivateSmartrulesForAsset(asset, parentRef) {
const { id: assetId } = asset;
const { id: parentId } = parentRef;
const rules = (await this.smartRulesService.listByContext(parentId)).data;
const upateSmartrulesPromises = rules.map(rule => this.smartRulesService.bulkDeactivateEnabledSources(rule, [assetId]));
try {
await Promise.all(upateSmartrulesPromises);
}
catch (error) {
const alertMessage = this.translateService.instant(gettext('Could not deactivate smart rules.'));
this.alertService.danger(alertMessage);
}
}
isDeviceUser(userId) {
return userId.match(/^device_/);
}
async deleteDeviceWithUser(device, cascade) {
const params = { cascade, withDeviceUser: true };
try {
return await this.inventoryService.delete(device, params);
}
catch (error) {
return await this.inventoryService.delete(device, { cascade });
}
}
getAssetsFilters(columns, pagination, baseQuery, text) {
const query = this.queriesUtil.addAndFilter(this.getQueryObj(columns), baseQuery);
return {
...(text && { text }),
query: this.queriesUtil.buildQuery(query),
pageSize: pagination.pageSize || this.DEFAULT_PAGE_SIZE,
currentPage: pagination.currentPage,
withTotalPages: true
};
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SubAssetsService, deps: [{ token: i1.TranslateService }, { token: i2.InventoryService }, { token: i3.AppStateService }, { token: i2.UserService }, { token: i4.AssetNodeService }, { token: i2.SmartGroupsService }, { token: i2.SmartRulesService }, { token: i3.AlertService }, { token: i3.Permissions }, { token: i3.AssetTypesRealtimeService }, { token: i3.UserPreferencesService }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SubAssetsService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SubAssetsService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}], ctorParameters: () => [{ type: i1.TranslateService }, { type: i2.InventoryService }, { type: i3.AppStateService }, { type: i2.UserService }, { type: i4.AssetNodeService }, { type: i2.SmartGroupsService }, { type: i2.SmartRulesService }, { type: i3.AlertService }, { type: i3.Permissions }, { type: i3.AssetTypesRealtimeService }, { type: i3.UserPreferencesService }] });
class AddGroupService {
constructor(inventoryService) {
this.inventoryService = inventoryService;
this.GROUP_FRAGMENT_TYPE = 'c8y_IsDeviceGroup';
}
async createGroupAndAssignDevices(groupForm, groupContextId, selectedDevices) {
let group;
const { name, description } = groupForm;
const newGroupMO = this.getGroupMO(name, description, groupContextId);
if (groupContextId) {
group = (await this.inventoryService.childAssetsCreate(newGroupMO, groupContextId)).data;
}
else {
group = (await this.inventoryService.create(newGroupMO)).data;
}
if (selectedDevices.length > 0) {
await this.assignDevices(group.id, selectedDevices);
}
return group;
}
getGroupMO(name, description = '', groupContextId) {
const group = {
type: this.getGroupType(groupContextId),
[this.GROUP_FRAGMENT_TYPE]: {},
name,
c8y_Notes: description
};
return group;
}
getGroupType(groupContextId) {
return groupContextId ? GroupFragment.subGroupType : GroupFragment.groupType;
}
async assignDevices(id, selectedDevices) {
const promises = [];
selectedDevices.forEach(moId => {
promises.push(this.inventoryService.childAssetsAdd(moId, id));
});
return await Promise.all(promises);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AddGroupService, deps: [{ token: i2.InventoryService }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AddGroupService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AddGroupService, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: i2.InventoryService }] });
class DeleteAssetsModalComponent {
constructor(translateService, gainsightService) {
this.translateService = translateService;
this.gainsightService = gainsightService;
this.CURRENT_LOCATION = location.href;
this.PRODUCT_EXPERIENCE = PRODUCT_EXPERIENCE_SUB_ASSETS_SHARED;
this.showWithCascadeCheckbox = true;
this.showWithDeviceUserCheckbox = false;
this.closeSubject = new Subject();
this.labels = { ok: gettext('Delete'), cancel: gettext('Cancel') };
this.title = gettext('Delete');
this.status = Status.DANGER;
this.config = {
cascade: false,
withDeviceUser: false
};
}
ngOnInit() {
this.setModalTexts();
}
async ngAfterViewInit() {
try {
await this.modalRef.result;
this.onClose();
}
catch (error) {
this.onDismiss();
}
}
onClose() {
this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_SUB_ASSETS_SHARED.EVENT, {
component: PRODUCT_EXPERIENCE_SUB_ASSETS_SHARED.DELETE_ASSET.COMPONENTS.DELETE_ASSETS_MODAL,
result: PRODUCT_EXPERIENCE_SUB_ASSETS_SHARED.DELETE_ASSET.RESULTS.DELETED,
url: this.CURRENT_LOCATION
});
this.closeSubject.next(this.config);
this.closeSubject.complete();
}
onDismiss() {
this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_SUB_ASSETS_SHARED.EVENT, {
component: PRODUCT_EXPERIENCE_SUB_ASSETS_SHARED.DELETE_ASSET.COMPONENTS.DELETE_ASSETS_MODAL,
result: PRODUCT_EXPERIENCE_SUB_ASSETS_SHARED.DELETE_ASSET.RESULTS.CANCELED,
url: this.CURRENT_LOCATION
});
this.closeSubject.complete();
}
setModalTexts() {
this.message = this.translateService.instant(gettext('You are about to delete: "{{name}}". This operation is irreversible. Do you want to proceed?'), { name: this.asset.name });
this.deleteGroupSubAssetsMsg = this.translateService.instant(gettext('Also delete all devices inside "{{name}}" and its subassets.'), { name: this.asset.name });
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DeleteAssetsModalComponent, deps: [{ token: i1.TranslateService }, { token: i3.GainsightService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DeleteAssetsModalComponent, isStandalone: true, selector: "c8y-delete-assets-modal", inputs: { showWithCascadeCheckbox: "showWithCascadeCheckbox", showWithDeviceUserCheckbox: "showWithDeviceUserCheckbox", asset: "asset" }, viewQueries: [{ propertyName: "modalRef", first: true, predicate: ["modalRef"], descendants: true }], ngImport: i0, template: "<c8y-confirm-modal [title]=\"title\" [status]=\"status\" [labels]=\"labels\" #modalRef>\n <form #assetsForm=\"ngForm\">\n <p class=\"text-wrap m-b-16\">\n {{ message | translate }}\n </p>\n <c8y-form-group *ngIf=\"showWithCascadeCheckbox\" class=\"m-b-0\">\n <label title=\"{{ 'Delete devices' | translate }}\" class=\"c8y-checkbox\">\n <input\n type=\"checkbox\"\n name=\"cascade\"\n [(ngModel)]=\"config.cascade\"\n c8yProductExperience\n [actionName]=\"PRODUCT_EXPERIENCE.EVENT\"\n [actionData]=\"{\n component: PRODUCT_EXPERIENCE.DELETE_ASSET.COMPONENTS.DELETE_ASSETS_MODAL,\n action: PRODUCT_EXPERIENCE.DELETE_ASSET.ACTIONS.CASCADE_DELETE\n }\"\n [disabled]=\"config?.withDeviceUser\"\n />\n <span></span>\n <span class=\"text-break-word\">\n {{ deleteGroupSubAssetsMsg | translate }}\n </span>\n </label>\n </c8y-form-group>\n <c8y-form-group *ngIf=\"showWithDeviceUserCheckbox\" class=\"m-b-0\">\n <label title=\"{{ 'Delete associated device owner' | translate }}\" class=\"c8y-checkbox\">\n <input\n type=\"checkbox\"\n name=\"withDeviceUser\"\n [(ngModel)]=\"config.withDeviceUser\"\n c8yProductExperience\n [actionName]=\"PRODUCT_EXPERIENCE.EVENT\"\n [actionData]=\"{\n component: PRODUCT_EXPERIENCE.DELETE_ASSET.COMPONENTS.DELETE_ASSETS_MODAL,\n action: PRODUCT_EXPERIENCE.DELETE_ASSET.ACTIONS.DELETE_DEVICE_OWNER\n }\"\n [disabled]=\"config?.cascade\"\n />\n <span></span>\n <span>\n {{ 'Also delete associated device owner.' | translate }}\n </span>\n </label>\n </c8y-form-group>\n </form>\n</c8y-confirm-modal>\n", dependencies: [{ kind: "component", type: ConfirmModalComponent, selector: "c8y-confirm-modal", inputs: ["title", "body", "confirmOptions", "status", "labels"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: ProductExperienceDirective, selector: "[c8yProductExperience]", inputs: ["actionName", "actionData", "inherit", "suppressDataOverriding"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DeleteAssetsModalComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-delete-assets-modal', imports: [
ConfirmModalComponent,
FormsModule,
NgIf,
FormGroupComponent,
ProductExperienceDirective,
C8yTranslatePipe
], template: "<c8y-confirm-modal [title]=\"title\" [status]=\"status\" [labels]=\"labels\" #modalRef>\n <form #assetsForm=\"ngForm\">\n <p class=\"text-wrap m-b-16\">\n {{ message | translate }}\n </p>\n <c8y-form-group *ngIf=\"showWithCascadeCheckbox\" class=\"m-b-0\">\n <label title=\"{{ 'Delete devices' | translate }}\" class=\"c8y-checkbox\">\n <input\n type=\"checkbox\"\n name=\"cascade\"\n [(ngModel)]=\"config.cascade\"\n c8yProductExperience\n [actionName]=\"PRODUCT_EXPERIENCE.EVENT\"\n [actionData]=\"{\n component: PRODUCT_EXPERIENCE.DELETE_ASSET.COMPONENTS.DELETE_ASSETS_MODAL,\n action: PRODUCT_EXPERIENCE.DELETE_ASSET.ACTIONS.CASCADE_DELETE\n }\"\n [disabled]=\"config?.withDeviceUser\"\n />\n <span></span>\n <span class=\"text-break-word\">\n {{ deleteGroupSubAssetsMsg | translate }}\n </span>\n </label>\n </c8y-form-group>\n <c8y-form-group *ngIf=\"showWithDeviceUserCheckbox\" class=\"m-b-0\">\n <label title=\"{{ 'Delete associated device owner' | translate }}\" class=\"c8y-checkbox\">\n <input\n type=\"checkbox\"\n name=\"withDeviceUser\"\n [(ngModel)]=\"config.withDeviceUser\"\n c8yProductExperience\n [actionName]=\"PRODUCT_EXPERIENCE.EVENT\"\n [actionData]=\"{\n component: PRODUCT_EXPERIENCE.DELETE_ASSET.COMPONENTS.DELETE_ASSETS_MODAL,\n action: PRODUCT_EXPERIENCE.DELETE_ASSET.ACTIONS.DELETE_DEVICE_OWNER\n }\"\n [disabled]=\"config?.cascade\"\n />\n <span></span>\n <span>\n {{ 'Also delete associated device owner.' | translate }}\n </span>\n </label>\n </c8y-form-group>\n </form>\n</c8y-confirm-modal>\n" }]
}], ctorParameters: () => [{ type: i1.TranslateService }, { type: i3.GainsightService }], propDecorators: { showWithCascadeCheckbox: [{
type: Input
}], showWithDeviceUserCheckbox: [{
type: Input
}], asset: [{
type: Input
}], modalRef: [{
type: ViewChild,
args: ['modalRef', { static: false }]
}] } });
class SmartGroupGridConfigurationStrategy extends AbstractConfigurationStrategy {
constructor(userPreferencesConfigurationStrategy, context, contextProvider) {
super(context, contextProvider);
this.userPreferencesConfigurationStrategy = userPreferencesConfigurationStrategy;
this.context = context;
this.contextProvider = contextProvider;
}
getConfig$(context) {
const group = cloneDeep(this.retrieveContext(context)?.group);
if (group?.c8y_DeviceColumnsConfig?.columns?.length) {
group.c8y_DeviceColumnsConfig.columns = group.c8y_DeviceColumnsConfig.columns.map(column => {
delete column.filter;
return column;
});
}
return of(group?.c8y_DeviceColumnsConfig);
}
saveConfig$(config, _context) {
return of(config);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SmartGroupGridConfigurationStrategy, deps: [{ token: i3.UserPreferencesConfigurationStrategy }, { token: DATA_GRID_CONFIGURATION_CONTEXT, optional: true }, { token: DATA_GRID_CONFIGURATION_CONTEXT_PROVIDER, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SmartGroupGridConfigurationStrategy, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SmartGroupGridConfigurationStrategy, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}], ctorParameters: () => [{ type: i3.UserPreferencesConfigurationStrategy }, { type: undefined, decorators: [{
type: Inject,
args: [DATA_GRID_CONFIGURATION_CONTEXT]
}, {
type: Optional
}] }, { type: undefined, decorators: [{
type: Inject,
args: [DATA_GRID_CONFIGURATION_CONTEXT_PROVIDER]
}, {
type: Optional
}] }] });
class SubAssetsGridConfigurationStrategy extends AbstractConfigurationStrategy {
constructor(userPreferencesConfigurationStrategy, smartGroupGridConfigurationStrategy, assetNodeService, context, contextProvider) {
super(context, contextProvider);
this.userPreferencesConfigurationStrategy = userPreferencesConfigurationStrategy;
this.smartGroupGridConfigurationStrategy = smartGroupGridConfigurationStrategy;
this.assetNodeService = assetNodeService;
this.context = context;
this.contextProvider = contextProvider;
}
getConfig$(context) {
return this.getStrategy(context).getConfig$(context);
}
saveConfig$(config, context) {
return this.getStrategy(context).saveConfig$(config, context);
}
getStrategy(ctx) {
const context = this.retrieveContext(ctx);
return !!context?.group &&
this.assetNodeService.isDynamicGroup(context?.group) &&
context?.group?.c8y_DeviceColumnsConfig
? this.smartGroupGridConfigurationStrategy
: this.userPreferencesConfigurationStrategy;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SubAssetsGridConfigurationStrategy, deps: [{ token: i3.UserPreferencesConfigurationStrategy }, { token: SmartGroupGridConfigurationStrategy }, { token: i4.AssetNodeService }, { token: DATA_GRID_CONFIGURATION_CONTEXT, optional: true }, { token: DATA_GRID_CONFIGURATION_CONTEXT_PROVIDER, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SubAssetsGridConfigurationStrategy, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SubAssetsGridConfigurationStrategy, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}], ctorParameters: () => [{ type: i3.UserPreferencesConfigurationStrategy }, { type: SmartGroupGridConfigurationStrategy }, { type: i4.AssetNodeService }, { type: undefined, decorators: [{
type: Inject,
args: [DATA_GRID_CONFIGURATION_CONTEXT]
}, {
type: Optional
}] }, { type: undefined, decorators: [{
type: Inject,
args: [DATA_GRID_CONFIGURATION_CONTEXT_PROVIDER]
}, {
type: Optional
}] }] });
class UnassignModalComponent {
constructor(translateService, gainsightService) {
this.translateService = translateService;
this.gainsightService = gainsightService;
this.CURRENT_LOCATION = location.href;
this.closeSubject = new Subject();
this.labels = { ok: gettext('Unassign'), cancel: gettext('Cancel') };
this.title = gettext('Unassign');
this.status = Status.WARNING;
}
ngOnInit() {
this.message = this.translateService.instant(gettext('You are about to unassign "{{name}}". Do you want to proceed?'), { name: this.asset.name });
}
async ngAfterViewInit() {
try {
await this.modalRef.result;
this.onClose();
}
catch (error) {
this.onDismiss();
}
}
onClose() {
this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_SUB_ASSETS_SHARED.EVENT, {
component: PRODUCT_EXPERIENCE_SUB_ASSETS_SHARED.UNASSIGN_MODAL.COMPONENTS.UNASSIGN_MODAL,
result: PRODUCT_EXPERIENCE_SUB_ASSETS_SHARED.UNASSIGN_MODAL.RESULTS.ASSET_UNASSIGNED,
url: this.CURRENT_LOCATION
});
this.closeSubject.next(true);
this.closeSubject.complete();
}
onDismiss() {
this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_SUB_ASSETS_SHARED.EVENT, {
component: PRODUCT_EXPERIENCE_SUB_ASSETS_SHARED.UNASSIGN_MODAL.COMPONENTS.UNASSIGN_MODAL,
action: PRODUCT_EXPERIENCE_SUB_ASSETS_SHARED.UNASSIGN_MODAL.ACTIONS.CANCEL,
url: this.CURRENT_LOCATION
});
this.closeSubject.complete();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UnassignModalComponent, deps: [{ token: i1.TranslateService }, { token: i3.GainsightService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: UnassignModalComponent, isStandalone: true, selector: "c8y-unassign-modal", inputs: { asset: "asset" }, viewQueries: [{ propertyName: "modalRef", first: true, predicate: ["modalRef"], descendants: true }], ngImport: i0, template: "<c8y-confirm-modal [title]=\"title\" [status]=\"status\" [labels]=\"labels\" #modalRef>\n <span>{{ message | translate }}</span>\n</c8y-confirm-modal>\n", dependencies: [{ kind: "component", type: ConfirmModalComponent, selector: "c8y-confirm-modal", inputs: ["title", "body", "confirmOptions", "status", "labels"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: UnassignModalComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-unassign-modal', imports: [ConfirmModalComponent, C8yTranslatePipe], template: "<c8y-confirm-modal [title]=\"title\" [status]=\"status\" [labels]=\"labels\" #modalRef>\n <span>{{ message | translate }}</span>\n</c8y-confirm-modal>\n" }]
}], ctorParameters: () => [{ type: i1.TranslateService }, { type: i3.GainsightService }], propDecorators: { asset: [{
type: Input
}], modalRef: [{
type: ViewChild,
args: ['modalRef', { static: false }]
}] } });
class SubAssetsGridComponent {
get columns() {
return this._columns;
}
set columns(value) {
this._columns = value ?? this.subAssetsGridService.getDefaultColumns();
}
set _pagination(value) {
if (value) {
this.pagination = value;
}
else {
this.pagination = this.subAssetsGridService.getDefaultPagination();
}
}
set _actionControls(value) {
if (value) {
this.actionControls = value;
}
else {
this.actionControls = this.subAssetsGridService.getDefaultActionControls();
}
}
set _bulkActionControls(value) {
if (value) {
this.bulkActionControls = value;
}
else {
this.bulkActionControls = this.subAssetsGridService.getDefaultBulkActionControls();
}
}
get isRootGroup() {
return !this.parentGroup;
}
get getInfiniteScrollMode() {
return this.isRootGroup && this.subAssetsGridService.isUsingInventoryRoles()
? 'auto'
: undefined;
}
set _displayOptions(displayOptions) {
this.displayOptions = { ...this.displayOptions, ...displayOptions };
}
constructor(subAssetsGridService, bsModalService, smartGroupsService, deviceListExtensionService, assetNodeService) {
this.subAssetsGridService = subAssetsGridService;
this.bsModalService = bsModalService;
this.smartGroupsService = smartGroupsService;
this.deviceListExtensionService = deviceListExtensionService;
this.assetNodeService = assetNodeService;
this.PRODUCT_EXPERIENCE = PRODUCT_EXPERIENCE_SUB_ASSETS_SHARED;
this.title = gettext('Subassets');
this.emptyStateText = gettext('Add your first group or assign devices using the buttons on the action bar.');
this.loadingItemsLabel = gettext('Loading assets…');
this.selectable = false;
this.baseQuery = {};
this.filterable = true;
this.sortable = true;
this.onColumnsChange = new EventEmitter();
this.itemsSelect = new EventEmitter();
this.pagination = this.subAssetsGridService.getDefaultPagination();
this.showCounterWarning = false;
this.bulkActionControls = this.subAssetsGridService.getDefaultBulkActionControls();
this.displayOptions = {
striped: true,
bordered: false,
gridHeader: true,
filter: true,
hover: true
};
this.showSearch = false;
this.noResultsMessage = gettext('No matching items.');
this.noDataMessage = gettext('No items to display.');
this.noResultsSubtitle = gettext('Refine your search terms or check your spelling.');
this.destroyed$ = new Subject();
this.serverSideDataCallback = this.onDataSourceModifier.bind(this);
}
getGridConfigContext() {
if (!!this.columnsConfigKey) {
return { key: this.columnsConfigKey, group: this.parentGroup };
}
}
ngOnInit() {
const isDynamicGroup = !!this.parentGroup && this.assetNodeService.isDynamicGroup(this.parentGroup);
if (!this.isRootGroup) {
(isDynamicGroup
? this.deviceListExtensionService.items$
: of(this.subAssetsGridService.getDefaultColumns(this.filterable, this.sortable)))
.pipe(takeUntil(this.destroyed$))
.subscribe(columns => (this.columns = columns));
}
if (!this.filterable || !this.sortable) {
this.displayOptions.filter = this.filterable;
this.columns.forEach(column => {
column.filterable = this.filterable;
column.sortable = this.sortable;
});
}
this.setActionControls();
this.showSearch = isDynamicGroup || !this.parentGroup;
}
setActionControls() {
const actionControls = [];
const unassignAction = {
type: 'UNASSIGN',
icon: 'unlink',
text: gettext('Unassign'),
priority: 1000,
callback: (asset) => this.onUnassignAsset(asset, this.parentGroup),
showIf: (asset) => this.subAssetsGridService.isDevice(asset) &&
!this.subAssetsGridService.isSmartGroup(this.parentGroup)
};
actionControls.push(unassignAction);
const deleteAction = {
type: BuiltInActionType.Delete,
priority: -Infinity,
callback: (asset) => this.onDeleteAsset(asset, this.parentGroup),
showIf: (asset) => {
if (this.smartGroupsService.isSmartGroup(asset)) {
return this.subAssetsGridService.canDeleteSmartGroup();
}
return true;
}
};
actionControls.push(deleteAction);
if (!this.actionControls) {
this.actionControls = actionControls;
}
}
onUnassignAsset(asset, parentRef) {
const initialState = {
asset
};
const modalRef = this.bsModalService.show(UnassignModalComponent, { initialState });
modalRef.content.closeSubject.subscribe(async (result) => {
if (result) {
await this.subAssetsGridService.unassignAsset(asset, parentRef);
this.refresh.emit();
}
});
}
async onDeleteAsset(asset, parentRef) {
const initialState = {
showWithDeviceUserCheckbox: this.subAssetsGridService.shouldShowWithDeviceUserCheckbox(asset),
asset,
showWithCascadeCheckbox: !this.smartGroupsService.isSmartGroup(asset)
};
const modalRef = this.bsModalService.show(DeleteAssetsModalComponent, { initialState });
modalRef.content.closeSubject.subscribe(async (result) => {
if (result) {
await this.subAssetsGridService.deleteAsset(asset, parentRef, result);
if (result.cascade) {
this.showCounterWarning = true;
}
this.refresh.emit();
}
});
}
ngOnChanges(changes) {
if (changes.parentGroup && !changes.parentGroup.firstChange) {
this.dataGrid.reload();
}
}
trackByName(_index, column) {
return column.name;
}
onReload() {
this.assetNodeService.rootNode.refresh();
}
async onDataSourceModifier(dataSourceModifier) {
const promises = [];
let counters;
promises.push(this.subAssetsGridService.getData(dataSourceModifier.columns, dataSourceModifier.pagination, this.parentGroup, this.baseQuery, dataSourceModifier.searchText));
promises.push(this.subAssetsGridService.getTotal(this.parentGroup, this.baseQuery));
promises.push(this.subAssetsGridService.getCount(dataSourceModifier.columns, dataSourceModifier.pagination, this.parentGroup, this.baseQuery, dataSourceModifier.searchText));
const [dataResponse, size, filteredSize] = await Promise.all(promises);
if (!counters) {
counters = {
size,
filteredSize
};
}
this.onColumnsChange.emit(dataSourceModifier.columns);
return {
res: dataResponse.res,
data: dataResponse.data,
paging: dataResponse.paging,
...counters
};
}
ngOnDestroy() {
this.destroyed$.next();
this.destroyed$.complete();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SubAssetsGridComponent, deps: [{ token: SubAssetsService }, { token: i2$1.BsModalService }, { token: i2.SmartGroupsService }, { token: i4$1.DeviceListExtensionService }, { token: i4.AssetNodeService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: SubAssetsGridComponent, isStandalone: true, selector: "c8y-sub-assets-grid", inputs: { parentGroup: ["parent-group", "parentGroup"], refresh: "refresh", title: "title", emptyStateText: "emptyStateText", loadingItemsLabel: "loadingItemsLabel", columnsConfigKey: "columnsConfigKey", columns: "columns", _pagination: ["pagination", "_pagination"], _actionControls: ["actionControls", "_actionControls"], selectable: "selectable", baseQuery: "baseQuery", _bulkActionControls: ["bulkActionControls", "_bulkActionControls"], filterable: "filterable", sortable: "sortable", _displayOptions: ["displayOptions", "_displayOptions"] }, outputs: { onColumnsChange: "onColumnsChange", itemsSelect: "itemsSelect" }, providers: [
{
provide: UserPreferencesConfigurationStrategy,
useClass: UserPreferencesConfigurationStrategy
},
{
provide: SmartGroupGridConfigurationStrategy,
useClass: SmartGroupGridConfigurationStrategy
},
{
provide: DATA_GRID_CONFIGURATION_STRATEGY,
useClass: SubAssetsGridConfigurationStrategy
},
{
provide: DATA_GRID_CONFIGURATION_CONTEXT_PROVIDER,
useExisting: SubAssetsGridComponent
}
], viewQueries: [{ propertyName: "dataGrid", first: true, predicate: DataGridComponent, descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<c8y-data-grid\n [title]=\"title\"\n [loadingItemsLabel]=\"loadingItemsLabel\"\n [columns]=\"columns\"\n [pagination]=\"pagination\"\n [actionControls]=\"actionControls\"\n [selectable]=\"selectable\"\n [bulkActionControls]=\"bulkActionControls\"\n [serverSideDataCallback]=\"serverSideDataCallback\"\n [infiniteScroll]=\"getInfiniteScrollMode\"\n [showCounterWarning]=\"showCounterWarning\"\n [refresh]=\"refresh\"\n [showSearch]=\"showSearch\"\n [displayOptions]=\"displayOptions\"\n (itemsSelect)=\"itemsSelect.emit($event)\"\n c8yProductExperience\n [actionName]=\"PRODUCT_EXPERIENCE.EVENT\"\n (onReload)=\"onReload()\"\n>\n <c8y-ui-empty-state\n [icon]=\"'c8y-group-add'\"\n [title]=\"stats?.size > 0 ? (noResultsMessage | translate) : (noDataMessage | translate)\"\n [subtitle]=\"stats?.size > 0 ? (noResultsSubtitle | translate) : (emptyStateText | translate)\"\n *emptyStateContext=\"let stats\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n\n <ng-container *ngFor=\"let column of columns; trackBy: trackByName\">\n <c8y-column [name]=\"column.name\"></c8y-column>\n </ng-container>\n</c8y-data-grid>\n", dependencies: [{ kind: "component", type: DataGridComponent, selector: "c8y-data-grid", inputs: ["title", "loadMoreItemsLabel", "loadingItemsLabel", "showSearch", "refresh", "columns", "rows", "pagination", "childNodePagination", "infiniteScroll", "serverSideDataCallback", "selectable", "singleSelection", "selectionPrimaryKey", "displayOptions", "actionControls", "bulkActionControls", "headerActionControls", "searchText", "configureColumnsEnabled", "showCounterWarning", "activeClassName", "expandableRows", "treeGrid", "hideReload", "childNodesProperty", "parentNodeLabelProperty"], outputs: ["rowMouseOver", "rowMouseLeave", "rowClick", "onConfigChange", "onBeforeFilter", "onBeforeSearch", "onFilter", "itemsSelect", "onReload", "onAddCustomColumn", "onRemoveCustomColumn", "onColumnFilterReset", "onSort", "onPageSizeChange", "onColumnReordered", "onColumnVisibilityChange"] }, { kind: "directive", type: ProductExperienceDirective, selector: "[c8yProductExperience]", inputs: ["actionName", "actionData", "inherit", "suppressDataOverriding"] }, { kind: "directive", type: EmptyStateContextDirective, selector: "[emptyStateContext]" }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: ColumnDirective, selector: "c8y-column", inputs: ["name"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SubAssetsGridComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-sub-assets-grid', providers: [
{
provide: UserPreferencesConfigurationStrategy,
useClass: UserPreferencesConfigurationStrategy
},
{
provide: SmartGroupGridConfigurationStrategy,
useClass: SmartGroupGridConfigurationStrategy
},
{
provide: DATA_GRID_CONFIGURATION_STRATEGY,
useClass: SubAssetsGridConfigurationStrategy
},
{
provide: DATA_GRID_CONFIGUR