UNPKG

@c8y/apps

Version:

Cumulocity IoT applications

267 lines (230 loc) • 7.71 kB
import { Injectable } from '@angular/core'; import { transform } from 'lodash-es'; import { IManagedObject, InventoryService, QueriesUtil } from '@c8y/client'; import { ActionControl, BuiltInActionType, BulkActionControl, Column, Pagination } from '@c8y/ngx-components'; import { TypeDataGridColumn } from './type-data-grid-column/type.data-grid-column'; /** Model for custom type filtering form. */ export interface TypeFilteringModel { group?: boolean; device?: boolean; smartRule?: boolean; dashboard?: boolean; file?: boolean; application?: boolean; } /** * This is the example service for a data grid: * provides the list of columns, initial pagination object, actions; * as well as performs the query for data based on the current grid setup. */ @Injectable() export class ServerGridExampleService { /** This will be used to build the inventory queries. */ protected queriesUtil: QueriesUtil; constructor(protected inventoryService: InventoryService) { this.queriesUtil = new QueriesUtil(); } /** * Returns a list of columns. * We define 2 columns with inline objects (they display simple properties * and use default header, cell and filtring form). * The last column is defined via a class instance (it displays a value based on * several properties of the row item and has custom header, cell and filtering form). */ getColumns(): Column[] { const columns = [ { name: 'id', header: 'ID', path: 'id', filterable: true, sortable: true }, { name: 'name', header: 'Name', path: 'name', filterable: true, sortable: true }, new TypeDataGridColumn() ]; return columns; } /** Returns initial pagination object. */ getPagination(): Pagination { return { pageSize: 10, currentPage: 1 }; } /** Returns an array of individual row actions. */ getActionControls(): ActionControl[] { return [ { type: BuiltInActionType.Edit, callback: item => console.dir(item) }, { type: BuiltInActionType.Export, callback: item => console.dir(item) }, { type: BuiltInActionType.Delete, callback: item => console.dir(item) }, { type: 'customAction', icon: 'online', text: 'Custom action', callback: item => console.dir(item) } ]; } /** Returns an array of bulk row actions. */ getBulkActionControls(): BulkActionControl[] { return [ { type: BuiltInActionType.Export, callback: selectedItemIds => console.dir(selectedItemIds) }, { type: BuiltInActionType.Delete, callback: selectedItemIds => console.dir(selectedItemIds) }, { type: 'customAction', icon: 'online', text: 'Custom action', callback: selectedItemIds => console.dir(selectedItemIds) } ]; } /** Returns data for current columns and pagination setup. */ async getData(columns: Column[], pagination: Pagination) { // build filters based on columns and pagination const filters = this.getFilters(columns, pagination); // execute inventory query for the list of managed objects return this.inventoryService.list(filters); } /** Returns the number of items matching current columns and pagination setup. */ async getCount(columns: Column[], pagination: Pagination) { const filters = { // build filters based on columns and pagination ...this.getFilters(columns, pagination), // but we only need the number of items, not the items themselves pageSize: 1, currentPage: 1 }; return (await this.inventoryService.list(filters)).paging.totalPages; } /** Returns the total number of items (with no filters). */ async getTotal(): Promise<number> { const filters = { pageSize: 1, withTotalPages: true }; return (await this.inventoryService.list(filters)).paging.totalPages; } /** Returns an icon and label representing the type of the managed object. */ getTypeIconAndLabel(mo: IManagedObject): { icon: string; label: string } { let icon = 'question'; let label = 'Other'; if (mo.type === 'c8y_DeviceGroup') { icon = 'c8y-group'; label = 'Group'; } if (mo.c8y_IsDevice !== undefined) { icon = 'exchange'; label = 'Device'; } if (mo.type === 'c8y_SmartRule' || mo.type === 'c8y_PrivateSmartRule') { icon = 'c8y-smart-rules'; label = 'Smart rule'; } if (mo.c8y_Dashboard !== undefined) { icon = 'th'; label = 'Dashboard'; } if (mo.c8y_IsBinary !== undefined) { icon = 'file'; label = 'File'; } if (mo.type && mo.type.startsWith('c8y_Application')) { icon = 'c8y-atom'; label = 'Application'; } return { icon, label }; } /** Returns a query object for given settings of filtering by type. */ getTypeQuery(model: TypeFilteringModel): any { let query: any = {}; if (model.group) { query = this.queriesUtil.addOrFilter(query, { type: 'c8y_DeviceGroup' }); } if (model.device) { query = this.queriesUtil.addOrFilter(query, { __has: 'c8y_IsDevice' }); } if (model.smartRule) { query = this.queriesUtil.addOrFilter(query, { type: { __in: ['c8y_SmartRule', 'c8y_PrivateSmartRule'] } }); } if (model.dashboard) { query = this.queriesUtil.addOrFilter(query, { type: { __has: 'c8y_Dashboard' } }); } if (model.file) { query = this.queriesUtil.addOrFilter(query, { type: { __has: 'c8y_IsBinary' } }); } if (model.application) { query = this.queriesUtil.addOrFilter(query, { type: 'c8y_Application_*' }); } return query; } /** Returns filters for given columns and pagination setup. */ private getFilters(columns: Column[], pagination: Pagination) { return { query: this.getQueryString(columns), pageSize: pagination.pageSize, currentPage: pagination.currentPage, withChildren: false, withTotalPages: true }; } /** Returns a query string based on columns setup. */ private getQueryString(columns: Column[]): string { const fullQuery = this.getQueryObj(columns); return this.queriesUtil.buildQuery(fullQuery); } /** Returns a query object based on columns setup. */ private getQueryObj(columns: Column[]): any { return transform(columns, (query, column) => this.addColumnQuery(query, column), { __filter: {}, __orderby: [] }); } /** Extends given query with a part based on the setup of given column. */ private addColumnQuery(query: any, column: Column): void { // when a column is marked as filterable if (column.filterable) { // in the case of default filtering form, `filterPredicate` will contain the string entered by a user if (column.filterPredicate) { // so we use it as the expected value, * allow to search for it anywhere in the property query.__filter[column.path] = `*${column.filterPredicate}*`; } // in the case of custom filtering form, we're storing the query in `externalFilterQuery.query` if (column.externalFilterQuery) { query = this.queriesUtil.addAndFilter(query, column.externalFilterQuery.query); } } // when a column is sortable and has a specified sorting order if (column.sortable && column.sortOrder) { // add sorting condition for the configured column `path` query.__orderby.push({ [column.path]: column.sortOrder === 'asc' ? 1 : -1 }); } return query; } }