From 65b87cc833472ba10a864d1f7d04830dd9065725 Mon Sep 17 00:00:00 2001 From: Artem Babak Date: Tue, 15 Dec 2020 21:39:19 +0200 Subject: [PATCH 1/3] 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/3] 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)); - }); + 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!"; } - ); - 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); - } - ); - } + 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 e23d2c7465cb139b33649c3a7c0b3d57f4fdf708 Mon Sep 17 00:00:00 2001 From: Artem Babak Date: Thu, 17 Dec 2020 05:40:42 +0200 Subject: [PATCH 3/3] 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":{