From c9717f4d1ddee68a572471202f08c5e5250d81d8 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Mon, 2 Apr 2018 20:07:20 +0300 Subject: [PATCH] Enrichment Rule nodes config UI --- .../rule/engine/data/RelationsQuery.java | 31 +++++++++++++++++++ .../engine/metadata/TbGetAttributesNode.java | 4 ++- .../metadata/TbGetCustomerAttributeNode.java | 4 ++- .../TbGetRelatedAttrNodeConfiguration.java | 17 +++++++--- .../metadata/TbGetRelatedAttributeNode.java | 7 +++-- .../metadata/TbGetTenantAttributeNode.java | 4 ++- .../transform/TbChangeOriginatorNode.java | 8 ++--- .../TbChangeOriginatorNodeConfiguration.java | 18 ++++++++--- .../EntitiesRelatedEntityIdAsyncLoader.java | 25 ++++++++++----- .../static/rulenode/rulenode-core-config.css | 2 +- .../static/rulenode/rulenode-core-config.js | 2 +- .../relation/relation-filters.directive.js | 1 + 12 files changed, 95 insertions(+), 28 deletions(-) create mode 100644 rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/data/RelationsQuery.java diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/data/RelationsQuery.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/data/RelationsQuery.java new file mode 100644 index 0000000000..1d944ec327 --- /dev/null +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/data/RelationsQuery.java @@ -0,0 +1,31 @@ +/** + * Copyright © 2016-2018 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. + */ +package org.thingsboard.rule.engine.data; + +import lombok.Data; +import org.thingsboard.server.common.data.relation.EntitySearchDirection; +import org.thingsboard.server.common.data.relation.EntityTypeFilter; + +import java.util.List; + +@Data +public class RelationsQuery { + + private EntitySearchDirection direction; + private int maxLevel = 1; + private List filters; + +} diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java index 7bf70f4ed9..fc65e43bf5 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java @@ -43,7 +43,9 @@ import static org.thingsboard.server.common.data.DataConstants.*; nodeDetails = "If Attributes enrichment configured, CLIENT/SHARED/SERVER attributes are added into Message metadata " + "with specific prefix: cs/shared/ss. To access those attributes in other nodes this template can be used " + "metadata.cs.temperature or metadata.shared.limit " + - "If Latest Telemetry enrichment configured, latest telemetry added into metadata without prefix.") + "If Latest Telemetry enrichment configured, latest telemetry added into metadata without prefix.", + uiResources = {"static/rulenode/rulenode-core-config.js"}, + configDirective = "tbEnrichmentNodeOriginatorAttributesConfig") public class TbGetAttributesNode implements TbNode { private TbGetAttributesNodeConfiguration config; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java index c59a65e27d..b092badaf4 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNode.java @@ -30,7 +30,9 @@ import org.thingsboard.server.common.data.plugin.ComponentType; nodeDescription = "Add Originators Customer Attributes or Latest Telemetry into Message Metadata", nodeDetails = "If Attributes enrichment configured, server scope attributes are added into Message metadata. " + "To access those attributes in other nodes this template can be used " + - "metadata.temperature. If Latest Telemetry enrichment configured, latest telemetry added into metadata") + "metadata.temperature. If Latest Telemetry enrichment configured, latest telemetry added into metadata", + uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"}, + configDirective = "tbEnrichmentNodeCustomerAttributesConfig") public class TbGetCustomerAttributeNode extends TbEntityGetAttrNode { @Override diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttrNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttrNodeConfiguration.java index 82119926af..dccd87879a 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttrNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttrNodeConfiguration.java @@ -16,18 +16,19 @@ package org.thingsboard.rule.engine.metadata; import lombok.Data; -import org.thingsboard.rule.engine.api.NodeConfiguration; +import org.thingsboard.rule.engine.data.RelationsQuery; import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntitySearchDirection; +import org.thingsboard.server.common.data.relation.EntityTypeFilter; +import java.util.Collections; import java.util.HashMap; import java.util.Map; @Data public class TbGetRelatedAttrNodeConfiguration extends TbGetEntityAttrNodeConfiguration { - private String relationType; - private EntitySearchDirection direction; + private RelationsQuery relationsQuery; @Override public TbGetRelatedAttrNodeConfiguration defaultConfiguration() { @@ -36,8 +37,14 @@ public class TbGetRelatedAttrNodeConfiguration extends TbGetEntityAttrNodeConfig attrMapping.putIfAbsent("temperature", "tempo"); configuration.setAttrMapping(attrMapping); configuration.setTelemetry(true); - configuration.setRelationType(EntityRelation.CONTAINS_TYPE); - configuration.setDirection(EntitySearchDirection.FROM); + + RelationsQuery relationsQuery = new RelationsQuery(); + relationsQuery.setDirection(EntitySearchDirection.FROM); + relationsQuery.setMaxLevel(1); + EntityTypeFilter entityTypeFilter = new EntityTypeFilter(EntityRelation.CONTAINS_TYPE, Collections.emptyList()); + relationsQuery.setFilters(Collections.singletonList(entityTypeFilter)); + configuration.setRelationsQuery(relationsQuery); + return configuration; } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java index 603746ef29..8f65c31aa4 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNode.java @@ -32,7 +32,10 @@ import org.thingsboard.server.common.data.plugin.ComponentType; "If multiple Related Entities are found, only first Entity is used for attributes enrichment, other entities are discarded. " + "If Attributes enrichment configured, server scope attributes are added into Message metadata. " + "To access those attributes in other nodes this template can be used " + - "metadata.temperature. If Latest Telemetry enrichment configured, latest telemetry added into metadata") + "metadata.temperature. If Latest Telemetry enrichment configured, latest telemetry added into metadata", + uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"}, + configDirective = "tbEnrichmentNodeRelatedAttributesConfig") + public class TbGetRelatedAttributeNode extends TbEntityGetAttrNode { private TbGetRelatedAttrNodeConfiguration config; @@ -45,6 +48,6 @@ public class TbGetRelatedAttributeNode extends TbEntityGetAttrNode { @Override protected ListenableFuture findEntityAsync(TbContext ctx, EntityId originator) { - return EntitiesRelatedEntityIdAsyncLoader.findEntityAsync(ctx, originator, config.getDirection(), config.getRelationType()); + return EntitiesRelatedEntityIdAsyncLoader.findEntityAsync(ctx, originator, config.getRelationsQuery()); } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java index 3165385587..f0d28d3290 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNode.java @@ -32,7 +32,9 @@ import org.thingsboard.server.common.data.plugin.ComponentType; nodeDescription = "Add Originators Tenant Attributes or Latest Telemetry into Message Metadata", nodeDetails = "If Attributes enrichment configured, server scope attributes are added into Message metadata. " + "To access those attributes in other nodes this template can be used " + - "metadata.temperature. If Latest Telemetry enrichment configured, latest telemetry added into metadata") + "metadata.temperature. If Latest Telemetry enrichment configured, latest telemetry added into metadata", + uiResources = {"static/rulenode/rulenode-core-config.js", "static/rulenode/rulenode-core-config.css"}, + configDirective = "tbEnrichmentNodeTenantAttributesConfig") public class TbGetTenantAttributeNode extends TbEntityGetAttrNode { @Override diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNode.java index cf761f295f..6f52fb95fc 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNode.java @@ -68,7 +68,7 @@ public class TbChangeOriginatorNode extends TbAbstractTransformNode { case TENANT_SOURCE: return EntitiesTenantIdAsyncLoader.findEntityIdAsync(ctx, original); case RELATED_SOURCE: - return EntitiesRelatedEntityIdAsyncLoader.findEntityAsync(ctx, original, config.getDirection(), config.getRelationType()); + return EntitiesRelatedEntityIdAsyncLoader.findEntityAsync(ctx, original, config.getRelationsQuery()); default: return Futures.immediateFailedFuture(new IllegalStateException("Unexpected originator source " + config.getOriginatorSource())); } @@ -82,9 +82,9 @@ public class TbChangeOriginatorNode extends TbAbstractTransformNode { } if (conf.getOriginatorSource().equals(RELATED_SOURCE)) { - if (conf.getDirection() == null || StringUtils.isBlank(conf.getRelationType())) { - log.error("Related source for TbChangeOriginatorNode should have direction and relationType. Actual [{}] [{}]", - conf.getDirection(), conf.getRelationType()); + if (conf.getRelationsQuery() == null) { + log.error("Related source for TbChangeOriginatorNode should have relations query. Actual [{}]", + conf.getRelationsQuery()); throw new IllegalArgumentException("Wrong config for RElated Source in TbChangeOriginatorNode" + conf.getOriginatorSource()); } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNodeConfiguration.java index 3370408231..7cd77bfc59 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNodeConfiguration.java @@ -17,22 +17,32 @@ package org.thingsboard.rule.engine.transform; import lombok.Data; import org.thingsboard.rule.engine.api.NodeConfiguration; +import org.thingsboard.rule.engine.data.RelationsQuery; import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntitySearchDirection; +import org.thingsboard.server.common.data.relation.EntityTypeFilter; + +import java.util.Collections; @Data public class TbChangeOriginatorNodeConfiguration extends TbTransformNodeConfiguration implements NodeConfiguration { private String originatorSource; - private EntitySearchDirection direction; - private String relationType; + + private RelationsQuery relationsQuery; @Override public TbChangeOriginatorNodeConfiguration defaultConfiguration() { TbChangeOriginatorNodeConfiguration configuration = new TbChangeOriginatorNodeConfiguration(); configuration.setOriginatorSource(TbChangeOriginatorNode.CUSTOMER_SOURCE); - configuration.setDirection(EntitySearchDirection.FROM); - configuration.setRelationType(EntityRelation.CONTAINS_TYPE); + + RelationsQuery relationsQuery = new RelationsQuery(); + relationsQuery.setDirection(EntitySearchDirection.FROM); + relationsQuery.setMaxLevel(1); + EntityTypeFilter entityTypeFilter = new EntityTypeFilter(EntityRelation.CONTAINS_TYPE, Collections.emptyList()); + relationsQuery.setFilters(Collections.singletonList(entityTypeFilter)); + configuration.setRelationsQuery(relationsQuery); + configuration.setStartNewChain(false); return configuration; } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesRelatedEntityIdAsyncLoader.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesRelatedEntityIdAsyncLoader.java index ac69c5dd59..08ce38e591 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesRelatedEntityIdAsyncLoader.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesRelatedEntityIdAsyncLoader.java @@ -20,32 +20,41 @@ import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import org.apache.commons.collections.CollectionUtils; import org.thingsboard.rule.engine.api.TbContext; +import org.thingsboard.rule.engine.data.RelationsQuery; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.relation.EntityRelation; +import org.thingsboard.server.common.data.relation.EntityRelationsQuery; import org.thingsboard.server.common.data.relation.EntitySearchDirection; +import org.thingsboard.server.common.data.relation.RelationsSearchParameters; import org.thingsboard.server.dao.relation.RelationService; import java.util.List; -import static org.thingsboard.server.common.data.relation.RelationTypeGroup.COMMON; - public class EntitiesRelatedEntityIdAsyncLoader { public static ListenableFuture findEntityAsync(TbContext ctx, EntityId originator, - EntitySearchDirection direction, String relationType) { + RelationsQuery relationsQuery) { RelationService relationService = ctx.getRelationService(); - if (direction == EntitySearchDirection.FROM) { - ListenableFuture> asyncRelation = relationService.findByFromAndTypeAsync(originator, relationType, COMMON); + EntityRelationsQuery query = buildQuery(originator, relationsQuery); + ListenableFuture> asyncRelation = relationService.findByQuery(query); + if (relationsQuery.getDirection() == EntitySearchDirection.FROM) { return Futures.transform(asyncRelation, (AsyncFunction, EntityId>) r -> CollectionUtils.isNotEmpty(r) ? Futures.immediateFuture(r.get(0).getTo()) : Futures.immediateFailedFuture(new IllegalStateException("Relation not found"))); - } else if (direction == EntitySearchDirection.TO) { - ListenableFuture> asyncRelation = relationService.findByToAndTypeAsync(originator, relationType, COMMON); + } else if (relationsQuery.getDirection() == EntitySearchDirection.TO) { return Futures.transform(asyncRelation, (AsyncFunction, EntityId>) r -> CollectionUtils.isNotEmpty(r) ? Futures.immediateFuture(r.get(0).getFrom()) : Futures.immediateFailedFuture(new IllegalStateException("Relation not found"))); } - return Futures.immediateFailedFuture(new IllegalStateException("Unknown direction")); } + + private static EntityRelationsQuery buildQuery(EntityId originator, RelationsQuery relationsQuery) { + EntityRelationsQuery query = new EntityRelationsQuery(); + RelationsSearchParameters parameters = new RelationsSearchParameters(originator, + relationsQuery.getDirection(), relationsQuery.getMaxLevel()); + query.setParameters(parameters); + query.setFilters(relationsQuery.getFilters()); + return query; + } } diff --git a/rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.css b/rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.css index a6103c1d56..c91d7da72d 100644 --- a/rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.css +++ b/rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.css @@ -1,2 +1,2 @@ -.tb-message-type-autocomplete .tb-not-found{display:block;line-height:1.5;height:48px}.tb-message-type-autocomplete .tb-not-found .tb-no-entries{line-height:48px}.tb-message-type-autocomplete li{height:auto!important;white-space:normal!important} +.tb-message-type-autocomplete .tb-not-found{display:block;line-height:1.5;height:48px}.tb-message-type-autocomplete .tb-not-found .tb-no-entries{line-height:48px}.tb-message-type-autocomplete li{height:auto!important;white-space:normal!important}.tb-kv-map-config .header{padding-left:5px;padding-right:5px;padding-bottom:5px}.tb-kv-map-config .header .cell{padding-left:5px;padding-right:5px;color:rgba(0,0,0,.54);font-size:12px;font-weight:700;white-space:nowrap}.tb-kv-map-config .body{padding-left:5px;padding-right:5px;padding-bottom:20px;max-height:300px;overflow:auto}.tb-kv-map-config .body .row{padding-top:5px;max-height:40px}.tb-kv-map-config .body .cell{padding-left:5px;padding-right:5px}.tb-kv-map-config .body md-input-container.cell{margin:0;max-height:40px}.tb-kv-map-config .body .md-button{margin:0} /*# sourceMappingURL=rulenode-core-config.css.map*/ \ No newline at end of file diff --git a/rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.js b/rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.js index 3fe859d90f..b2d2af9088 100644 --- a/rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.js +++ b/rule-engine/rule-engine-components/src/main/resources/public/static/rulenode/rulenode-core-config.js @@ -1,2 +1,2 @@ -!function(e){function t(s){if(a[s])return a[s].exports;var n=a[s]={exports:{},id:s,loaded:!1};return e[s].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var a={};return t.m=e,t.c=a,t.p="/static/",t(0)}([function(e,t,a){e.exports=a(8)},function(e,t){},function(e,t){e.exports='
{{item}}
tb.rulenode.no-message-types-found
tb.rulenode.no-message-type-matching tb.rulenode.create-new-message-type
{{$chip.name}}
'},function(e,t){e.exports="
"},function(e,t){e.exports="
"},function(e,t,a){"use strict";function s(e){return e&&e.__esModule?e:{default:e}}function n(e,t,a){var s=function(s,n,r,l){function u(){if(l.$viewValue){for(var e=[],t=0;t {{ 'tb.rulenode.latest-telemetry' | translate }} "},function(e,t){e.exports='
'},function(e,t){e.exports="
{{ 'tb.rulenode.latest-telemetry' | translate }}
"},3,function(e,t){e.exports='
{{item}}
tb.rulenode.no-message-types-found
tb.rulenode.no-message-type-matching tb.rulenode.create-new-message-type
{{$chip.name}}
'},function(e,t){e.exports="
"},function(e,t){e.exports="
"},function(e,t){e.exports='
{{ keyText }} {{ valText }}  
{{keyRequiredText}}
{{valRequiredText}}
{{ \'tb.key-val.remove-entry\' | translate }} close
{{ \'tb.key-val.add-entry\' | translate }} add {{ \'action.add\' | translate }}
'},function(e,t){e.exports="
{{ ('relation.search-direction.' + direction) | translate}}
relation.relation-filters
"},function(e,t,a){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function n(e){var t=function(t,a,r,n){var i=l.default;a.html(i),t.$watch("configuration",function(e,a){angular.equals(e,a)||n.$setViewValue(t.configuration)}),n.$render=function(){t.configuration=n.$viewValue},e(a.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{},link:t}}n.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=n;var i=a(3),l=r(i)},function(e,t,a){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var n=a(14),i=r(n),l=a(15),s=r(l),o=a(12),u=r(o),d=a(16),c=r(d);t.default=angular.module("thingsboard.ruleChain.config.enrichment",[]).directive("tbEnrichmentNodeOriginatorAttributesConfig",i.default).directive("tbEnrichmentNodeRelatedAttributesConfig",s.default).directive("tbEnrichmentNodeCustomerAttributesConfig",u.default).directive("tbEnrichmentNodeTenantAttributesConfig",c.default).name},function(e,t,a){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function n(e,t){var a=function(a,r,n,i){var s=l.default;r.html(s);var o=186;a.separatorKeys=[t.KEY_CODE.ENTER,t.KEY_CODE.COMMA,o],a.$watch("configuration",function(e,t){angular.equals(e,t)||i.$setViewValue(a.configuration)}),i.$render=function(){a.configuration=i.$viewValue},e(r.contents())(a)};return{restrict:"E",require:"^ngModel",scope:{},link:a}}n.$inject=["$compile","$mdConstant"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=n;var i=a(4),l=r(i)},function(e,t,a){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function n(e){var t=function(t,a,r,n){var i=l.default;a.html(i),t.$watch("configuration",function(e,a){angular.equals(e,a)||n.$setViewValue(t.configuration)}),n.$render=function(){t.configuration=n.$viewValue},e(a.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{},link:t}}n.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=n;var i=a(5),l=r(i)},function(e,t,a){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function n(e){var t=function(t,a,r,n){var i=l.default;a.html(i),t.$watch("configuration",function(e,a){angular.equals(e,a)||n.$setViewValue(t.configuration)}),n.$render=function(){t.configuration=n.$viewValue},e(a.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{},link:t}}n.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=n;var i=a(6),l=r(i)},function(e,t,a){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var n=a(19),i=r(n),l=a(18),s=r(l),o=a(20),u=r(o);t.default=angular.module("thingsboard.ruleChain.config.filter",[]).directive("tbFilterNodeScriptConfig",i.default).directive("tbFilterNodeMessageTypeConfig",s.default).directive("tbFilterNodeSwitchConfig",u.default).name},function(e,t,a){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function n(e,t,a){var r=function(r,n,i,s){function o(){if(s.$viewValue){for(var e=[],t=0;t-1&&t.kvList.splice(e,1)}function s(){t.kvList||(t.kvList=[]),t.kvList.push({key:"",value:""})}function o(){var e={};t.kvList.forEach(function(t){t.key&&(e[t.key]=t.value)}),n.$setViewValue(e),u()}function u(){var e=!0;t.required&&!t.kvList.length&&(e=!1),n.$setValidity("kvMap",e)}var d=l.default;a.html(d),t.ngModelCtrl=n,t.removeKeyVal=i,t.addKeyVal=s,t.kvList=[],t.$watch("query",function(e,a){angular.equals(e,a)||n.$setViewValue(t.query)}),n.$render=function(){if(n.$viewValue){var e=n.$viewValue;t.kvList.length=0;for(var a in e)t.kvList.push({key:a,value:e[a]})}t.$watch("kvList",function(e,t){angular.equals(e,t)||o()},!0),u()},e(a.contents())(t)};return{restrict:"E",require:"^ngModel",scope:{required:"=ngRequired",disabled:"=ngDisabled",requiredText:"=",keyText:"=",keyRequiredText:"=",valText:"=",valRequiredText:"="},link:t}}n.$inject=["$compile"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=n;var i=a(10),l=r(i);a(2)},function(e,t,a){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function n(e,t){var a=function(a,r,n,i){var s=l.default;r.html(s),a.types=t,a.$watch("query",function(e,t){angular.equals(e,t)||i.$setViewValue(a.query)}),i.$render=function(){a.query=i.$viewValue},e(r.contents())(a)};return{restrict:"E",require:"^ngModel",scope:{},link:a}}n.$inject=["$compile","types"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=n;var i=a(11),l=r(i)},function(e,t,a){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var n=a(26),i=r(n),l=a(17),s=r(l),o=a(13),u=r(o),d=a(22),c=r(d),m=a(21),f=r(m),p=a(25),g=r(p);t.default=angular.module("thingsboard.ruleChain.config",[i.default,s.default,u.default]).directive("tbRelationsQueryConfig",c.default).directive("tbKvMapConfig",f.default).config(g.default).name},function(e,t){"use strict";function a(e){var t={tb:{rulenode:{filter:"Filter",switch:"Switch","message-type":"Message type","message-types-filter":"Message types filter","no-message-types-found":"No message types found","no-message-type-matching":"'{{messageType}}' not found.","create-new-message-type":"Create a new one!","message-types-required":"Message types are required.","client-attributes":"Client attributes","shared-attributes":"Shared attributes","server-attributes":"Server attributes","latest-timeseries":"Latest timeseries","relations-query":"Relations query","max-relation-level":"Max relation level","unlimited-level":"Unlimited level","latest-telemetry":"Latest telemetry","attr-mapping":"Attributes mapping","source-attribute":"Source attribute","source-attribute-required":"Source attribute is required.","source-telemetry":"Source telemetry","source-telemetry-required":"Source telemetry is required.","target-attribute":"Target attribute","target-attribute-required":"Target attribute is required.","attr-mapping-required":"At least one attribute mapping should be specified."},"key-val":{key:"Key",value:"Value","remove-entry":"Remove entry","add-entry":"Add entry"}}};angular.merge(e.en_US,t)}Object.defineProperty(t,"__esModule",{value:!0}),t.default=a},function(e,t,a){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function n(e,t){(0,l.default)(t);for(var a in t){var r=t[a];e.translations(a,r)}}n.$inject=["$translateProvider","locales"],Object.defineProperty(t,"__esModule",{value:!0}),t.default=n;var i=a(24),l=r(i)},function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=angular.module("thingsboard.ruleChain.config.types",[]).constant("ruleNodeTypes",{messageType:{POST_ATTRIBUTES:{name:"Post attributes",value:"POST_ATTRIBUTES"},POST_TELEMETRY:{name:"Post telemetry",value:"POST_TELEMETRY"},RPC_REQUEST:{name:"RPC Request",value:"RPC_REQUEST"}}}).name}])); //# sourceMappingURL=rulenode-core-config.js.map \ No newline at end of file diff --git a/ui/src/app/entity/relation/relation-filters.directive.js b/ui/src/app/entity/relation/relation-filters.directive.js index 00d3b26035..9ab66cac72 100644 --- a/ui/src/app/entity/relation/relation-filters.directive.js +++ b/ui/src/app/entity/relation/relation-filters.directive.js @@ -46,6 +46,7 @@ export default function RelationFilters($compile, $templateCache) { ngModelCtrl.$render = function () { if (ngModelCtrl.$viewValue) { var value = ngModelCtrl.$viewValue; + scope.relationFilters.length = 0; value.forEach(function (filter) { scope.relationFilters.push(filter); });