From 65b87cc833472ba10a864d1f7d04830dd9065725 Mon Sep 17 00:00:00 2001 From: Artem Babak Date: Tue, 15 Dec 2020 21:39:19 +0200 Subject: [PATCH 1/9] Entities hierarchy edge prototype --- ui/src/app/dashboard/dashboards.controller.js | 2 +- .../widget/lib/entities-hierarchy-widget.js | 112 ++++++++++++++---- 2 files changed, 93 insertions(+), 21 deletions(-) diff --git a/ui/src/app/dashboard/dashboards.controller.js b/ui/src/app/dashboard/dashboards.controller.js index f5fc50d538..4186745ff4 100644 --- a/ui/src/app/dashboard/dashboards.controller.js +++ b/ui/src/app/dashboard/dashboards.controller.js @@ -383,7 +383,7 @@ export function DashboardsController(userService, dashboardService, customerServ } } else if (vm.dashboardsScope === 'edge') { fetchDashboardsFunction = function (pageLink) { - return dashboardService.getEdgeDashboards(edgeId, pageLink); + return dashboardService.getEdgeDashboards(edgeId, pageLink, null); }; deleteDashboardFunction = function (dashboardId) { return dashboardService.unassignDashboardFromEdge(edgeId, dashboardId); diff --git a/ui/src/app/widget/lib/entities-hierarchy-widget.js b/ui/src/app/widget/lib/entities-hierarchy-widget.js index 3bd5c30d59..a34abf79d6 100644 --- a/ui/src/app/widget/lib/entities-hierarchy-widget.js +++ b/ui/src/app/widget/lib/entities-hierarchy-widget.js @@ -41,7 +41,8 @@ function EntitiesHierarchyWidget() { } /*@ngInject*/ -function EntitiesHierarchyWidgetController($element, $scope, $q, $timeout, toast, types, entityService, entityRelationService /*$filter, $mdMedia, $mdPanel, $document, $translate, $timeout, utils, types*/) { +function EntitiesHierarchyWidgetController($element, $scope, $q, $timeout, toast, types, entityService, entityRelationService, + assetService, deviceService, entityViewService, dashboardService, ruleChainService /*$filter, $mdMedia, $mdPanel, $document, $translate, $timeout, utils, types*/) { var vm = this; vm.showData = true; @@ -293,27 +294,95 @@ function EntitiesHierarchyWidgetController($element, $scope, $q, $timeout, toast }); } else { if (node.data && node.data.nodeCtx.entity && node.data.nodeCtx.entity.id && node.data.nodeCtx.entity.id.entityType !== 'function') { - var relationQuery = prepareNodeRelationQuery(node.data.nodeCtx); - entityRelationService.findByQuery(relationQuery, {ignoreErrors: true, ignoreLoading: true}).then( - (entityRelations) => { - var tasks = []; - for (var i=0;i { + var tasks = []; + for (var i=0;i { + cb(prepareNodes(nodes)); + }); } - $q.all(tasks).then((nodes) => { - cb(prepareNodes(nodes)); - }); - }, - (error) => { - var errorText = "Failed to get relations!"; - if (error && error.status === 400) { - errorText = "Invalid relations query returned by 'Node relations query function'! Please check widget configuration!"; + ); + deviceService.getEdgeDevices(node.data.nodeCtx.entity.id.id, {limit: 20}, null).then( + (entities) => { + var tasks = []; + for (var i=0;i { + cb(prepareNodes(nodes)); + }); } - showError(errorText); - } - ); + ); + entityViewService.getEdgeEntityViews(node.data.nodeCtx.entity.id.id, {limit: 20}, null).then( + (entities) => { + var tasks = []; + for (var i=0;i { + cb(prepareNodes(nodes)); + }); + } + ); + dashboardService.getEdgeDashboards(node.data.nodeCtx.entity.id.id, {limit: 20}, null).then( + (entities) => { + var tasks = []; + for (var i=0;i { + cb(prepareNodes(nodes)); + }); + } + ) + ruleChainService.getEdgeRuleChains(node.data.nodeCtx.entity.id.id, {limit: 20}, null).then( + (entities) => { + var tasks = []; + for (var i=0;i { + cb(prepareNodes(nodes)); + }); + } + ) + } else { + var relationQuery = prepareNodeRelationQuery(node.data.nodeCtx); + entityRelationService.findByQuery(relationQuery, {ignoreErrors: true, ignoreLoading: true}).then( + (entityRelations) => { + var tasks = []; + for (var i=0;i { + cb(prepareNodes(nodes)); + }); + }, + (error) => { + var errorText = "Failed to get relations!"; + if (error && error.status === 400) { + errorText = "Invalid relations query returned by 'Node relations query function'! Please check widget configuration!"; + } + showError(errorText); + } + ); + } } else { cb([]); } @@ -511,6 +580,9 @@ function EntitiesHierarchyWidgetController($element, $scope, $q, $timeout, toast case types.entityType.edge: materialIcon = 'router'; break; + case types.entityType.rulechain: + materialIcon = 'settings_ethernet'; + break; } } return { From 9d4372dc0fbbc80cd5e3aaeaafc31e664ab143d8 Mon Sep 17 00:00:00 2001 From: deaflynx Date: Wed, 16 Dec 2020 14:18:27 +0200 Subject: [PATCH 2/9] Import edge implementation --- ui/src/app/api/edge.service.js | 21 +++- ui/src/app/api/entity.service.js | 13 ++ ui/src/app/common/types.constant.js | 16 +++ .../import-dialog-csv.controller.js | 18 ++- .../table-columns-assignment.directive.js | 32 ++++- ui/src/app/locale/locale.constant-en_US.json | 6 +- .../widget/lib/entities-hierarchy-widget.js | 112 ++++-------------- 7 files changed, 121 insertions(+), 97 deletions(-) diff --git a/ui/src/app/api/edge.service.js b/ui/src/app/api/edge.service.js index 8cd7aa81c1..e8abec1fd9 100644 --- a/ui/src/app/api/edge.service.js +++ b/ui/src/app/api/edge.service.js @@ -31,6 +31,7 @@ function EdgeService($http, $q, customerService) { getCustomerEdges: getCustomerEdges, assignEdgeToCustomer: assignEdgeToCustomer, findByQuery: findByQuery, + findByName: findByName, unassignEdgeFromCustomer: unassignEdgeFromCustomer, makeEdgePublic: makeEdgePublic, setRootRuleChain: setRootRuleChain, @@ -95,10 +96,14 @@ function EdgeService($http, $q, customerService) { return deferred.promise; } - function saveEdge(edge) { + function saveEdge(edge, ignoreErrors, config) { var deferred = $q.defer(); var url = '/api/edge'; - $http.post(url, edge).then(function success(response) { + if (!config) { + config = {}; + } + config = Object.assign(config, { ignoreErrors: ignoreErrors }); + $http.post(url, edge, config).then(function success(response) { deferred.resolve(response.data); }, function fail(response) { deferred.reject(response.data); @@ -214,6 +219,18 @@ function EdgeService($http, $q, customerService) { return deferred.promise; } + function findByName(edgeName, config) { + config = config || {}; + var deferred = $q.defer(); + var url = '/api/tenant/edges?edgeName=' + edgeName; + $http.get(url, config).then(function success(response) { + deferred.resolve(response.data); + }, function fail() { + deferred.reject(); + }); + return deferred.promise; + } + function assignEdgeToCustomer(customerId, edgeId) { var deferred = $q.defer(); var url = '/api/customer/' + customerId + '/edge/' + edgeId; diff --git a/ui/src/app/api/entity.service.js b/ui/src/app/api/entity.service.js index 32fac7b5db..7c94c4b574 100644 --- a/ui/src/app/api/entity.service.js +++ b/ui/src/app/api/entity.service.js @@ -1277,6 +1277,13 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device }; } + if (entityType === types.entityType.edge) { + newEntity.edgeLicenseKey = entityParameters.edgeLicenseKey; + newEntity.cloudEndpoint = entityParameters.cloudEndpoint; + newEntity.routingKey = entityParameters.routingKey; + newEntity.secret = entityParameters.secret; + } + let saveEntityPromise = getEntitySavePromise(entityType, newEntity, config); saveEntityPromise.then(function success(response) { @@ -1301,6 +1308,9 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device case types.entityType.asset: findIdEntity = assetService.findByName(entityParameters.name, config); break; + case types.entityType.edge: + findIdEntity = edgeService.findByName(entityParameters.name, config); + break; } findIdEntity.then(function success(response) { let promises = []; @@ -1347,6 +1357,9 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device case types.entityType.asset: promise = assetService.saveAsset(newEntity, true, config); break; + case types.entityType.edge: + promise = edgeService.saveEdge(newEntity, true, config); + break; } return promise; } diff --git a/ui/src/app/common/types.constant.js b/ui/src/app/common/types.constant.js index 998e2b612e..a9a833bd7e 100644 --- a/ui/src/app/common/types.constant.js +++ b/ui/src/app/common/types.constant.js @@ -465,6 +465,22 @@ export default angular.module('thingsboard.types', []) description: { name: 'import.column-type.description', value: 'description' + }, + edgeLicenseKey: { + name: 'import.column-type.edgeLicenseKey', + value: 'edgeLicenseKey' + }, + cloudEndpoint: { + name: 'import.column-type.cloudEndpoint', + value: 'cloudEndpoint' + }, + routingKey: { + name: 'import.column-type.routingKey', + value: 'routingKey' + }, + secret: { + name: 'import.column-type.secret', + value: 'secret' } }, aliasEntityType: { diff --git a/ui/src/app/import-export/import-dialog-csv.controller.js b/ui/src/app/import-export/import-dialog-csv.controller.js index 4ae2a7a9f0..d109291bb7 100644 --- a/ui/src/app/import-export/import-dialog-csv.controller.js +++ b/ui/src/app/import-export/import-dialog-csv.controller.js @@ -135,7 +135,11 @@ export default function ImportDialogCsvController($scope, $mdDialog, toast, impo server: [], shared: [] }, - timeseries: [] + timeseries: [], + edgeLicenseKey: "", + cloudEndpoint: "", + routingKey: "", + secret: "" }; for (var j = 0; j < parameterColumns.length; j++) { switch (parameterColumns[j].type) { @@ -175,6 +179,18 @@ export default function ImportDialogCsvController($scope, $mdDialog, toast, impo case types.importEntityColumnType.description.value: entityData.description = importData.rows[i][j]; break; + case types.importEntityColumnType.edgeLicenseKey.value: + entityData.edgeLicenseKey = importData.rows[i][j]; + break; + case types.importEntityColumnType.cloudEndpoint.value: + entityData.cloudEndpoint = importData.rows[i][j]; + break; + case types.importEntityColumnType.routingKey.value: + entityData.routingKey = importData.rows[i][j]; + break; + case types.importEntityColumnType.secret.value: + entityData.secret = importData.rows[i][j]; + break; } } entitiesData.push(entityData); diff --git a/ui/src/app/import-export/table-columns-assignment.directive.js b/ui/src/app/import-export/table-columns-assignment.directive.js index a295621799..ebfa0c8af6 100644 --- a/ui/src/app/import-export/table-columns-assignment.directive.js +++ b/ui/src/app/import-export/table-columns-assignment.directive.js @@ -58,6 +58,12 @@ function TableColumnsAssignmentController($scope, types, $timeout) { vm.columnTypes.serverAttribute = types.importEntityColumnType.serverAttribute; vm.columnTypes.timeseries = types.importEntityColumnType.timeseries; break; + case types.entityType.edge: + vm.columnTypes.edgeLicenseKey = types.importEntityColumnType.edgeLicenseKey; + vm.columnTypes.cloudEndpoint = types.importEntityColumnType.cloudEndpoint; + vm.columnTypes.routingKey = types.importEntityColumnType.routingKey; + vm.columnTypes.secret = types.importEntityColumnType.secret; + break; } $scope.isColumnTypeDiffers = function(columnType) { @@ -66,7 +72,11 @@ function TableColumnsAssignmentController($scope, types, $timeout) { columnType !== types.importEntityColumnType.label.value && columnType !== types.importEntityColumnType.accessToken.value&& columnType !== types.importEntityColumnType.isGateway.value&& - columnType !== types.importEntityColumnType.description.value; + columnType !== types.importEntityColumnType.description.value&& + columnType !== types.importEntityColumnType.edgeLicenseKey.value&& + columnType !== types.importEntityColumnType.cloudEndpoint.value&& + columnType !== types.importEntityColumnType.routingKey.value&& + columnType !== types.importEntityColumnType.secret.value; }; $scope.$watch('vm.columns', function(newVal){ @@ -77,6 +87,10 @@ function TableColumnsAssignmentController($scope, types, $timeout) { var isSelectCredentials = false; var isSelectGateway = false; var isSelectDescription = false; + var isSelectEdgeLicenseKey = false; + var isSelectCloudEndpoint = false; + var isSelectRoutingKey = false; + var isSelectSecret = false; for (var i = 0; i < newVal.length; i++) { switch (newVal[i].type) { case types.importEntityColumnType.name.value: @@ -94,6 +108,18 @@ function TableColumnsAssignmentController($scope, types, $timeout) { case types.importEntityColumnType.isGateway.value: isSelectGateway = true; break; + case types.importEntityColumnType.edgeLicenseKey.value: + isSelectEdgeLicenseKey = true; + break; + case types.importEntityColumnType.cloudEndpoint.value: + isSelectCloudEndpoint = true; + break; + case types.importEntityColumnType.routingKey.value: + isSelectRoutingKey = true; + break; + case types.importEntityColumnType.secret.value: + isSelectSecret = true; + break; case types.importEntityColumnType.description.value: isSelectDescription = true; } @@ -112,6 +138,10 @@ function TableColumnsAssignmentController($scope, types, $timeout) { if (angular.isDefined(vm.columnTypes.accessToken)) { vm.columnTypes.accessToken.disable = isSelectCredentials; } + vm.columnTypes.edgeLicenseKey.disable = isSelectEdgeLicenseKey; + vm.columnTypes.cloudEndpoint.disable = isSelectCloudEndpoint; + vm.columnTypes.routingKey.disable = isSelectRoutingKey; + vm.columnTypes.secret.disable = isSelectSecret; }); } }, true); diff --git a/ui/src/app/locale/locale.constant-en_US.json b/ui/src/app/locale/locale.constant-en_US.json index e97afff89f..cf553f23c2 100644 --- a/ui/src/app/locale/locale.constant-en_US.json +++ b/ui/src/app/locale/locale.constant-en_US.json @@ -1404,7 +1404,11 @@ "entity-field": "Entity field", "access-token": "Access token", "isgateway": "Is Gateway", - "description": "Description" + "description": "Description", + "edgeLicenseKey": "Edge license key", + "cloudEndpoint": "Cloud endpoint", + "routingKey": "Edge routing key", + "secret": "Edge secret" }, "stepper-text":{ "select-file": "Select a file", diff --git a/ui/src/app/widget/lib/entities-hierarchy-widget.js b/ui/src/app/widget/lib/entities-hierarchy-widget.js index a34abf79d6..3bd5c30d59 100644 --- a/ui/src/app/widget/lib/entities-hierarchy-widget.js +++ b/ui/src/app/widget/lib/entities-hierarchy-widget.js @@ -41,8 +41,7 @@ function EntitiesHierarchyWidget() { } /*@ngInject*/ -function EntitiesHierarchyWidgetController($element, $scope, $q, $timeout, toast, types, entityService, entityRelationService, - assetService, deviceService, entityViewService, dashboardService, ruleChainService /*$filter, $mdMedia, $mdPanel, $document, $translate, $timeout, utils, types*/) { +function EntitiesHierarchyWidgetController($element, $scope, $q, $timeout, toast, types, entityService, entityRelationService /*$filter, $mdMedia, $mdPanel, $document, $translate, $timeout, utils, types*/) { var vm = this; vm.showData = true; @@ -294,95 +293,27 @@ function EntitiesHierarchyWidgetController($element, $scope, $q, $timeout, toast }); } else { if (node.data && node.data.nodeCtx.entity && node.data.nodeCtx.entity.id && node.data.nodeCtx.entity.id.entityType !== 'function') { - if (node.data.nodeCtx.entity.id.entityType === types.entityType.edge) { - assetService.getEdgeAssets(node.data.nodeCtx.entity.id.id, {limit: 20}, null).then( - (entities) => { - var tasks = []; - for (var i=0;i { - cb(prepareNodes(nodes)); - }); - } - ); - deviceService.getEdgeDevices(node.data.nodeCtx.entity.id.id, {limit: 20}, null).then( - (entities) => { - var tasks = []; - for (var i=0;i { - cb(prepareNodes(nodes)); - }); - } - ); - entityViewService.getEdgeEntityViews(node.data.nodeCtx.entity.id.id, {limit: 20}, null).then( - (entities) => { - var tasks = []; - for (var i=0;i { - cb(prepareNodes(nodes)); - }); + var relationQuery = prepareNodeRelationQuery(node.data.nodeCtx); + entityRelationService.findByQuery(relationQuery, {ignoreErrors: true, ignoreLoading: true}).then( + (entityRelations) => { + var tasks = []; + for (var i=0;i { - var tasks = []; - for (var i=0;i { - cb(prepareNodes(nodes)); - }); + $q.all(tasks).then((nodes) => { + cb(prepareNodes(nodes)); + }); + }, + (error) => { + var errorText = "Failed to get relations!"; + if (error && error.status === 400) { + errorText = "Invalid relations query returned by 'Node relations query function'! Please check widget configuration!"; } - ) - ruleChainService.getEdgeRuleChains(node.data.nodeCtx.entity.id.id, {limit: 20}, null).then( - (entities) => { - var tasks = []; - for (var i=0;i { - cb(prepareNodes(nodes)); - }); - } - ) - } else { - var relationQuery = prepareNodeRelationQuery(node.data.nodeCtx); - entityRelationService.findByQuery(relationQuery, {ignoreErrors: true, ignoreLoading: true}).then( - (entityRelations) => { - var tasks = []; - for (var i=0;i { - cb(prepareNodes(nodes)); - }); - }, - (error) => { - var errorText = "Failed to get relations!"; - if (error && error.status === 400) { - errorText = "Invalid relations query returned by 'Node relations query function'! Please check widget configuration!"; - } - showError(errorText); - } - ); - } + showError(errorText); + } + ); } else { cb([]); } @@ -580,9 +511,6 @@ function EntitiesHierarchyWidgetController($element, $scope, $q, $timeout, toast case types.entityType.edge: materialIcon = 'router'; break; - case types.entityType.rulechain: - materialIcon = 'settings_ethernet'; - break; } } return { From 6a566070585c3d87c55ba060685389a401677ce8 Mon Sep 17 00:00:00 2001 From: deaflynx Date: Wed, 16 Dec 2020 14:32:50 +0200 Subject: [PATCH 3/9] Edge hierarchy widget starting implementation --- ui/src/app/api/widget.service.js | 3 +- .../app/widget/lib/edges-hierarchy-widget.js | 679 ++++++++++++++++++ .../widget/lib/edges-hierarchy-widget.scss | 109 +++ .../lib/edges-hierarchy-widget.tpl.html | 51 ++ 4 files changed, 841 insertions(+), 1 deletion(-) create mode 100644 ui/src/app/widget/lib/edges-hierarchy-widget.js create mode 100644 ui/src/app/widget/lib/edges-hierarchy-widget.scss create mode 100644 ui/src/app/widget/lib/edges-hierarchy-widget.tpl.html diff --git a/ui/src/app/api/widget.service.js b/ui/src/app/api/widget.service.js index 4b706e827d..b6be883466 100644 --- a/ui/src/app/api/widget.service.js +++ b/ui/src/app/api/widget.service.js @@ -22,6 +22,7 @@ import thingsboardTimeseriesTableWidget from '../widget/lib/timeseries-table-wid import thingsboardAlarmsTableWidget from '../widget/lib/alarms-table-widget'; import thingsboardEntitiesTableWidget from '../widget/lib/entities-table-widget'; import thingsboardEntitiesHierarchyWidget from '../widget/lib/entities-hierarchy-widget'; +import thingsboardEdgesHierarchyWidget from '../widget/lib/edges-hierarchy-widget'; import thingsboardExtensionsTableWidget from '../widget/lib/extensions-table-widget'; import thingsboardDateRangeNavigatorWidget from '../widget/lib/date-range-navigator/date-range-navigator'; import thingsboardMultipleInputWidget from '../widget/lib/multiple-input-widget'; @@ -52,7 +53,7 @@ import thingsboardUtils from '../common/utils.service'; export default angular.module('thingsboard.api.widget', ['oc.lazyLoad', thingsboardLedLight, thingsboardTimeseriesTableWidget, thingsboardAlarmsTableWidget, thingsboardEntitiesTableWidget, - thingsboardEntitiesHierarchyWidget, thingsboardExtensionsTableWidget, thingsboardDateRangeNavigatorWidget, + thingsboardEntitiesHierarchyWidget, thingsboardEdgesHierarchyWidget, thingsboardExtensionsTableWidget, thingsboardDateRangeNavigatorWidget, thingsboardMultipleInputWidget, thingsboardWebCameraInputWidget, thingsboardRpcWidgets, thingsboardTypes, thingsboardUtils, thingsboardJsonToString, TripAnimationWidget]) .factory('widgetService', WidgetService) diff --git a/ui/src/app/widget/lib/edges-hierarchy-widget.js b/ui/src/app/widget/lib/edges-hierarchy-widget.js new file mode 100644 index 0000000000..42b58eafc0 --- /dev/null +++ b/ui/src/app/widget/lib/edges-hierarchy-widget.js @@ -0,0 +1,679 @@ +/* + * Copyright © 2016-2020 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import './edges-hierarchy-widget.scss'; + +/* eslint-disable import/no-unresolved, import/default */ + +import edgesHierarchyWidgetTemplate from './edges-hierarchy-widget.tpl.html'; + +/* eslint-enable import/no-unresolved, import/default */ + +export default angular.module('thingsboard.widgets.edgesHierarchyWidget', []) + .directive('tbEdgesHierarchyWidget', EdgesHierarchyWidget) + .name; +/* eslint-disable no-unused-vars */ +/*@ngInject*/ +function EdgesHierarchyWidget() { + return { + restrict: "E", + scope: true, + bindToController: { + hierarchyId: '=', + ctx: '=' + }, + controller: EdgesHierarchyWidgetController, + controllerAs: 'vm', + templateUrl: edgesHierarchyWidgetTemplate + }; +} + +/*@ngInject*/ +function EdgesHierarchyWidgetController($element, $scope, $q, $timeout, toast, types, entityService, entityRelationService, + assetService, deviceService, entityViewService, dashboardService, ruleChainService /*$filter, $mdMedia, $mdPanel, $document, $translate, $timeout, utils, types*/) { + var vm = this; + + vm.showData = true; + + vm.nodeEditCallbacks = {}; + + vm.nodeIdCounter = 0; + + vm.nodesMap = {}; + vm.pendingUpdateNodeTasks = {}; + vm.edgeGroupsNodesMap = {}; + + vm.query = { + search: null + }; + + vm.searchAction = { + name: 'action.search', + show: true, + onAction: function() { + vm.enterFilterMode(); + }, + icon: 'search' + }; + + vm.onNodesInserted = onNodesInserted; + vm.onNodeSelected = onNodeSelected; + vm.enterFilterMode = enterFilterMode; + vm.exitFilterMode = exitFilterMode; + vm.searchCallback = searchCallback; + + $scope.$watch('vm.ctx', function() { + if (vm.ctx && vm.ctx.defaultSubscription) { + vm.settings = vm.ctx.settings; + vm.widgetConfig = vm.ctx.widgetConfig; + vm.subscription = vm.ctx.defaultSubscription; + vm.datasources = vm.subscription.datasources; + initializeConfig(); + updateDatasources(); + } + }); + + $scope.$watch("vm.query.search", function(newVal, prevVal) { + if (!angular.equals(newVal, prevVal) && vm.query.search != null) { + updateSearchNodes(); + } + }); + + $scope.$on('edges-hierarchy-data-updated', function(event, hierarchyId) { + if (vm.hierarchyId == hierarchyId) { + if (vm.subscription) { + updateNodeData(vm.subscription.data); + } + } + }); + + function initializeConfig() { + + vm.ctx.widgetActions = [ vm.searchAction ]; + + var testNodeCtx = { + entity: { + id: { + entityType: 'DEVICE', + id: '123' + }, + name: 'TEST DEV1' + }, + data: {}, + level: 2 + }; + var parentNodeCtx = angular.copy(testNodeCtx); + parentNodeCtx.level = 1; + testNodeCtx.parentNodeCtx = parentNodeCtx; + + var nodeRelationQueryFunction = loadNodeCtxFunction(vm.settings.nodeRelationQueryFunction, 'nodeCtx', testNodeCtx); + var nodeIconFunction = loadNodeCtxFunction(vm.settings.nodeIconFunction, 'nodeCtx', testNodeCtx); + var nodeTextFunction = loadNodeCtxFunction(vm.settings.nodeTextFunction, 'nodeCtx', testNodeCtx); + var nodeDisabledFunction = loadNodeCtxFunction(vm.settings.nodeDisabledFunction, 'nodeCtx', testNodeCtx); + var nodeOpenedFunction = loadNodeCtxFunction(vm.settings.nodeOpenedFunction, 'nodeCtx', testNodeCtx); + var nodeHasChildrenFunction = loadNodeCtxFunction(vm.settings.nodeHasChildrenFunction, 'nodeCtx', testNodeCtx); + + var testNodeCtx2 = angular.copy(testNodeCtx); + testNodeCtx2.entity.name = 'TEST DEV2'; + + var nodesSortFunction = loadNodeCtxFunction(vm.settings.nodesSortFunction, 'nodeCtx1,nodeCtx2', testNodeCtx, testNodeCtx2); + + vm.nodeRelationQueryFunction = nodeRelationQueryFunction || defaultNodeRelationQueryFunction; + vm.nodeIconFunction = nodeIconFunction || defaultNodeIconFunction; + vm.nodeTextFunction = nodeTextFunction || ((nodeCtx) => nodeCtx.entity.name); + vm.nodeDisabledFunction = nodeDisabledFunction || (() => false); + vm.nodeOpenedFunction = nodeOpenedFunction || defaultNodeOpenedFunction; + vm.nodeHasChildrenFunction = nodeHasChildrenFunction || (() => true); + vm.nodesSortFunction = nodesSortFunction || defaultSortFunction; + } + + function loadNodeCtxFunction(functionBody, argNames, ...args) { + var nodeCtxFunction = null; + if (angular.isDefined(functionBody) && functionBody.length) { + try { + nodeCtxFunction = new Function(argNames, functionBody); + var res = nodeCtxFunction.apply(null, args); + if (angular.isUndefined(res)) { + nodeCtxFunction = null; + } + } catch (e) { + nodeCtxFunction = null; + } + } + return nodeCtxFunction; + } + + function enterFilterMode () { + vm.query.search = ''; + vm.ctx.hideTitlePanel = true; + $timeout(()=>{ + angular.element(vm.ctx.$container).find('.searchInput').focus(); + }) + } + + function exitFilterMode () { + vm.query.search = null; + updateSearchNodes(); + vm.ctx.hideTitlePanel = false; + } + + function searchCallback (searchText, node) { + var theNode = vm.nodesMap[node.id]; + if (theNode && theNode.data.searchText) { + return theNode.data.searchText.includes(searchText.toLowerCase()); + } + return false; + } + + function updateDatasources() { + vm.loadNodes = loadNodes; + } + + function updateSearchNodes() { + if (vm.query.search != null) { + vm.nodeEditCallbacks.search(vm.query.search); + } else { + vm.nodeEditCallbacks.clearSearch(); + } + } + + function onNodesInserted(nodes/*, parent*/) { + if (nodes) { + nodes.forEach((nodeId) => { + var task = vm.pendingUpdateNodeTasks[nodeId]; + if (task) { + task(); + delete vm.pendingUpdateNodeTasks[nodeId]; + } + }); + } + } + + function onNodeSelected(node, event) { + var nodeId; + if (!node) { + nodeId = -1; + } else { + nodeId = node.id; + } + if (nodeId !== -1) { + var selectedNode = vm.nodesMap[nodeId]; + if (selectedNode) { + var descriptors = vm.ctx.actionsApi.getActionDescriptors('nodeSelected'); + if (descriptors.length) { + var entity = selectedNode.data.nodeCtx.entity; + vm.ctx.actionsApi.handleWidgetAction(event, descriptors[0], entity.id, entity.name, { nodeCtx: selectedNode.data.nodeCtx }); + } + } + } + } + + function updateNodeData(subscriptionData) { + var affectedNodes = []; + if (subscriptionData) { + for (var i=0;i { + var node = vm.nodeEditCallbacks.getNode(nodeId); + if (node) { + updateNodeStyle(vm.nodesMap[nodeId]); + } else { + vm.pendingUpdateNodeTasks[nodeId] = () => { + updateNodeStyle(vm.nodesMap[nodeId]); + }; + } + }); + } + + function updateNodeStyle(node) { + var newText = prepareNodeText(node); + if (!angular.equals(node.text, newText)) { + node.text = newText; + vm.nodeEditCallbacks.updateNode(node.id, node.text); + } + var newDisabled = vm.nodeDisabledFunction(node.data.nodeCtx); + if (!angular.equals(node.state.disabled, newDisabled)) { + node.state.disabled = newDisabled; + if (node.state.disabled) { + vm.nodeEditCallbacks.disableNode(node.id); + } else { + vm.nodeEditCallbacks.enableNode(node.id); + } + } + var newHasChildren = vm.nodeHasChildrenFunction(node.data.nodeCtx); + if (!angular.equals(node.children, newHasChildren)) { + node.children = newHasChildren; + vm.nodeEditCallbacks.setNodeHasChildren(node.id, node.children); + } + } + + function prepareNodeText(node) { + var nodeIcon = prepareNodeIcon(node.data.nodeCtx); + var nodeText = vm.nodeTextFunction(node.data.nodeCtx); + node.data.searchText = nodeText ? nodeText.replace(/<[^>]+>/g, '').toLowerCase() : ""; + return nodeIcon + nodeText; + } + + function loadNodes(node, cb) { + if (node.id === '#') { + var tasks = []; + for (var i=0;i { + cb(prepareNodes(nodes)); + updateNodeData(vm.subscription.data); + }); + } else { + if (node.data && node.data.nodeCtx.entity && node.data.nodeCtx.entity.id && node.data.nodeCtx.entity.id.entityType !== 'function') { + if (node.data.nodeCtx.entity.id.entityType === types.entityType.edge) { + /* assetService.getEdgeAssets(node.data.nodeCtx.entity.id.id, {limit: 20}, null).then( + (entities) => { + var tasks = []; + for (var i=0;i { + cb(prepareNodes(nodes)); + }); + } + ); + deviceService.getEdgeDevices(node.data.nodeCtx.entity.id.id, {limit: 20}, null).then( + (entities) => { + var tasks = []; + for (var i=0;i { + cb(prepareNodes(nodes)); + }); + } + ); + entityViewService.getEdgeEntityViews(node.data.nodeCtx.entity.id.id, {limit: 20}, null).then( + (entities) => { + var tasks = []; + for (var i=0;i { + cb(prepareNodes(nodes)); + }); + } + ); + dashboardService.getEdgeDashboards(node.data.nodeCtx.entity.id.id, {limit: 20}, null).then( + (entities) => { + var tasks = []; + for (var i=0;i { + cb(prepareNodes(nodes)); + }); + } + ) + ruleChainService.getEdgeRuleChains(node.data.nodeCtx.entity.id.id, {limit: 20}, null).then( + (entities) => { + var tasks = []; + for (var i=0;i { + cb(prepareNodes(nodes)); + }); + } + ) + */ + + entityIdToNodeEdge("edgeGroup", "001", node.data.datasource, ) + + } else { + var relationQuery = prepareNodeRelationQuery(node.data.nodeCtx); + entityRelationService.findByQuery(relationQuery, {ignoreErrors: true, ignoreLoading: true}).then( + (entityRelations) => { + var tasks = []; + for (var i=0;i { + cb(prepareNodes(nodes)); + }); + }, + (error) => { + var errorText = "Failed to get relations!"; + if (error && error.status === 400) { + errorText = "Invalid relations query returned by 'Node relations query function'! Please check widget configuration!"; + } + showError(errorText); + } + ); + } + } else { + cb([]); + } + } + } + + function showError(errorText) { + var toastParent = angular.element('.tb-edges-hierarchy', $element); + toast.showError(errorText, toastParent, 'bottom left'); + } + + function prepareNodes(nodes) { + nodes = nodes.filter((node) => node !== null); + nodes.sort((node1, node2) => vm.nodesSortFunction(node1.data.nodeCtx, node2.data.nodeCtx)); + return nodes; + } + + function datasourceToNode(datasource, parentNodeCtx) { + var deferred = $q.defer(); + resolveEntity(datasource).then( + (entity) => { + if (entity != null) { + var node = { + id: ++vm.nodeIdCounter + }; + vm.nodesMap[node.id] = node; + datasource.nodeId = node.id; + node.icon = false; + var nodeCtx = { + parentNodeCtx: parentNodeCtx, + entity: entity, + data: {} + }; + nodeCtx.level = parentNodeCtx ? parentNodeCtx.level + 1 : 1; + node.data = { + datasource: datasource, + nodeCtx: nodeCtx + }; + node.state = { + disabled: vm.nodeDisabledFunction(node.data.nodeCtx), + opened: vm.nodeOpenedFunction(node.data.nodeCtx) + }; + node.text = prepareNodeText(node); + node.children = vm.nodeHasChildrenFunction(node.data.nodeCtx); + deferred.resolve(node); + } else { + deferred.resolve(null); + } + } + ); + return deferred.promise; + } + + function datasourceToNodeEdge(datasource, parentNodeCtx) { + var deferred = $q.defer(); + resolveEntity(datasource).then( + (entity) => { + if (entity != null) { + var node = { + id: ++vm.nodeIdCounter + }; + vm.nodesMap[node.id] = node; + datasource.nodeId = node.id; + node.icon = false; + var nodeCtx = { + parentNodeCtx: parentNodeCtx, + entity: entity, + data: {} + }; + nodeCtx.level = parentNodeCtx ? parentNodeCtx.level + 1 : 1; + node.data = { + datasource: datasource, + nodeCtx: nodeCtx + }; + node.state = { + disabled: vm.nodeDisabledFunction(node.data.nodeCtx), + opened: vm.nodeOpenedFunction(node.data.nodeCtx) + }; + node.text = prepareNodeText(node); + node.children = vm.nodeHasChildrenFunction(node.data.nodeCtx); + deferred.resolve(node); + } else { + deferred.resolve(null); + } + } + ); + return deferred.promise; + } + + + function entityIdToNodeEdge(entityType, entityId, parentDatasource, parentNodeCtx) { + var deferred = $q.defer(); + var datasource = { + dataKeys: parentDatasource.dataKeys, + type: types.datasourceType.entity, + entityType: entityType, + entityId: entityId + }; + datasourceToNodeEdge(datasource, parentNodeCtx).then( + (node) => { + if (node != null) { + var subscriptionOptions = { + type: types.widgetType.latest.value, + datasources: [datasource], + callbacks: { + onDataUpdated: (subscription) => { + updateNodeData(subscription.data); + } + } + }; + vm.ctx.subscriptionApi.createSubscription(subscriptionOptions, true).then( + (/*subscription*/) => { + deferred.resolve(node); + } + ); + } else { + deferred.resolve(node); + } + } + ); + return deferred.promise; + } + + function entityIdToNode(entityType, entityId, parentDatasource, parentNodeCtx) { + var deferred = $q.defer(); + var datasource = { + dataKeys: parentDatasource.dataKeys, + type: types.datasourceType.entity, + entityType: entityType, + entityId: entityId + }; + datasourceToNode(datasource, parentNodeCtx).then( + (node) => { + if (node != null) { + var subscriptionOptions = { + type: types.widgetType.latest.value, + datasources: [datasource], + callbacks: { + onDataUpdated: (subscription) => { + updateNodeData(subscription.data); + } + } + }; + vm.ctx.subscriptionApi.createSubscription(subscriptionOptions, true).then( + (/*subscription*/) => { + deferred.resolve(node); + } + ); + } else { + deferred.resolve(node); + } + } + ); + return deferred.promise; + } + + function resolveEntity(datasource) { + var deferred = $q.defer(); + if (datasource.type === types.datasourceType.function) { + var entity = { + id: { + entityType: "function" + }, + name: datasource.name + } + deferred.resolve(entity); + } else { + entityService.getEntity(datasource.entityType, datasource.entityId, {ignoreLoading: true}).then( + (entity) => { + deferred.resolve(entity); + }, + () => { + deferred.resolve(null); + } + ); + } + return deferred.promise; + } + + + function prepareNodeRelationQuery(nodeCtx) { + var relationQuery = vm.nodeRelationQueryFunction(nodeCtx); + if (relationQuery && relationQuery === 'default') { + relationQuery = defaultNodeRelationQueryFunction(nodeCtx); + } + return relationQuery; + } + + function defaultNodeRelationQueryFunction(nodeCtx) { + var entity = nodeCtx.entity; + var query = { + parameters: { + rootId: entity.id.id, + rootType: entity.id.entityType, + direction: types.entitySearchDirection.from, + relationTypeGroup: "COMMON", + maxLevel: 1 + }, + filters: [ + { + relationType: "Contains", + entityTypes: [] + } + ] + }; + return query; + } + + function prepareNodeIcon(nodeCtx) { + var iconInfo = vm.nodeIconFunction(nodeCtx); + if (iconInfo && iconInfo === 'default') { + iconInfo = defaultNodeIconFunction(nodeCtx); + } + if (iconInfo && (iconInfo.iconUrl || iconInfo.materialIcon)) { + if (iconInfo.materialIcon) { + return materialIconHtml(iconInfo.materialIcon); + } else { + return iconUrlHtml(iconInfo.iconUrl); + } + } else { + return ""; + } + } + + function materialIconHtml(materialIcon) { + return ''+materialIcon+''; + } + + function iconUrlHtml(iconUrl) { + return '
 
'; + } + + function defaultNodeIconFunction(nodeCtx) { + var materialIcon = 'insert_drive_file'; + var entity = nodeCtx.entity; + if (entity && entity.id && entity.id.entityType) { + switch (entity.id.entityType) { + case 'function': + materialIcon = 'functions'; + break; + case types.entityType.device: + materialIcon = 'devices_other'; + break; + case types.entityType.asset: + materialIcon = 'domain'; + break; + case types.entityType.tenant: + materialIcon = 'supervisor_account'; + break; + case types.entityType.customer: + materialIcon = 'supervisor_account'; + break; + case types.entityType.user: + materialIcon = 'account_circle'; + break; + case types.entityType.dashboard: + materialIcon = 'dashboards'; + break; + case types.entityType.alarm: + materialIcon = 'notifications_active'; + break; + case types.entityType.entityView: + materialIcon = 'view_quilt'; + break; + case types.entityType.edge: + materialIcon = 'router'; + break; + case types.entityType.rulechain: + materialIcon = 'settings_ethernet'; + break; + } + } + return { + materialIcon: materialIcon + }; + } + + function defaultNodeOpenedFunction(nodeCtx) { + return nodeCtx.level <= 4; + } + + function defaultSortFunction(nodeCtx1, nodeCtx2) { + var result = nodeCtx1.entity.id.entityType.localeCompare(nodeCtx2.entity.id.entityType); + if (result === 0) { + result = nodeCtx1.entity.name.localeCompare(nodeCtx2.entity.name); + } + return result; + } +} diff --git a/ui/src/app/widget/lib/edges-hierarchy-widget.scss b/ui/src/app/widget/lib/edges-hierarchy-widget.scss new file mode 100644 index 0000000000..b7613aad7e --- /dev/null +++ b/ui/src/app/widget/lib/edges-hierarchy-widget.scss @@ -0,0 +1,109 @@ +/** + * Copyright © 2016-2020 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +.tb-has-timewindow { + .tb-edges-hierarchy { + md-toolbar { + min-height: 60px; + max-height: 60px; + } + } +} + +.tb-edges-hierarchy { + md-toolbar { + min-height: 39px; + max-height: 39px; + } + + .tb-entities-nav-tree-panel { + overflow-x: auto; + overflow-y: auto; + + .tb-nav-tree-container { + &.jstree-proton { + .jstree-anchor { + div.node-icon { + display: inline-block; + width: 22px; + height: 22px; + margin-right: 2px; + margin-bottom: 2px; + background-color: transparent; + background-repeat: no-repeat; + background-attachment: scroll; + background-position: center center; + background-size: 18px 18px; + } + + md-icon.node-icon { + width: 22px; + min-width: 22px; + height: 22px; + min-height: 22px; + margin-right: 2px; + margin-bottom: 2px; + color: inherit; + + &.material-icons { /* stylelint-disable-line selector-max-class */ + font-size: 18px; + line-height: 22px; + text-align: center; + } + } + + &.jstree-hovered:not(.jstree-clicked), + &.jstree-disabled { + div.node-icon { /* stylelint-disable-line selector-max-class */ + opacity: .5; + } + } + } + } + } + } +} + +@media (max-width: 768px) { + .tb-edges-hierarchy { + .tb-entities-nav-tree-panel { + .tb-nav-tree-container { + &.jstree-proton-responsive { + .jstree-anchor { + div.node-icon { + width: 40px; + height: 40px; + margin: 0; + background-size: 24px 24px; + } + + md-icon.node-icon { + width: 40px; + min-width: 40px; + height: 40px; + min-height: 40px; + margin: 0; + + &.material-icons { /* stylelint-disable-line selector-max-class */ + font-size: 24px; + line-height: 40px; + } + } + } + } + } + } + } +} diff --git a/ui/src/app/widget/lib/edges-hierarchy-widget.tpl.html b/ui/src/app/widget/lib/edges-hierarchy-widget.tpl.html new file mode 100644 index 0000000000..e16ebe97d9 --- /dev/null +++ b/ui/src/app/widget/lib/edges-hierarchy-widget.tpl.html @@ -0,0 +1,51 @@ + +
+
+ +
+ + search + + {{'entity.search' | translate}} + + + + + + + + close + + {{ 'action.close' | translate }} + + +
+
+
+ +
+
+
From 36b8bc452ac52f3045cdf966c694f40e588de982 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Wed, 16 Dec 2020 17:05:10 +0200 Subject: [PATCH 4/9] Fixed issue if entity created --- .../thingsboard/server/controller/AlarmController.java | 8 ++++---- .../thingsboard/server/controller/AssetController.java | 8 ++++---- .../thingsboard/server/controller/AuthController.java | 5 +++-- .../thingsboard/server/controller/BaseController.java | 8 ++++---- .../server/controller/CustomerController.java | 4 ++-- .../server/controller/DashboardController.java | 8 ++++---- .../server/controller/DeviceController.java | 10 +++++----- .../server/controller/EntityViewController.java | 8 ++++---- .../server/controller/RuleChainController.java | 10 +++++----- .../thingsboard/server/controller/UserController.java | 4 ++-- .../server/controller/WidgetTypeController.java | 5 +++-- .../server/controller/WidgetsBundleController.java | 5 +++-- 12 files changed, 43 insertions(+), 40 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java index 01beb1371e..74a73cc064 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java @@ -93,7 +93,7 @@ public class AlarmController extends BaseController { getCurrentUser().getCustomerId(), alarm.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null); - sendNotificationMsgToEdgeService(getTenantId(), savedAlarm.getId(), + sendNotificationMsgToEdgeService(getTenantId(), savedAlarm.getId(), EntityType.ALARM, alarm.getId() == null ? EdgeEventActionType.ADDED : EdgeEventActionType.UPDATED); return savedAlarm; @@ -113,7 +113,7 @@ public class AlarmController extends BaseController { AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); checkAlarmId(alarmId, Operation.WRITE); - sendNotificationMsgToEdgeService(getTenantId(), alarmId, EdgeEventActionType.DELETED); + sendNotificationMsgToEdgeService(getTenantId(), alarmId, EntityType.ALARM, EdgeEventActionType.DELETED); return alarmService.deleteAlarm(getTenantId(), alarmId); } catch (Exception e) { @@ -135,7 +135,7 @@ public class AlarmController extends BaseController { alarm.setStatus(alarm.getStatus().isCleared() ? AlarmStatus.CLEARED_ACK : AlarmStatus.ACTIVE_ACK); logEntityAction(alarmId, alarm, getCurrentUser().getCustomerId(), ActionType.ALARM_ACK, null); - sendNotificationMsgToEdgeService(getTenantId(), alarmId, EdgeEventActionType.ALARM_ACK); + sendNotificationMsgToEdgeService(getTenantId(), alarmId, EntityType.ALARM, EdgeEventActionType.ALARM_ACK); } catch (Exception e) { throw handleException(e); } @@ -155,7 +155,7 @@ public class AlarmController extends BaseController { alarm.setStatus(alarm.getStatus().isAck() ? AlarmStatus.CLEARED_ACK : AlarmStatus.CLEARED_UNACK); logEntityAction(alarmId, alarm, getCurrentUser().getCustomerId(), ActionType.ALARM_CLEAR, null); - sendNotificationMsgToEdgeService(getTenantId(), alarmId, EdgeEventActionType.ALARM_CLEAR); + sendNotificationMsgToEdgeService(getTenantId(), alarmId, EntityType.ALARM, EdgeEventActionType.ALARM_CLEAR); } catch (Exception e) { throw handleException(e); } diff --git a/application/src/main/java/org/thingsboard/server/controller/AssetController.java b/application/src/main/java/org/thingsboard/server/controller/AssetController.java index 9a4ebb1f92..5ad6430a7f 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AssetController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AssetController.java @@ -92,7 +92,7 @@ public class AssetController extends BaseController { asset.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null); if (asset.getId() != null) { - sendNotificationMsgToEdgeService(savedAsset.getTenantId(), savedAsset.getId(), EdgeEventActionType.UPDATED); + sendNotificationMsgToEdgeService(savedAsset.getTenantId(), savedAsset.getId(), EntityType.ASSET, EdgeEventActionType.UPDATED); } return savedAsset; @@ -117,7 +117,7 @@ public class AssetController extends BaseController { asset.getCustomerId(), ActionType.DELETED, null, strAssetId); - sendNotificationMsgToEdgeService(getTenantId(), assetId, EdgeEventActionType.DELETED); + sendNotificationMsgToEdgeService(getTenantId(), assetId, EntityType.ASSET, EdgeEventActionType.DELETED); } catch (Exception e) { logEntityAction(emptyId(EntityType.ASSET), null, @@ -366,7 +366,7 @@ public class AssetController extends BaseController { savedAsset.getCustomerId(), ActionType.ASSIGNED_TO_EDGE, null, strAssetId, strEdgeId, edge.getName()); - sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedAsset.getId(), EdgeEventActionType.ASSIGNED_TO_EDGE); + sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedAsset.getId(), EntityType.ASSET, EdgeEventActionType.ASSIGNED_TO_EDGE); return savedAsset; } catch (Exception e) { @@ -399,7 +399,7 @@ public class AssetController extends BaseController { asset.getCustomerId(), ActionType.UNASSIGNED_FROM_EDGE, null, strAssetId, strEdgeId, edge.getName()); - sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedAsset.getId(), EdgeEventActionType.UNASSIGNED_FROM_EDGE); + sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedAsset.getId(), EntityType.ASSET, EdgeEventActionType.UNASSIGNED_FROM_EDGE); return savedAsset; } catch (Exception e) { diff --git a/application/src/main/java/org/thingsboard/server/controller/AuthController.java b/application/src/main/java/org/thingsboard/server/controller/AuthController.java index eb65a14b4a..f3cfe99129 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AuthController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AuthController.java @@ -33,6 +33,7 @@ import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; import org.thingsboard.rule.engine.api.MailService; +import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.EdgeEventActionType; @@ -127,7 +128,7 @@ public class AuthController extends BaseController { userCredentials.setPassword(passwordEncoder.encode(newPassword)); userService.replaceUserCredentials(securityUser.getTenantId(), userCredentials); - sendNotificationMsgToEdgeService(getTenantId(), userCredentials.getUserId(), EdgeEventActionType.CREDENTIALS_UPDATED); + sendNotificationMsgToEdgeService(getTenantId(), userCredentials.getUserId(), EntityType.USER, EdgeEventActionType.CREDENTIALS_UPDATED); } catch (Exception e) { throw handleException(e); @@ -237,7 +238,7 @@ public class AuthController extends BaseController { } } - sendNotificationMsgToEdgeService(user.getTenantId(), user.getId(), EdgeEventActionType.CREDENTIALS_UPDATED); + sendNotificationMsgToEdgeService(user.getTenantId(), user.getId(), EntityType.USER, EdgeEventActionType.CREDENTIALS_UPDATED); JwtToken accessToken = tokenFactory.createAccessJwtToken(securityUser); JwtToken refreshToken = refreshTokenRepository.requestRefreshToken(securityUser); diff --git a/application/src/main/java/org/thingsboard/server/controller/BaseController.java b/application/src/main/java/org/thingsboard/server/controller/BaseController.java index 3d7d4e2393..3d0f015678 100644 --- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java +++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java @@ -799,15 +799,15 @@ public abstract class BaseController { } } - protected void sendNotificationMsgToEdgeService(TenantId tenantId, EntityId entityId, EdgeEventActionType action) { - sendNotificationMsgToEdgeService(tenantId, null, entityId, action); + protected void sendNotificationMsgToEdgeService(TenantId tenantId, EntityId entityId, EntityType entityType, EdgeEventActionType action) { + sendNotificationMsgToEdgeService(tenantId, null, entityId, entityType, action); } - protected void sendNotificationMsgToEdgeService(TenantId tenantId, EdgeId edgeId, EntityId entityId, EdgeEventActionType action) { + protected void sendNotificationMsgToEdgeService(TenantId tenantId, EdgeId edgeId, EntityId entityId, EntityType entityType, EdgeEventActionType action) { if (!edgesRpcEnabled) { return; } - EdgeEventType type = EdgeUtils.getEdgeEventTypeByEntityType(entityId.getEntityType()); + EdgeEventType type = EdgeUtils.getEdgeEventTypeByEntityType(entityType); if (type != null) { sendNotificationMsgToEdgeService(tenantId, edgeId, entityId, null, type, action); } diff --git a/application/src/main/java/org/thingsboard/server/controller/CustomerController.java b/application/src/main/java/org/thingsboard/server/controller/CustomerController.java index 39ae1b8ec1..8de16b8ede 100644 --- a/application/src/main/java/org/thingsboard/server/controller/CustomerController.java +++ b/application/src/main/java/org/thingsboard/server/controller/CustomerController.java @@ -110,7 +110,7 @@ public class CustomerController extends BaseController { customer.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null); if (customer.getId() != null) { - sendNotificationMsgToEdgeService(savedCustomer.getTenantId(), savedCustomer.getId(), EdgeEventActionType.UPDATED); + sendNotificationMsgToEdgeService(savedCustomer.getTenantId(), savedCustomer.getId(), EntityType.CUSTOMER, EdgeEventActionType.UPDATED); } return savedCustomer; @@ -137,7 +137,7 @@ public class CustomerController extends BaseController { customer.getId(), ActionType.DELETED, null, strCustomerId); - sendNotificationMsgToEdgeService(getTenantId(), customerId, EdgeEventActionType.DELETED); + sendNotificationMsgToEdgeService(getTenantId(), customerId, EntityType.CUSTOMER, EdgeEventActionType.DELETED); } catch (Exception e) { logEntityAction(emptyId(EntityType.CUSTOMER), diff --git a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java index bee8a46f65..adfcedea82 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java @@ -117,7 +117,7 @@ public class DashboardController extends BaseController { dashboard.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null); if (dashboard.getId() != null) { - sendNotificationMsgToEdgeService(savedDashboard.getTenantId(), savedDashboard.getId(), EdgeEventActionType.UPDATED); + sendNotificationMsgToEdgeService(savedDashboard.getTenantId(), savedDashboard.getId(), EntityType.DASHBOARD, EdgeEventActionType.UPDATED); } return savedDashboard; @@ -143,7 +143,7 @@ public class DashboardController extends BaseController { null, ActionType.DELETED, null, strDashboardId); - sendNotificationMsgToEdgeService(getTenantId(), dashboardId, EdgeEventActionType.DELETED); + sendNotificationMsgToEdgeService(getTenantId(), dashboardId, EntityType.DASHBOARD, EdgeEventActionType.DELETED); } catch (Exception e) { logEntityAction(emptyId(EntityType.DASHBOARD), @@ -505,7 +505,7 @@ public class DashboardController extends BaseController { null, ActionType.ASSIGNED_TO_EDGE, null, strDashboardId, strEdgeId, edge.getName()); - sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedDashboard.getId(), EdgeEventActionType.ASSIGNED_TO_EDGE); + sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedDashboard.getId(), EntityType.DASHBOARD, EdgeEventActionType.ASSIGNED_TO_EDGE); return savedDashboard; } catch (Exception e) { @@ -537,7 +537,7 @@ public class DashboardController extends BaseController { null, ActionType.UNASSIGNED_FROM_EDGE, null, strDashboardId, strEdgeId, edge.getName()); - sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedDashboard.getId(), EdgeEventActionType.UNASSIGNED_FROM_EDGE); + sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedDashboard.getId(), EntityType.DASHBOARD, EdgeEventActionType.UNASSIGNED_FROM_EDGE); return savedDashboard; } catch (Exception e) { diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java index e64b3d37d5..653b9cd64b 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java @@ -114,7 +114,7 @@ public class DeviceController extends BaseController { savedDevice.getId(), savedDevice.getName(), savedDevice.getType()), null); if (device.getId() != null) { - sendNotificationMsgToEdgeService(savedDevice.getTenantId(), savedDevice.getId(), EdgeEventActionType.UPDATED); + sendNotificationMsgToEdgeService(savedDevice.getTenantId(), savedDevice.getId(), EntityType.DEVICE, EdgeEventActionType.UPDATED); } logEntityAction(savedDevice.getId(), savedDevice, @@ -148,7 +148,7 @@ public class DeviceController extends BaseController { device.getCustomerId(), ActionType.DELETED, null, strDeviceId); - sendNotificationMsgToEdgeService(getTenantId(), deviceId, EdgeEventActionType.DELETED); + sendNotificationMsgToEdgeService(getTenantId(), deviceId, EntityType.DEVICE, EdgeEventActionType.DELETED); deviceStateService.onDeviceDeleted(device); } catch (Exception e) { @@ -279,7 +279,7 @@ public class DeviceController extends BaseController { tbClusterService.pushMsgToCore(new DeviceCredentialsUpdateNotificationMsg(getCurrentUser().getTenantId(), deviceCredentials.getDeviceId()), null); - sendNotificationMsgToEdgeService(getTenantId(), device.getId(), EdgeEventActionType.CREDENTIALS_UPDATED); + sendNotificationMsgToEdgeService(getTenantId(), device.getId(), EntityType.DEVICE, EdgeEventActionType.CREDENTIALS_UPDATED); logEntityAction(device.getId(), device, device.getCustomerId(), @@ -583,7 +583,7 @@ public class DeviceController extends BaseController { savedDevice.getCustomerId(), ActionType.ASSIGNED_TO_EDGE, null, strDeviceId, strEdgeId, edge.getName()); - sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedDevice.getId(), EdgeEventActionType.ASSIGNED_TO_EDGE); + sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedDevice.getId(), EntityType.DEVICE, EdgeEventActionType.ASSIGNED_TO_EDGE); return savedDevice; } catch (Exception e) { @@ -617,7 +617,7 @@ public class DeviceController extends BaseController { device.getCustomerId(), ActionType.UNASSIGNED_FROM_EDGE, null, strDeviceId, strEdgeId, edge.getName()); - sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedDevice.getId(), EdgeEventActionType.UNASSIGNED_FROM_EDGE); + sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedDevice.getId(), EntityType.DEVICE, EdgeEventActionType.UNASSIGNED_FROM_EDGE); return savedDevice; } catch (Exception e) { diff --git a/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java b/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java index cb514eda1d..da4022684d 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java @@ -119,7 +119,7 @@ public class EntityViewController extends BaseController { entityView.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null); if (entityView.getId() != null) { - sendNotificationMsgToEdgeService(savedEntityView.getTenantId(), savedEntityView.getId(), EdgeEventActionType.UPDATED); + sendNotificationMsgToEdgeService(savedEntityView.getTenantId(), savedEntityView.getId(), EntityType.ENTITY_VIEW, EdgeEventActionType.UPDATED); } return savedEntityView; @@ -192,7 +192,7 @@ public class EntityViewController extends BaseController { logEntityAction(entityViewId, entityView, entityView.getCustomerId(), ActionType.DELETED, null, strEntityViewId); - sendNotificationMsgToEdgeService(getTenantId(), entityViewId, EdgeEventActionType.DELETED); + sendNotificationMsgToEdgeService(getTenantId(), entityViewId, EntityType.ENTITY_VIEW, EdgeEventActionType.DELETED); } catch (Exception e) { logEntityAction(emptyId(EntityType.ENTITY_VIEW), null, @@ -405,7 +405,7 @@ public class EntityViewController extends BaseController { savedEntityView.getCustomerId(), ActionType.ASSIGNED_TO_EDGE, null, strEntityViewId, strEdgeId, edge.getName()); - sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedEntityView.getId(), EdgeEventActionType.ASSIGNED_TO_EDGE); + sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedEntityView.getId(), EntityType.ENTITY_VIEW, EdgeEventActionType.ASSIGNED_TO_EDGE); return savedEntityView; } catch (Exception e) { @@ -435,7 +435,7 @@ public class EntityViewController extends BaseController { entityView.getCustomerId(), ActionType.UNASSIGNED_FROM_EDGE, null, strEntityViewId, strEdgeId, edge.getName()); - sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedEntityView.getId(), EdgeEventActionType.UNASSIGNED_FROM_EDGE); + sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedEntityView.getId(), EntityType.ENTITY_VIEW, EdgeEventActionType.UNASSIGNED_FROM_EDGE); return savedEntityView; } catch (Exception e) { diff --git a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java index bce274dc3b..43f4143182 100644 --- a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java +++ b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java @@ -146,7 +146,7 @@ public class RuleChainController extends BaseController { if (RuleChainType.EDGE.equals(savedRuleChain.getType())) { if (!created) { - sendNotificationMsgToEdgeService(savedRuleChain.getTenantId(), savedRuleChain.getId(), EdgeEventActionType.UPDATED); + sendNotificationMsgToEdgeService(savedRuleChain.getTenantId(), savedRuleChain.getId(), EntityType.RULE_CHAIN, EdgeEventActionType.UPDATED); } } @@ -226,7 +226,7 @@ public class RuleChainController extends BaseController { if (RuleChainType.EDGE.equals(ruleChain.getType())) { sendNotificationMsgToEdgeService(ruleChain.getTenantId(), - ruleChain.getId(), EdgeEventActionType.UPDATED); + ruleChain.getId(), EntityType.RULE_CHAIN, EdgeEventActionType.UPDATED); } return savedRuleChainMetaData; @@ -290,7 +290,7 @@ public class RuleChainController extends BaseController { ActionType.DELETED, null, strRuleChainId); if (RuleChainType.EDGE.equals(ruleChain.getType())) { - sendNotificationMsgToEdgeService(ruleChain.getTenantId(), ruleChain.getId(), EdgeEventActionType.DELETED); + sendNotificationMsgToEdgeService(ruleChain.getTenantId(), ruleChain.getId(), EntityType.RULE_CHAIN, EdgeEventActionType.DELETED); } } catch (Exception e) { @@ -422,7 +422,7 @@ public class RuleChainController extends BaseController { null, ActionType.ASSIGNED_TO_EDGE, null, strRuleChainId, strEdgeId, edge.getName()); - sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedRuleChain.getId(), EdgeEventActionType.ASSIGNED_TO_EDGE); + sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedRuleChain.getId(), EntityType.RULE_CHAIN, EdgeEventActionType.ASSIGNED_TO_EDGE); return savedRuleChain; } catch (Exception e) { @@ -454,7 +454,7 @@ public class RuleChainController extends BaseController { null, ActionType.UNASSIGNED_FROM_EDGE, null, strRuleChainId, strEdgeId, edge.getName()); - sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedRuleChain.getId(), EdgeEventActionType.UNASSIGNED_FROM_EDGE); + sendNotificationMsgToEdgeService(getTenantId(), edgeId, savedRuleChain.getId(), EntityType.RULE_CHAIN, EdgeEventActionType.UNASSIGNED_FROM_EDGE); return savedRuleChain; } catch (Exception e) { diff --git a/application/src/main/java/org/thingsboard/server/controller/UserController.java b/application/src/main/java/org/thingsboard/server/controller/UserController.java index 5f141a241b..1ba54091df 100644 --- a/application/src/main/java/org/thingsboard/server/controller/UserController.java +++ b/application/src/main/java/org/thingsboard/server/controller/UserController.java @@ -166,7 +166,7 @@ public class UserController extends BaseController { savedUser.getCustomerId(), user.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null); - sendNotificationMsgToEdgeService(getTenantId(), savedUser.getId(), + sendNotificationMsgToEdgeService(getTenantId(), savedUser.getId(), EntityType.USER, user.getId() == null ? EdgeEventActionType.ADDED : EdgeEventActionType.UPDATED); return savedUser; @@ -244,7 +244,7 @@ public class UserController extends BaseController { user.getCustomerId(), ActionType.DELETED, null, strUserId); - sendNotificationMsgToEdgeService(getTenantId(), user.getId(), EdgeEventActionType.DELETED); + sendNotificationMsgToEdgeService(getTenantId(), user.getId(), EntityType.USER, EdgeEventActionType.DELETED); } catch (Exception e) { logEntityAction(emptyId(EntityType.USER), diff --git a/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java b/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java index b061f3170f..fb203ff9ca 100644 --- a/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java +++ b/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java @@ -26,6 +26,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; +import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.exception.ThingsboardException; @@ -73,7 +74,7 @@ public class WidgetTypeController extends BaseController { checkEntity(widgetType.getId(), widgetType, Resource.WIDGET_TYPE); WidgetType savedWidgetType = widgetTypeService.saveWidgetType(widgetType); - sendNotificationMsgToEdgeService(getTenantId(), savedWidgetType.getId(), + sendNotificationMsgToEdgeService(getTenantId(), savedWidgetType.getId(), EntityType.WIDGET_TYPE, widgetType.getId() == null ? EdgeEventActionType.ADDED : EdgeEventActionType.UPDATED); return checkNotNull(savedWidgetType); @@ -92,7 +93,7 @@ public class WidgetTypeController extends BaseController { checkWidgetTypeId(widgetTypeId, Operation.DELETE); widgetTypeService.deleteWidgetType(getCurrentUser().getTenantId(), widgetTypeId); - sendNotificationMsgToEdgeService(getTenantId(), widgetTypeId, EdgeEventActionType.DELETED); + sendNotificationMsgToEdgeService(getTenantId(), widgetTypeId, EntityType.WIDGET_TYPE, EdgeEventActionType.DELETED); } catch (Exception e) { throw handleException(e); diff --git a/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java b/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java index 08d9cfe4b7..72fccaf41a 100644 --- a/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java +++ b/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java @@ -25,6 +25,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; +import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.exception.ThingsboardException; @@ -72,7 +73,7 @@ public class WidgetsBundleController extends BaseController { checkEntity(widgetsBundle.getId(), widgetsBundle, Resource.WIDGETS_BUNDLE); WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle); - sendNotificationMsgToEdgeService(getTenantId(), savedWidgetsBundle.getId(), + sendNotificationMsgToEdgeService(getTenantId(), savedWidgetsBundle.getId(), EntityType.WIDGETS_BUNDLE, widgetsBundle.getId() == null ? EdgeEventActionType.ADDED : EdgeEventActionType.UPDATED); return checkNotNull(savedWidgetsBundle); @@ -91,7 +92,7 @@ public class WidgetsBundleController extends BaseController { checkWidgetsBundleId(widgetsBundleId, Operation.DELETE); widgetsBundleService.deleteWidgetsBundle(getTenantId(), widgetsBundleId); - sendNotificationMsgToEdgeService(getTenantId(), widgetsBundleId, EdgeEventActionType.DELETED); + sendNotificationMsgToEdgeService(getTenantId(), widgetsBundleId, EntityType.WIDGETS_BUNDLE, EdgeEventActionType.DELETED); } catch (Exception e) { throw handleException(e); From e23d2c7465cb139b33649c3a7c0b3d57f4fdf708 Mon Sep 17 00:00:00 2001 From: Artem Babak Date: Thu, 17 Dec 2020 05:40:42 +0200 Subject: [PATCH 5/9] Edge import finished --- ui/src/app/api/entity.service.js | 12 ++++++++---- .../table-columns-assignment.directive.js | 14 +++++++++----- ui/src/app/locale/locale.constant-en_US.json | 6 +++--- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/ui/src/app/api/entity.service.js b/ui/src/app/api/entity.service.js index 7c94c4b574..df684c334e 100644 --- a/ui/src/app/api/entity.service.js +++ b/ui/src/app/api/entity.service.js @@ -1278,10 +1278,14 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device } if (entityType === types.entityType.edge) { - newEntity.edgeLicenseKey = entityParameters.edgeLicenseKey; - newEntity.cloudEndpoint = entityParameters.cloudEndpoint; - newEntity.routingKey = entityParameters.routingKey; - newEntity.secret = entityParameters.secret; + Object.assign(newEntity, + { + edgeLicenseKey: entityParameters.edgeLicenseKey, + cloudEndpoint: entityParameters.cloudEndpoint, + routingKey: entityParameters.routingKey, + secret: entityParameters.secret + } + ); } let saveEntityPromise = getEntitySavePromise(entityType, newEntity, config); diff --git a/ui/src/app/import-export/table-columns-assignment.directive.js b/ui/src/app/import-export/table-columns-assignment.directive.js index ebfa0c8af6..012f7afad5 100644 --- a/ui/src/app/import-export/table-columns-assignment.directive.js +++ b/ui/src/app/import-export/table-columns-assignment.directive.js @@ -133,15 +133,19 @@ function TableColumnsAssignmentController($scope, types, $timeout) { vm.columnTypes.name.disable = isSelectName; vm.columnTypes.type.disable = isSelectType; vm.columnTypes.label.disable = isSelectLabel; - vm.columnTypes.gateway.disable = isSelectGateway; + if (angular.isDefined(vm.columnTypes.gateway)) { + vm.columnTypes.gateway.disable = isSelectGateway; + } vm.columnTypes.description.disable = isSelectDescription; if (angular.isDefined(vm.columnTypes.accessToken)) { vm.columnTypes.accessToken.disable = isSelectCredentials; } - vm.columnTypes.edgeLicenseKey.disable = isSelectEdgeLicenseKey; - vm.columnTypes.cloudEndpoint.disable = isSelectCloudEndpoint; - vm.columnTypes.routingKey.disable = isSelectRoutingKey; - vm.columnTypes.secret.disable = isSelectSecret; + if (vm.entityType === types.entityType.edge) { + vm.columnTypes.edgeLicenseKey.disable = isSelectEdgeLicenseKey; + vm.columnTypes.cloudEndpoint.disable = isSelectCloudEndpoint; + vm.columnTypes.routingKey.disable = isSelectRoutingKey; + vm.columnTypes.secret.disable = isSelectSecret; + } }); } }, true); diff --git a/ui/src/app/locale/locale.constant-en_US.json b/ui/src/app/locale/locale.constant-en_US.json index cf553f23c2..fe63f6e96b 100644 --- a/ui/src/app/locale/locale.constant-en_US.json +++ b/ui/src/app/locale/locale.constant-en_US.json @@ -1405,9 +1405,9 @@ "access-token": "Access token", "isgateway": "Is Gateway", "description": "Description", - "edgeLicenseKey": "Edge license key", - "cloudEndpoint": "Cloud endpoint", - "routingKey": "Edge routing key", + "edgeLicenseKey": "License Key", + "cloudEndpoint": "Cloud Endpoint", + "routingKey": "Edge key", "secret": "Edge secret" }, "stepper-text":{ From 785ac9835551a0f29bcd13b86994b2e929f220df Mon Sep 17 00:00:00 2001 From: deaflynx Date: Fri, 18 Dec 2020 10:28:34 +0200 Subject: [PATCH 6/9] Added Make edge public, locale for edge types --- ui/src/app/edge/edge-fieldset.tpl.html | 3 +++ ui/src/app/locale/locale.constant-en_US.json | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ui/src/app/edge/edge-fieldset.tpl.html b/ui/src/app/edge/edge-fieldset.tpl.html index ddc109a2cc..2f2195ec39 100644 --- a/ui/src/app/edge/edge-fieldset.tpl.html +++ b/ui/src/app/edge/edge-fieldset.tpl.html @@ -21,6 +21,9 @@ {{ isPublic ? 'edge.make-private' : 'edge.unassign-from-customer' | translate }} +{{ 'edge.make-public' | translate }} {{ 'edge.manage-edge-assets' | translate }} diff --git a/ui/src/app/locale/locale.constant-en_US.json b/ui/src/app/locale/locale.constant-en_US.json index 17fc467285..5e02bc95b5 100644 --- a/ui/src/app/locale/locale.constant-en_US.json +++ b/ui/src/app/locale/locale.constant-en_US.json @@ -849,7 +849,10 @@ "deployed": "Deployed", "pending": "Pending", "unassign-edges-action-title": "Unassign { count, plural, 1 {1 edge} other {# edges} } from customer", - "enter-edge-type": "Enter edge type" + "enter-edge-type": "Enter edge type", + "no-edge-types-matching": "No edge types matching '{{entitySubtype}}' were found.", + "edge-type-list-empty": "No edge types selected.", + "edge-types": "Edge types" }, "error": { "unable-to-connect": "Unable to connect to the server! Please check your internet connection.", From b1011f43a524886904615b876e3bfac8c926aee4 Mon Sep 17 00:00:00 2001 From: deaflynx Date: Fri, 18 Dec 2020 10:59:52 +0200 Subject: [PATCH 7/9] Fix for import rule chains without type --- ui/src/app/import-export/import-export.service.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/app/import-export/import-export.service.js b/ui/src/app/import-export/import-export.service.js index dc0fbf1ea7..52b0e35786 100644 --- a/ui/src/app/import-export/import-export.service.js +++ b/ui/src/app/import-export/import-export.service.js @@ -310,7 +310,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, return false; } if (angular.isUndefined(ruleChainImport.ruleChain.type)) { - return false; + ruleChainImport.ruleChain.type = types.ruleChainType.core; } return true; } From 00a40e63ba0cbb974fc9dd4ea034d27da0bba83d Mon Sep 17 00:00:00 2001 From: deaflynx Date: Fri, 18 Dec 2020 11:56:24 +0200 Subject: [PATCH 8/9] Deleted edges hierarchy widget --- ui/src/app/api/widget.service.js | 3 +- .../app/widget/lib/edges-hierarchy-widget.js | 679 ------------------ .../widget/lib/edges-hierarchy-widget.scss | 109 --- .../lib/edges-hierarchy-widget.tpl.html | 51 -- 4 files changed, 1 insertion(+), 841 deletions(-) delete mode 100644 ui/src/app/widget/lib/edges-hierarchy-widget.js delete mode 100644 ui/src/app/widget/lib/edges-hierarchy-widget.scss delete mode 100644 ui/src/app/widget/lib/edges-hierarchy-widget.tpl.html diff --git a/ui/src/app/api/widget.service.js b/ui/src/app/api/widget.service.js index b6be883466..4b706e827d 100644 --- a/ui/src/app/api/widget.service.js +++ b/ui/src/app/api/widget.service.js @@ -22,7 +22,6 @@ import thingsboardTimeseriesTableWidget from '../widget/lib/timeseries-table-wid import thingsboardAlarmsTableWidget from '../widget/lib/alarms-table-widget'; import thingsboardEntitiesTableWidget from '../widget/lib/entities-table-widget'; import thingsboardEntitiesHierarchyWidget from '../widget/lib/entities-hierarchy-widget'; -import thingsboardEdgesHierarchyWidget from '../widget/lib/edges-hierarchy-widget'; import thingsboardExtensionsTableWidget from '../widget/lib/extensions-table-widget'; import thingsboardDateRangeNavigatorWidget from '../widget/lib/date-range-navigator/date-range-navigator'; import thingsboardMultipleInputWidget from '../widget/lib/multiple-input-widget'; @@ -53,7 +52,7 @@ import thingsboardUtils from '../common/utils.service'; export default angular.module('thingsboard.api.widget', ['oc.lazyLoad', thingsboardLedLight, thingsboardTimeseriesTableWidget, thingsboardAlarmsTableWidget, thingsboardEntitiesTableWidget, - thingsboardEntitiesHierarchyWidget, thingsboardEdgesHierarchyWidget, thingsboardExtensionsTableWidget, thingsboardDateRangeNavigatorWidget, + thingsboardEntitiesHierarchyWidget, thingsboardExtensionsTableWidget, thingsboardDateRangeNavigatorWidget, thingsboardMultipleInputWidget, thingsboardWebCameraInputWidget, thingsboardRpcWidgets, thingsboardTypes, thingsboardUtils, thingsboardJsonToString, TripAnimationWidget]) .factory('widgetService', WidgetService) diff --git a/ui/src/app/widget/lib/edges-hierarchy-widget.js b/ui/src/app/widget/lib/edges-hierarchy-widget.js deleted file mode 100644 index 42b58eafc0..0000000000 --- a/ui/src/app/widget/lib/edges-hierarchy-widget.js +++ /dev/null @@ -1,679 +0,0 @@ -/* - * Copyright © 2016-2020 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import './edges-hierarchy-widget.scss'; - -/* eslint-disable import/no-unresolved, import/default */ - -import edgesHierarchyWidgetTemplate from './edges-hierarchy-widget.tpl.html'; - -/* eslint-enable import/no-unresolved, import/default */ - -export default angular.module('thingsboard.widgets.edgesHierarchyWidget', []) - .directive('tbEdgesHierarchyWidget', EdgesHierarchyWidget) - .name; -/* eslint-disable no-unused-vars */ -/*@ngInject*/ -function EdgesHierarchyWidget() { - return { - restrict: "E", - scope: true, - bindToController: { - hierarchyId: '=', - ctx: '=' - }, - controller: EdgesHierarchyWidgetController, - controllerAs: 'vm', - templateUrl: edgesHierarchyWidgetTemplate - }; -} - -/*@ngInject*/ -function EdgesHierarchyWidgetController($element, $scope, $q, $timeout, toast, types, entityService, entityRelationService, - assetService, deviceService, entityViewService, dashboardService, ruleChainService /*$filter, $mdMedia, $mdPanel, $document, $translate, $timeout, utils, types*/) { - var vm = this; - - vm.showData = true; - - vm.nodeEditCallbacks = {}; - - vm.nodeIdCounter = 0; - - vm.nodesMap = {}; - vm.pendingUpdateNodeTasks = {}; - vm.edgeGroupsNodesMap = {}; - - vm.query = { - search: null - }; - - vm.searchAction = { - name: 'action.search', - show: true, - onAction: function() { - vm.enterFilterMode(); - }, - icon: 'search' - }; - - vm.onNodesInserted = onNodesInserted; - vm.onNodeSelected = onNodeSelected; - vm.enterFilterMode = enterFilterMode; - vm.exitFilterMode = exitFilterMode; - vm.searchCallback = searchCallback; - - $scope.$watch('vm.ctx', function() { - if (vm.ctx && vm.ctx.defaultSubscription) { - vm.settings = vm.ctx.settings; - vm.widgetConfig = vm.ctx.widgetConfig; - vm.subscription = vm.ctx.defaultSubscription; - vm.datasources = vm.subscription.datasources; - initializeConfig(); - updateDatasources(); - } - }); - - $scope.$watch("vm.query.search", function(newVal, prevVal) { - if (!angular.equals(newVal, prevVal) && vm.query.search != null) { - updateSearchNodes(); - } - }); - - $scope.$on('edges-hierarchy-data-updated', function(event, hierarchyId) { - if (vm.hierarchyId == hierarchyId) { - if (vm.subscription) { - updateNodeData(vm.subscription.data); - } - } - }); - - function initializeConfig() { - - vm.ctx.widgetActions = [ vm.searchAction ]; - - var testNodeCtx = { - entity: { - id: { - entityType: 'DEVICE', - id: '123' - }, - name: 'TEST DEV1' - }, - data: {}, - level: 2 - }; - var parentNodeCtx = angular.copy(testNodeCtx); - parentNodeCtx.level = 1; - testNodeCtx.parentNodeCtx = parentNodeCtx; - - var nodeRelationQueryFunction = loadNodeCtxFunction(vm.settings.nodeRelationQueryFunction, 'nodeCtx', testNodeCtx); - var nodeIconFunction = loadNodeCtxFunction(vm.settings.nodeIconFunction, 'nodeCtx', testNodeCtx); - var nodeTextFunction = loadNodeCtxFunction(vm.settings.nodeTextFunction, 'nodeCtx', testNodeCtx); - var nodeDisabledFunction = loadNodeCtxFunction(vm.settings.nodeDisabledFunction, 'nodeCtx', testNodeCtx); - var nodeOpenedFunction = loadNodeCtxFunction(vm.settings.nodeOpenedFunction, 'nodeCtx', testNodeCtx); - var nodeHasChildrenFunction = loadNodeCtxFunction(vm.settings.nodeHasChildrenFunction, 'nodeCtx', testNodeCtx); - - var testNodeCtx2 = angular.copy(testNodeCtx); - testNodeCtx2.entity.name = 'TEST DEV2'; - - var nodesSortFunction = loadNodeCtxFunction(vm.settings.nodesSortFunction, 'nodeCtx1,nodeCtx2', testNodeCtx, testNodeCtx2); - - vm.nodeRelationQueryFunction = nodeRelationQueryFunction || defaultNodeRelationQueryFunction; - vm.nodeIconFunction = nodeIconFunction || defaultNodeIconFunction; - vm.nodeTextFunction = nodeTextFunction || ((nodeCtx) => nodeCtx.entity.name); - vm.nodeDisabledFunction = nodeDisabledFunction || (() => false); - vm.nodeOpenedFunction = nodeOpenedFunction || defaultNodeOpenedFunction; - vm.nodeHasChildrenFunction = nodeHasChildrenFunction || (() => true); - vm.nodesSortFunction = nodesSortFunction || defaultSortFunction; - } - - function loadNodeCtxFunction(functionBody, argNames, ...args) { - var nodeCtxFunction = null; - if (angular.isDefined(functionBody) && functionBody.length) { - try { - nodeCtxFunction = new Function(argNames, functionBody); - var res = nodeCtxFunction.apply(null, args); - if (angular.isUndefined(res)) { - nodeCtxFunction = null; - } - } catch (e) { - nodeCtxFunction = null; - } - } - return nodeCtxFunction; - } - - function enterFilterMode () { - vm.query.search = ''; - vm.ctx.hideTitlePanel = true; - $timeout(()=>{ - angular.element(vm.ctx.$container).find('.searchInput').focus(); - }) - } - - function exitFilterMode () { - vm.query.search = null; - updateSearchNodes(); - vm.ctx.hideTitlePanel = false; - } - - function searchCallback (searchText, node) { - var theNode = vm.nodesMap[node.id]; - if (theNode && theNode.data.searchText) { - return theNode.data.searchText.includes(searchText.toLowerCase()); - } - return false; - } - - function updateDatasources() { - vm.loadNodes = loadNodes; - } - - function updateSearchNodes() { - if (vm.query.search != null) { - vm.nodeEditCallbacks.search(vm.query.search); - } else { - vm.nodeEditCallbacks.clearSearch(); - } - } - - function onNodesInserted(nodes/*, parent*/) { - if (nodes) { - nodes.forEach((nodeId) => { - var task = vm.pendingUpdateNodeTasks[nodeId]; - if (task) { - task(); - delete vm.pendingUpdateNodeTasks[nodeId]; - } - }); - } - } - - function onNodeSelected(node, event) { - var nodeId; - if (!node) { - nodeId = -1; - } else { - nodeId = node.id; - } - if (nodeId !== -1) { - var selectedNode = vm.nodesMap[nodeId]; - if (selectedNode) { - var descriptors = vm.ctx.actionsApi.getActionDescriptors('nodeSelected'); - if (descriptors.length) { - var entity = selectedNode.data.nodeCtx.entity; - vm.ctx.actionsApi.handleWidgetAction(event, descriptors[0], entity.id, entity.name, { nodeCtx: selectedNode.data.nodeCtx }); - } - } - } - } - - function updateNodeData(subscriptionData) { - var affectedNodes = []; - if (subscriptionData) { - for (var i=0;i { - var node = vm.nodeEditCallbacks.getNode(nodeId); - if (node) { - updateNodeStyle(vm.nodesMap[nodeId]); - } else { - vm.pendingUpdateNodeTasks[nodeId] = () => { - updateNodeStyle(vm.nodesMap[nodeId]); - }; - } - }); - } - - function updateNodeStyle(node) { - var newText = prepareNodeText(node); - if (!angular.equals(node.text, newText)) { - node.text = newText; - vm.nodeEditCallbacks.updateNode(node.id, node.text); - } - var newDisabled = vm.nodeDisabledFunction(node.data.nodeCtx); - if (!angular.equals(node.state.disabled, newDisabled)) { - node.state.disabled = newDisabled; - if (node.state.disabled) { - vm.nodeEditCallbacks.disableNode(node.id); - } else { - vm.nodeEditCallbacks.enableNode(node.id); - } - } - var newHasChildren = vm.nodeHasChildrenFunction(node.data.nodeCtx); - if (!angular.equals(node.children, newHasChildren)) { - node.children = newHasChildren; - vm.nodeEditCallbacks.setNodeHasChildren(node.id, node.children); - } - } - - function prepareNodeText(node) { - var nodeIcon = prepareNodeIcon(node.data.nodeCtx); - var nodeText = vm.nodeTextFunction(node.data.nodeCtx); - node.data.searchText = nodeText ? nodeText.replace(/<[^>]+>/g, '').toLowerCase() : ""; - return nodeIcon + nodeText; - } - - function loadNodes(node, cb) { - if (node.id === '#') { - var tasks = []; - for (var i=0;i { - cb(prepareNodes(nodes)); - updateNodeData(vm.subscription.data); - }); - } else { - if (node.data && node.data.nodeCtx.entity && node.data.nodeCtx.entity.id && node.data.nodeCtx.entity.id.entityType !== 'function') { - if (node.data.nodeCtx.entity.id.entityType === types.entityType.edge) { - /* assetService.getEdgeAssets(node.data.nodeCtx.entity.id.id, {limit: 20}, null).then( - (entities) => { - var tasks = []; - for (var i=0;i { - cb(prepareNodes(nodes)); - }); - } - ); - deviceService.getEdgeDevices(node.data.nodeCtx.entity.id.id, {limit: 20}, null).then( - (entities) => { - var tasks = []; - for (var i=0;i { - cb(prepareNodes(nodes)); - }); - } - ); - entityViewService.getEdgeEntityViews(node.data.nodeCtx.entity.id.id, {limit: 20}, null).then( - (entities) => { - var tasks = []; - for (var i=0;i { - cb(prepareNodes(nodes)); - }); - } - ); - dashboardService.getEdgeDashboards(node.data.nodeCtx.entity.id.id, {limit: 20}, null).then( - (entities) => { - var tasks = []; - for (var i=0;i { - cb(prepareNodes(nodes)); - }); - } - ) - ruleChainService.getEdgeRuleChains(node.data.nodeCtx.entity.id.id, {limit: 20}, null).then( - (entities) => { - var tasks = []; - for (var i=0;i { - cb(prepareNodes(nodes)); - }); - } - ) - */ - - entityIdToNodeEdge("edgeGroup", "001", node.data.datasource, ) - - } else { - var relationQuery = prepareNodeRelationQuery(node.data.nodeCtx); - entityRelationService.findByQuery(relationQuery, {ignoreErrors: true, ignoreLoading: true}).then( - (entityRelations) => { - var tasks = []; - for (var i=0;i { - cb(prepareNodes(nodes)); - }); - }, - (error) => { - var errorText = "Failed to get relations!"; - if (error && error.status === 400) { - errorText = "Invalid relations query returned by 'Node relations query function'! Please check widget configuration!"; - } - showError(errorText); - } - ); - } - } else { - cb([]); - } - } - } - - function showError(errorText) { - var toastParent = angular.element('.tb-edges-hierarchy', $element); - toast.showError(errorText, toastParent, 'bottom left'); - } - - function prepareNodes(nodes) { - nodes = nodes.filter((node) => node !== null); - nodes.sort((node1, node2) => vm.nodesSortFunction(node1.data.nodeCtx, node2.data.nodeCtx)); - return nodes; - } - - function datasourceToNode(datasource, parentNodeCtx) { - var deferred = $q.defer(); - resolveEntity(datasource).then( - (entity) => { - if (entity != null) { - var node = { - id: ++vm.nodeIdCounter - }; - vm.nodesMap[node.id] = node; - datasource.nodeId = node.id; - node.icon = false; - var nodeCtx = { - parentNodeCtx: parentNodeCtx, - entity: entity, - data: {} - }; - nodeCtx.level = parentNodeCtx ? parentNodeCtx.level + 1 : 1; - node.data = { - datasource: datasource, - nodeCtx: nodeCtx - }; - node.state = { - disabled: vm.nodeDisabledFunction(node.data.nodeCtx), - opened: vm.nodeOpenedFunction(node.data.nodeCtx) - }; - node.text = prepareNodeText(node); - node.children = vm.nodeHasChildrenFunction(node.data.nodeCtx); - deferred.resolve(node); - } else { - deferred.resolve(null); - } - } - ); - return deferred.promise; - } - - function datasourceToNodeEdge(datasource, parentNodeCtx) { - var deferred = $q.defer(); - resolveEntity(datasource).then( - (entity) => { - if (entity != null) { - var node = { - id: ++vm.nodeIdCounter - }; - vm.nodesMap[node.id] = node; - datasource.nodeId = node.id; - node.icon = false; - var nodeCtx = { - parentNodeCtx: parentNodeCtx, - entity: entity, - data: {} - }; - nodeCtx.level = parentNodeCtx ? parentNodeCtx.level + 1 : 1; - node.data = { - datasource: datasource, - nodeCtx: nodeCtx - }; - node.state = { - disabled: vm.nodeDisabledFunction(node.data.nodeCtx), - opened: vm.nodeOpenedFunction(node.data.nodeCtx) - }; - node.text = prepareNodeText(node); - node.children = vm.nodeHasChildrenFunction(node.data.nodeCtx); - deferred.resolve(node); - } else { - deferred.resolve(null); - } - } - ); - return deferred.promise; - } - - - function entityIdToNodeEdge(entityType, entityId, parentDatasource, parentNodeCtx) { - var deferred = $q.defer(); - var datasource = { - dataKeys: parentDatasource.dataKeys, - type: types.datasourceType.entity, - entityType: entityType, - entityId: entityId - }; - datasourceToNodeEdge(datasource, parentNodeCtx).then( - (node) => { - if (node != null) { - var subscriptionOptions = { - type: types.widgetType.latest.value, - datasources: [datasource], - callbacks: { - onDataUpdated: (subscription) => { - updateNodeData(subscription.data); - } - } - }; - vm.ctx.subscriptionApi.createSubscription(subscriptionOptions, true).then( - (/*subscription*/) => { - deferred.resolve(node); - } - ); - } else { - deferred.resolve(node); - } - } - ); - return deferred.promise; - } - - function entityIdToNode(entityType, entityId, parentDatasource, parentNodeCtx) { - var deferred = $q.defer(); - var datasource = { - dataKeys: parentDatasource.dataKeys, - type: types.datasourceType.entity, - entityType: entityType, - entityId: entityId - }; - datasourceToNode(datasource, parentNodeCtx).then( - (node) => { - if (node != null) { - var subscriptionOptions = { - type: types.widgetType.latest.value, - datasources: [datasource], - callbacks: { - onDataUpdated: (subscription) => { - updateNodeData(subscription.data); - } - } - }; - vm.ctx.subscriptionApi.createSubscription(subscriptionOptions, true).then( - (/*subscription*/) => { - deferred.resolve(node); - } - ); - } else { - deferred.resolve(node); - } - } - ); - return deferred.promise; - } - - function resolveEntity(datasource) { - var deferred = $q.defer(); - if (datasource.type === types.datasourceType.function) { - var entity = { - id: { - entityType: "function" - }, - name: datasource.name - } - deferred.resolve(entity); - } else { - entityService.getEntity(datasource.entityType, datasource.entityId, {ignoreLoading: true}).then( - (entity) => { - deferred.resolve(entity); - }, - () => { - deferred.resolve(null); - } - ); - } - return deferred.promise; - } - - - function prepareNodeRelationQuery(nodeCtx) { - var relationQuery = vm.nodeRelationQueryFunction(nodeCtx); - if (relationQuery && relationQuery === 'default') { - relationQuery = defaultNodeRelationQueryFunction(nodeCtx); - } - return relationQuery; - } - - function defaultNodeRelationQueryFunction(nodeCtx) { - var entity = nodeCtx.entity; - var query = { - parameters: { - rootId: entity.id.id, - rootType: entity.id.entityType, - direction: types.entitySearchDirection.from, - relationTypeGroup: "COMMON", - maxLevel: 1 - }, - filters: [ - { - relationType: "Contains", - entityTypes: [] - } - ] - }; - return query; - } - - function prepareNodeIcon(nodeCtx) { - var iconInfo = vm.nodeIconFunction(nodeCtx); - if (iconInfo && iconInfo === 'default') { - iconInfo = defaultNodeIconFunction(nodeCtx); - } - if (iconInfo && (iconInfo.iconUrl || iconInfo.materialIcon)) { - if (iconInfo.materialIcon) { - return materialIconHtml(iconInfo.materialIcon); - } else { - return iconUrlHtml(iconInfo.iconUrl); - } - } else { - return ""; - } - } - - function materialIconHtml(materialIcon) { - return ''+materialIcon+''; - } - - function iconUrlHtml(iconUrl) { - return '
 
'; - } - - function defaultNodeIconFunction(nodeCtx) { - var materialIcon = 'insert_drive_file'; - var entity = nodeCtx.entity; - if (entity && entity.id && entity.id.entityType) { - switch (entity.id.entityType) { - case 'function': - materialIcon = 'functions'; - break; - case types.entityType.device: - materialIcon = 'devices_other'; - break; - case types.entityType.asset: - materialIcon = 'domain'; - break; - case types.entityType.tenant: - materialIcon = 'supervisor_account'; - break; - case types.entityType.customer: - materialIcon = 'supervisor_account'; - break; - case types.entityType.user: - materialIcon = 'account_circle'; - break; - case types.entityType.dashboard: - materialIcon = 'dashboards'; - break; - case types.entityType.alarm: - materialIcon = 'notifications_active'; - break; - case types.entityType.entityView: - materialIcon = 'view_quilt'; - break; - case types.entityType.edge: - materialIcon = 'router'; - break; - case types.entityType.rulechain: - materialIcon = 'settings_ethernet'; - break; - } - } - return { - materialIcon: materialIcon - }; - } - - function defaultNodeOpenedFunction(nodeCtx) { - return nodeCtx.level <= 4; - } - - function defaultSortFunction(nodeCtx1, nodeCtx2) { - var result = nodeCtx1.entity.id.entityType.localeCompare(nodeCtx2.entity.id.entityType); - if (result === 0) { - result = nodeCtx1.entity.name.localeCompare(nodeCtx2.entity.name); - } - return result; - } -} diff --git a/ui/src/app/widget/lib/edges-hierarchy-widget.scss b/ui/src/app/widget/lib/edges-hierarchy-widget.scss deleted file mode 100644 index b7613aad7e..0000000000 --- a/ui/src/app/widget/lib/edges-hierarchy-widget.scss +++ /dev/null @@ -1,109 +0,0 @@ -/** - * Copyright © 2016-2020 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -.tb-has-timewindow { - .tb-edges-hierarchy { - md-toolbar { - min-height: 60px; - max-height: 60px; - } - } -} - -.tb-edges-hierarchy { - md-toolbar { - min-height: 39px; - max-height: 39px; - } - - .tb-entities-nav-tree-panel { - overflow-x: auto; - overflow-y: auto; - - .tb-nav-tree-container { - &.jstree-proton { - .jstree-anchor { - div.node-icon { - display: inline-block; - width: 22px; - height: 22px; - margin-right: 2px; - margin-bottom: 2px; - background-color: transparent; - background-repeat: no-repeat; - background-attachment: scroll; - background-position: center center; - background-size: 18px 18px; - } - - md-icon.node-icon { - width: 22px; - min-width: 22px; - height: 22px; - min-height: 22px; - margin-right: 2px; - margin-bottom: 2px; - color: inherit; - - &.material-icons { /* stylelint-disable-line selector-max-class */ - font-size: 18px; - line-height: 22px; - text-align: center; - } - } - - &.jstree-hovered:not(.jstree-clicked), - &.jstree-disabled { - div.node-icon { /* stylelint-disable-line selector-max-class */ - opacity: .5; - } - } - } - } - } - } -} - -@media (max-width: 768px) { - .tb-edges-hierarchy { - .tb-entities-nav-tree-panel { - .tb-nav-tree-container { - &.jstree-proton-responsive { - .jstree-anchor { - div.node-icon { - width: 40px; - height: 40px; - margin: 0; - background-size: 24px 24px; - } - - md-icon.node-icon { - width: 40px; - min-width: 40px; - height: 40px; - min-height: 40px; - margin: 0; - - &.material-icons { /* stylelint-disable-line selector-max-class */ - font-size: 24px; - line-height: 40px; - } - } - } - } - } - } - } -} diff --git a/ui/src/app/widget/lib/edges-hierarchy-widget.tpl.html b/ui/src/app/widget/lib/edges-hierarchy-widget.tpl.html deleted file mode 100644 index e16ebe97d9..0000000000 --- a/ui/src/app/widget/lib/edges-hierarchy-widget.tpl.html +++ /dev/null @@ -1,51 +0,0 @@ - -
-
- -
- - search - - {{'entity.search' | translate}} - - - - - - - - close - - {{ 'action.close' | translate }} - - -
-
-
- -
-
-
From aabaada1980b95e0592fa9ffd809f1ac64314284 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Fri, 18 Dec 2020 13:25:42 +0200 Subject: [PATCH 9/9] Added edges enabled endpoint. Refactored yml edges config --- .../server/actors/ActorSystemContext.java | 4 ++-- .../actors/device/DeviceActorMessageProcessor.java | 4 ++-- .../server/controller/BaseController.java | 12 ++++++------ .../server/controller/EdgeController.java | 9 ++++++++- .../service/edge/rpc/EdgeEventStorageSettings.java | 6 +++--- .../server/service/edge/rpc/EdgeGrpcService.java | 2 +- application/src/main/resources/thingsboard.yml | 10 +++++----- .../thingsboard/server/dao/edge/EdgeServiceImpl.java | 6 +++--- 8 files changed, 30 insertions(+), 23 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java b/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java index 10dd1e87ea..d937e04979 100644 --- a/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java +++ b/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java @@ -291,9 +291,9 @@ public class ActorSystemContext { @Getter private long statisticsPersistFrequency; - @Value("${edges.rpc.enabled}") + @Value("${edges.enabled}") @Getter - private boolean edgesRpcEnabled; + private boolean edgesEnabled; @Scheduled(fixedDelayString = "${actors.statistics.js_print_interval_ms}") public void printStats() { diff --git a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java index 68ced0b7ab..0ddcd60eca 100644 --- a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java +++ b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java @@ -130,7 +130,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { this.defaultMetaData = new TbMsgMetaData(); this.defaultMetaData.putValue("deviceName", deviceName); this.defaultMetaData.putValue("deviceType", deviceType); - if (systemContext.isEdgesRpcEnabled()) { + if (systemContext.isEdgesEnabled()) { this.edgeId = findRelatedEdgeId(); } return true; @@ -169,7 +169,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { } boolean sent; - if (systemContext.isEdgesRpcEnabled() && edgeId != null) { + if (systemContext.isEdgesEnabled() && edgeId != null) { log.debug("[{}][{}] device is related to edge [{}]. Saving RPC request to edge queue", tenantId, deviceId, edgeId.getId()); saveRpcRequestToEdgeQueue(request, rpcRequest.getRequestId()); sent = true; diff --git a/application/src/main/java/org/thingsboard/server/controller/BaseController.java b/application/src/main/java/org/thingsboard/server/controller/BaseController.java index 3d0f015678..b163282ad0 100644 --- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java +++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java @@ -221,9 +221,9 @@ public abstract class BaseController { @Getter private boolean logControllerErrorStackTrace; - @Value("${edges.rpc.enabled}") + @Value("${edges.enabled}") @Getter - private boolean edgesRpcEnabled; + protected boolean edgesEnabled; @ExceptionHandler(ThingsboardException.class) public void handleThingsboardException(ThingsboardException ex, HttpServletResponse response) { @@ -761,7 +761,7 @@ public abstract class BaseController { } protected void sendNotificationMsgToEdgeService(TenantId tenantId, EdgeId edgeId, CustomerId customerId, EdgeEventActionType action) { - if (!edgesRpcEnabled) { + if (!edgesEnabled) { return; } try { @@ -772,7 +772,7 @@ public abstract class BaseController { } protected void sendNotificationMsgToEdgeService(TenantId tenantId, EntityId entityId, CustomerId customerId, EdgeEventActionType action) { - if (!edgesRpcEnabled) { + if (!edgesEnabled) { return; } EdgeEventType type = EdgeUtils.getEdgeEventTypeByEntityType(entityId.getEntityType()); @@ -786,7 +786,7 @@ public abstract class BaseController { } protected void sendNotificationMsgToEdgeService(TenantId tenantId, EntityRelation relation, EdgeEventActionType action) { - if (!edgesRpcEnabled) { + if (!edgesEnabled) { return; } try { @@ -804,7 +804,7 @@ public abstract class BaseController { } protected void sendNotificationMsgToEdgeService(TenantId tenantId, EdgeId edgeId, EntityId entityId, EntityType entityType, EdgeEventActionType action) { - if (!edgesRpcEnabled) { + if (!edgesEnabled) { return; } EdgeEventType type = EdgeUtils.getEdgeEventTypeByEntityType(entityType); diff --git a/application/src/main/java/org/thingsboard/server/controller/EdgeController.java b/application/src/main/java/org/thingsboard/server/controller/EdgeController.java index 47cfb26553..45c3e51b9d 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EdgeController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EdgeController.java @@ -63,6 +63,13 @@ public class EdgeController extends BaseController { public static final String EDGE_ID = "edgeId"; + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") + @RequestMapping(value = "/edges/enabled", method = RequestMethod.GET) + @ResponseBody + public boolean isEdgesSupportEnabled() { + return edgesEnabled; + } + @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/{edgeId}", method = RequestMethod.GET) @ResponseBody @@ -416,7 +423,7 @@ public class EdgeController extends BaseController { public void syncEdge(@RequestBody EdgeId edgeId) throws ThingsboardException { try { edgeId = checkNotNull(edgeId); - if (isEdgesRpcEnabled()) { + if (isEdgesEnabled()) { EdgeGrpcSession session = edgeGrpcService.getEdgeGrpcSessionById(edgeId); Edge edge = session.getEdge(); syncEdgeService.sync(edge); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeEventStorageSettings.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeEventStorageSettings.java index 13e05e905f..a9368bbd1f 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeEventStorageSettings.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeEventStorageSettings.java @@ -23,10 +23,10 @@ import org.springframework.stereotype.Component; @Component @Data public class EdgeEventStorageSettings { - @Value("${edges.rpc.storage.max_read_records_count}") + @Value("${edges.storage.max_read_records_count}") private int maxReadRecordsCount; - @Value("${edges.rpc.storage.no_read_records_sleep}") + @Value("${edges.storage.no_read_records_sleep}") private long noRecordsSleepInterval; - @Value("${edges.rpc.storage.sleep_between_batches}") + @Value("${edges.storage.sleep_between_batches}") private long sleepIntervalBetweenBatches; } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java index ca3b578734..8fd335efea 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java @@ -59,7 +59,7 @@ import java.util.concurrent.TimeUnit; @Service @Slf4j -@ConditionalOnProperty(prefix = "edges.rpc", value = "enabled", havingValue = "true") +@ConditionalOnProperty(prefix = "edges", value = "enabled", havingValue = "true") @TbCoreComponent public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase implements EdgeRpcService { diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 11c14aa3ba..bdc7de69b5 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -589,8 +589,8 @@ transport: # Edges parameters edges: + enabled: "${EDGES_ENABLED:false}" rpc: - enabled: "${EDGES_RPC_ENABLED:false}" port: "${EDGES_RPC_PORT:7070}" client_max_keep_alive_time_sec: "${EDGES_RPC_CLIENT_MAX_KEEP_ALIVE_TIME_SEC:300}" ssl: @@ -598,10 +598,10 @@ edges: enabled: "${EDGES_RPC_SSL_ENABLED:false}" cert: "${EDGES_RPC_SSL_CERT:certChainFile.pem}" private_key: "${EDGES_RPC_SSL_PRIVATE_KEY:privateKeyFile.pem}" - storage: - max_read_records_count: "${EDGES_RPC_STORAGE_MAX_READ_RECORDS_COUNT:50}" - no_read_records_sleep: "${EDGES_RPC_NO_READ_RECORDS_SLEEP:1000}" - sleep_between_batches: "${EDGES_RPC_SLEEP_BETWEEN_BATCHES:1000}" + storage: + max_read_records_count: "${EDGES_STORAGE_MAX_READ_RECORDS_COUNT:50}" + no_read_records_sleep: "${EDGES_NO_READ_RECORDS_SLEEP:1000}" + sleep_between_batches: "${EDGES_SLEEP_BETWEEN_BATCHES:1000}" scheduler_pool_size: "${EDGES_SCHEDULER_POOL_SIZE:4}" edge_events_ttl: "${EDGES_EDGE_EVENTS_TTL:0}" state: diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java index db0da5016e..92cb65ad08 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java @@ -127,13 +127,13 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic @Autowired private RelationService relationService; - @Value("${edges.rpc.enabled:false}") - private boolean edgesRpcEnabled; + @Value("${edges.enabled:false}") + private boolean edgesEnabled; @PostConstruct public void init() { super.init(); - if (edgesRpcEnabled) { + if (edgesEnabled) { initRestTemplate(); } }