UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

828 lines (820 loc) 202 kB
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