{
  "widgetsBundle": {
    "alias": "entity_admin_widgets",
    "title": "Entity admin widgets",
    "image": null
  },
  "widgetTypes": [
    {
      "alias": "device_admin_table",
      "name": "Device admin table",
      "descriptor": {
        "type": "latest",
        "sizeX": 7.5,
        "sizeY": 6.5,
        "resources": [],
        "templateHtml": "<tb-entities-table-widget \n    table-id=\"tableId\"\n    ctx=\"ctx\">\n</tb-entities-table-widget>",
        "templateCss": "",
        "controllerScript": "self.onInit = function() {\n    var scope = self.ctx.$scope;\n    var id = self.ctx.$scope.$injector.get('utils').guid();\n    scope.tableId = \"table-\"+id;\n    scope.ctx = self.ctx;\n}\n\nself.onDataUpdated = function() {\n    self.ctx.$scope.$broadcast('entities-table-data-updated', self.ctx.$scope.tableId);\n}\n\nself.typeParameters = function() {\n    return {\n        maxDatasources: 1,\n        dataKeysOptional: true\n    };\n}\n\nself.actionSources = function() {\n    return {\n        'actionCellButton': {\n            name: 'widget-action.action-cell-button',\n            multiple: true\n        },\n        'rowClick': {\n            name: 'widget-action.row-click',\n            multiple: false\n        }\n    };\n}\n\nself.onDestroy = function() {\n}\n",
        "settingsSchema": "{\n    \"schema\": {\n        \"type\": \"object\",\n        \"title\": \"EntitiesTableSettings\",\n        \"properties\": {\n            \"entitiesTitle\": {\n                \"title\": \"Entities table title\",\n                \"type\": \"string\",\n                \"default\": \"\"\n            },\n            \"enableSearch\": {\n                \"title\": \"Enable entities search\",\n                \"type\": \"boolean\",\n                \"default\": true\n            },\n            \"enableSelectColumnDisplay\": {\n                \"title\": \"Enable select columns to display\",\n                \"type\": \"boolean\",\n                \"default\": true\n            },\n            \"displayEntityName\": {\n                \"title\": \"Display entity name column\",\n                \"type\": \"boolean\",\n                \"default\": true\n            },\n            \"entityNameColumnTitle\": {\n                \"title\": \"Entity name column title\",\n                \"type\": \"string\",\n                \"default\": \"\"\n            },\n            \"displayEntityLabel\": {\n                \"title\": \"Display entity label column\",\n                \"type\": \"boolean\",\n                \"default\": false\n            },\n            \"entityLabelColumnTitle\": {\n                \"title\": \"Entity label column title\",\n                \"type\": \"string\",\n                \"default\": \"\"\n            },\n            \"displayEntityType\": {\n                \"title\": \"Display entity type column\",\n                \"type\": \"boolean\",\n                \"default\": true\n            },\n            \"displayPagination\": {\n                \"title\": \"Display pagination\",\n                \"type\": \"boolean\",\n                \"default\": true\n            },\n            \"defaultPageSize\": {\n                \"title\": \"Default page size\",\n                \"type\": \"number\",\n                \"default\": 10\n            },\n            \"defaultSortOrder\": {\n                \"title\": \"Default sort order\",\n                \"type\": \"string\",\n                \"default\": \"entityName\"\n            }\n        },\n        \"required\": []\n    },\n    \"form\": [\n        \"entitiesTitle\",\n        \"enableSearch\",\n        \"enableSelectColumnDisplay\",\n        \"displayEntityName\",\n        \"entityNameColumnTitle\",\n        \"displayEntityLabel\",\n        \"entityLabelColumnTitle\",\n        \"displayEntityType\",\n        \"displayPagination\",\n        \"defaultPageSize\",\n        \"defaultSortOrder\"\n    ]\n}",
        "dataKeySettingsSchema": "{\n    \"schema\": {\n        \"type\": \"object\",\n        \"title\": \"DataKeySettings\",\n        \"properties\": {\n            \"columnWidth\": {\n                \"title\": \"Column width (px or %)\",\n                \"type\": \"string\",\n                \"default\": \"0px\"\n            },\n            \"useCellStyleFunction\": {\n                \"title\": \"Use cell style function\",\n                \"type\": \"boolean\",\n                \"default\": false\n            },\n            \"cellStyleFunction\": {\n                \"title\": \"Cell style function: f(value)\",\n                \"type\": \"string\",\n                \"default\": \"\"\n            },\n            \"useCellContentFunction\": {\n                \"title\": \"Use cell content function\",\n                \"type\": \"boolean\",\n                \"default\": false\n            },\n            \"cellContentFunction\": {\n                \"title\": \"Cell content function: f(value, entity, filter)\",\n                \"type\": \"string\",\n                \"default\": \"\"\n            }\n        },\n        \"required\": []\n    },\n    \"form\": [\n        \"columnWidth\",\n        \"useCellStyleFunction\",\n        {\n            \"key\": \"cellStyleFunction\",\n            \"type\": \"javascript\"\n        },\n        \"useCellContentFunction\",\n        {\n            \"key\": \"cellContentFunction\",\n            \"type\": \"javascript\"\n        }\n    ]\n}",
        "defaultConfig": "{\"timewindow\":{\"realtime\":{\"interval\":1000,\"timewindowMs\":86400000},\"aggregation\":{\"type\":\"NONE\",\"limit\":200}},\"showTitle\":true,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"4px\",\"settings\":{\"enableSearch\":true,\"displayPagination\":true,\"defaultPageSize\":10,\"defaultSortOrder\":\"entityName\",\"displayEntityName\":true,\"displayEntityType\":true,\"entitiesTitle\":\"Device admin table\",\"enableSelectColumnDisplay\":true},\"title\":\"device\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400,\"padding\":\"5px 10px 5px 10px\"},\"useDashboardTimewindow\":false,\"showLegend\":false,\"datasources\":[{\"type\":\"function\",\"name\":\"Simulated\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#f44336\",\"settings\":{\"columnWidth\":\"0px\",\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.6401141393938932,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}],\"showTitleIcon\":false,\"titleIcon\":\"more_horiz\",\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\",\"titleTooltip\":\"\",\"widgetStyle\":{},\"displayTimewindow\":true,\"actions\":{\"headerButton\":[{\"id\":\"70837a9d-c3de-a9a7-03c5-dccd14998758\",\"name\":\"Add device\",\"icon\":\"add\",\"type\":\"customPretty\",\"customHtml\":\"<md-dialog aria-label=\\\"Add entity\\\" style=\\\"width: 480px\\\">\\n    <form name=\\\"addDeviceForm\\\" ng-submit=\\\"vm.save()\\\">\\n        <md-toolbar>\\n            <div class=\\\"md-toolbar-tools\\\">\\n                <h2>Add device</h2>\\n                <span flex></span>\\n                <md-button class=\\\"md-icon-button\\\" ng-click=\\\"vm.cancel()\\\">\\n                    <ng-md-icon icon=\\\"close\\\" aria-label=\\\"Close\\\"></ng-md-icon>\\n                </md-button>\\n            </div>\\n        </md-toolbar>\\n        <md-progress-linear class=\\\"md-warn\\\" md-mode=\\\"indeterminate\\\" ng-disabled=\\\"!$root.loading && !vm.loading\\\" ng-show=\\\"$root.loading || vm.loading\\\"></md-progress-linear>\\n        <span style=\\\"min-height: 5px;\\\" flex=\\\"\\\" ng-show=\\\"!$root.loading && !vm.loading\\\"></span>\\n        <md-dialog-content>\\n            <div class=\\\"md-dialog-content\\\">\\n                <fieldset ng-disabled=\\\"$root.loading || vm.loading\\\">\\n                    <md-input-container flex class=\\\"md-block\\\">\\n                        <label>Device name</label>\\n                        <input ng-model=\\\"vm.deviceName\\\" name=deviceName required>\\n                        <div ng-messages=\\\"addDeviceForm.deviceName.$error\\\">\\n                            <div ng-message=\\\"required\\\">Device name is required.</div>\\n                        </div>\\n                    </md-input-container>\\n                    <div flex layout=\\\"row\\\">\\n                        <tb-entity-subtype-autocomplete flex=\\\"50\\\"\\n                            ng-disabled=\\\"$root.loading || vm.loading\\\"\\n                            tb-required=\\\"true\\\"\\n                            the-form=\\\"addDeviceForm\\\"\\n                            ng-model=\\\"vm.deviceType\\\"\\n                            entity-type=\\\"vm.types.entityType.device\\\">\\n                        </tb-entity-subtype-autocomplete>\\n                        <md-input-container flex=\\\"50\\\" class=\\\"md-block\\\">\\n                            <label>Label</label>\\n                            <input name=\\\"deviceLabel\\\" ng-model=\\\"vm.deviceLabel\\\">\\n                        </md-input-container>\\n                    </div>\\n                    <div flex layout=\\\"row\\\">\\n                        <md-input-container flex=\\\"50\\\" class=\\\"md-block\\\">\\n                            <label>Latitude</label>\\n                            <input type=\\\"number\\\" step=\\\"any\\\" name=\\\"latitude\\\" ng-model=\\\"vm.attributes.latitude\\\">\\n                        </md-input-container>\\n                        <md-input-container flex=\\\"50\\\" class=\\\"md-block\\\">\\n                            <label>Longitude</label>\\n                            <input type=\\\"number\\\" step=\\\"any\\\" name=\\\"longitude\\\" ng-model=\\\"vm.attributes.longitude\\\">\\n                        </md-input-container>\\n                    </div>\\n                </fieldset>\\n            </div>\\n        </md-dialog-content>\\n        <md-dialog-actions>\\n            <md-button type=\\\"submit\\\" ng-disabled=\\\"vm.loading || addDeviceForm.$invalid || !addDeviceForm.$dirty\\\" class=\\\"md-raised md-primary\\\">Create</md-button>\\n            <md-button ng-click=\\\"vm.cancel()\\\" class=\\\"md-primary\\\">Cancel</md-button>\\n        </md-dialog-actions>\\n    </form>\\n</md-dialog>\\n\",\"customCss\":\"\",\"customFunction\":\"let $injector = widgetContext.$scope.$injector;\\nlet $mdDialog = $injector.get('$mdDialog'),\\n    $document = $injector.get('$document'),\\n    $q = $injector.get('$q'),\\n    $rootScope = $injector.get('$rootScope'),\\n    types = $injector.get('types'),\\n    deviceService = $injector.get('deviceService'),\\n    attributeService = $injector.get('attributeService');\\n    \\nopenAddDeviceDialog();\\n\\nfunction openAddDeviceDialog() {\\n    $mdDialog.show({\\n        controller: ['$scope','$mdDialog', AddDeviceDialogController],\\n        controllerAs: 'vm',\\n        template: htmlTemplate,\\n        parent: angular.element($document[0].body),\\n        targetEvent: $event,\\n        multiple: true,\\n        clickOutsideToClose: false\\n    });\\n}\\n\\nfunction AddDeviceDialogController($scope, $mdDialog) {\\n    let vm = this;\\n    vm.types = types;\\n    vm.attributes = {};\\n    \\n    vm.cancel = () => {\\n        $mdDialog.hide();\\n    };\\n    \\n    vm.save = () => {\\n        vm.loading = true;\\n        $scope.addDeviceForm.$setPristine();\\n        let device = {\\n            name: vm.deviceName,\\n            type: vm.deviceType,\\n            label: vm.deviceLabel\\n        };\\n        deviceService.saveDevice(device).then(\\n            (device) => {\\n                saveAttributes(device.id).then(\\n                    () => {\\n                        vm.loading = false;\\n                        updateAliasData();\\n                        $mdDialog.hide();\\n                    }\\n                );\\n            },\\n            () => {\\n                vm.loading = false;\\n            }\\n        );\\n    };\\n    \\n    function saveAttributes(entityId) {\\n        let attributesArray = [];\\n        for (let key in vm.attributes) {\\n            attributesArray.push({key: key, value: vm.attributes[key]});\\n        }\\n        if (attributesArray.length > 0) {\\n            return attributeService.saveEntityAttributes(entityId.entityType, entityId.id, \\\"SERVER_SCOPE\\\", attributesArray);\\n        } else {\\n            return $q.when([]);\\n        }\\n    }\\n    \\n    function updateAliasData() {\\n        let aliasIds = [];\\n        for (let id in widgetContext.aliasController.resolvedAliases) {\\n            aliasIds.push(id);\\n        }\\n        let tasks = [];\\n        aliasIds.forEach((aliasId) => {\\n            widgetContext.aliasController.setAliasUnresolved(aliasId);\\n            tasks.push(widgetContext.aliasController.getAliasInfo(aliasId));\\n        });\\n        $q.all(tasks).then(() => {\\n            $rootScope.$broadcast('widgetForceReInit');\\n        });\\n    }\\n}\"}],\"actionCellButton\":[{\"id\":\"93931e52-5d7c-903e-67aa-b9435df44ff4\",\"name\":\"Edit device\",\"icon\":\"edit\",\"type\":\"customPretty\",\"customHtml\":\"<md-dialog aria-label=\\\"Edit entity\\\" style=\\\"width: 480px\\\">\\n    <form name=\\\"editDeviceForm\\\" ng-submit=\\\"vm.save()\\\">\\n        <md-toolbar>\\n            <div class=\\\"md-toolbar-tools\\\">\\n                <h2>Edit device</h2>\\n                <span flex></span>\\n                <md-button class=\\\"md-icon-button\\\" ng-click=\\\"vm.cancel()\\\">\\n                    <ng-md-icon icon=\\\"close\\\" aria-label=\\\"Close\\\"></ng-md-icon>\\n                </md-button>\\n            </div>\\n        </md-toolbar>\\n        <md-progress-linear class=\\\"md-warn\\\" md-mode=\\\"indeterminate\\\" ng-disabled=\\\"!$root.loading && !vm.loading\\\" ng-show=\\\"$root.loading || vm.loading\\\"></md-progress-linear>\\n        <span style=\\\"min-height: 5px;\\\" flex=\\\"\\\" ng-show=\\\"!$root.loading && !vm.loading\\\"></span>\\n        <md-dialog-content>\\n            <div class=\\\"md-dialog-content\\\">\\n                <fieldset ng-disabled=\\\"$root.loading || vm.loading\\\">\\n                    <md-input-container flex class=\\\"md-block\\\">\\n                        <label>Device name</label>\\n                        <input ng-model=\\\"vm.device.name\\\" name=deviceName required>\\n                        <div ng-messages=\\\"editDeviceForm.deviceName.$error\\\">\\n                            <div ng-message=\\\"required\\\">Device name is required.</div>\\n                        </div>\\n                    </md-input-container>\\n                    <div flex layout=\\\"row\\\">\\n                        <tb-entity-subtype-autocomplete flex=\\\"50\\\"\\n                            ng-disabled=\\\"$root.loading || vm.loading\\\"\\n                            tb-required=\\\"true\\\"\\n                            the-form=\\\"editDeviceForm\\\"\\n                            ng-model=\\\"vm.device.type\\\"\\n                            entity-type=\\\"vm.types.entityType.device\\\">\\n                        </tb-entity-subtype-autocomplete>\\n                        <md-input-container flex=\\\"50\\\" class=\\\"md-block\\\">\\n                            <label>Label</label>\\n                            <input name=\\\"deviceLabel\\\" ng-model=\\\"vm.device.label\\\">\\n                        </md-input-container>\\n                    </div>\\n                    <div flex layout=\\\"row\\\">\\n                        <md-input-container flex=\\\"50\\\" class=\\\"md-block\\\">\\n                            <label>Latitude</label>\\n                            <input type=\\\"number\\\" step=\\\"any\\\" name=\\\"latitude\\\" ng-model=\\\"vm.attributes.latitude\\\">\\n                        </md-input-container>\\n                        <md-input-container flex=\\\"50\\\" class=\\\"md-block\\\">\\n                            <label>Longitude</label>\\n                            <input type=\\\"number\\\" step=\\\"any\\\" name=\\\"longitude\\\" ng-model=\\\"vm.attributes.longitude\\\">\\n                        </md-input-container>\\n                    </div>\\n                </fieldset>\\n            </div>\\n        </md-dialog-content>\\n        <md-dialog-actions>\\n            <md-button type=\\\"submit\\\" ng-disabled=\\\"vm.loading || editDeviceForm.$invalid || !editDeviceForm.$dirty\\\" class=\\\"md-raised md-primary\\\">Create</md-button>\\n            <md-button ng-click=\\\"vm.cancel()\\\" class=\\\"md-primary\\\">Cancel</md-button>\\n        </md-dialog-actions>\\n    </form>\\n</md-dialog>\",\"customCss\":\"\",\"customFunction\":\"let $injector = widgetContext.$scope.$injector;\\nlet $mdDialog = $injector.get('$mdDialog'),\\n    $document = $injector.get('$document'),\\n    $q = $injector.get('$q'),\\n    $rootScope = $injector.get('$rootScope'),\\n    types = $injector.get('types'),\\n    deviceService = $injector.get('deviceService'),\\n    attributeService = $injector.get('attributeService');\\n    \\nopenEditDeviceDialog();\\n\\nfunction openEditDeviceDialog() {\\n    $mdDialog.show({\\n        controller: ['$scope','$mdDialog', EditDeviceDialogController],\\n        controllerAs: 'vm',\\n        template: htmlTemplate,\\n        parent: angular.element($document[0].body),\\n        targetEvent: $event,\\n        multiple: true,\\n        clickOutsideToClose: false\\n    });\\n}\\n\\nfunction EditDeviceDialogController($scope,$mdDialog) {\\n    let vm = this;\\n    vm.types = types;\\n    vm.loading = false;\\n    vm.attributes = {};\\n    \\n    getEntityInfo();\\n    \\n    function getEntityInfo() {\\n        vm.loading = true;\\n        deviceService.getDevice(entityId.id).then(\\n            (device) => {\\n                attributeService.getEntityAttributesValues(entityId.entityType, entityId.id, 'SERVER_SCOPE').then(\\n                   (data) => {\\n                        if (data.length) {\\n                            getEntityAttributes(data);\\n                        }\\n                        vm.device = device;\\n                        vm.loading = false;\\n                   } \\n                );\\n            }\\n        )\\n    }\\n    \\n    vm.cancel = function() {\\n        $mdDialog.hide();\\n    };\\n    \\n    vm.save = () => {\\n        vm.loading = true;\\n        $scope.editDeviceForm.$setPristine();\\n        deviceService.saveDevice(vm.device).then(\\n            () => {\\n                saveAttributes().then(\\n                    () => {\\n                        updateAliasData();\\n                        vm.loading = false;\\n                        $mdDialog.hide();\\n                    }\\n                );\\n            },\\n            () => {\\n                vm.loading = false;\\n            }\\n        );\\n    }\\n    \\n    function getEntityAttributes(attributes) {\\n        for (let i = 0; i < attributes.length; i++) {\\n            vm.attributes[attributes[i].key] = attributes[i].value; \\n        }\\n    }\\n    \\n    function saveAttributes() {\\n        let attributesArray = [];\\n        for (let key in vm.attributes) {\\n            attributesArray.push({key: key, value: vm.attributes[key]});\\n        }\\n        if (attributesArray.length > 0) {\\n            return attributeService.saveEntityAttributes(entityId.entityType, entityId.id, \\\"SERVER_SCOPE\\\", attributesArray);\\n        }  else {\\n            return $q.when([]);\\n        }\\n    }\\n    \\n    function updateAliasData() {\\n        let aliasIds = [];\\n        for (let id in widgetContext.aliasController.resolvedAliases) {\\n            aliasIds.push(id);\\n        }\\n        let tasks = [];\\n        aliasIds.forEach((aliasId) => {\\n            widgetContext.aliasController.setAliasUnresolved(aliasId);\\n            tasks.push(widgetContext.aliasController.getAliasInfo(aliasId));\\n        });\\n        console.log(widgetContext);\\n        $q.all(tasks).then(() => {\\n            $rootScope.$broadcast('widgetForceReInit');\\n        });\\n    }\\n}\\n\"},{\"id\":\"ec2708f6-9ff0-186b-e4fc-7635ebfa3074\",\"name\":\"Delete device\",\"icon\":\"delete\",\"type\":\"custom\",\"customFunction\":\"let $injector = widgetContext.$scope.$injector;\\nlet $mdDialog = $injector.get('$mdDialog'),\\n    $document = $injector.get('$document'),\\n    types = $injector.get('types'),\\n    deviceService = $injector.get('deviceService'),\\n    $rootScope = $injector.get('$rootScope'),\\n    $q = $injector.get('$q');\\n\\nopenDeleteDeviceDialog();\\n\\nfunction openDeleteDeviceDialog() {\\n    let title = \\\"Are you sure you want to delete the device \\\" + entityName +  \\\"?\\\";\\n    let content = \\\"Be careful, after the confirmation, the device and all related data will become unrecoverable!\\\";\\n    let confirm = $mdDialog.confirm()\\n        .targetEvent($event)\\n        .title(title)\\n        .htmlContent(content)\\n        .ariaLabel(title)\\n        .cancel('Cancel')\\n        .ok('Delete');\\n    $mdDialog.show(confirm).then(() => {\\n        deleteDevice();\\n    })\\n}\\n\\nfunction deleteDevice() {\\n    deviceService.deleteDevice(entityId.id).then(\\n        () => {\\n            updateAliasData();\\n        }\\n    );\\n}\\n\\nfunction updateAliasData() {\\n    let aliasIds = [];\\n    for (let id in widgetContext.aliasController.resolvedAliases) {\\n        aliasIds.push(id);\\n    }\\n    let tasks = [];\\n    aliasIds.forEach((aliasId) => {\\n        widgetContext.aliasController.setAliasUnresolved(aliasId);\\n        tasks.push(widgetContext.aliasController.getAliasInfo(aliasId));\\n    });\\n    $q.all(tasks).then(() => {\\n        $rootScope.$broadcast('entityAliasesChanged', aliasIds);\\n    });\\n}\"}]}}"
      }
    },
    {
      "alias": "asset_admin_table",
      "name": "Asset admin table",
      "descriptor": {
        "type": "latest",
        "sizeX": 7.5,
        "sizeY": 6.5,
        "resources": [],
        "templateHtml": "<tb-entities-table-widget \n    table-id=\"tableId\"\n    ctx=\"ctx\">\n</tb-entities-table-widget>",
        "templateCss": "",
        "controllerScript": "self.onInit = function() {\n    var scope = self.ctx.$scope;\n    var id = self.ctx.$scope.$injector.get('utils').guid();\n    scope.tableId = \"table-\"+id;\n    scope.ctx = self.ctx;\n}\n\nself.onDataUpdated = function() {\n    self.ctx.$scope.$broadcast('entities-table-data-updated', self.ctx.$scope.tableId);\n}\n\nself.typeParameters = function() {\n    return {\n        maxDatasources: 1,\n        dataKeysOptional: true\n    };\n}\n\nself.actionSources = function() {\n    return {\n        'actionCellButton': {\n            name: 'widget-action.action-cell-button',\n            multiple: true\n        },\n        'rowClick': {\n            name: 'widget-action.row-click',\n            multiple: false\n        }\n    };\n}\n\nself.onDestroy = function() {\n}\n",
        "settingsSchema": "{\n    \"schema\": {\n        \"type\": \"object\",\n        \"title\": \"EntitiesTableSettings\",\n        \"properties\": {\n            \"entitiesTitle\": {\n                \"title\": \"Entities table title\",\n                \"type\": \"string\",\n                \"default\": \"\"\n            },\n            \"enableSearch\": {\n                \"title\": \"Enable entities search\",\n                \"type\": \"boolean\",\n                \"default\": true\n            },\n            \"enableSelectColumnDisplay\": {\n                \"title\": \"Enable select columns to display\",\n                \"type\": \"boolean\",\n                \"default\": true\n            },\n            \"displayEntityName\": {\n                \"title\": \"Display entity name column\",\n                \"type\": \"boolean\",\n                \"default\": true\n            },\n            \"entityNameColumnTitle\": {\n                \"title\": \"Entity name column title\",\n                \"type\": \"string\",\n                \"default\": \"\"\n            },\n            \"displayEntityLabel\": {\n                \"title\": \"Display entity label column\",\n                \"type\": \"boolean\",\n                \"default\": false\n            },\n            \"entityLabelColumnTitle\": {\n                \"title\": \"Entity label column title\",\n                \"type\": \"string\",\n                \"default\": \"\"\n            },\n            \"displayEntityType\": {\n                \"title\": \"Display entity type column\",\n                \"type\": \"boolean\",\n                \"default\": true\n            },\n            \"displayPagination\": {\n                \"title\": \"Display pagination\",\n                \"type\": \"boolean\",\n                \"default\": true\n            },\n            \"defaultPageSize\": {\n                \"title\": \"Default page size\",\n                \"type\": \"number\",\n                \"default\": 10\n            },\n            \"defaultSortOrder\": {\n                \"title\": \"Default sort order\",\n                \"type\": \"string\",\n                \"default\": \"entityName\"\n            }\n        },\n        \"required\": []\n    },\n    \"form\": [\n        \"entitiesTitle\",\n        \"enableSearch\",\n        \"enableSelectColumnDisplay\",\n        \"displayEntityName\",\n        \"entityNameColumnTitle\",\n        \"displayEntityLabel\",\n        \"entityLabelColumnTitle\",\n        \"displayEntityType\",\n        \"displayPagination\",\n        \"defaultPageSize\",\n        \"defaultSortOrder\"\n    ]\n}",
        "dataKeySettingsSchema": "{\n    \"schema\": {\n        \"type\": \"object\",\n        \"title\": \"DataKeySettings\",\n        \"properties\": {\n            \"columnWidth\": {\n                \"title\": \"Column width (px or %)\",\n                \"type\": \"string\",\n                \"default\": \"0px\"\n            },\n            \"useCellStyleFunction\": {\n                \"title\": \"Use cell style function\",\n                \"type\": \"boolean\",\n                \"default\": false\n            },\n            \"cellStyleFunction\": {\n                \"title\": \"Cell style function: f(value)\",\n                \"type\": \"string\",\n                \"default\": \"\"\n            },\n            \"useCellContentFunction\": {\n                \"title\": \"Use cell content function\",\n                \"type\": \"boolean\",\n                \"default\": false\n            },\n            \"cellContentFunction\": {\n                \"title\": \"Cell content function: f(value, entity, filter)\",\n                \"type\": \"string\",\n                \"default\": \"\"\n            }\n        },\n        \"required\": []\n    },\n    \"form\": [\n        \"columnWidth\",\n        \"useCellStyleFunction\",\n        {\n            \"key\": \"cellStyleFunction\",\n            \"type\": \"javascript\"\n        },\n        \"useCellContentFunction\",\n        {\n            \"key\": \"cellContentFunction\",\n            \"type\": \"javascript\"\n        }\n    ]\n}",
        "defaultConfig": "{\"timewindow\":{\"realtime\":{\"interval\":1000,\"timewindowMs\":86400000},\"aggregation\":{\"type\":\"NONE\",\"limit\":200}},\"showTitle\":true,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"4px\",\"settings\":{\"enableSearch\":true,\"displayPagination\":true,\"defaultPageSize\":10,\"defaultSortOrder\":\"entityName\",\"displayEntityName\":true,\"displayEntityType\":true,\"entitiesTitle\":\"Asset admin table\",\"enableSelectColumnDisplay\":true},\"title\":\"asset\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400,\"padding\":\"5px 10px 5px 10px\"},\"useDashboardTimewindow\":false,\"showLegend\":false,\"datasources\":[{\"type\":\"function\",\"name\":\"Simulated\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#f44336\",\"settings\":{\"columnWidth\":\"0px\",\"useCellStyleFunction\":false,\"cellStyleFunction\":\"\",\"useCellContentFunction\":false,\"cellContentFunction\":\"\"},\"_hash\":0.6401141393938932,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}],\"showTitleIcon\":false,\"titleIcon\":\"more_horiz\",\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\",\"titleTooltip\":\"\",\"widgetStyle\":{},\"displayTimewindow\":true,\"actions\":{\"headerButton\":[{\"id\":\"70837a9d-c3de-a9a7-03c5-dccd14998758\",\"name\":\"Add asset\",\"icon\":\"add\",\"type\":\"customPretty\",\"customHtml\":\"<md-dialog aria-label=\\\"Add entity\\\" style=\\\"width: 480px\\\">\\n    <form name=\\\"addAssetForm\\\" ng-submit=\\\"vm.save()\\\">\\n        <md-toolbar>\\n            <div class=\\\"md-toolbar-tools\\\">\\n                <h2>Add asset</h2>\\n                <span flex></span>\\n                <md-button class=\\\"md-icon-button\\\" ng-click=\\\"vm.cancel()\\\">\\n                    <ng-md-icon icon=\\\"close\\\" aria-label=\\\"Close\\\"></ng-md-icon>\\n                </md-button>\\n            </div>\\n        </md-toolbar>\\n        <md-progress-linear class=\\\"md-warn\\\" md-mode=\\\"indeterminate\\\" ng-disabled=\\\"!$root.loading && !vm.loading\\\" ng-show=\\\"$root.loading || vm.loading\\\"></md-progress-linear>\\n        <span style=\\\"min-height: 5px;\\\" flex=\\\"\\\" ng-show=\\\"!$root.loading && !vm.loading\\\"></span>\\n        <md-dialog-content>\\n            <div class=\\\"md-dialog-content\\\">\\n                <fieldset ng-disabled=\\\"$root.loading || vm.loading\\\">\\n                    <md-input-container flex class=\\\"md-block\\\">\\n                        <label>Asset name</label>\\n                        <input ng-model=\\\"vm.assetName\\\" name=assetName required>\\n                        <div ng-messages=\\\"addAssetForm.assetName.$error\\\">\\n                            <div ng-message=\\\"required\\\">Asset name is required.</div>\\n                        </div>\\n                    </md-input-container>\\n                    <tb-entity-subtype-autocomplete flex=\\\"50\\\"\\n                        ng-disabled=\\\"$root.loading || vm.loading\\\"\\n                        tb-required=\\\"true\\\"\\n                        the-form=\\\"addAssetForm\\\"\\n                        ng-model=\\\"vm.assetType\\\"\\n                        entity-type=\\\"vm.types.entityType.asset\\\">\\n                    </tb-entity-subtype-autocomplete>\\n                    <div flex layout=\\\"row\\\">\\n                        <md-input-container flex=\\\"50\\\" class=\\\"md-block\\\">\\n                            <label>Latitude</label>\\n                            <input type=\\\"number\\\" step=\\\"any\\\" name=\\\"latitude\\\" ng-model=\\\"vm.attributes.latitude\\\">\\n                        </md-input-container>\\n                        <md-input-container flex=\\\"50\\\" class=\\\"md-block\\\">\\n                            <label>Longitude</label>\\n                            <input type=\\\"number\\\" step=\\\"any\\\" name=\\\"longitude\\\" ng-model=\\\"vm.attributes.longitude\\\">\\n                        </md-input-container>\\n                    </div>\\n                </fieldset>\\n            </div>\\n        </md-dialog-content>\\n        <md-dialog-actions>\\n            <md-button type=\\\"submit\\\" ng-disabled=\\\"vm.loading || addAssetForm.$invalid || !addAssetForm.$dirty\\\" class=\\\"md-raised md-primary\\\">Create</md-button>\\n            <md-button ng-click=\\\"vm.cancel()\\\" class=\\\"md-primary\\\">Cancel</md-button>\\n        </md-dialog-actions>\\n    </form>\\n</md-dialog>\\n\",\"customCss\":\"\",\"customFunction\":\"let $injector = widgetContext.$scope.$injector;\\nlet $mdDialog = $injector.get('$mdDialog'),\\n    $document = $injector.get('$document'),\\n    $q = $injector.get('$q'),\\n    $rootScope = $injector.get('$rootScope'),\\n    types = $injector.get('types'),\\n    assetService = $injector.get('assetService'),\\n    attributeService = $injector.get('attributeService');\\n    \\nopenAddAssetDialog();\\n\\nfunction openAddAssetDialog() {\\n    $mdDialog.show({\\n        controller: ['$scope','$mdDialog', AddAssetDialogController],\\n        controllerAs: 'vm',\\n        template: htmlTemplate,\\n        parent: angular.element($document[0].body),\\n        targetEvent: $event,\\n        multiple: true,\\n        clickOutsideToClose: false\\n    });\\n}\\n\\nfunction AddAssetDialogController($scope, $mdDialog) {\\n    let vm = this;\\n    vm.types = types;\\n    vm.attributes = {};\\n    \\n    vm.cancel = () => {\\n        $mdDialog.hide();\\n    };\\n    \\n    vm.save = () => {\\n        vm.loading = true;\\n        $scope.addAssetForm.$setPristine();\\n        let asset = {\\n            name: vm.assetName,\\n            type: vm.assetType\\n        };\\n        assetService.saveAsset(asset).then(\\n            (asset) => {\\n                saveAttributes(asset.id).then(\\n                    () => {\\n                        vm.loading = false;\\n                        updateAliasData();\\n                        $mdDialog.hide();\\n                    }\\n                );\\n            },\\n            () => {\\n                vm.loading = false;\\n            }\\n        );\\n    };\\n    \\n    function saveAttributes(entityId) {\\n        let attributesArray = [];\\n        for (let key in vm.attributes) {\\n            attributesArray.push({key: key, value: vm.attributes[key]});\\n        }\\n        if (attributesArray.length > 0) {\\n            return attributeService.saveEntityAttributes(entityId.entityType, entityId.id, \\\"SERVER_SCOPE\\\", attributesArray);\\n        } else {\\n            return $q.when([]);\\n        }\\n    }\\n    \\n    function updateAliasData() {\\n        let aliasIds = [];\\n        for (let id in widgetContext.aliasController.resolvedAliases) {\\n            aliasIds.push(id);\\n        }\\n        let tasks = [];\\n        aliasIds.forEach((aliasId) => {\\n            widgetContext.aliasController.setAliasUnresolved(aliasId);\\n            tasks.push(widgetContext.aliasController.getAliasInfo(aliasId));\\n        });\\n        $q.all(tasks).then(() => {\\n            $rootScope.$broadcast('widgetForceReInit');\\n        });\\n    }\\n}\"}],\"actionCellButton\":[{\"id\":\"93931e52-5d7c-903e-67aa-b9435df44ff4\",\"name\":\"Edit asset\",\"icon\":\"edit\",\"type\":\"customPretty\",\"customHtml\":\"<md-dialog aria-label=\\\"Add entity\\\" style=\\\"width: 480px\\\">\\n    <form name=\\\"editAssetForm\\\" ng-submit=\\\"vm.save()\\\">\\n        <md-toolbar>\\n            <div class=\\\"md-toolbar-tools\\\">\\n                <h2>Edit asset</h2>\\n                <span flex></span>\\n                <md-button class=\\\"md-icon-button\\\" ng-click=\\\"vm.cancel()\\\">\\n                    <ng-md-icon icon=\\\"close\\\" aria-label=\\\"Close\\\"></ng-md-icon>\\n                </md-button>\\n            </div>\\n        </md-toolbar>\\n        <md-progress-linear class=\\\"md-warn\\\" md-mode=\\\"indeterminate\\\" ng-disabled=\\\"!$root.loading && !vm.loading\\\" ng-show=\\\"$root.loading || vm.loading\\\"></md-progress-linear>\\n        <span style=\\\"min-height: 5px;\\\" flex=\\\"\\\" ng-show=\\\"!$root.loading && !vm.loading\\\"></span>\\n        <md-dialog-content>\\n            <div class=\\\"md-dialog-content\\\">\\n                <fieldset ng-disabled=\\\"$root.loading || vm.loading\\\">\\n                    <md-input-container flex class=\\\"md-block\\\">\\n                        <label>Asset name</label>\\n                        <input ng-model=\\\"vm.asset.name\\\" name=assetName required>\\n                        <div ng-messages=\\\"editAssetForm.assetName.$error\\\">\\n                            <div ng-message=\\\"required\\\">Asset name is required.</div>\\n                        </div>\\n                    </md-input-container>\\n                    <tb-entity-subtype-autocomplete flex=\\\"50\\\"\\n                        ng-disabled=\\\"$root.loading || vm.loading\\\"\\n                        tb-required=\\\"true\\\"\\n                        the-form=\\\"editAssetForm\\\"\\n                        ng-model=\\\"vm.asset.type\\\"\\n                        entity-type=\\\"vm.types.entityType.asset\\\">\\n                    </tb-entity-subtype-autocomplete>\\n                    <div flex layout=\\\"row\\\">\\n                        <md-input-container flex=\\\"50\\\" class=\\\"md-block\\\">\\n                            <label>Latitude</label>\\n                            <input type=\\\"number\\\" step=\\\"any\\\" name=\\\"latitude\\\" ng-model=\\\"vm.attributes.latitude\\\">\\n                        </md-input-container>\\n                        <md-input-container flex=\\\"50\\\" class=\\\"md-block\\\">\\n                            <label>Longitude</label>\\n                            <input type=\\\"number\\\" step=\\\"any\\\" name=\\\"longitude\\\" ng-model=\\\"vm.attributes.longitude\\\">\\n                        </md-input-container>\\n                    </div>\\n                </fieldset>\\n            </div>\\n        </md-dialog-content>\\n        <md-dialog-actions>\\n            <md-button type=\\\"submit\\\" ng-disabled=\\\"vm.loading || editAssetForm.$invalid || !editAssetForm.$dirty\\\" class=\\\"md-raised md-primary\\\">Create</md-button>\\n            <md-button ng-click=\\\"vm.cancel()\\\" class=\\\"md-primary\\\">Cancel</md-button>\\n        </md-dialog-actions>\\n    </form>\\n</md-dialog>\\n\",\"customCss\":\"\",\"customFunction\":\"let $injector = widgetContext.$scope.$injector;\\nlet $mdDialog = $injector.get('$mdDialog'),\\n    $document = $injector.get('$document'),\\n    $q = $injector.get('$q'),\\n    $rootScope = $injector.get('$rootScope'),\\n    types = $injector.get('types'),\\n    assetService = $injector.get('assetService'),\\n    attributeService = $injector.get('attributeService');\\n    \\nopenEditAssetDialog();\\n\\nfunction openEditAssetDialog() {\\n    $mdDialog.show({\\n        controller: ['$scope','$mdDialog', EditAssetDialogController],\\n        controllerAs: 'vm',\\n        template: htmlTemplate,\\n        parent: angular.element($document[0].body),\\n        targetEvent: $event,\\n        multiple: true,\\n        clickOutsideToClose: false\\n    });\\n}\\n\\nfunction EditAssetDialogController($scope,$mdDialog) {\\n    let vm = this;\\n    vm.types = types;\\n    vm.loading = false;\\n    vm.attributes = {};\\n    \\n    getEntityInfo();\\n    \\n    function getEntityInfo() {\\n        vm.loading = true;\\n        assetService.getAsset(entityId.id).then(\\n            (asset) => {\\n                attributeService.getEntityAttributesValues(entityId.entityType, entityId.id, 'SERVER_SCOPE').then(\\n                   (data) => {\\n                        if (data.length) {\\n                            getEntityAttributes(data);\\n                        }\\n                        vm.asset = asset;\\n                        vm.loading = false;\\n                   } \\n                );\\n            }\\n        )\\n    }\\n    \\n    vm.cancel = function() {\\n        $mdDialog.hide();\\n    };\\n    \\n    vm.save = () => {\\n        vm.loading = true;\\n        $scope.editAssetForm.$setPristine();\\n        assetService.saveAsset(vm.asset).then(\\n            () => {\\n                saveAttributes().then(\\n                    () => {\\n                        updateAliasData();\\n                        vm.loading = false;\\n                        $mdDialog.hide();\\n                    }\\n                );\\n            },\\n            () => {\\n                vm.loading = false;\\n            }\\n        );\\n    }\\n    \\n    function getEntityAttributes(attributes) {\\n        for (let i = 0; i < attributes.length; i++) {\\n            vm.attributes[attributes[i].key] = attributes[i].value; \\n        }\\n    }\\n    \\n    function saveAttributes() {\\n        let attributesArray = [];\\n        for (let key in vm.attributes) {\\n            attributesArray.push({key: key, value: vm.attributes[key]});\\n        }\\n        if (attributesArray.length > 0) {\\n            return attributeService.saveEntityAttributes(entityId.entityType, entityId.id, \\\"SERVER_SCOPE\\\", attributesArray);\\n        }  else {\\n            return $q.when([]);\\n        }\\n    }\\n    \\n    function updateAliasData() {\\n        let aliasIds = [];\\n        for (let id in widgetContext.aliasController.resolvedAliases) {\\n            aliasIds.push(id);\\n        }\\n        let tasks = [];\\n        aliasIds.forEach((aliasId) => {\\n            widgetContext.aliasController.setAliasUnresolved(aliasId);\\n            tasks.push(widgetContext.aliasController.getAliasInfo(aliasId));\\n        });\\n        console.log(widgetContext);\\n        $q.all(tasks).then(() => {\\n            $rootScope.$broadcast('widgetForceReInit');\\n        });\\n    }\\n}\\n\"},{\"id\":\"ec2708f6-9ff0-186b-e4fc-7635ebfa3074\",\"name\":\"Delete asset\",\"icon\":\"delete\",\"type\":\"custom\",\"customFunction\":\"let $injector = widgetContext.$scope.$injector;\\nlet $mdDialog = $injector.get('$mdDialog'),\\n    $document = $injector.get('$document'),\\n    types = $injector.get('types'),\\n    assetService = $injector.get('assetService'),\\n    $rootScope = $injector.get('$rootScope'),\\n    $q = $injector.get('$q');\\n\\nopenDeleteAssetDialog();\\n\\nfunction openDeleteAssetDialog() {\\n    let title = \\\"Are you sure you want to delete the asset \\\" + entityName +  \\\"?\\\";\\n    let content = \\\"Be careful, after the confirmation, the asset and all related data will become unrecoverable!\\\";\\n    let confirm = $mdDialog.confirm()\\n        .targetEvent($event)\\n        .title(title)\\n        .htmlContent(content)\\n        .ariaLabel(title)\\n        .cancel('Cancel')\\n        .ok('Delete');\\n    $mdDialog.show(confirm).then(() => {\\n        deleteAsset();\\n    })\\n}\\n\\nfunction deleteAsset() {\\n    assetService.deleteAsset(entityId.id).then(\\n        () => {\\n            updateAliasData();\\n        }\\n    );\\n}\\n\\nfunction updateAliasData() {\\n    let aliasIds = [];\\n    for (let id in widgetContext.aliasController.resolvedAliases) {\\n        aliasIds.push(id);\\n    }\\n    let tasks = [];\\n    aliasIds.forEach((aliasId) => {\\n        widgetContext.aliasController.setAliasUnresolved(aliasId);\\n        tasks.push(widgetContext.aliasController.getAliasInfo(aliasId));\\n    });\\n    $q.all(tasks).then(() => {\\n        $rootScope.$broadcast('entityAliasesChanged', aliasIds);\\n    });\\n}\"}]}}"
      }
    }
  ]
}
