From 1d09fa2bd8509760bd7fef5cf655db99598b01a0 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Tue, 29 Dec 2020 20:15:46 +0200 Subject: [PATCH 01/14] removed ServiceId from kafka consumer groupId --- .../queue/provider/KafkaMonolithQueueFactory.java | 10 +++++----- .../server/queue/provider/KafkaTbCoreQueueFactory.java | 6 +++--- .../queue/provider/KafkaTbRuleEngineQueueFactory.java | 6 +++--- .../queue/provider/KafkaTbTransportQueueFactory.java | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaMonolithQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaMonolithQueueFactory.java index 31ef4d3e45..6ed49d21fc 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaMonolithQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaMonolithQueueFactory.java @@ -152,7 +152,7 @@ public class KafkaMonolithQueueFactory implements TbCoreQueueFactory, TbRuleEngi consumerBuilder.settings(kafkaSettings); consumerBuilder.topic(ruleEngineSettings.getTopic()); consumerBuilder.clientId("re-" + queueName + "-consumer-" + serviceInfoProvider.getServiceId()); - consumerBuilder.groupId("re-" + queueName + "-consumer-" + serviceInfoProvider.getServiceId()); + consumerBuilder.groupId("re-" + queueName + "-consumer"); consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToRuleEngineMsg.parseFrom(msg.getData()), msg.getHeaders())); consumerBuilder.admin(ruleEngineAdmin); return consumerBuilder.build(); @@ -164,7 +164,7 @@ public class KafkaMonolithQueueFactory implements TbCoreQueueFactory, TbRuleEngi consumerBuilder.settings(kafkaSettings); consumerBuilder.topic(partitionService.getNotificationsTopic(ServiceType.TB_RULE_ENGINE, serviceInfoProvider.getServiceId()).getFullTopicName()); consumerBuilder.clientId("monolith-rule-engine-notifications-consumer-" + serviceInfoProvider.getServiceId()); - consumerBuilder.groupId("monolith-rule-engine-notifications-consumer-" + serviceInfoProvider.getServiceId()); + consumerBuilder.groupId("monolith-rule-engine-notifications-consumer"); consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToRuleEngineNotificationMsg.parseFrom(msg.getData()), msg.getHeaders())); consumerBuilder.admin(notificationAdmin); return consumerBuilder.build(); @@ -176,7 +176,7 @@ public class KafkaMonolithQueueFactory implements TbCoreQueueFactory, TbRuleEngi consumerBuilder.settings(kafkaSettings); consumerBuilder.topic(coreSettings.getTopic()); consumerBuilder.clientId("monolith-core-consumer-" + serviceInfoProvider.getServiceId()); - consumerBuilder.groupId("monolith-core-consumer-" + serviceInfoProvider.getServiceId()); + consumerBuilder.groupId("monolith-core-consumer"); consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToCoreMsg.parseFrom(msg.getData()), msg.getHeaders())); consumerBuilder.admin(coreAdmin); return consumerBuilder.build(); @@ -188,7 +188,7 @@ public class KafkaMonolithQueueFactory implements TbCoreQueueFactory, TbRuleEngi consumerBuilder.settings(kafkaSettings); consumerBuilder.topic(partitionService.getNotificationsTopic(ServiceType.TB_CORE, serviceInfoProvider.getServiceId()).getFullTopicName()); consumerBuilder.clientId("monolith-core-notifications-consumer-" + serviceInfoProvider.getServiceId()); - consumerBuilder.groupId("monolith-core-notifications-consumer-" + serviceInfoProvider.getServiceId()); + consumerBuilder.groupId("monolith-core-notifications-consumer"); consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToCoreNotificationMsg.parseFrom(msg.getData()), msg.getHeaders())); consumerBuilder.admin(notificationAdmin); return consumerBuilder.build(); @@ -229,7 +229,7 @@ public class KafkaMonolithQueueFactory implements TbCoreQueueFactory, TbRuleEngi responseBuilder.settings(kafkaSettings); responseBuilder.topic(jsInvokeSettings.getResponseTopic() + "." + serviceInfoProvider.getServiceId()); responseBuilder.clientId("js-" + serviceInfoProvider.getServiceId()); - responseBuilder.groupId("rule-engine-node-" + serviceInfoProvider.getServiceId()); + responseBuilder.groupId("rule-engine-node"); responseBuilder.decoder(msg -> { JsInvokeProtos.RemoteJsResponse.Builder builder = JsInvokeProtos.RemoteJsResponse.newBuilder(); JsonFormat.parser().ignoringUnknownFields().merge(new String(msg.getData(), StandardCharsets.UTF_8), builder); diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbCoreQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbCoreQueueFactory.java index bf2ec6751e..7ca2f9196d 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbCoreQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbCoreQueueFactory.java @@ -146,7 +146,7 @@ public class KafkaTbCoreQueueFactory implements TbCoreQueueFactory { consumerBuilder.settings(kafkaSettings); consumerBuilder.topic(coreSettings.getTopic()); consumerBuilder.clientId("tb-core-consumer-" + serviceInfoProvider.getServiceId()); - consumerBuilder.groupId("tb-core-node-" + serviceInfoProvider.getServiceId()); + consumerBuilder.groupId("tb-core-node"); consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToCoreMsg.parseFrom(msg.getData()), msg.getHeaders())); consumerBuilder.admin(coreAdmin); return consumerBuilder.build(); @@ -158,7 +158,7 @@ public class KafkaTbCoreQueueFactory implements TbCoreQueueFactory { consumerBuilder.settings(kafkaSettings); consumerBuilder.topic(partitionService.getNotificationsTopic(ServiceType.TB_CORE, serviceInfoProvider.getServiceId()).getFullTopicName()); consumerBuilder.clientId("tb-core-notifications-consumer-" + serviceInfoProvider.getServiceId()); - consumerBuilder.groupId("tb-core-notifications-node-" + serviceInfoProvider.getServiceId()); + consumerBuilder.groupId("tb-core-notifications-node"); consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToCoreNotificationMsg.parseFrom(msg.getData()), msg.getHeaders())); consumerBuilder.admin(notificationAdmin); return consumerBuilder.build(); @@ -199,7 +199,7 @@ public class KafkaTbCoreQueueFactory implements TbCoreQueueFactory { responseBuilder.settings(kafkaSettings); responseBuilder.topic(jsInvokeSettings.getResponseTopic() + "." + serviceInfoProvider.getServiceId()); responseBuilder.clientId("js-" + serviceInfoProvider.getServiceId()); - responseBuilder.groupId("rule-engine-node-" + serviceInfoProvider.getServiceId()); + responseBuilder.groupId("rule-engine-node"); responseBuilder.decoder(msg -> { JsInvokeProtos.RemoteJsResponse.Builder builder = JsInvokeProtos.RemoteJsResponse.newBuilder(); JsonFormat.parser().ignoringUnknownFields().merge(new String(msg.getData(), StandardCharsets.UTF_8), builder); diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbRuleEngineQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbRuleEngineQueueFactory.java index dc44caf3f0..3bab6d1866 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbRuleEngineQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbRuleEngineQueueFactory.java @@ -141,7 +141,7 @@ public class KafkaTbRuleEngineQueueFactory implements TbRuleEngineQueueFactory { consumerBuilder.settings(kafkaSettings); consumerBuilder.topic(ruleEngineSettings.getTopic()); consumerBuilder.clientId("re-" + queueName + "-consumer-" + serviceInfoProvider.getServiceId()); - consumerBuilder.groupId("re-" + queueName + "-consumer-" + serviceInfoProvider.getServiceId()); + consumerBuilder.groupId("re-" + queueName + "-consumer"); consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToRuleEngineMsg.parseFrom(msg.getData()), msg.getHeaders())); consumerBuilder.admin(ruleEngineAdmin); return consumerBuilder.build(); @@ -153,7 +153,7 @@ public class KafkaTbRuleEngineQueueFactory implements TbRuleEngineQueueFactory { consumerBuilder.settings(kafkaSettings); consumerBuilder.topic(partitionService.getNotificationsTopic(ServiceType.TB_RULE_ENGINE, serviceInfoProvider.getServiceId()).getFullTopicName()); consumerBuilder.clientId("tb-rule-engine-notifications-consumer-" + serviceInfoProvider.getServiceId()); - consumerBuilder.groupId("tb-rule-engine-notifications-node-" + serviceInfoProvider.getServiceId()); + consumerBuilder.groupId("tb-rule-engine-notifications-node"); consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToRuleEngineNotificationMsg.parseFrom(msg.getData()), msg.getHeaders())); consumerBuilder.admin(notificationAdmin); return consumerBuilder.build(); @@ -172,7 +172,7 @@ public class KafkaTbRuleEngineQueueFactory implements TbRuleEngineQueueFactory { responseBuilder.settings(kafkaSettings); responseBuilder.topic(jsInvokeSettings.getResponseTopic() + "." + serviceInfoProvider.getServiceId()); responseBuilder.clientId("js-" + serviceInfoProvider.getServiceId()); - responseBuilder.groupId("rule-engine-node-" + serviceInfoProvider.getServiceId()); + responseBuilder.groupId("rule-engine-node"); responseBuilder.decoder(msg -> { JsInvokeProtos.RemoteJsResponse.Builder builder = JsInvokeProtos.RemoteJsResponse.newBuilder(); JsonFormat.parser().ignoringUnknownFields().merge(new String(msg.getData(), StandardCharsets.UTF_8), builder); diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbTransportQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbTransportQueueFactory.java index 505aa203d7..58623a8f0b 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbTransportQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbTransportQueueFactory.java @@ -91,7 +91,7 @@ public class KafkaTbTransportQueueFactory implements TbTransportQueueFactory { responseBuilder.settings(kafkaSettings); responseBuilder.topic(transportApiSettings.getResponsesTopic() + "." + serviceInfoProvider.getServiceId()); responseBuilder.clientId("transport-api-response-" + serviceInfoProvider.getServiceId()); - responseBuilder.groupId("transport-node-" + serviceInfoProvider.getServiceId()); + responseBuilder.groupId("transport-node"); responseBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), TransportApiResponseMsg.parseFrom(msg.getData()), msg.getHeaders())); responseBuilder.admin(transportApiAdmin); @@ -132,7 +132,7 @@ public class KafkaTbTransportQueueFactory implements TbTransportQueueFactory { responseBuilder.settings(kafkaSettings); responseBuilder.topic(transportNotificationSettings.getNotificationsTopic() + "." + serviceInfoProvider.getServiceId()); responseBuilder.clientId("transport-api-notifications-" + serviceInfoProvider.getServiceId()); - responseBuilder.groupId("transport-node-" + serviceInfoProvider.getServiceId()); + responseBuilder.groupId("transport-node"); responseBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToTransportMsg.parseFrom(msg.getData()), msg.getHeaders())); responseBuilder.admin(notificationAdmin); return responseBuilder.build(); From 36868537517d5b1c0d5cba633c206710e56b2475 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Wed, 30 Dec 2020 15:07:14 +0200 Subject: [PATCH 02/14] refactored --- .../server/queue/provider/KafkaMonolithQueueFactory.java | 6 +++--- .../server/queue/provider/KafkaTbCoreQueueFactory.java | 4 ++-- .../queue/provider/KafkaTbRuleEngineQueueFactory.java | 4 ++-- .../server/queue/provider/KafkaTbTransportQueueFactory.java | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaMonolithQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaMonolithQueueFactory.java index 6ed49d21fc..8e2ab69915 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaMonolithQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaMonolithQueueFactory.java @@ -164,7 +164,7 @@ public class KafkaMonolithQueueFactory implements TbCoreQueueFactory, TbRuleEngi consumerBuilder.settings(kafkaSettings); consumerBuilder.topic(partitionService.getNotificationsTopic(ServiceType.TB_RULE_ENGINE, serviceInfoProvider.getServiceId()).getFullTopicName()); consumerBuilder.clientId("monolith-rule-engine-notifications-consumer-" + serviceInfoProvider.getServiceId()); - consumerBuilder.groupId("monolith-rule-engine-notifications-consumer"); + consumerBuilder.groupId("monolith-rule-engine-notifications-consumer-" + serviceInfoProvider.getServiceId()); consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToRuleEngineNotificationMsg.parseFrom(msg.getData()), msg.getHeaders())); consumerBuilder.admin(notificationAdmin); return consumerBuilder.build(); @@ -188,7 +188,7 @@ public class KafkaMonolithQueueFactory implements TbCoreQueueFactory, TbRuleEngi consumerBuilder.settings(kafkaSettings); consumerBuilder.topic(partitionService.getNotificationsTopic(ServiceType.TB_CORE, serviceInfoProvider.getServiceId()).getFullTopicName()); consumerBuilder.clientId("monolith-core-notifications-consumer-" + serviceInfoProvider.getServiceId()); - consumerBuilder.groupId("monolith-core-notifications-consumer"); + consumerBuilder.groupId("monolith-core-notifications-consumer-" + serviceInfoProvider.getServiceId()); consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToCoreNotificationMsg.parseFrom(msg.getData()), msg.getHeaders())); consumerBuilder.admin(notificationAdmin); return consumerBuilder.build(); @@ -229,7 +229,7 @@ public class KafkaMonolithQueueFactory implements TbCoreQueueFactory, TbRuleEngi responseBuilder.settings(kafkaSettings); responseBuilder.topic(jsInvokeSettings.getResponseTopic() + "." + serviceInfoProvider.getServiceId()); responseBuilder.clientId("js-" + serviceInfoProvider.getServiceId()); - responseBuilder.groupId("rule-engine-node"); + responseBuilder.groupId("rule-engine-node-" + serviceInfoProvider.getServiceId()); responseBuilder.decoder(msg -> { JsInvokeProtos.RemoteJsResponse.Builder builder = JsInvokeProtos.RemoteJsResponse.newBuilder(); JsonFormat.parser().ignoringUnknownFields().merge(new String(msg.getData(), StandardCharsets.UTF_8), builder); diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbCoreQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbCoreQueueFactory.java index 7ca2f9196d..c6acc0fd6a 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbCoreQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbCoreQueueFactory.java @@ -158,7 +158,7 @@ public class KafkaTbCoreQueueFactory implements TbCoreQueueFactory { consumerBuilder.settings(kafkaSettings); consumerBuilder.topic(partitionService.getNotificationsTopic(ServiceType.TB_CORE, serviceInfoProvider.getServiceId()).getFullTopicName()); consumerBuilder.clientId("tb-core-notifications-consumer-" + serviceInfoProvider.getServiceId()); - consumerBuilder.groupId("tb-core-notifications-node"); + consumerBuilder.groupId("tb-core-notifications-node-" + serviceInfoProvider.getServiceId()); consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToCoreNotificationMsg.parseFrom(msg.getData()), msg.getHeaders())); consumerBuilder.admin(notificationAdmin); return consumerBuilder.build(); @@ -199,7 +199,7 @@ public class KafkaTbCoreQueueFactory implements TbCoreQueueFactory { responseBuilder.settings(kafkaSettings); responseBuilder.topic(jsInvokeSettings.getResponseTopic() + "." + serviceInfoProvider.getServiceId()); responseBuilder.clientId("js-" + serviceInfoProvider.getServiceId()); - responseBuilder.groupId("rule-engine-node"); + responseBuilder.groupId("rule-engine-node-" + serviceInfoProvider.getServiceId()); responseBuilder.decoder(msg -> { JsInvokeProtos.RemoteJsResponse.Builder builder = JsInvokeProtos.RemoteJsResponse.newBuilder(); JsonFormat.parser().ignoringUnknownFields().merge(new String(msg.getData(), StandardCharsets.UTF_8), builder); diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbRuleEngineQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbRuleEngineQueueFactory.java index 3bab6d1866..ad8d84b4b6 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbRuleEngineQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbRuleEngineQueueFactory.java @@ -153,7 +153,7 @@ public class KafkaTbRuleEngineQueueFactory implements TbRuleEngineQueueFactory { consumerBuilder.settings(kafkaSettings); consumerBuilder.topic(partitionService.getNotificationsTopic(ServiceType.TB_RULE_ENGINE, serviceInfoProvider.getServiceId()).getFullTopicName()); consumerBuilder.clientId("tb-rule-engine-notifications-consumer-" + serviceInfoProvider.getServiceId()); - consumerBuilder.groupId("tb-rule-engine-notifications-node"); + consumerBuilder.groupId("tb-rule-engine-notifications-node-" + serviceInfoProvider.getServiceId()); consumerBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToRuleEngineNotificationMsg.parseFrom(msg.getData()), msg.getHeaders())); consumerBuilder.admin(notificationAdmin); return consumerBuilder.build(); @@ -172,7 +172,7 @@ public class KafkaTbRuleEngineQueueFactory implements TbRuleEngineQueueFactory { responseBuilder.settings(kafkaSettings); responseBuilder.topic(jsInvokeSettings.getResponseTopic() + "." + serviceInfoProvider.getServiceId()); responseBuilder.clientId("js-" + serviceInfoProvider.getServiceId()); - responseBuilder.groupId("rule-engine-node"); + responseBuilder.groupId("rule-engine-node-" + serviceInfoProvider.getServiceId()); responseBuilder.decoder(msg -> { JsInvokeProtos.RemoteJsResponse.Builder builder = JsInvokeProtos.RemoteJsResponse.newBuilder(); JsonFormat.parser().ignoringUnknownFields().merge(new String(msg.getData(), StandardCharsets.UTF_8), builder); diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbTransportQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbTransportQueueFactory.java index 58623a8f0b..505aa203d7 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbTransportQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbTransportQueueFactory.java @@ -91,7 +91,7 @@ public class KafkaTbTransportQueueFactory implements TbTransportQueueFactory { responseBuilder.settings(kafkaSettings); responseBuilder.topic(transportApiSettings.getResponsesTopic() + "." + serviceInfoProvider.getServiceId()); responseBuilder.clientId("transport-api-response-" + serviceInfoProvider.getServiceId()); - responseBuilder.groupId("transport-node"); + responseBuilder.groupId("transport-node-" + serviceInfoProvider.getServiceId()); responseBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), TransportApiResponseMsg.parseFrom(msg.getData()), msg.getHeaders())); responseBuilder.admin(transportApiAdmin); @@ -132,7 +132,7 @@ public class KafkaTbTransportQueueFactory implements TbTransportQueueFactory { responseBuilder.settings(kafkaSettings); responseBuilder.topic(transportNotificationSettings.getNotificationsTopic() + "." + serviceInfoProvider.getServiceId()); responseBuilder.clientId("transport-api-notifications-" + serviceInfoProvider.getServiceId()); - responseBuilder.groupId("transport-node"); + responseBuilder.groupId("transport-node-" + serviceInfoProvider.getServiceId()); responseBuilder.decoder(msg -> new TbProtoQueueMsg<>(msg.getKey(), ToTransportMsg.parseFrom(msg.getData()), msg.getHeaders())); responseBuilder.admin(notificationAdmin); return responseBuilder.build(); From b85b51f5376d0542ed28c20414ff42223b3506aa Mon Sep 17 00:00:00 2001 From: Artem Babak Date: Tue, 5 Jan 2021 12:23:36 +0200 Subject: [PATCH 03/14] Deleted comma --- ui/src/app/common/types.constant.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/app/common/types.constant.js b/ui/src/app/common/types.constant.js index e43dd9aa8a..7dbc10de6d 100644 --- a/ui/src/app/common/types.constant.js +++ b/ui/src/app/common/types.constant.js @@ -1197,6 +1197,6 @@ export default angular.module('thingsboard.types', []) "ADMIN_SETTINGS": { name: "permission.resource.display-type.ADMIN_SETTINGS" } - }, + } } ).name; From 0a5796c9fded2939c54290fd48e964b176f67605 Mon Sep 17 00:00:00 2001 From: Artem Babak Date: Tue, 5 Jan 2021 16:59:37 +0200 Subject: [PATCH 04/14] Edge Downlinks as tab --- ui/src/app/api/edge.service.js | 4 +- ui/src/app/common/types.constant.js | 12 +- ui/src/app/edge/edges.tpl.html | 7 + .../event/edge-downlinks-table.directive.js | 272 ++++++++++++++++++ .../app/event/edge-downlinks-table.tpl.html | 46 +++ ui/src/app/event/event-header.directive.js | 2 +- ui/src/app/event/event-row.directive.js | 2 +- ui/src/app/event/event-table.directive.js | 84 +----- ui/src/app/event/event.scss | 72 +++++ ui/src/app/event/index.js | 2 + ui/src/app/locale/locale.constant-en_US.json | 5 +- 11 files changed, 421 insertions(+), 87 deletions(-) create mode 100644 ui/src/app/event/edge-downlinks-table.directive.js create mode 100644 ui/src/app/event/edge-downlinks-table.tpl.html diff --git a/ui/src/app/api/edge.service.js b/ui/src/app/api/edge.service.js index debd49069a..809b0b12af 100644 --- a/ui/src/app/api/edge.service.js +++ b/ui/src/app/api/edge.service.js @@ -35,7 +35,7 @@ function EdgeService($http, $q, customerService) { unassignEdgeFromCustomer: unassignEdgeFromCustomer, makeEdgePublic: makeEdgePublic, setRootRuleChain: setRootRuleChain, - getEdgeEvents: getEdgeEvents, + getEdgeDownlinks: getEdgeDownlinks, syncEdge: syncEdge, findMissingToRelatedRuleChains: findMissingToRelatedRuleChains }; @@ -276,7 +276,7 @@ function EdgeService($http, $q, customerService) { return deferred.promise; } - function getEdgeEvents(edgeId, pageLink) { + function getEdgeDownlinks(edgeId, pageLink) { var deferred = $q.defer(); var url = '/api/edge/' + edgeId + '/events' + '?limit=' + pageLink.limit; if (angular.isDefined(pageLink.startTime) && pageLink.startTime != null) { diff --git a/ui/src/app/common/types.constant.js b/ui/src/app/common/types.constant.js index 7dbc10de6d..0bdb4fae71 100644 --- a/ui/src/app/common/types.constant.js +++ b/ui/src/app/common/types.constant.js @@ -661,10 +661,6 @@ export default angular.module('thingsboard.types', []) stats: { value: "STATS", name: "event.type-stats" - }, - edgeEvent: { - value: "EDGE_EVENT", - name: "event.type-edge-event" } }, debugEventType: { @@ -1197,6 +1193,14 @@ export default angular.module('thingsboard.types', []) "ADMIN_SETTINGS": { name: "permission.resource.display-type.ADMIN_SETTINGS" } + }, + edgeEvent: { + value: "EDGE_EVENT", + name: "edge.downlink" + }, + edgeDownlinks: { + value: "EDGE_DOWNLINKS", + name: "edge.downlinks" } } ).name; diff --git a/ui/src/app/edge/edges.tpl.html b/ui/src/app/edge/edges.tpl.html index 2600413255..016634fea9 100644 --- a/ui/src/app/edge/edges.tpl.html +++ b/ui/src/app/edge/edges.tpl.html @@ -65,6 +65,13 @@ default-event-type="{{vm.types.eventType.error.value}}"> + + + + scope.events.data.length) { + scope.theEvents.fetchMoreItems_(index); + return null; + } + var item = scope.events.data[index]; + if (item) { + item.indexNumber = index + 1; + } + return item; + }, + + getLength: function () { + if (scope.events.hasNext) { + return scope.events.data.length + scope.events.nextPageLink.limit; + } else { + return scope.events.data.length; + } + }, + + fetchMoreItems_: function () { + if (scope.events.hasNext && !scope.events.pending) { + if (scope.entityType && scope.entityId && scope.eventType && scope.tenantId) { + scope.loadEdgeInfo(); + scope.events.pending = true; + edgeService.getEdgeDownlinks(scope.entityId, scope.events.nextPageLink).then( + function success(events) { + scope.events.data = scope.events.data.concat(prepareEdgeEventData(events.data)); + scope.events.nextPageLink = events.nextPageLink; + scope.events.hasNext = events.hasNext; + if (scope.events.hasNext) { + scope.events.nextPageLink.limit = pageSize; + } + scope.events.pending = false; + }, + function fail() { + scope.events.hasNext = false; + scope.events.pending = false; + }); + } else { + scope.events.hasNext = false; + } + } + } + }; + + scope.$watch("entityId", function(newVal, prevVal) { + if (newVal && !angular.equals(newVal, prevVal)) { + scope.resetFilter(); + scope.reload(); + } + }); + + scope.$watch("eventType", function(newVal, prevVal) { + if (newVal && !angular.equals(newVal, prevVal)) { + scope.reload(); + } + }); + + scope.$watch("timewindow", function(newVal, prevVal) { + if (newVal && !angular.equals(newVal, prevVal)) { + scope.reload(); + } + }, true); + + scope.resetFilter = function() { + scope.timewindow = { + history: { + timewindowMs: 24 * 60 * 60 * 1000 // 1 day + } + }; + } + + scope.updateTimeWindowRange = function() { + if (scope.timewindow.history.timewindowMs) { + var currentTime = (new Date).getTime(); + startTime = currentTime - scope.timewindow.history.timewindowMs; + endTime = currentTime; + } else { + startTime = scope.timewindow.history.fixedTimewindow.startTimeMs; + endTime = scope.timewindow.history.fixedTimewindow.endTimeMs; + } + } + + scope.reload = function() { + scope.topIndex = 0; + scope.selected = []; + scope.updateTimeWindowRange(); + scope.events = { + data: [], + nextPageLink: { + limit: pageSize, + startTime: startTime, + endTime: endTime + }, + hasNext: true, + pending: false + }; + scope.theEvents.getItemAtIndex(pageSize); + } + + scope.noData = function() { + return scope.events.data.length == 0 && !scope.events.hasNext; + } + + scope.hasData = function() { + return scope.events.data.length > 0; + } + + scope.loading = function() { + return $rootScope.loading; + } + + scope.hasScroll = function() { + var repeatContainer = scope.repeatContainer[0]; + if (repeatContainer) { + var scrollElement = repeatContainer.children[0]; + if (scrollElement) { + return scrollElement.scrollHeight > scrollElement.clientHeight; + } + } + return false; + } + + scope.subscriptionId = null; + + scope.loadEdgeInfo = function() { + attributeService.getEntityAttributesValues( + scope.entityType, + scope.entityId, + types.attributesScope.server.value, + types.edgeAttributeKeys.queueStartTs, + null).then( + function success(attributes) { + attributes.length > 0 ? scope.onEdgeAttributesUpdate(attributes) : scope.queueStartTs = 0; + }); + scope.checkSubscription(); + } + + scope.onEdgeAttributesUpdate = function(attributes) { + let edgeAttributes = attributes.reduce(function (map, attribute) { + map[attribute.key] = attribute; + return map; + }, {}); + if (edgeAttributes.queueStartTs) { + scope.queueStartTs = edgeAttributes.queueStartTs.lastUpdateTs; + } + } + + scope.checkSubscription = function() { + var newSubscriptionId = null; + if (scope.entityId && scope.entityType && types.attributesScope.server.value) { + newSubscriptionId = + attributeService.subscribeForEntityAttributes(scope.entityType, scope.entityId, types.attributesScope.server.value); + } + if (scope.subscriptionId && scope.subscriptionId != newSubscriptionId) { + attributeService.unsubscribeForEntityAttributes(scope.subscriptionId); + } + scope.subscriptionId = newSubscriptionId; + } + + scope.$on('$destroy', function () { + if (scope.subscriptionId) { + attributeService.unsubscribeForEntityAttributes(scope.subscriptionId); + } + }); + + scope.reload(); + + $compile(element.contents())(scope); + } + function prepareEdgeEventData(data) { + + data.forEach( + edgeEvent => { + edgeEvent.edgeEventActionText = $translate.instant(types.edgeEventActionType[edgeEvent.action].name); + edgeEvent.edgeEventTypeText = $translate.instant(types.edgeEventTypeTranslations[edgeEvent.edgeId.entityType].name); + } + ); + return data; + } + + return { + restrict: "E", + link: linker, + scope: { + entityType: '=', + entityId: '=', + tenantId: '=' + } + }; +} diff --git a/ui/src/app/event/edge-downlinks-table.tpl.html b/ui/src/app/event/edge-downlinks-table.tpl.html new file mode 100644 index 0000000000..e0281a2cf0 --- /dev/null +++ b/ui/src/app/event/edge-downlinks-table.tpl.html @@ -0,0 +1,46 @@ + + +
+ + + refresh + + {{ 'action.refresh' | translate }} + + +
+ + + + + + event.no-events-prompt + + + + + + + + +
diff --git a/ui/src/app/event/event-header.directive.js b/ui/src/app/event/event-header.directive.js index efe3dab21c..ac5e968745 100644 --- a/ui/src/app/event/event-header.directive.js +++ b/ui/src/app/event/event-header.directive.js @@ -46,7 +46,7 @@ export default function EventHeaderDirective($compile, $templateCache, types) { case types.debugEventType.debugRuleChain.value: template = eventHeaderDebugRuleNodeTemplate; break; - case types.eventType.edgeEvent.value: + case types.edgeDownlinks.value: template = eventHeaderEdgeEventTemplate; break; } diff --git a/ui/src/app/event/event-row.directive.js b/ui/src/app/event/event-row.directive.js index 77718a5968..b4d20fd72a 100644 --- a/ui/src/app/event/event-row.directive.js +++ b/ui/src/app/event/event-row.directive.js @@ -49,7 +49,7 @@ export default function EventRowDirective($compile, $templateCache, $mdDialog, $ case types.debugEventType.debugRuleChain.value: template = eventRowDebugRuleNodeTemplate; break; - case types.eventType.edgeEvent.value: + case types.edgeDownlinks.value: template = eventRowEdgeEventTemplate; break; } diff --git a/ui/src/app/event/event-table.directive.js b/ui/src/app/event/event-table.directive.js index ba41da8c34..7537c808f3 100644 --- a/ui/src/app/event/event-table.directive.js +++ b/ui/src/app/event/event-table.directive.js @@ -22,8 +22,7 @@ import eventTableTemplate from './event-table.tpl.html'; /* eslint-enable import/no-unresolved, import/default */ /*@ngInject*/ -export default function EventTableDirective($compile, $templateCache, $rootScope, $translate, types, - eventService, edgeService, attributeService) { +export default function EventTableDirective($compile, $templateCache, $rootScope, types, eventService) { var linker = function (scope, element, attrs) { @@ -31,16 +30,11 @@ export default function EventTableDirective($compile, $templateCache, $rootScope element.html(template); - scope.eventTypeScope = angular.copy(types.eventType); - if (scope.entityType !== types.entityType.edge) { - delete scope.eventTypeScope.edgeEvent; - } - if (attrs.disabledEventTypes) { var disabledEventTypes = attrs.disabledEventTypes.split(','); scope.eventTypes = {}; - for (var type in scope.eventTypeScope) { - var eventType = scope.eventTypeScope[type]; + for (var type in types.eventType) { + var eventType = types.eventType[type]; var enabled = true; for (var i=0;i 0 ? scope.onEdgeAttributesUpdate(attributes) : scope.queueStartTs = 0; - }); - scope.checkSubscription(); - } - - scope.onEdgeAttributesUpdate = function(attributes) { - let edgeAttributes = attributes.reduce(function (map, attribute) { - map[attribute.key] = attribute; - return map; - }, {}); - if (edgeAttributes.queueStartTs) { - scope.queueStartTs = edgeAttributes.queueStartTs.lastUpdateTs; - } - } - - scope.checkSubscription = function() { - var newSubscriptionId = null; - if (scope.entityId && scope.entityType && types.attributesScope.server.value) { - newSubscriptionId = - attributeService.subscribeForEntityAttributes(scope.entityType, scope.entityId, types.attributesScope.server.value); - } - if (scope.subscriptionId && scope.subscriptionId != newSubscriptionId) { - attributeService.unsubscribeForEntityAttributes(scope.subscriptionId); - } - scope.subscriptionId = newSubscriptionId; - } - - scope.$on('$destroy', function () { - if (scope.subscriptionId) { - attributeService.unsubscribeForEntityAttributes(scope.subscriptionId); - } - }); - scope.reload(); $compile(element.contents())(scope); } - - function prepareEdgeEventData(data) { - data.forEach( - edgeEvent => { - edgeEvent.edgeEventActionText = $translate.instant(types.edgeEventActionType[edgeEvent.action].name); - edgeEvent.edgeEventTypeText = $translate.instant(types.edgeEventTypeTranslations[edgeEvent.edgeId.entityType].name); - } - ); - return data; - } - return { restrict: "E", link: linker, diff --git a/ui/src/app/event/event.scss b/ui/src/app/event/event.scss index f1b5eb0d46..ffdb4217bd 100644 --- a/ui/src/app/event/event.scss +++ b/ui/src/app/event/event.scss @@ -85,6 +85,78 @@ md-list.tb-event-table { } } +md-list.tb-edge-downlinks-table { + padding: 0; + + md-list-item { + padding: 0; + } + + .tb-row { + height: 48px; + padding: 0; + overflow: hidden; + + .tb-cell { + text-overflow: ellipsis; + + &.tb-scroll { + overflow-x: auto; + overflow-y: hidden; + white-space: nowrap; + } + + &.tb-nowrap { + white-space: nowrap; + } + } + } + + .tb-row:hover { + background-color: #eee; + } + + .tb-header:hover { + background: none; + } + + .tb-header { + .tb-cell { + font-size: 12px; + font-weight: 700; + color: rgba(0, 0, 0, .54); + white-space: nowrap; + background: none; + } + } + + .tb-cell { + &:first-child { + padding-left: 14px; + } + + &:last-child { + padding-right: 14px; + } + padding: 0 6px; + margin: auto 0; + overflow: hidden; + font-size: 13px; + color: rgba(0, 0, 0, .87); + text-align: left; + vertical-align: middle; + + .md-button { + padding: 0; + margin: 0; + } + } + + .tb-cell.tb-number { + text-align: right; + } +} + #tb-event-content { width: 100%; min-width: 400px; diff --git a/ui/src/app/event/index.js b/ui/src/app/event/index.js index 69227eef8b..370f31a17b 100644 --- a/ui/src/app/event/index.js +++ b/ui/src/app/event/index.js @@ -19,6 +19,7 @@ import EventContentDialogController from './event-content-dialog.controller'; import EventHeaderDirective from './event-header.directive'; import EventRowDirective from './event-row.directive'; import EventTableDirective from './event-table.directive'; +import EdgeDownlinksDirective from "./edge-downlinks-table.directive"; export default angular.module('thingsboard.event', [ thingsboardApiEvent @@ -27,4 +28,5 @@ export default angular.module('thingsboard.event', [ .directive('tbEventHeader', EventHeaderDirective) .directive('tbEventRow', EventRowDirective) .directive('tbEventTable', EventTableDirective) + .directive('tbEdgeDownlinksTable', EdgeDownlinksDirective) .name; diff --git a/ui/src/app/locale/locale.constant-en_US.json b/ui/src/app/locale/locale.constant-en_US.json index 56f45586c3..781ceced3f 100644 --- a/ui/src/app/locale/locale.constant-en_US.json +++ b/ui/src/app/locale/locale.constant-en_US.json @@ -856,7 +856,9 @@ "license-key-hint": "To obtain your license please navigate to the pricing page and select the best license option for your case.", "cloud-endpoint-hint": "Edge requires HTTP(s) access to Cloud (ThingsBoard CE/PE) to verify the license key. Please specify Cloud URL that Edge is able to connect to.", "missing-related-rule-chains-title": "Edge has missing related rule chain(s)", - "missing-related-rule-chains-text": "Assigned to edge rule chain(s) use rule nodes that forward message(s) to rule chain(s) that are not assigned to this edge.

List of missing rule chain(s):
{{missingRuleChains}}" + "missing-related-rule-chains-text": "Assigned to edge rule chain(s) use rule nodes that forward message(s) to rule chain(s) that are not assigned to this edge.

List of missing rule chain(s):
{{missingRuleChains}}", + "downlinks": "Downlinks", + "no-downlinks-prompt": "No downlinks found" }, "error": { "unable-to-connect": "Unable to connect to the server! Please check your internet connection.", @@ -1097,7 +1099,6 @@ "type-debug-rule-chain": "Debug", "no-events-prompt": "No events found", "error": "Error", - "type-edge-event": "Downlink", "alarm": "Alarm", "event-time": "Event time", "server": "Server", From 83c2758c7c481d43887d3d7cdfd0d0d7bd0a21fc Mon Sep 17 00:00:00 2001 From: Artem Babak Date: Wed, 6 Jan 2021 09:13:59 +0200 Subject: [PATCH 05/14] Edge Downlinks new tab implementation --- ui/src/app/common/types.constant.js | 4 -- .../event/edge-downlinks-table.directive.js | 42 +---------- .../app/event/edge-downlinks-table.tpl.html | 2 +- ui/src/app/event/event-header.directive.js | 4 +- ui/src/app/event/event-row.directive.js | 4 +- ui/src/app/event/event.scss | 72 +------------------ 6 files changed, 9 insertions(+), 119 deletions(-) diff --git a/ui/src/app/common/types.constant.js b/ui/src/app/common/types.constant.js index 0bdb4fae71..ccb9b76f01 100644 --- a/ui/src/app/common/types.constant.js +++ b/ui/src/app/common/types.constant.js @@ -1194,10 +1194,6 @@ export default angular.module('thingsboard.types', []) name: "permission.resource.display-type.ADMIN_SETTINGS" } }, - edgeEvent: { - value: "EDGE_EVENT", - name: "edge.downlink" - }, edgeDownlinks: { value: "EDGE_DOWNLINKS", name: "edge.downlinks" diff --git a/ui/src/app/event/edge-downlinks-table.directive.js b/ui/src/app/event/edge-downlinks-table.directive.js index cd17d7c6b9..24e6f558c8 100644 --- a/ui/src/app/event/edge-downlinks-table.directive.js +++ b/ui/src/app/event/edge-downlinks-table.directive.js @@ -25,45 +25,13 @@ import edgeDownlinksTableTemplate from './edge-downlinks-table.tpl.html'; export default function EdgeDownlinksDirective($compile, $templateCache, $rootScope, $translate, types, eventService, edgeService, attributeService) { - var linker = function (scope, element, attrs) { + var linker = function (scope, element) { var template = $templateCache.get(edgeDownlinksTableTemplate); element.html(template); - if (attrs.disabledEventTypes) { - var disabledEventTypes = attrs.disabledEventTypes.split(','); - scope.eventTypes = {}; - for (var type in types.eventType) { - var eventType = types.eventType[type]; - var enabled = true; - for (var i=0;i event.no-events-prompt + class="tb-prompt" ng-show="noData()">edge.no-downlinks-prompt diff --git a/ui/src/app/event/event-header.directive.js b/ui/src/app/event/event-header.directive.js index ac5e968745..a9db6fa5fb 100644 --- a/ui/src/app/event/event-header.directive.js +++ b/ui/src/app/event/event-header.directive.js @@ -19,7 +19,7 @@ import eventHeaderLcEventTemplate from './event-header-lc-event.tpl.html'; import eventHeaderStatsTemplate from './event-header-stats.tpl.html'; import eventHeaderErrorTemplate from './event-header-error.tpl.html'; import eventHeaderDebugRuleNodeTemplate from './event-header-debug-rulenode.tpl.html'; -import eventHeaderEdgeEventTemplate from './event-header-edge-event.tpl.html' +import edgeDownlinksHeaderTemplate from './event-header-edge-event.tpl.html' /* eslint-enable import/no-unresolved, import/default */ @@ -47,7 +47,7 @@ export default function EventHeaderDirective($compile, $templateCache, types) { template = eventHeaderDebugRuleNodeTemplate; break; case types.edgeDownlinks.value: - template = eventHeaderEdgeEventTemplate; + template = edgeDownlinksHeaderTemplate; break; } return $templateCache.get(template); diff --git a/ui/src/app/event/event-row.directive.js b/ui/src/app/event/event-row.directive.js index b4d20fd72a..fd5fce3a0c 100644 --- a/ui/src/app/event/event-row.directive.js +++ b/ui/src/app/event/event-row.directive.js @@ -21,7 +21,7 @@ import eventRowLcEventTemplate from './event-row-lc-event.tpl.html'; import eventRowStatsTemplate from './event-row-stats.tpl.html'; import eventRowErrorTemplate from './event-row-error.tpl.html'; import eventRowDebugRuleNodeTemplate from './event-row-debug-rulenode.tpl.html'; -import eventRowEdgeEventTemplate from './event-row-edge-event.tpl.html'; +import edgeDownlinlsRowTemplate from './event-row-edge-event.tpl.html'; /* eslint-enable import/no-unresolved, import/default */ @@ -50,7 +50,7 @@ export default function EventRowDirective($compile, $templateCache, $mdDialog, $ template = eventRowDebugRuleNodeTemplate; break; case types.edgeDownlinks.value: - template = eventRowEdgeEventTemplate; + template = edgeDownlinlsRowTemplate; break; } return $templateCache.get(template); diff --git a/ui/src/app/event/event.scss b/ui/src/app/event/event.scss index ffdb4217bd..b0d0d19157 100644 --- a/ui/src/app/event/event.scss +++ b/ui/src/app/event/event.scss @@ -85,76 +85,8 @@ md-list.tb-event-table { } } -md-list.tb-edge-downlinks-table { - padding: 0; - - md-list-item { - padding: 0; - } - - .tb-row { - height: 48px; - padding: 0; - overflow: hidden; - - .tb-cell { - text-overflow: ellipsis; - - &.tb-scroll { - overflow-x: auto; - overflow-y: hidden; - white-space: nowrap; - } - - &.tb-nowrap { - white-space: nowrap; - } - } - } - - .tb-row:hover { - background-color: #eee; - } - - .tb-header:hover { - background: none; - } - - .tb-header { - .tb-cell { - font-size: 12px; - font-weight: 700; - color: rgba(0, 0, 0, .54); - white-space: nowrap; - background: none; - } - } - - .tb-cell { - &:first-child { - padding-left: 14px; - } - - &:last-child { - padding-right: 14px; - } - padding: 0 6px; - margin: auto 0; - overflow: hidden; - font-size: 13px; - color: rgba(0, 0, 0, .87); - text-align: left; - vertical-align: middle; - - .md-button { - padding: 0; - margin: 0; - } - } - - .tb-cell.tb-number { - text-align: right; - } +.tb-edge-downlinks-table { + @extend .tb-event-table; } #tb-event-content { From a0e74d72054393cc28bb34cd6ecca0b896798715 Mon Sep 17 00:00:00 2001 From: Artem Babak Date: Wed, 6 Jan 2021 09:38:31 +0200 Subject: [PATCH 06/14] Edge Downlinks new tab implementation 2 --- ...dge-downlinks-content-dialog.controller.js | 92 +++++++ .../edge-downlinks-header.directive.js | 54 ++++ .../downlinks/edge-downlinks-row.directive.js | 140 +++++++++++ .../edge-downlinks-table.directive.js | 234 ++++++++++++++++++ .../downlinks/edge-downlinks-table.tpl.html | 46 ++++ .../downlinks/event-content-dialog.tpl.html | 42 ++++ .../event-header-edge-event.tpl.html | 23 ++ .../downlinks/event-row-edge-event.tpl.html | 37 +++ ui/src/app/edge/downlinks/event.scss | 97 ++++++++ ui/src/app/edge/edges.tpl.html | 11 +- ui/src/app/edge/index.js | 8 + .../app/event/edge-downlinks-table.tpl.html | 2 +- ui/src/app/event/index.js | 2 +- 13 files changed, 784 insertions(+), 4 deletions(-) create mode 100644 ui/src/app/edge/downlinks/edge-downlinks-content-dialog.controller.js create mode 100644 ui/src/app/edge/downlinks/edge-downlinks-header.directive.js create mode 100644 ui/src/app/edge/downlinks/edge-downlinks-row.directive.js create mode 100644 ui/src/app/edge/downlinks/edge-downlinks-table.directive.js create mode 100644 ui/src/app/edge/downlinks/edge-downlinks-table.tpl.html create mode 100644 ui/src/app/edge/downlinks/event-content-dialog.tpl.html create mode 100644 ui/src/app/edge/downlinks/event-header-edge-event.tpl.html create mode 100644 ui/src/app/edge/downlinks/event-row-edge-event.tpl.html create mode 100644 ui/src/app/edge/downlinks/event.scss diff --git a/ui/src/app/edge/downlinks/edge-downlinks-content-dialog.controller.js b/ui/src/app/edge/downlinks/edge-downlinks-content-dialog.controller.js new file mode 100644 index 0000000000..7be69ea17f --- /dev/null +++ b/ui/src/app/edge/downlinks/edge-downlinks-content-dialog.controller.js @@ -0,0 +1,92 @@ +/* + * 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 $ from 'jquery'; +import 'brace/ext/language_tools'; +import 'brace/ext/searchbox'; +import 'brace/mode/java'; +import 'brace/theme/github'; +import beautify from 'js-beautify'; + +/* eslint-disable angular/angularelement */ + +const js_beautify = beautify.js; + +/*@ngInject*/ +export default function EdgeDownlinksContentDialogController($mdDialog, types, content, contentType, title, showingCallback) { + + var vm = this; + + showingCallback.onShowing = function(scope, element) { + updateEditorSize(element); + } + + vm.content = content; + vm.title = title; + + var mode; + if (contentType) { + mode = types.contentType[contentType].code; + if (contentType == types.contentType.JSON.value && vm.content) { + vm.content = js_beautify(vm.content, {indent_size: 4}); + } + } else { + mode = 'java'; + } + + vm.contentOptions = { + useWrapMode: false, + mode: mode, + showGutter: false, + showPrintMargin: false, + theme: 'github', + advanced: { + enableSnippets: false, + enableBasicAutocompletion: false, + enableLiveAutocompletion: false + }, + onLoad: function (_ace) { + vm.editor = _ace; + } + }; + + function updateEditorSize(element) { + var newHeight = 400; + var newWidth = 600; + if (vm.content && vm.content.length > 0) { + var lines = vm.content.split('\n'); + newHeight = 16 * lines.length + 16; + var maxLineLength = 0; + for (var i = 0; i < lines.length; i++) { + var line = lines[i].replace(/\t/g, ' ').replace(/\n/g, ''); + var lineLength = line.length; + maxLineLength = Math.max(maxLineLength, lineLength); + } + newWidth = 8 * maxLineLength + 16; + } + $('#tb-event-content', element).height(newHeight.toString() + "px") + .width(newWidth.toString() + "px"); + vm.editor.resize(); + } + + vm.close = close; + + function close () { + $mdDialog.hide(); + } + +} + +/* eslint-enable angular/angularelement */ diff --git a/ui/src/app/edge/downlinks/edge-downlinks-header.directive.js b/ui/src/app/edge/downlinks/edge-downlinks-header.directive.js new file mode 100644 index 0000000000..fd14df88d5 --- /dev/null +++ b/ui/src/app/edge/downlinks/edge-downlinks-header.directive.js @@ -0,0 +1,54 @@ +/* + * 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. + */ +/* eslint-disable import/no-unresolved, import/default */ + +import edgeDownlinksHeaderTemplate from './event-header-edge-event.tpl.html' + +/* eslint-enable import/no-unresolved, import/default */ + +/*@ngInject*/ +export default function EventHeaderDirective2($compile, $templateCache, types) { + + var linker = function (scope, element, attrs) { + + var getTemplate = function(eventType) { + var template = ''; + switch(eventType) { + case types.edgeDownlinks.value: + template = edgeDownlinksHeaderTemplate; + break; + } + return $templateCache.get(template); + } + + scope.loadTemplate = function() { + element.html(getTemplate(attrs.eventType)); + $compile(element.contents())(scope); + } + + attrs.$observe('eventType', function() { + scope.loadTemplate(); + }); + + } + + return { + restrict: "A", + replace: false, + link: linker, + scope: false + }; +} diff --git a/ui/src/app/edge/downlinks/edge-downlinks-row.directive.js b/ui/src/app/edge/downlinks/edge-downlinks-row.directive.js new file mode 100644 index 0000000000..20c2eab89c --- /dev/null +++ b/ui/src/app/edge/downlinks/edge-downlinks-row.directive.js @@ -0,0 +1,140 @@ +/* + * 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. + */ +/* eslint-disable import/no-unresolved, import/default */ + +import eventErrorDialogTemplate from './event-content-dialog.tpl.html'; + +import edgeDownlinlsRowTemplate from './event-row-edge-event.tpl.html'; + +/* eslint-enable import/no-unresolved, import/default */ + +/*@ngInject*/ +export default function EventRowDirective2($compile, $templateCache, $mdDialog, $document, $translate, + types, utils, toast, entityService, ruleChainService) { + + var linker = function (scope, element, attrs) { + + var getTemplate = function(eventType) { + var template = ''; + switch(eventType) { + case types.edgeDownlinks.value: + template = edgeDownlinlsRowTemplate; + break; + } + return $templateCache.get(template); + } + + scope.loadTemplate = function() { + element.html(getTemplate(attrs.eventType)); + $compile(element.contents())(scope); + } + + attrs.$observe('eventType', function() { + scope.loadTemplate(); + }); + + scope.types = types; + + scope.event = attrs.event; + + scope.showEdgeEntityContent = function($event, title, contentType) { + var onShowingCallback = { + onShowing: function(){} + } + if (!contentType) { + contentType = null; + } + var content = ''; + switch(scope.event.type) { + case types.edgeEventType.relation: + content = angular.toJson(scope.event.body); + showDialog(); + break; + case types.edgeEventType.ruleChainMetaData: + content = ruleChainService.getRuleChainMetaData(scope.event.entityId, {ignoreErrors: true}).then( + function success(info) { + showDialog(); + return angular.toJson(info); + }, function fail() { + showError(); + }); + break; + default: + content = entityService.getEntity(scope.event.type, scope.event.entityId, {ignoreErrors: true}).then( + function success(info) { + showDialog(); + return angular.toJson(info); + }, function fail() { + showError(); + }); + break; + } + function showDialog() { + $mdDialog.show({ + controller: 'EventContentDialogController2', + controllerAs: 'vm', + templateUrl: eventErrorDialogTemplate, + locals: {content: content, title: title, contentType: contentType, showingCallback: onShowingCallback}, + parent: angular.element($document[0].body), + fullscreen: true, + targetEvent: $event, + multiple: true, + onShowing: function(scope, element) { + onShowingCallback.onShowing(scope, element); + } + }); + } + function showError() { + toast.showError($translate.instant('edge.load-entity-error')); + } + } + + scope.checkEdgeEventType = function (type) { + return !(type === types.edgeEventType.widgetType || + type === types.edgeEventType.adminSettings || + type === types.edgeEventType.widgetsBundle ); + } + + scope.checkTooltip = function($event) { + var el = $event.target; + var $el = angular.element(el); + if(el.offsetWidth < el.scrollWidth && !$el.attr('title')){ + $el.attr('title', $el.text()); + } + } + + $compile(element.contents())(scope); + + scope.updateStatus = function(eventCreatedTime) { + var status; + if (eventCreatedTime < scope.queueStartTs) { + status = $translate.instant(types.edgeEventStatus.DEPLOYED.name); + scope.statusColor = types.edgeEventStatus.DEPLOYED.color; + } else { + status = $translate.instant(types.edgeEventStatus.PENDING.name); + scope.statusColor = types.edgeEventStatus.PENDING.color; + } + return status; + } + } + + return { + restrict: "A", + replace: false, + link: linker, + scope: false + }; +} diff --git a/ui/src/app/edge/downlinks/edge-downlinks-table.directive.js b/ui/src/app/edge/downlinks/edge-downlinks-table.directive.js new file mode 100644 index 0000000000..46f194b68b --- /dev/null +++ b/ui/src/app/edge/downlinks/edge-downlinks-table.directive.js @@ -0,0 +1,234 @@ +/* + * 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 './event.scss'; + +/* eslint-disable import/no-unresolved, import/default */ + +import edgeDownlinksTableTemplate from './edge-downlinks-table.tpl.html'; + +/* eslint-enable import/no-unresolved, import/default */ + +/*@ngInject*/ +export default function EdgeDownlinksDirective2($compile, $templateCache, $rootScope, $translate, types, + eventService, edgeService, attributeService) { + + var linker = function (scope, element) { + + var template = $templateCache.get(edgeDownlinksTableTemplate); + + element.html(template); + + scope.eventType = types.edgeDownlinks.value; + + var pageSize = 20; + var startTime = 0; + var endTime = 0; + + scope.timewindow = { + history: { + timewindowMs: 24 * 60 * 60 * 1000 // 1 day + } + } + + scope.topIndex = 0; + + scope.theEvents = { + getItemAtIndex: function (index) { + if (index > scope.events.data.length) { + scope.theEvents.fetchMoreItems_(index); + return null; + } + var item = scope.events.data[index]; + if (item) { + item.indexNumber = index + 1; + } + return item; + }, + + getLength: function () { + if (scope.events.hasNext) { + return scope.events.data.length + scope.events.nextPageLink.limit; + } else { + return scope.events.data.length; + } + }, + + fetchMoreItems_: function () { + if (scope.events.hasNext && !scope.events.pending) { + if (scope.entityType && scope.entityId && scope.eventType && scope.tenantId) { + scope.loadEdgeInfo(); + scope.events.pending = true; + edgeService.getEdgeDownlinks(scope.entityId, scope.events.nextPageLink).then( + function success(events) { + scope.events.data = scope.events.data.concat(prepareEdgeEventData(events.data)); + scope.events.nextPageLink = events.nextPageLink; + scope.events.hasNext = events.hasNext; + if (scope.events.hasNext) { + scope.events.nextPageLink.limit = pageSize; + } + scope.events.pending = false; + }, + function fail() { + scope.events.hasNext = false; + scope.events.pending = false; + }); + } else { + scope.events.hasNext = false; + } + } + } + }; + + scope.$watch("entityId", function(newVal, prevVal) { + if (newVal && !angular.equals(newVal, prevVal)) { + scope.resetFilter(); + scope.reload(); + } + }); + + scope.$watch("timewindow", function(newVal, prevVal) { + if (newVal && !angular.equals(newVal, prevVal)) { + scope.reload(); + } + }, true); + + scope.resetFilter = function() { + scope.timewindow = { + history: { + timewindowMs: 24 * 60 * 60 * 1000 // 1 day + } + }; + } + + scope.updateTimeWindowRange = function() { + if (scope.timewindow.history.timewindowMs) { + var currentTime = (new Date).getTime(); + startTime = currentTime - scope.timewindow.history.timewindowMs; + endTime = currentTime; + } else { + startTime = scope.timewindow.history.fixedTimewindow.startTimeMs; + endTime = scope.timewindow.history.fixedTimewindow.endTimeMs; + } + } + + scope.reload = function() { + scope.topIndex = 0; + scope.selected = []; + scope.updateTimeWindowRange(); + scope.events = { + data: [], + nextPageLink: { + limit: pageSize, + startTime: startTime, + endTime: endTime + }, + hasNext: true, + pending: false + }; + scope.theEvents.getItemAtIndex(pageSize); + } + + scope.noData = function() { + return scope.events.data.length == 0 && !scope.events.hasNext; + } + + scope.hasData = function() { + return scope.events.data.length > 0; + } + + scope.loading = function() { + return $rootScope.loading; + } + + scope.hasScroll = function() { + var repeatContainer = scope.repeatContainer[0]; + if (repeatContainer) { + var scrollElement = repeatContainer.children[0]; + if (scrollElement) { + return scrollElement.scrollHeight > scrollElement.clientHeight; + } + } + return false; + } + + scope.subscriptionId = null; + + scope.loadEdgeInfo = function() { + attributeService.getEntityAttributesValues( + scope.entityType, + scope.entityId, + types.attributesScope.server.value, + types.edgeAttributeKeys.queueStartTs, + null).then( + function success(attributes) { + attributes.length > 0 ? scope.onEdgeAttributesUpdate(attributes) : scope.queueStartTs = 0; + }); + scope.checkSubscription(); + } + + scope.onEdgeAttributesUpdate = function(attributes) { + let edgeAttributes = attributes.reduce(function (map, attribute) { + map[attribute.key] = attribute; + return map; + }, {}); + if (edgeAttributes.queueStartTs) { + scope.queueStartTs = edgeAttributes.queueStartTs.lastUpdateTs; + } + } + + scope.checkSubscription = function() { + var newSubscriptionId = null; + if (scope.entityId && scope.entityType && types.attributesScope.server.value) { + newSubscriptionId = + attributeService.subscribeForEntityAttributes(scope.entityType, scope.entityId, types.attributesScope.server.value); + } + if (scope.subscriptionId && scope.subscriptionId != newSubscriptionId) { + attributeService.unsubscribeForEntityAttributes(scope.subscriptionId); + } + scope.subscriptionId = newSubscriptionId; + } + + scope.$on('$destroy', function () { + if (scope.subscriptionId) { + attributeService.unsubscribeForEntityAttributes(scope.subscriptionId); + } + }); + + scope.reload(); + + $compile(element.contents())(scope); + } + function prepareEdgeEventData(data) { + + data.forEach( + edgeEvent => { + edgeEvent.edgeEventActionText = $translate.instant(types.edgeEventActionType[edgeEvent.action].name); + edgeEvent.edgeEventTypeText = $translate.instant(types.edgeEventTypeTranslations[edgeEvent.edgeId.entityType].name); + } + ); + return data; + } + + return { + restrict: "E", + link: linker, + scope: { + entityType: '=', + entityId: '=', + tenantId: '=' + } + }; +} diff --git a/ui/src/app/edge/downlinks/edge-downlinks-table.tpl.html b/ui/src/app/edge/downlinks/edge-downlinks-table.tpl.html new file mode 100644 index 0000000000..4bff7afa4b --- /dev/null +++ b/ui/src/app/edge/downlinks/edge-downlinks-table.tpl.html @@ -0,0 +1,46 @@ + + +
+ + + refresh + + {{ 'action.refresh' | translate }} + + +
+ + + + + + edge.no-downlinks-prompt + + + + + + + + +
diff --git a/ui/src/app/edge/downlinks/event-content-dialog.tpl.html b/ui/src/app/edge/downlinks/event-content-dialog.tpl.html new file mode 100644 index 0000000000..3959da43f4 --- /dev/null +++ b/ui/src/app/edge/downlinks/event-content-dialog.tpl.html @@ -0,0 +1,42 @@ + + + +
+

{{ vm.title }}

+ + + + +
+
+ +
+
+
+
+
+ + + {{ 'action.close' | + translate }} + + +
diff --git a/ui/src/app/edge/downlinks/event-header-edge-event.tpl.html b/ui/src/app/edge/downlinks/event-header-edge-event.tpl.html new file mode 100644 index 0000000000..3de281ddc7 --- /dev/null +++ b/ui/src/app/edge/downlinks/event-header-edge-event.tpl.html @@ -0,0 +1,23 @@ + +
event.event-time
+
event.event-type
+
edge.event-action
+
edge.entity-id
+
edge.status
+
edge.entity-info
diff --git a/ui/src/app/edge/downlinks/event-row-edge-event.tpl.html b/ui/src/app/edge/downlinks/event-row-edge-event.tpl.html new file mode 100644 index 0000000000..a842b5d787 --- /dev/null +++ b/ui/src/app/edge/downlinks/event-row-edge-event.tpl.html @@ -0,0 +1,37 @@ + +
{{ event.createdTime | date : 'yyyy-MM-dd HH:mm:ss' }}
+
{{ event.edgeEventTypeText }}
+
{{ event.edgeEventActionText }}
+
{{ event.entityId }}
+
{{ updateStatus(event.createdTime) }}
+
+ + + {{ 'action.view' | translate }} + + + more_horiz + + +
+ + diff --git a/ui/src/app/edge/downlinks/event.scss b/ui/src/app/edge/downlinks/event.scss new file mode 100644 index 0000000000..7e67d0aac7 --- /dev/null +++ b/ui/src/app/edge/downlinks/event.scss @@ -0,0 +1,97 @@ +/** + * 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. + */ +md-list.tb-event-table { + padding: 0; + + md-list-item { + padding: 0; + } + + .tb-row { + height: 48px; + padding: 0; + overflow: hidden; + + .tb-cell { + text-overflow: ellipsis; + + &.tb-scroll { + overflow-x: auto; + overflow-y: hidden; + white-space: nowrap; + } + + &.tb-nowrap { + white-space: nowrap; + } + } + } + + .tb-row:hover { + background-color: #eee; + } + + .tb-header:hover { + background: none; + } + + .tb-header { + .tb-cell { + font-size: 12px; + font-weight: 700; + color: rgba(0, 0, 0, .54); + white-space: nowrap; + background: none; + } + } + + .tb-cell { + &:first-child { + padding-left: 14px; + } + + &:last-child { + padding-right: 14px; + } + padding: 0 6px; + margin: auto 0; + overflow: hidden; + font-size: 13px; + color: rgba(0, 0, 0, .87); + text-align: left; + vertical-align: middle; + + .md-button { + padding: 0; + margin: 0; + } + } + + .tb-cell.tb-number { + text-align: right; + } +} + +.tb-edge-downlinks-table-2 { + @extend .tb-event-table; +} + +#tb-event-content { + width: 100%; + min-width: 400px; + height: 100%; + min-height: 50px; +} diff --git a/ui/src/app/edge/edges.tpl.html b/ui/src/app/edge/edges.tpl.html index 016634fea9..d1cb6182cd 100644 --- a/ui/src/app/edge/edges.tpl.html +++ b/ui/src/app/edge/edges.tpl.html @@ -65,11 +65,18 @@ default-event-type="{{vm.types.eventType.error.value}}">
- - + + + + + diff --git a/ui/src/app/edge/index.js b/ui/src/app/edge/index.js index ef9f34d601..56a8558dd1 100644 --- a/ui/src/app/edge/index.js +++ b/ui/src/app/edge/index.js @@ -25,6 +25,10 @@ import AssignEdgeToCustomerController from './assign-to-customer.controller'; import AddEdgesToCustomerController from './add-edges-to-customer.controller'; import SetRootRuleChainToEdgesController from './set-root-rule-chain-to-edges.controller'; import EdgeDirective from './edge.directive'; +import EdgeDownlinksContentDialogController from './downlinks/edge-downlinks-content-dialog.controller'; +import EdgeDownlinksHeaderDirective from './downlinks/edge-downlinks-header.directive'; +import EdgeDownlinksRowDirective from './downlinks/edge-downlinks-row.directive'; +import EdgeDownlinksDirective from "./downlinks/edge-downlinks-table.directive"; export default angular.module('thingsboard.edge', [ uiRouter, @@ -39,5 +43,9 @@ export default angular.module('thingsboard.edge', [ .controller('AssignEdgeToCustomerController', AssignEdgeToCustomerController) .controller('AddEdgesToCustomerController', AddEdgesToCustomerController) .controller('SetRootRuleChainToEdgesController', SetRootRuleChainToEdgesController) + .controller('EdgeDownlinksContentDialogController', EdgeDownlinksContentDialogController) .directive('tbEdge', EdgeDirective) + .directive('tbEdgeDownlinksHeader', EdgeDownlinksHeaderDirective) + .directive('tbEdgeDownlinksRow', EdgeDownlinksRowDirective) + .directive('tbEdgeDownlinksTable', EdgeDownlinksDirective) .name; diff --git a/ui/src/app/event/edge-downlinks-table.tpl.html b/ui/src/app/event/edge-downlinks-table.tpl.html index 2660cab1b3..d55e61457c 100644 --- a/ui/src/app/event/edge-downlinks-table.tpl.html +++ b/ui/src/app/event/edge-downlinks-table.tpl.html @@ -26,7 +26,7 @@ - + Date: Wed, 6 Jan 2021 10:32:23 +0200 Subject: [PATCH 07/14] Edge Downlinks new tab final implementation --- ui/src/app/common/types.constant.js | 12 +- .../downlinks/{event.scss => downlink.scss} | 8 +- ...dge-downlinks-content-dialog.controller.js | 2 +- ...=> edge-downlinks-content-dialog.tpl.html} | 2 +- .../edge-downlinks-header.directive.js | 27 +- ...pl.html => edge-downlinks-header.tpl.html} | 0 .../downlinks/edge-downlinks-row.directive.js | 66 ++--- .../downlinks/edge-downlinks-row.tpl.html} | 12 +- .../edge-downlinks-table.directive.js | 66 +++-- .../downlinks/edge-downlinks-table.tpl.html | 6 +- .../downlinks/event-row-edge-event.tpl.html | 37 --- ui/src/app/edge/edges.tpl.html | 7 - ui/src/app/edge/index.js | 2 +- .../event/edge-downlinks-table.directive.js | 234 ------------------ .../app/event/edge-downlinks-table.tpl.html | 46 ---- .../event/event-header-edge-event.tpl.html | 23 -- ui/src/app/event/event-header.directive.js | 4 - ui/src/app/event/event-row.directive.js | 84 +------ ui/src/app/event/event.scss | 4 - ui/src/app/event/index.js | 2 - 20 files changed, 81 insertions(+), 563 deletions(-) rename ui/src/app/edge/downlinks/{event.scss => downlink.scss} (94%) rename ui/src/app/edge/downlinks/{event-content-dialog.tpl.html => edge-downlinks-content-dialog.tpl.html} (96%) rename ui/src/app/edge/downlinks/{event-header-edge-event.tpl.html => edge-downlinks-header.tpl.html} (100%) rename ui/src/app/{event/event-row-edge-event.tpl.html => edge/downlinks/edge-downlinks-row.tpl.html} (71%) delete mode 100644 ui/src/app/edge/downlinks/event-row-edge-event.tpl.html delete mode 100644 ui/src/app/event/edge-downlinks-table.directive.js delete mode 100644 ui/src/app/event/edge-downlinks-table.tpl.html delete mode 100644 ui/src/app/event/event-header-edge-event.tpl.html diff --git a/ui/src/app/common/types.constant.js b/ui/src/app/common/types.constant.js index ccb9b76f01..f65cc59e06 100644 --- a/ui/src/app/common/types.constant.js +++ b/ui/src/app/common/types.constant.js @@ -384,7 +384,7 @@ export default angular.module('thingsboard.types', []) entityView: "ENTITY_VIEW", edge: "EDGE" }, - edgeEventType:{ + edgeDownlinksType:{ dashboard: "DASHBOARD", asset: "ASSET", device: "DEVICE", @@ -405,7 +405,7 @@ export default angular.module('thingsboard.types', []) widgetType: "WIDGET_TYPE", adminSettings: "ADMIN_SETTINGS" }, - edgeEventStatus: { + edgeDownlinksStatus: { "DEPLOYED": { name: "edge.deployed", color: grey900 @@ -1073,7 +1073,7 @@ export default angular.module('thingsboard.types', []) translate: { customTranslationsPrefix: "custom." }, - edgeEventActionType: { + edgeDownlinksActionType: { "ADDED": { name: "audit-log.type-added" }, @@ -1135,7 +1135,7 @@ export default angular.module('thingsboard.types', []) name: "audit-log.type-unassigned-from-edge" } }, - edgeEventTypeTranslations:{ + edgeDownlinksTypeTranslations:{ "DASHBOARD": { name: "entity.type-dashboard" }, @@ -1193,10 +1193,6 @@ export default angular.module('thingsboard.types', []) "ADMIN_SETTINGS": { name: "permission.resource.display-type.ADMIN_SETTINGS" } - }, - edgeDownlinks: { - value: "EDGE_DOWNLINKS", - name: "edge.downlinks" } } ).name; diff --git a/ui/src/app/edge/downlinks/event.scss b/ui/src/app/edge/downlinks/downlink.scss similarity index 94% rename from ui/src/app/edge/downlinks/event.scss rename to ui/src/app/edge/downlinks/downlink.scss index 7e67d0aac7..9f975fc1e1 100644 --- a/ui/src/app/edge/downlinks/event.scss +++ b/ui/src/app/edge/downlinks/downlink.scss @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -md-list.tb-event-table { +md-list.tb-edge-downlinks-table { padding: 0; md-list-item { @@ -85,11 +85,7 @@ md-list.tb-event-table { } } -.tb-edge-downlinks-table-2 { - @extend .tb-event-table; -} - -#tb-event-content { +#tb-edge-downlinks-content { width: 100%; min-width: 400px; height: 100%; diff --git a/ui/src/app/edge/downlinks/edge-downlinks-content-dialog.controller.js b/ui/src/app/edge/downlinks/edge-downlinks-content-dialog.controller.js index 7be69ea17f..432bdf4d50 100644 --- a/ui/src/app/edge/downlinks/edge-downlinks-content-dialog.controller.js +++ b/ui/src/app/edge/downlinks/edge-downlinks-content-dialog.controller.js @@ -76,7 +76,7 @@ export default function EdgeDownlinksContentDialogController($mdDialog, types, c } newWidth = 8 * maxLineLength + 16; } - $('#tb-event-content', element).height(newHeight.toString() + "px") + $('#tb-edge-downlinks-content', element).height(newHeight.toString() + "px") .width(newWidth.toString() + "px"); vm.editor.resize(); } diff --git a/ui/src/app/edge/downlinks/event-content-dialog.tpl.html b/ui/src/app/edge/downlinks/edge-downlinks-content-dialog.tpl.html similarity index 96% rename from ui/src/app/edge/downlinks/event-content-dialog.tpl.html rename to ui/src/app/edge/downlinks/edge-downlinks-content-dialog.tpl.html index 3959da43f4..798990ec07 100644 --- a/ui/src/app/edge/downlinks/event-content-dialog.tpl.html +++ b/ui/src/app/edge/downlinks/edge-downlinks-content-dialog.tpl.html @@ -27,7 +27,7 @@
-
diff --git a/ui/src/app/edge/downlinks/edge-downlinks-header.directive.js b/ui/src/app/edge/downlinks/edge-downlinks-header.directive.js index fd14df88d5..3af243ca48 100644 --- a/ui/src/app/edge/downlinks/edge-downlinks-header.directive.js +++ b/ui/src/app/edge/downlinks/edge-downlinks-header.directive.js @@ -15,34 +15,19 @@ */ /* eslint-disable import/no-unresolved, import/default */ -import edgeDownlinksHeaderTemplate from './event-header-edge-event.tpl.html' +import edgeDownlinksHeaderTemplate from './edge-downlinks-header.tpl.html' /* eslint-enable import/no-unresolved, import/default */ /*@ngInject*/ -export default function EventHeaderDirective2($compile, $templateCache, types) { +export default function EdgeDownlinksHeaderDirective($compile, $templateCache) { - var linker = function (scope, element, attrs) { + var linker = function (scope, element) { - var getTemplate = function(eventType) { - var template = ''; - switch(eventType) { - case types.edgeDownlinks.value: - template = edgeDownlinksHeaderTemplate; - break; - } - return $templateCache.get(template); - } - - scope.loadTemplate = function() { - element.html(getTemplate(attrs.eventType)); - $compile(element.contents())(scope); - } - - attrs.$observe('eventType', function() { - scope.loadTemplate(); - }); + var template = edgeDownlinksHeaderTemplate; + element.html($templateCache.get(template)); + $compile(element.contents())(scope); } return { diff --git a/ui/src/app/edge/downlinks/event-header-edge-event.tpl.html b/ui/src/app/edge/downlinks/edge-downlinks-header.tpl.html similarity index 100% rename from ui/src/app/edge/downlinks/event-header-edge-event.tpl.html rename to ui/src/app/edge/downlinks/edge-downlinks-header.tpl.html diff --git a/ui/src/app/edge/downlinks/edge-downlinks-row.directive.js b/ui/src/app/edge/downlinks/edge-downlinks-row.directive.js index 20c2eab89c..8e848dfaf6 100644 --- a/ui/src/app/edge/downlinks/edge-downlinks-row.directive.js +++ b/ui/src/app/edge/downlinks/edge-downlinks-row.directive.js @@ -15,40 +15,24 @@ */ /* eslint-disable import/no-unresolved, import/default */ -import eventErrorDialogTemplate from './event-content-dialog.tpl.html'; - -import edgeDownlinlsRowTemplate from './event-row-edge-event.tpl.html'; +import edgeDownlinksContentTemplate from './edge-downlinks-content-dialog.tpl.html'; +import edgeDownlinlsRowTemplate from './edge-downlinks-row.tpl.html'; /* eslint-enable import/no-unresolved, import/default */ /*@ngInject*/ -export default function EventRowDirective2($compile, $templateCache, $mdDialog, $document, $translate, +export default function EdgeDownlinksRowDirective($compile, $templateCache, $mdDialog, $document, $translate, types, utils, toast, entityService, ruleChainService) { var linker = function (scope, element, attrs) { - var getTemplate = function(eventType) { - var template = ''; - switch(eventType) { - case types.edgeDownlinks.value: - template = edgeDownlinlsRowTemplate; - break; - } - return $templateCache.get(template); - } - - scope.loadTemplate = function() { - element.html(getTemplate(attrs.eventType)); - $compile(element.contents())(scope); - } + var template = edgeDownlinlsRowTemplate; - attrs.$observe('eventType', function() { - scope.loadTemplate(); - }); + element.html($templateCache.get(template)); + $compile(element.contents())(scope); scope.types = types; - - scope.event = attrs.event; + scope.downlink = attrs.downlink; scope.showEdgeEntityContent = function($event, title, contentType) { var onShowingCallback = { @@ -58,13 +42,13 @@ export default function EventRowDirective2($compile, $templateCache, $mdDialog, contentType = null; } var content = ''; - switch(scope.event.type) { - case types.edgeEventType.relation: - content = angular.toJson(scope.event.body); + switch(scope.downlink.type) { + case types.edgeDownlinksType.relation: + content = angular.toJson(scope.downlink.body); showDialog(); break; - case types.edgeEventType.ruleChainMetaData: - content = ruleChainService.getRuleChainMetaData(scope.event.entityId, {ignoreErrors: true}).then( + case types.edgeDownlinksType.ruleChainMetaData: + content = ruleChainService.getRuleChainMetaData(scope.downlink.entityId, {ignoreErrors: true}).then( function success(info) { showDialog(); return angular.toJson(info); @@ -73,7 +57,7 @@ export default function EventRowDirective2($compile, $templateCache, $mdDialog, }); break; default: - content = entityService.getEntity(scope.event.type, scope.event.entityId, {ignoreErrors: true}).then( + content = entityService.getEntity(scope.downlink.type, scope.downlink.entityId, {ignoreErrors: true}).then( function success(info) { showDialog(); return angular.toJson(info); @@ -84,9 +68,9 @@ export default function EventRowDirective2($compile, $templateCache, $mdDialog, } function showDialog() { $mdDialog.show({ - controller: 'EventContentDialogController2', + controller: 'EdgeDownlinksContentDialogController', controllerAs: 'vm', - templateUrl: eventErrorDialogTemplate, + templateUrl: edgeDownlinksContentTemplate, locals: {content: content, title: title, contentType: contentType, showingCallback: onShowingCallback}, parent: angular.element($document[0].body), fullscreen: true, @@ -102,10 +86,10 @@ export default function EventRowDirective2($compile, $templateCache, $mdDialog, } } - scope.checkEdgeEventType = function (type) { - return !(type === types.edgeEventType.widgetType || - type === types.edgeEventType.adminSettings || - type === types.edgeEventType.widgetsBundle ); + scope.checkEdgeDownlinksType = function (type) { + return !(type === types.edgeDownlinksType.widgetType || + type === types.edgeDownlinksType.adminSettings || + type === types.edgeDownlinksType.widgetsBundle ); } scope.checkTooltip = function($event) { @@ -118,14 +102,14 @@ export default function EventRowDirective2($compile, $templateCache, $mdDialog, $compile(element.contents())(scope); - scope.updateStatus = function(eventCreatedTime) { + scope.updateStatus = function(downlinkCreatedTime) { var status; - if (eventCreatedTime < scope.queueStartTs) { - status = $translate.instant(types.edgeEventStatus.DEPLOYED.name); - scope.statusColor = types.edgeEventStatus.DEPLOYED.color; + if (downlinkCreatedTime < scope.queueStartTs) { + status = $translate.instant(types.edgeDownlinksStatus.DEPLOYED.name); + scope.statusColor = types.edgeDownlinksStatus.DEPLOYED.color; } else { - status = $translate.instant(types.edgeEventStatus.PENDING.name); - scope.statusColor = types.edgeEventStatus.PENDING.color; + status = $translate.instant(types.edgeDownlinksStatus.PENDING.name); + scope.statusColor = types.edgeDownlinksStatus.PENDING.color; } return status; } diff --git a/ui/src/app/event/event-row-edge-event.tpl.html b/ui/src/app/edge/downlinks/edge-downlinks-row.tpl.html similarity index 71% rename from ui/src/app/event/event-row-edge-event.tpl.html rename to ui/src/app/edge/downlinks/edge-downlinks-row.tpl.html index a842b5d787..67a52e6836 100644 --- a/ui/src/app/event/event-row-edge-event.tpl.html +++ b/ui/src/app/edge/downlinks/edge-downlinks-row.tpl.html @@ -15,13 +15,13 @@ limitations under the License. --> -
{{ event.createdTime | date : 'yyyy-MM-dd HH:mm:ss' }}
-
{{ event.edgeEventTypeText }}
-
{{ event.edgeEventActionText }}
-
{{ event.entityId }}
-
{{ updateStatus(event.createdTime) }}
+
{{ downlink.createdTime | date : 'yyyy-MM-dd HH:mm:ss' }}
+
{{ downlink.edgeDownlinksTypeText }}
+
{{ downlink.edgeDownlinksActionText }}
+
{{ downlink.entityId }}
+
{{ updateStatus(downlink.createdTime) }}
- diff --git a/ui/src/app/edge/downlinks/edge-downlinks-table.directive.js b/ui/src/app/edge/downlinks/edge-downlinks-table.directive.js index 46f194b68b..50f8f34524 100644 --- a/ui/src/app/edge/downlinks/edge-downlinks-table.directive.js +++ b/ui/src/app/edge/downlinks/edge-downlinks-table.directive.js @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import './event.scss'; +import './downlink.scss'; /* eslint-disable import/no-unresolved, import/default */ @@ -22,17 +22,13 @@ import edgeDownlinksTableTemplate from './edge-downlinks-table.tpl.html'; /* eslint-enable import/no-unresolved, import/default */ /*@ngInject*/ -export default function EdgeDownlinksDirective2($compile, $templateCache, $rootScope, $translate, types, - eventService, edgeService, attributeService) { +export default function EdgeDownlinksDirective($compile, $templateCache, $rootScope, $translate, types, edgeService, attributeService) { var linker = function (scope, element) { var template = $templateCache.get(edgeDownlinksTableTemplate); - element.html(template); - scope.eventType = types.edgeDownlinks.value; - var pageSize = 20; var startTime = 0; var endTime = 0; @@ -45,13 +41,13 @@ export default function EdgeDownlinksDirective2($compile, $templateCache, $rootS scope.topIndex = 0; - scope.theEvents = { + scope.theDownlinks = { getItemAtIndex: function (index) { - if (index > scope.events.data.length) { - scope.theEvents.fetchMoreItems_(index); + if (index > scope.downlinks.data.length) { + scope.theDownlinks.fetchMoreItems_(index); return null; } - var item = scope.events.data[index]; + var item = scope.downlinks.data[index]; if (item) { item.indexNumber = index + 1; } @@ -59,34 +55,34 @@ export default function EdgeDownlinksDirective2($compile, $templateCache, $rootS }, getLength: function () { - if (scope.events.hasNext) { - return scope.events.data.length + scope.events.nextPageLink.limit; + if (scope.downlinks.hasNext) { + return scope.downlinks.data.length + scope.downlinks.nextPageLink.limit; } else { - return scope.events.data.length; + return scope.downlinks.data.length; } }, fetchMoreItems_: function () { - if (scope.events.hasNext && !scope.events.pending) { - if (scope.entityType && scope.entityId && scope.eventType && scope.tenantId) { + if (scope.downlinks.hasNext && !scope.downlinks.pending) { + if (scope.entityType && scope.entityId && scope.tenantId) { scope.loadEdgeInfo(); - scope.events.pending = true; - edgeService.getEdgeDownlinks(scope.entityId, scope.events.nextPageLink).then( - function success(events) { - scope.events.data = scope.events.data.concat(prepareEdgeEventData(events.data)); - scope.events.nextPageLink = events.nextPageLink; - scope.events.hasNext = events.hasNext; - if (scope.events.hasNext) { - scope.events.nextPageLink.limit = pageSize; + scope.downlinks.pending = true; + edgeService.getEdgeDownlinks(scope.entityId, scope.downlinks.nextPageLink).then( + function success(downlinks) { + scope.downlinks.data = scope.downlinks.data.concat(prepareEdgeDownlinksData(downlinks.data)); + scope.downlinks.nextPageLink = downlinks.nextPageLink; + scope.downlinks.hasNext = downlinks.hasNext; + if (scope.downlinks.hasNext) { + scope.downlinks.nextPageLink.limit = pageSize; } - scope.events.pending = false; + scope.downlinks.pending = false; }, function fail() { - scope.events.hasNext = false; - scope.events.pending = false; + scope.downlinks.hasNext = false; + scope.downlinks.pending = false; }); } else { - scope.events.hasNext = false; + scope.downlinks.hasNext = false; } } } @@ -128,7 +124,7 @@ export default function EdgeDownlinksDirective2($compile, $templateCache, $rootS scope.topIndex = 0; scope.selected = []; scope.updateTimeWindowRange(); - scope.events = { + scope.downlinks = { data: [], nextPageLink: { limit: pageSize, @@ -138,15 +134,15 @@ export default function EdgeDownlinksDirective2($compile, $templateCache, $rootS hasNext: true, pending: false }; - scope.theEvents.getItemAtIndex(pageSize); + scope.theDownlinks.getItemAtIndex(pageSize); } scope.noData = function() { - return scope.events.data.length == 0 && !scope.events.hasNext; + return scope.downlinks.data.length == 0 && !scope.downlinks.hasNext; } scope.hasData = function() { - return scope.events.data.length > 0; + return scope.downlinks.data.length > 0; } scope.loading = function() { @@ -211,12 +207,12 @@ export default function EdgeDownlinksDirective2($compile, $templateCache, $rootS $compile(element.contents())(scope); } - function prepareEdgeEventData(data) { + function prepareEdgeDownlinksData(data) { data.forEach( - edgeEvent => { - edgeEvent.edgeEventActionText = $translate.instant(types.edgeEventActionType[edgeEvent.action].name); - edgeEvent.edgeEventTypeText = $translate.instant(types.edgeEventTypeTranslations[edgeEvent.edgeId.entityType].name); + edgeDownlink => { + edgeDownlink.edgeDownlinksActionText = $translate.instant(types.edgeDownlinksActionType[edgeDownlink.action].name); + edgeDownlink.edgeDownlinksTypeText = $translate.instant(types.edgeDownlinksTypeTranslations[edgeDownlink.edgeId.entityType].name); } ); return data; diff --git a/ui/src/app/edge/downlinks/edge-downlinks-table.tpl.html b/ui/src/app/edge/downlinks/edge-downlinks-table.tpl.html index 4bff7afa4b..0e66b2b685 100644 --- a/ui/src/app/edge/downlinks/edge-downlinks-table.tpl.html +++ b/ui/src/app/edge/downlinks/edge-downlinks-table.tpl.html @@ -27,7 +27,7 @@ - + @@ -36,8 +36,8 @@ style="margin-top: 25px;" class="tb-prompt" ng-show="noData()">edge.no-downlinks-prompt - - + + diff --git a/ui/src/app/edge/downlinks/event-row-edge-event.tpl.html b/ui/src/app/edge/downlinks/event-row-edge-event.tpl.html deleted file mode 100644 index a842b5d787..0000000000 --- a/ui/src/app/edge/downlinks/event-row-edge-event.tpl.html +++ /dev/null @@ -1,37 +0,0 @@ - -
{{ event.createdTime | date : 'yyyy-MM-dd HH:mm:ss' }}
-
{{ event.edgeEventTypeText }}
-
{{ event.edgeEventActionText }}
-
{{ event.entityId }}
-
{{ updateStatus(event.createdTime) }}
-
- - - {{ 'action.view' | translate }} - - - more_horiz - - -
- - diff --git a/ui/src/app/edge/edges.tpl.html b/ui/src/app/edge/edges.tpl.html index d1cb6182cd..e53ebba83a 100644 --- a/ui/src/app/edge/edges.tpl.html +++ b/ui/src/app/edge/edges.tpl.html @@ -65,13 +65,6 @@ default-event-type="{{vm.types.eventType.error.value}}"> - - - - scope.events.data.length) { - scope.theEvents.fetchMoreItems_(index); - return null; - } - var item = scope.events.data[index]; - if (item) { - item.indexNumber = index + 1; - } - return item; - }, - - getLength: function () { - if (scope.events.hasNext) { - return scope.events.data.length + scope.events.nextPageLink.limit; - } else { - return scope.events.data.length; - } - }, - - fetchMoreItems_: function () { - if (scope.events.hasNext && !scope.events.pending) { - if (scope.entityType && scope.entityId && scope.eventType && scope.tenantId) { - scope.loadEdgeInfo(); - scope.events.pending = true; - edgeService.getEdgeDownlinks(scope.entityId, scope.events.nextPageLink).then( - function success(events) { - scope.events.data = scope.events.data.concat(prepareEdgeEventData(events.data)); - scope.events.nextPageLink = events.nextPageLink; - scope.events.hasNext = events.hasNext; - if (scope.events.hasNext) { - scope.events.nextPageLink.limit = pageSize; - } - scope.events.pending = false; - }, - function fail() { - scope.events.hasNext = false; - scope.events.pending = false; - }); - } else { - scope.events.hasNext = false; - } - } - } - }; - - scope.$watch("entityId", function(newVal, prevVal) { - if (newVal && !angular.equals(newVal, prevVal)) { - scope.resetFilter(); - scope.reload(); - } - }); - - scope.$watch("timewindow", function(newVal, prevVal) { - if (newVal && !angular.equals(newVal, prevVal)) { - scope.reload(); - } - }, true); - - scope.resetFilter = function() { - scope.timewindow = { - history: { - timewindowMs: 24 * 60 * 60 * 1000 // 1 day - } - }; - } - - scope.updateTimeWindowRange = function() { - if (scope.timewindow.history.timewindowMs) { - var currentTime = (new Date).getTime(); - startTime = currentTime - scope.timewindow.history.timewindowMs; - endTime = currentTime; - } else { - startTime = scope.timewindow.history.fixedTimewindow.startTimeMs; - endTime = scope.timewindow.history.fixedTimewindow.endTimeMs; - } - } - - scope.reload = function() { - scope.topIndex = 0; - scope.selected = []; - scope.updateTimeWindowRange(); - scope.events = { - data: [], - nextPageLink: { - limit: pageSize, - startTime: startTime, - endTime: endTime - }, - hasNext: true, - pending: false - }; - scope.theEvents.getItemAtIndex(pageSize); - } - - scope.noData = function() { - return scope.events.data.length == 0 && !scope.events.hasNext; - } - - scope.hasData = function() { - return scope.events.data.length > 0; - } - - scope.loading = function() { - return $rootScope.loading; - } - - scope.hasScroll = function() { - var repeatContainer = scope.repeatContainer[0]; - if (repeatContainer) { - var scrollElement = repeatContainer.children[0]; - if (scrollElement) { - return scrollElement.scrollHeight > scrollElement.clientHeight; - } - } - return false; - } - - scope.subscriptionId = null; - - scope.loadEdgeInfo = function() { - attributeService.getEntityAttributesValues( - scope.entityType, - scope.entityId, - types.attributesScope.server.value, - types.edgeAttributeKeys.queueStartTs, - null).then( - function success(attributes) { - attributes.length > 0 ? scope.onEdgeAttributesUpdate(attributes) : scope.queueStartTs = 0; - }); - scope.checkSubscription(); - } - - scope.onEdgeAttributesUpdate = function(attributes) { - let edgeAttributes = attributes.reduce(function (map, attribute) { - map[attribute.key] = attribute; - return map; - }, {}); - if (edgeAttributes.queueStartTs) { - scope.queueStartTs = edgeAttributes.queueStartTs.lastUpdateTs; - } - } - - scope.checkSubscription = function() { - var newSubscriptionId = null; - if (scope.entityId && scope.entityType && types.attributesScope.server.value) { - newSubscriptionId = - attributeService.subscribeForEntityAttributes(scope.entityType, scope.entityId, types.attributesScope.server.value); - } - if (scope.subscriptionId && scope.subscriptionId != newSubscriptionId) { - attributeService.unsubscribeForEntityAttributes(scope.subscriptionId); - } - scope.subscriptionId = newSubscriptionId; - } - - scope.$on('$destroy', function () { - if (scope.subscriptionId) { - attributeService.unsubscribeForEntityAttributes(scope.subscriptionId); - } - }); - - scope.reload(); - - $compile(element.contents())(scope); - } - function prepareEdgeEventData(data) { - - data.forEach( - edgeEvent => { - edgeEvent.edgeEventActionText = $translate.instant(types.edgeEventActionType[edgeEvent.action].name); - edgeEvent.edgeEventTypeText = $translate.instant(types.edgeEventTypeTranslations[edgeEvent.edgeId.entityType].name); - } - ); - return data; - } - - return { - restrict: "E", - link: linker, - scope: { - entityType: '=', - entityId: '=', - tenantId: '=' - } - }; -} diff --git a/ui/src/app/event/edge-downlinks-table.tpl.html b/ui/src/app/event/edge-downlinks-table.tpl.html deleted file mode 100644 index d55e61457c..0000000000 --- a/ui/src/app/event/edge-downlinks-table.tpl.html +++ /dev/null @@ -1,46 +0,0 @@ - - -
- - - refresh - - {{ 'action.refresh' | translate }} - - -
- - - - - - edge.no-downlinks-prompt - - - - - - - - -
diff --git a/ui/src/app/event/event-header-edge-event.tpl.html b/ui/src/app/event/event-header-edge-event.tpl.html deleted file mode 100644 index 3de281ddc7..0000000000 --- a/ui/src/app/event/event-header-edge-event.tpl.html +++ /dev/null @@ -1,23 +0,0 @@ - -
event.event-time
-
event.event-type
-
edge.event-action
-
edge.entity-id
-
edge.status
-
edge.entity-info
diff --git a/ui/src/app/event/event-header.directive.js b/ui/src/app/event/event-header.directive.js index a9db6fa5fb..ce0fe4e81c 100644 --- a/ui/src/app/event/event-header.directive.js +++ b/ui/src/app/event/event-header.directive.js @@ -19,7 +19,6 @@ import eventHeaderLcEventTemplate from './event-header-lc-event.tpl.html'; import eventHeaderStatsTemplate from './event-header-stats.tpl.html'; import eventHeaderErrorTemplate from './event-header-error.tpl.html'; import eventHeaderDebugRuleNodeTemplate from './event-header-debug-rulenode.tpl.html'; -import edgeDownlinksHeaderTemplate from './event-header-edge-event.tpl.html' /* eslint-enable import/no-unresolved, import/default */ @@ -46,9 +45,6 @@ export default function EventHeaderDirective($compile, $templateCache, types) { case types.debugEventType.debugRuleChain.value: template = eventHeaderDebugRuleNodeTemplate; break; - case types.edgeDownlinks.value: - template = edgeDownlinksHeaderTemplate; - break; } return $templateCache.get(template); } diff --git a/ui/src/app/event/event-row.directive.js b/ui/src/app/event/event-row.directive.js index fd5fce3a0c..2195e68ad3 100644 --- a/ui/src/app/event/event-row.directive.js +++ b/ui/src/app/event/event-row.directive.js @@ -21,13 +21,12 @@ import eventRowLcEventTemplate from './event-row-lc-event.tpl.html'; import eventRowStatsTemplate from './event-row-stats.tpl.html'; import eventRowErrorTemplate from './event-row-error.tpl.html'; import eventRowDebugRuleNodeTemplate from './event-row-debug-rulenode.tpl.html'; -import edgeDownlinlsRowTemplate from './event-row-edge-event.tpl.html'; /* eslint-enable import/no-unresolved, import/default */ /*@ngInject*/ export default function EventRowDirective($compile, $templateCache, $mdDialog, $document, $translate, - types, utils, toast, entityService, ruleChainService) { + types, utils) { var linker = function (scope, element, attrs) { @@ -49,9 +48,6 @@ export default function EventRowDirective($compile, $templateCache, $mdDialog, $ case types.debugEventType.debugRuleChain.value: template = eventRowDebugRuleNodeTemplate; break; - case types.edgeDownlinks.value: - template = edgeDownlinlsRowTemplate; - break; } return $templateCache.get(template); } @@ -98,85 +94,7 @@ export default function EventRowDirective($compile, $templateCache, $mdDialog, $ }); } - scope.showEdgeEntityContent = function($event, title, contentType) { - var onShowingCallback = { - onShowing: function(){} - } - if (!contentType) { - contentType = null; - } - var content = ''; - switch(scope.event.type) { - case types.edgeEventType.relation: - content = angular.toJson(scope.event.body); - showDialog(); - break; - case types.edgeEventType.ruleChainMetaData: - content = ruleChainService.getRuleChainMetaData(scope.event.entityId, {ignoreErrors: true}).then( - function success(info) { - showDialog(); - return angular.toJson(info); - }, function fail() { - showError(); - }); - break; - default: - content = entityService.getEntity(scope.event.type, scope.event.entityId, {ignoreErrors: true}).then( - function success(info) { - showDialog(); - return angular.toJson(info); - }, function fail() { - showError(); - }); - break; - } - function showDialog() { - $mdDialog.show({ - controller: 'EventContentDialogController', - controllerAs: 'vm', - templateUrl: eventErrorDialogTemplate, - locals: {content: content, title: title, contentType: contentType, showingCallback: onShowingCallback}, - parent: angular.element($document[0].body), - fullscreen: true, - targetEvent: $event, - multiple: true, - onShowing: function(scope, element) { - onShowingCallback.onShowing(scope, element); - } - }); - } - function showError() { - toast.showError($translate.instant('edge.load-entity-error')); - } - } - - scope.checkEdgeEventType = function (type) { - return !(type === types.edgeEventType.widgetType || - type === types.edgeEventType.adminSettings || - type === types.edgeEventType.widgetsBundle ); - } - - scope.checkTooltip = function($event) { - var el = $event.target; - var $el = angular.element(el); - if(el.offsetWidth < el.scrollWidth && !$el.attr('title')){ - $el.attr('title', $el.text()); - } - } - $compile(element.contents())(scope); - - scope.updateStatus = function(eventCreatedTime) { - var status; - if (eventCreatedTime < scope.queueStartTs) { - status = $translate.instant(types.edgeEventStatus.DEPLOYED.name); - scope.statusColor = types.edgeEventStatus.DEPLOYED.color; - } else { - status = $translate.instant(types.edgeEventStatus.PENDING.name); - scope.statusColor = types.edgeEventStatus.PENDING.color; - } - return status; - } } return { diff --git a/ui/src/app/event/event.scss b/ui/src/app/event/event.scss index b0d0d19157..f1b5eb0d46 100644 --- a/ui/src/app/event/event.scss +++ b/ui/src/app/event/event.scss @@ -85,10 +85,6 @@ md-list.tb-event-table { } } -.tb-edge-downlinks-table { - @extend .tb-event-table; -} - #tb-event-content { width: 100%; min-width: 400px; diff --git a/ui/src/app/event/index.js b/ui/src/app/event/index.js index fb918833c7..69227eef8b 100644 --- a/ui/src/app/event/index.js +++ b/ui/src/app/event/index.js @@ -19,7 +19,6 @@ import EventContentDialogController from './event-content-dialog.controller'; import EventHeaderDirective from './event-header.directive'; import EventRowDirective from './event-row.directive'; import EventTableDirective from './event-table.directive'; -import EdgeDownlinksDirective from "./edge-downlinks-table.directive"; export default angular.module('thingsboard.event', [ thingsboardApiEvent @@ -28,5 +27,4 @@ export default angular.module('thingsboard.event', [ .directive('tbEventHeader', EventHeaderDirective) .directive('tbEventRow', EventRowDirective) .directive('tbEventTable', EventTableDirective) - .directive('tbEdgeDownlinksTableOld', EdgeDownlinksDirective) .name; From aface0ab04c43b35fab189384650e7a410385605 Mon Sep 17 00:00:00 2001 From: Artem Babak Date: Wed, 6 Jan 2021 11:30:57 +0200 Subject: [PATCH 08/14] Edge Downlinks events refactored --- ui/src/app/common/types.constant.js | 105 +++++++++--------- .../downlinks/edge-downlinks-header.tpl.html | 6 +- .../downlinks/edge-downlinks-row.tpl.html | 4 +- .../edge-downlinks-table.directive.js | 4 +- ui/src/app/locale/locale.constant-de_DE.json | 1 - ui/src/app/locale/locale.constant-en_US.json | 44 +++++++- ui/src/app/locale/locale.constant-es_ES.json | 1 - 7 files changed, 100 insertions(+), 65 deletions(-) diff --git a/ui/src/app/common/types.constant.js b/ui/src/app/common/types.constant.js index f65cc59e06..585e56acb8 100644 --- a/ui/src/app/common/types.constant.js +++ b/ui/src/app/common/types.constant.js @@ -1073,125 +1073,122 @@ export default angular.module('thingsboard.types', []) translate: { customTranslationsPrefix: "custom." }, - edgeDownlinksActionType: { + edgeEventActionTypeTranslations: { "ADDED": { - name: "audit-log.type-added" + name: "edge-event.action-type-added" }, "DELETED": { - name: "audit-log.type-deleted" + name: "edge-event.action-type-deleted" }, "UPDATED": { - name: "audit-log.type-updated" + name: "edge-event.action-type-updated" + }, + "POST_ATTRIBUTES": { + name: "edge-event.action-type-post-attributes" }, "ATTRIBUTES_UPDATED": { - name: "audit-log.type-attributes-updated" + name: "edge-event.action-type-attributes-updated" }, "ATTRIBUTES_DELETED": { - name: "audit-log.type-attributes-deleted" - }, - "RPC_CALL": { - name: "audit-log.type-rpc-call" + name: "edge-event.action-type-attributes-deleted" }, "CREDENTIALS_UPDATED": { - name: "audit-log.type-credentials-updated" + name: "edge-event.action-type-credentials-updated" + }, + "ASSIGNED_TO_CUSTOMER": { + name: "edge-event.action-type-assigned-to-customer" + }, + "UNASSIGNED_TO_CUSTOMER": { + name: "edge-event.action-type-unassigned-from-customer" }, "RELATION_ADD_OR_UPDATE": { - name: "audit-log.type-relation-add-or-update" + name: "edge-event.action-type-relation-add-or-update" }, "RELATION_DELETED": { - name: "audit-log.type-relation-delete" + name: "edge-event.action-type-relation-deleted" + }, + "RPC_CALL": { + name: "edge-event.action-type-rpc-call" }, "ALARM_ACK": { - name: "audit-log.type-alarm-ack" + name: "edge-event.action-type-alarm-ack" }, "ALARM_CLEAR": { - name: "audit-log.type-alarm-clear" + name: "edge-event.action-type-alarm-clear" }, "CREDENTIALS_REQUEST": { - name: "edge.credentials-request" - }, - "ATTRIBUTES_REQUEST": { - name: "edge.attributes-request" + name: "edge-event.action-type-credentials-request" }, "TIMESERIES_UPDATED": { - name: "edge.timeseries-updated" - }, - "RELATION_REQUEST": { - name: "edge.relation-request" - }, - "RULE_CHAIN_METADATA_REQUEST": { - name: "edge.rule-chain-metadata-request" - }, - "GROUP_ENTITIES_REQUEST": { - name: "edge.group_entities_request" - }, - "GROUP_PERMISSIONS_REQUEST": { - name: "edge.group-permissions-request" + name: "edge-event.action-type-timeseries-updated" }, "ASSIGNED_TO_EDGE": { - name: "audit-log.type-assigned-to-edge" + name: "edge-event.action-type-assigned-to-edge" }, "UNASSIGNED_FROM_EDGE": { - name: "audit-log.type-unassigned-from-edge" + name: "edge-event.action-type-unassigned-from-edge" } }, - edgeDownlinksTypeTranslations:{ + edgeEventTypeTranslations:{ "DASHBOARD": { - name: "entity.type-dashboard" + name: "edge-event.type-dashboard" }, "ASSET": { - name: "entity.type-asset" + name: "edge-event.type-asset" }, "DEVICE": { - name: "entity.type-device" + name: "edge-event.type-device" }, "ENTITY_VIEW": { - name: "entity.type-entity_view" + name: "edge-event.type-entity-view" }, "ALARM": { - name: "entity.type-alarm" + name: "edge-event.type-alarm" }, "RULE_CHAIN": { - name: "entity.type-rulechain" + name: "edge-event.type-rule-chain" }, - "RULE_CHAIN_META_DATA": { - name: "entity.type-rule-chain-metadata" + "RULE_CHAIN_METADATA": { + name: "edge-event.type-rule-chain-metadata" }, "EDGE": { - name: "entity.type-edge" + name: "edge-event.type-edge" }, "USER": { - name: "entity.type-user" + name: "edge-event.type-user" + }, + "TENANT": { + name: "edge-event.type-tenant" }, "CUSTOMER": { - name: "entity.type-customer" + name: "edge-event.type-customer" }, "RELATION": { - name: "entity.type-relation" + name: "edge-event.type-relation" }, "ENTITY_GROUP": { - name: "entity.type-entity-group" + name: "edge-event.type-entity-group" }, "SCHEDULER_EVENT": { - name: "entity.type-scheduler-event" + name: "edge-event.type-scheduler-event" }, "WHITE_LABELING": { - name: "white-labeling.white-labeling" + name: "edge-event.type-white-labeling" }, "LOGIN_WHITE_LABELING": { - name: "white-labeling.login-white-labeling" + name: "edge-event.type-login-white-labeling" }, "CUSTOM_TRANSLATION": { - name: "custom-translation.custom-translation", + name: "edge-event.custom-translation", }, "WIDGETS_BUNDLE": { - name: "widget.widget-bundle" + name: "edge-event.type-widgets-bundle" }, "WIDGET_TYPE": { - name: "widget.type" + name: "edge-event.type-widgets-type" }, "ADMIN_SETTINGS": { - name: "permission.resource.display-type.ADMIN_SETTINGS" + name: "edge-event.type-admin-settings" } } } diff --git a/ui/src/app/edge/downlinks/edge-downlinks-header.tpl.html b/ui/src/app/edge/downlinks/edge-downlinks-header.tpl.html index 3de281ddc7..e08f688142 100644 --- a/ui/src/app/edge/downlinks/edge-downlinks-header.tpl.html +++ b/ui/src/app/edge/downlinks/edge-downlinks-header.tpl.html @@ -16,8 +16,8 @@ -->
event.event-time
-
event.event-type
+
event.type
edge.event-action
edge.entity-id
-
edge.status
-
edge.entity-info
+
event.status
+
event.data
diff --git a/ui/src/app/edge/downlinks/edge-downlinks-row.tpl.html b/ui/src/app/edge/downlinks/edge-downlinks-row.tpl.html index 67a52e6836..369d705b04 100644 --- a/ui/src/app/edge/downlinks/edge-downlinks-row.tpl.html +++ b/ui/src/app/edge/downlinks/edge-downlinks-row.tpl.html @@ -16,10 +16,10 @@ -->
{{ downlink.createdTime | date : 'yyyy-MM-dd HH:mm:ss' }}
-
{{ downlink.edgeDownlinksTypeText }}
+
{{ downlink.edgeDownlinksTypeText }}
{{ downlink.edgeDownlinksActionText }}
{{ downlink.entityId }}
-
{{ updateStatus(downlink.createdTime) }}
+
{{ updateStatus(downlink.createdTime) }}
{ - edgeDownlink.edgeDownlinksActionText = $translate.instant(types.edgeDownlinksActionType[edgeDownlink.action].name); - edgeDownlink.edgeDownlinksTypeText = $translate.instant(types.edgeDownlinksTypeTranslations[edgeDownlink.edgeId.entityType].name); + edgeDownlink.edgeDownlinksActionText = $translate.instant(types.edgeEventActionTypeTranslations[edgeDownlink.action].name); + edgeDownlink.edgeDownlinksTypeText = $translate.instant(types.edgeEventTypeTranslations[edgeDownlink.type].name); } ); return data; diff --git a/ui/src/app/locale/locale.constant-de_DE.json b/ui/src/app/locale/locale.constant-de_DE.json index 6c69c25910..1f495ccdf0 100644 --- a/ui/src/app/locale/locale.constant-de_DE.json +++ b/ui/src/app/locale/locale.constant-de_DE.json @@ -808,7 +808,6 @@ "deployed": "Bereitgestellt", "pending": "Steht aus", "entity-id": "Entität ID", - "entity-info": "Entitätsinfo", "event-action": "Ereignisaktion", "load-entity-error": "Entität nicht gefunden. Fehler beim Laden der Informationen", "unassign-edges-text": "Nach der Bestätigung werden alle ausgewählten Kanten nicht zugewiesen und sind für den Kunden nicht zugänglich.", diff --git a/ui/src/app/locale/locale.constant-en_US.json b/ui/src/app/locale/locale.constant-en_US.json index 781ceced3f..c9522365b6 100644 --- a/ui/src/app/locale/locale.constant-en_US.json +++ b/ui/src/app/locale/locale.constant-en_US.json @@ -788,7 +788,6 @@ "cloud-endpoint": "Cloud Endpoint", "cloud-endpoint-required": "Cloud Endpoint is required.", "description": "Description", - "entity-info": "Entity info", "details": "Details", "events": "Events", "copy-id": "Copy Edge Id", @@ -845,7 +844,6 @@ "set-root-rule-chain-text": "Please select root rule chain for edge(s)", "set-root-rule-chain-to-edges": "Set root rule chain for Edge(s)", "set-root-rule-chain-to-edges-text": "Set root rule chain for { count, plural, 1 {1 edge} other {# edges} }", - "status": "Received by edge", "deployed": "Deployed", "pending": "Pending", "unassign-edges-action-title": "Unassign { count, plural, 1 {1 edge} other {# edges} } from customer", @@ -860,6 +858,48 @@ "downlinks": "Downlinks", "no-downlinks-prompt": "No downlinks found" }, + "edge-event": { + "type-dashboard": "Dashboard", + "type-asset": "Asset", + "type-device": "Device", + "type-device-profile": "Device Profile", + "type-entity-view": "Entity View", + "type-alarm": "Alar", + "type-rule-chain": "Rule Chain", + "type-rule-chain-metadata": "Rule Chain Metadata", + "type-edge": "Edge", + "type-entity-group": "Entity Group", + "type-scheduler-event": "Scheduler Event", + "type-white-labeling": "White Labeling", + "type-login-white-labeling": "White Labeling Login", + "type-user": "User", + "type-tenant": "Tenant", + "type-customer": "Customer", + "type-custom-translation": "Custom Translation", + "type-relation": "Relation", + "type-widgets-bundle": "Widgets Bundle", + "type-widgets-type": "Widgets Type", + "type-admin-settings": "Admin Settings", + "action-type-added": "Added", + "action-type-deleted": "Deleted", + "action-type-updated": "Updated", + "action-type-post-attributes": "Post Attributes", + "action-type-attributes-updated": "Attributes Updated", + "action-type-attributes-deleted": "Attributes Deleted", + "action-type-timeseries-updated": "Timeseries Updated", + "action-type-credentials-updated": "Credentials Updated", + "action-type-assigned-to-customer": "Assigned to Customer", + "action-type-unassigned-from-customer": "Unassigned from Customer", + "action-type-relation-add-or-update": "Relation Add or Update", + "action-type-relation-deleted": "Relation Deleted", + "action-type-rpc-call": "RPC Call", + "action-type-alarm-ack": "Alarm Ack", + "action-type-alarm-clear": "Alarm Clear", + "action-type-assigned-to-edge": "Assigned to Edge", + "action-type-unassigned-from-edge": "Unassigned from Edge", + "action-type-credentials-request": "Credentials Request", + "action-type-entity-merge-request": "Entity Merge Request" + }, "error": { "unable-to-connect": "Unable to connect to the server! Please check your internet connection.", "unhandled-error-code": "Unhandled error code: {{errorCode}}", diff --git a/ui/src/app/locale/locale.constant-es_ES.json b/ui/src/app/locale/locale.constant-es_ES.json index 301e292de2..07acd04e3a 100644 --- a/ui/src/app/locale/locale.constant-es_ES.json +++ b/ui/src/app/locale/locale.constant-es_ES.json @@ -821,7 +821,6 @@ "deployed": "Desplegada", "pending": "Pendiente", "entity-id": "ID de entidad", - "entity-info": "Entity info", "event-action": "Información de la entidad", "load-entity-error": "Entidad no encontrada. No se pudo cargar la información", "unassign-edges-text": "Después de la confirmación de todos los bordes seleccionados, se anulará la asignación y el cliente no podrá acceder a ellos.", From 8082930a852afc5be3a97616e936cbf1240d3cdc Mon Sep 17 00:00:00 2001 From: Artem Babak Date: Wed, 6 Jan 2021 11:38:18 +0200 Subject: [PATCH 09/14] Edge Downlinks translations fixed --- ui/src/app/common/types.constant.js | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/ui/src/app/common/types.constant.js b/ui/src/app/common/types.constant.js index 585e56acb8..33eaf16ba4 100644 --- a/ui/src/app/common/types.constant.js +++ b/ui/src/app/common/types.constant.js @@ -1086,6 +1086,9 @@ export default angular.module('thingsboard.types', []) "POST_ATTRIBUTES": { name: "edge-event.action-type-post-attributes" }, + "TIMESERIES_UPDATED": { + name: "edge-event.action-type-timeseries-updated" + }, "ATTRIBUTES_UPDATED": { name: "edge-event.action-type-attributes-updated" }, @@ -1098,7 +1101,7 @@ export default angular.module('thingsboard.types', []) "ASSIGNED_TO_CUSTOMER": { name: "edge-event.action-type-assigned-to-customer" }, - "UNASSIGNED_TO_CUSTOMER": { + "UNASSIGNED_FROM_CUSTOMER": { name: "edge-event.action-type-unassigned-from-customer" }, "RELATION_ADD_OR_UPDATE": { @@ -1119,14 +1122,14 @@ export default angular.module('thingsboard.types', []) "CREDENTIALS_REQUEST": { name: "edge-event.action-type-credentials-request" }, - "TIMESERIES_UPDATED": { - name: "edge-event.action-type-timeseries-updated" - }, "ASSIGNED_TO_EDGE": { name: "edge-event.action-type-assigned-to-edge" }, "UNASSIGNED_FROM_EDGE": { name: "edge-event.action-type-unassigned-from-edge" + }, + "ENTITY_MERGE_REQUEST": { + name: "edge-event.action-type-entity-merge-request" } }, edgeEventTypeTranslations:{ @@ -1166,6 +1169,15 @@ export default angular.module('thingsboard.types', []) "RELATION": { name: "edge-event.type-relation" }, + "WIDGETS_BUNDLE": { + name: "edge-event.type-widgets-bundle" + }, + "WIDGET_TYPE": { + name: "edge-event.type-widgets-type" + }, + "ADMIN_SETTINGS": { + name: "edge-event.type-admin-settings" + }, "ENTITY_GROUP": { name: "edge-event.type-entity-group" }, @@ -1180,15 +1192,6 @@ export default angular.module('thingsboard.types', []) }, "CUSTOM_TRANSLATION": { name: "edge-event.custom-translation", - }, - "WIDGETS_BUNDLE": { - name: "edge-event.type-widgets-bundle" - }, - "WIDGET_TYPE": { - name: "edge-event.type-widgets-type" - }, - "ADMIN_SETTINGS": { - name: "edge-event.type-admin-settings" } } } From bee4da8995ea87f28170781df7bc7ba530375cf6 Mon Sep 17 00:00:00 2001 From: Artem Babak Date: Wed, 6 Jan 2021 11:42:45 +0200 Subject: [PATCH 10/14] Edge Downlinks refactored --- ui/src/app/api/edge.service.js | 4 ++-- ui/src/app/edge/downlinks/edge-downlinks-table.directive.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/src/app/api/edge.service.js b/ui/src/app/api/edge.service.js index 809b0b12af..debd49069a 100644 --- a/ui/src/app/api/edge.service.js +++ b/ui/src/app/api/edge.service.js @@ -35,7 +35,7 @@ function EdgeService($http, $q, customerService) { unassignEdgeFromCustomer: unassignEdgeFromCustomer, makeEdgePublic: makeEdgePublic, setRootRuleChain: setRootRuleChain, - getEdgeDownlinks: getEdgeDownlinks, + getEdgeEvents: getEdgeEvents, syncEdge: syncEdge, findMissingToRelatedRuleChains: findMissingToRelatedRuleChains }; @@ -276,7 +276,7 @@ function EdgeService($http, $q, customerService) { return deferred.promise; } - function getEdgeDownlinks(edgeId, pageLink) { + function getEdgeEvents(edgeId, pageLink) { var deferred = $q.defer(); var url = '/api/edge/' + edgeId + '/events' + '?limit=' + pageLink.limit; if (angular.isDefined(pageLink.startTime) && pageLink.startTime != null) { diff --git a/ui/src/app/edge/downlinks/edge-downlinks-table.directive.js b/ui/src/app/edge/downlinks/edge-downlinks-table.directive.js index 2373000a73..06928c3e83 100644 --- a/ui/src/app/edge/downlinks/edge-downlinks-table.directive.js +++ b/ui/src/app/edge/downlinks/edge-downlinks-table.directive.js @@ -67,7 +67,7 @@ export default function EdgeDownlinksDirective($compile, $templateCache, $rootSc if (scope.entityType && scope.entityId && scope.tenantId) { scope.loadEdgeInfo(); scope.downlinks.pending = true; - edgeService.getEdgeDownlinks(scope.entityId, scope.downlinks.nextPageLink).then( + edgeService.getEdgeEvents(scope.entityId, scope.downlinks.nextPageLink).then( function success(downlinks) { scope.downlinks.data = scope.downlinks.data.concat(prepareEdgeDownlinksData(downlinks.data)); scope.downlinks.nextPageLink = downlinks.nextPageLink; From f34420cfa814af185328d83e2deb5860daf7bf7e Mon Sep 17 00:00:00 2001 From: Artem Babak Date: Wed, 6 Jan 2021 11:46:59 +0200 Subject: [PATCH 11/14] Edge Downlinks refactored --- ui/src/app/common/types.constant.js | 4 ++-- .../downlinks/edge-downlinks-row.directive.js | 18 +++++++++--------- .../edge/downlinks/edge-downlinks-row.tpl.html | 4 ++-- .../edge-downlinks-table.directive.js | 4 ++-- ui/src/app/edge/edges.tpl.html | 3 +-- 5 files changed, 16 insertions(+), 17 deletions(-) diff --git a/ui/src/app/common/types.constant.js b/ui/src/app/common/types.constant.js index 33eaf16ba4..c4c110d1ee 100644 --- a/ui/src/app/common/types.constant.js +++ b/ui/src/app/common/types.constant.js @@ -384,7 +384,7 @@ export default angular.module('thingsboard.types', []) entityView: "ENTITY_VIEW", edge: "EDGE" }, - edgeDownlinksType:{ + edgeEventType:{ dashboard: "DASHBOARD", asset: "ASSET", device: "DEVICE", @@ -405,7 +405,7 @@ export default angular.module('thingsboard.types', []) widgetType: "WIDGET_TYPE", adminSettings: "ADMIN_SETTINGS" }, - edgeDownlinksStatus: { + getEdgeStatus: { "DEPLOYED": { name: "edge.deployed", color: grey900 diff --git a/ui/src/app/edge/downlinks/edge-downlinks-row.directive.js b/ui/src/app/edge/downlinks/edge-downlinks-row.directive.js index 8e848dfaf6..d2cf7ee0a6 100644 --- a/ui/src/app/edge/downlinks/edge-downlinks-row.directive.js +++ b/ui/src/app/edge/downlinks/edge-downlinks-row.directive.js @@ -43,11 +43,11 @@ export default function EdgeDownlinksRowDirective($compile, $templateCache, $mdD } var content = ''; switch(scope.downlink.type) { - case types.edgeDownlinksType.relation: + case types.edgeEventType.relation: content = angular.toJson(scope.downlink.body); showDialog(); break; - case types.edgeDownlinksType.ruleChainMetaData: + case types.edgeEventType.ruleChainMetaData: content = ruleChainService.getRuleChainMetaData(scope.downlink.entityId, {ignoreErrors: true}).then( function success(info) { showDialog(); @@ -87,9 +87,9 @@ export default function EdgeDownlinksRowDirective($compile, $templateCache, $mdD } scope.checkEdgeDownlinksType = function (type) { - return !(type === types.edgeDownlinksType.widgetType || - type === types.edgeDownlinksType.adminSettings || - type === types.edgeDownlinksType.widgetsBundle ); + return !(type === types.edgeEventType.widgetType || + type === types.edgeEventType.adminSettings || + type === types.edgeEventType.widgetsBundle ); } scope.checkTooltip = function($event) { @@ -105,11 +105,11 @@ export default function EdgeDownlinksRowDirective($compile, $templateCache, $mdD scope.updateStatus = function(downlinkCreatedTime) { var status; if (downlinkCreatedTime < scope.queueStartTs) { - status = $translate.instant(types.edgeDownlinksStatus.DEPLOYED.name); - scope.statusColor = types.edgeDownlinksStatus.DEPLOYED.color; + status = $translate.instant(types.getEdgeStatus.DEPLOYED.name); + scope.statusColor = types.getEdgeStatus.DEPLOYED.color; } else { - status = $translate.instant(types.edgeDownlinksStatus.PENDING.name); - scope.statusColor = types.edgeDownlinksStatus.PENDING.color; + status = $translate.instant(types.getEdgeStatus.PENDING.name); + scope.statusColor = types.getEdgeStatus.PENDING.color; } return status; } diff --git a/ui/src/app/edge/downlinks/edge-downlinks-row.tpl.html b/ui/src/app/edge/downlinks/edge-downlinks-row.tpl.html index 369d705b04..7fe595bc8c 100644 --- a/ui/src/app/edge/downlinks/edge-downlinks-row.tpl.html +++ b/ui/src/app/edge/downlinks/edge-downlinks-row.tpl.html @@ -16,8 +16,8 @@ -->
{{ downlink.createdTime | date : 'yyyy-MM-dd HH:mm:ss' }}
-
{{ downlink.edgeDownlinksTypeText }}
-
{{ downlink.edgeDownlinksActionText }}
+
{{ downlink.edgeEventTypeText }}
+
{{ downlink.edgeEventActionText }}
{{ downlink.entityId }}
{{ updateStatus(downlink.createdTime) }}
diff --git a/ui/src/app/edge/downlinks/edge-downlinks-table.directive.js b/ui/src/app/edge/downlinks/edge-downlinks-table.directive.js index 06928c3e83..98bd63abb0 100644 --- a/ui/src/app/edge/downlinks/edge-downlinks-table.directive.js +++ b/ui/src/app/edge/downlinks/edge-downlinks-table.directive.js @@ -211,8 +211,8 @@ export default function EdgeDownlinksDirective($compile, $templateCache, $rootSc data.forEach( edgeDownlink => { - edgeDownlink.edgeDownlinksActionText = $translate.instant(types.edgeEventActionTypeTranslations[edgeDownlink.action].name); - edgeDownlink.edgeDownlinksTypeText = $translate.instant(types.edgeEventTypeTranslations[edgeDownlink.type].name); + edgeDownlink.edgeEventActionText = $translate.instant(types.edgeEventActionTypeTranslations[edgeDownlink.action].name); + edgeDownlink.edgeEventTypeText = $translate.instant(types.edgeEventTypeTranslations[edgeDownlink.type].name); } ); return data; diff --git a/ui/src/app/edge/edges.tpl.html b/ui/src/app/edge/edges.tpl.html index e53ebba83a..ea40c80b06 100644 --- a/ui/src/app/edge/edges.tpl.html +++ b/ui/src/app/edge/edges.tpl.html @@ -68,8 +68,7 @@ + tenant-id="vm.grid.operatingItem().tenantId.id"> From 31b8a686f88a18fc636bab977ec9b6db7f040bc0 Mon Sep 17 00:00:00 2001 From: Artem Babak Date: Wed, 6 Jan 2021 11:48:23 +0200 Subject: [PATCH 12/14] Edge Downlinks refactored --- ui/src/app/common/types.constant.js | 2 +- ui/src/app/edge/downlinks/edge-downlinks-row.directive.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ui/src/app/common/types.constant.js b/ui/src/app/common/types.constant.js index c4c110d1ee..375adad109 100644 --- a/ui/src/app/common/types.constant.js +++ b/ui/src/app/common/types.constant.js @@ -405,7 +405,7 @@ export default angular.module('thingsboard.types', []) widgetType: "WIDGET_TYPE", adminSettings: "ADMIN_SETTINGS" }, - getEdgeStatus: { + edgeEventStatus: { "DEPLOYED": { name: "edge.deployed", color: grey900 diff --git a/ui/src/app/edge/downlinks/edge-downlinks-row.directive.js b/ui/src/app/edge/downlinks/edge-downlinks-row.directive.js index d2cf7ee0a6..16015d12db 100644 --- a/ui/src/app/edge/downlinks/edge-downlinks-row.directive.js +++ b/ui/src/app/edge/downlinks/edge-downlinks-row.directive.js @@ -105,11 +105,11 @@ export default function EdgeDownlinksRowDirective($compile, $templateCache, $mdD scope.updateStatus = function(downlinkCreatedTime) { var status; if (downlinkCreatedTime < scope.queueStartTs) { - status = $translate.instant(types.getEdgeStatus.DEPLOYED.name); - scope.statusColor = types.getEdgeStatus.DEPLOYED.color; + status = $translate.instant(types.edgeEventStatus.DEPLOYED.name); + scope.statusColor = types.edgeEventStatus.DEPLOYED.color; } else { - status = $translate.instant(types.getEdgeStatus.PENDING.name); - scope.statusColor = types.getEdgeStatus.PENDING.color; + status = $translate.instant(types.edgeEventStatus.PENDING.name); + scope.statusColor = types.edgeEventStatus.PENDING.color; } return status; } From 143e9cb877fb6f6e5b885184643b47d2c48e5905 Mon Sep 17 00:00:00 2001 From: ShvaykaD Date: Thu, 14 Jan 2021 10:21:51 +0200 Subject: [PATCH 13/14] added new methods to JacksonUtil & replaced objectMapper from AuditLogServiceImpl --- .../server/dao/audit/AuditLogServiceImpl.java | 16 +++++++--------- .../server/dao/util/mapping/JacksonUtil.java | 9 +++++++++ 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java index 0d1c708f68..6c8e2a25ff 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java @@ -17,7 +17,6 @@ package org.thingsboard.server.dao.audit; import com.datastax.driver.core.utils.UUIDs; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.collect.Lists; @@ -48,6 +47,7 @@ import org.thingsboard.server.dao.audit.sink.AuditLogSink; import org.thingsboard.server.dao.entity.EntityService; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.service.DataValidator; +import org.thingsboard.server.dao.util.mapping.JacksonUtil; import java.io.PrintWriter; import java.io.StringWriter; @@ -61,8 +61,6 @@ import static org.thingsboard.server.dao.service.Validator.validateId; @ConditionalOnProperty(prefix = "audit-log", value = "enabled", havingValue = "true") public class AuditLogServiceImpl implements AuditLogService { - private static final ObjectMapper objectMapper = new ObjectMapper(); - private static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; private static final int INSERTS_PER_ENTRY = 3; @@ -159,7 +157,7 @@ public class AuditLogServiceImpl implements AuditLogService { private JsonNode constructActionData(I entityId, E entity, ActionType actionType, Object... additionalInfo) { - ObjectNode actionData = objectMapper.createObjectNode(); + ObjectNode actionData = JacksonUtil.newObjectNode(); switch (actionType) { case ADDED: case UPDATED: @@ -168,7 +166,7 @@ public class AuditLogServiceImpl implements AuditLogService { case RELATIONS_DELETED: case ASSIGNED_TO_TENANT: if (entity != null) { - ObjectNode entityNode = objectMapper.valueToTree(entity); + ObjectNode entityNode = (ObjectNode) JacksonUtil.valueToTree(entity); if (entityId.getEntityType() == EntityType.DASHBOARD) { entityNode.put("configuration", ""); } @@ -177,7 +175,7 @@ public class AuditLogServiceImpl implements AuditLogService { if (entityId.getEntityType() == EntityType.RULE_CHAIN) { RuleChainMetaData ruleChainMetaData = extractParameter(RuleChainMetaData.class, additionalInfo); if (ruleChainMetaData != null) { - ObjectNode ruleChainMetaDataNode = objectMapper.valueToTree(ruleChainMetaData); + ObjectNode ruleChainMetaDataNode = (ObjectNode) JacksonUtil.valueToTree(ruleChainMetaData); actionData.set("metadata", ruleChainMetaDataNode); } } @@ -194,7 +192,7 @@ public class AuditLogServiceImpl implements AuditLogService { String scope = extractParameter(String.class, 0, additionalInfo); List attributes = extractParameter(List.class, 1, additionalInfo); actionData.put("scope", scope); - ObjectNode attrsNode = objectMapper.createObjectNode(); + ObjectNode attrsNode = JacksonUtil.newObjectNode(); if (attributes != null) { for (AttributeKvEntry attr : attributes) { attrsNode.put(attr.getKey(), attr.getValueAsString()); @@ -225,7 +223,7 @@ public class AuditLogServiceImpl implements AuditLogService { case CREDENTIALS_UPDATED: actionData.put("entityId", entityId.toString()); DeviceCredentials deviceCredentials = extractParameter(DeviceCredentials.class, additionalInfo); - actionData.set("credentials", objectMapper.valueToTree(deviceCredentials)); + actionData.set("credentials", JacksonUtil.valueToTree(deviceCredentials)); break; case ASSIGNED_TO_CUSTOMER: strEntityId = extractParameter(String.class, 0, additionalInfo); @@ -246,7 +244,7 @@ public class AuditLogServiceImpl implements AuditLogService { case RELATION_ADD_OR_UPDATE: case RELATION_DELETED: EntityRelation relation = extractParameter(EntityRelation.class, 0, additionalInfo); - actionData.set("relation", objectMapper.valueToTree(relation)); + actionData.set("relation", JacksonUtil.valueToTree(relation)); break; case LOGIN: case LOGOUT: diff --git a/dao/src/main/java/org/thingsboard/server/dao/util/mapping/JacksonUtil.java b/dao/src/main/java/org/thingsboard/server/dao/util/mapping/JacksonUtil.java index d654e85d5c..fd40d71189 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/util/mapping/JacksonUtil.java +++ b/dao/src/main/java/org/thingsboard/server/dao/util/mapping/JacksonUtil.java @@ -18,6 +18,7 @@ package org.thingsboard.server.dao.util.mapping; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; import java.io.IOException; @@ -66,7 +67,15 @@ public class JacksonUtil { } } + public static ObjectNode newObjectNode(){ + return OBJECT_MAPPER.createObjectNode(); + } + public static T clone(T value) { return fromString(toString(value), (Class) value.getClass()); } + + public static JsonNode valueToTree(T value) { + return OBJECT_MAPPER.valueToTree(value); + } } From 6682d66be3397d74dd64ac6aed0d660072a16f61 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Sun, 17 Jan 2021 00:47:02 +0200 Subject: [PATCH 14/14] Make device private, if edge is public --- .../server/controller/EdgeController.java | 3 +++ .../edge/rpc/processor/DeviceProcessor.java | 18 ++++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) 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 e31e711e5c..15d905bfed 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EdgeController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EdgeController.java @@ -254,6 +254,9 @@ public class EdgeController extends BaseController { Customer publicCustomer = customerService.findOrCreatePublicCustomer(edge.getTenantId()); Edge savedEdge = checkNotNull(edgeService.assignEdgeToCustomer(getCurrentUser().getTenantId(), edgeId, publicCustomer.getId())); + tbClusterService.onEntityStateChange(getTenantId(), edgeId, + ComponentLifecycleEvent.UPDATED); + logEntityAction(edgeId, savedEdge, savedEdge.getCustomerId(), ActionType.ASSIGNED_TO_CUSTOMER, null, strEdgeId, publicCustomer.getId().toString(), publicCustomer.getName()); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProcessor.java index 9aab6ec124..8d536d5076 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/DeviceProcessor.java @@ -25,9 +25,9 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.RandomStringUtils; import org.apache.commons.lang.StringUtils; import org.checkerframework.checker.nullness.qual.Nullable; -import org.springframework.security.core.parameters.P; import org.springframework.stereotype.Component; import org.thingsboard.rule.engine.api.RpcError; +import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.edge.Edge; @@ -45,6 +45,7 @@ import org.thingsboard.server.common.data.security.DeviceCredentialsType; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgDataType; import org.thingsboard.server.common.msg.TbMsgMetaData; +import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.util.mapping.JacksonUtil; import org.thingsboard.server.gen.edge.DeviceCredentialsUpdateMsg; import org.thingsboard.server.gen.edge.DeviceRpcCallMsg; @@ -179,7 +180,8 @@ public class DeviceProcessor extends BaseProcessor { log.debug("[{}] Creating device entity [{}] from edge [{}]", tenantId, deviceUpdateMsg, edge.getName()); device = new Device(); device.setTenantId(edge.getTenantId()); - device.setCustomerId(edge.getCustomerId()); + // make device private, if edge is public + device.setCustomerId(getCustomerId(edge)); device.setName(deviceName); device.setType(deviceUpdateMsg.getType()); device.setLabel(deviceUpdateMsg.getLabel()); @@ -194,6 +196,18 @@ public class DeviceProcessor extends BaseProcessor { return device; } + private CustomerId getCustomerId(Edge edge) { + if (edge.getCustomerId() == null || edge.getCustomerId().getId().equals(ModelConstants.NULL_UUID)) { + return edge.getCustomerId(); + } + Customer publicCustomer = customerService.findOrCreatePublicCustomer(edge.getTenantId()); + if (publicCustomer.getId().equals(edge.getCustomerId())) { + return null; + } else { + return edge.getCustomerId(); + } + } + private void createRelationFromEdge(TenantId tenantId, EdgeId edgeId, EntityId entityId) { EntityRelation relation = new EntityRelation(); relation.setFrom(edgeId);